Module 8: Capstone Project — Migrating a Real Legacy Project
Onboarding and Architecture Analysis of the Legacy Project
Onboarding and Architecture Analysis of the Legacy Project
Capsule description
With the assessment complete (capsule 01), you have an initial snapshot of the legacy project: size, stack, priority tech debt, health score. That tells you what to fix. This capsule teaches you to understand the project in depth — the where and the how — before touching anything.
You're going to apply the Phase 1 techniques (Modules 1-3) to the project you assessed: systematic onboarding with the 5 questions (M1), deep exploration with the Explore subagent (M2), and generation of an architecture map with dependency maps + flow analysis + pattern identification (M3). You already practiced each technique in isolation — here you orchestrate them into a single integrated document.
The output of this capsule is a complete Architecture Analysis Document. It's the direct input for capsule 03 (migration planning): the anti-patterns inform what to refactor, the dependency maps inform the order, and the flow traces inform where to put regression tests.
By the end, you'll be able to produce a professional Architecture Analysis by applying M1-M3 in sequence, identify the priority change points with evidence, and deliver a document a senior architect would recognize as rigorous.
Why Onboarding and Architecture GO Before Any Change
It's tempting to start refactoring immediately — "I already read the assessment, I already know what needs to change". But the assessment is a 30K-foot view. To make migration decisions, you need the 100-foot view.
The ASSESSMENT (capsule 01) tells you:
→ "There's logic in route handlers" (general problem)
→ "No tests" (coverage state)
→ "Dead code" (estimated amount)
The ARCHITECTURE ANALYSIS (this capsule) tells you:
→ "There are 23 handlers with business logic. The 5 most complex are:
/payments, /orders, /reports, /auth, /admin — and they share 4 helper
functions that should go to a service layer"
→ "The /payments flow touches 8 files in this order: ...
Tests should cover those 8 points"
→ "The 'dead' callbacks in notifications.py are registered as
dynamic handlers in config.py — they're NOT dead"
The difference is actionable vs general. Without architecture analysis, you refactor with the assessment view — guessing where to place the scalpel. With architecture analysis, you have exact coordinates.
Step 1: Systematic Onboarding (M1)
The 5 initial questions
We apply the 5 questions from Module 1 to the specific codebase:
> "Apply systematic onboarding to this project.
For each of these 5 questions, give the answer with
references to specific files and line numbers
where applicable:
1. What's the directory structure and what does each folder do?
2. What are the entry points (main.py, app.py, wsgi.py, etc.)?
3. How does the data flow from the input to the response
(at least for the main flow)?
4. What architectural patterns are used (MVC, service layer,
repository, etc.)? Are they consistent?
5. Where's the most visible tech debt? Give the 3-5 most
representative examples with file and line."
Document findings: Onboarding Doc
Produce a brief onboarding doc (1-2 pages) that gets incorporated into the final Architecture Analysis Document:
## Onboarding Summary
### Directory Structure
- `app/` — Flask application code
- `routes/` — 23 route handlers (with mixed logic)
- `models/` — 12 SQLAlchemy models
- `utils/` — helper functions with no clear organization
- `tests/` — EMPTY DIRECTORY ⚠️
- `requirements.txt` — 14 dependencies, 2 deprecated
### Entry Points
- `app.py` — Flask factory, registers blueprints
- `wsgi.py` — gunicorn entry point for deployment
- `manage.py` — CLI commands for administrative tasks
### Main Data Flow (Buying a product)
1. POST `/api/orders` → `routes/orders.py:create_order()`
2. Validates payload → `utils/validators.py:validate_order_payload()`
3. Creates Order → `models/order.py:Order.__init__()`
4. Charges → `routes/orders.py:_charge_card()` (inline logic)
5. Notifies → `utils/notifications.py:send_order_email()`
6. Returns response → `routes/orders.py:create_order()` (200 or 400)
### Patterns Observed
- ❌ NO service layer (logic in handlers)
- ✅ Implicit repository via SQLAlchemy ORM
- ❌ Scattered validation (validators.py + inline + ad-hoc Pydantic-ish)
- ❌ No central error handling
### Visible Tech Debt (top 3)
1. `routes/orders.py:50-150` — 100 lines of inline charging logic
2. `utils/notifications.py:1-200` — similar duplicated functions for email/SMS/push
3. `routes/admin.py:230-380` — god handler with 7 distinct responsibilities
Step 2: Exploration with Explore (M2)
Once you have the onboarding overview, dig deeper with Explore for specific questions the general onboarding doesn't answer.
Deep investigation with Explore
> "Use Explore (read-only) to investigate 4 specific questions:
1. How is authentication handled end-to-end?
Trace from the incoming request → user identification → authorization.
2. What dependencies does each module have?
For each file in app/, list what it imports and what imports it.
3. Is there duplicated logic between modules?
Look for functions with a similar body (>70% similarity) in different files.
4. Where are the possible security problems?
SQL injection candidates, hardcoded secrets, missing validation,
error handling that leaks info."
Apply the three exploration patterns from Module 2
| Pattern | When to use it in this project |
|---|---|
| Top-Down | To understand the general structure first, before zooming in |
| Feature-Tracing | To map the flow of the main features (orders, payments, auth) |
| Dependency-Following | To understand which modules are coupled and which are independent |
Explore's output gets incorporated into the Architecture Analysis Document as deep onboarding context.
Step 3: Architecture Map (M3)
With onboarding + deep exploration in hand, you generate the 3 components of the Module 3 Architecture Map.
Component 1: Dependency Map
> "Generate a dependency map of the project showing the main modules
and their dependencies. Mermaid format. Mark:
- Modules with many incoming dependencies (high risk when modifying)
- Modules with many outgoing dependencies (service layer candidates)
- Circular dependencies (critical anti-pattern)"
Example of expected output:
graph LR
routes/orders --> utils/validators
routes/orders --> models/order
routes/orders --> utils/notifications
routes/admin --> models/order
routes/admin --> utils/notifications
utils/notifications --> models/user
models/order --> models/user
style routes/orders fill:#f99
style utils/notifications fill:#ff9
(routes/orders in red = high fan-out, a refactoring candidate; utils/notifications in yellow = high reuse, a service layer candidate.)
Component 2: Flow Analysis
> "Trace the complete flow of the project's most important endpoint
(typically: the one that touches money or the most critical data).
Step-by-step with files and functions. Identify:
- Each function involved
- The points where business logic is mixed with I/O
- The points where a regression test should go"
Example:
## Flow Analysis: POST /api/orders
| Step | File | Function | Type | Test Point |
|------|------|----------|------|------------|
| 1 | routes/orders.py | create_order | Handler + Mixed logic | ✅ Yes (input/output) |
| 2 | utils/validators.py | validate_order_payload | Pure validation | ✅ Yes (unit) |
| 3 | models/order.py | Order.__init__ | Domain logic | ✅ Yes (unit) |
| 4 | routes/orders.py | _charge_card | Inline payment logic | ✅ Yes (CRITICAL — touches money) |
| 5 | external | Stripe API | External I/O | Mock mandatory |
| 6 | utils/notifications.py | send_order_email | External I/O | Mock |
| 7 | routes/orders.py | (return) | Response building | ✅ Yes (integration) |
**Change points identified:**
- Step 1: extract create_order to a service layer
- Step 4: move _charge_card to payment_service
- Step 6: abstract the notification interface
Component 3: Pattern + Anti-Pattern Analysis
> "Identify architectural patterns (if any) and anti-patterns.
List each one with:
- Location (file:line)
- Severity (high/medium/low)
- Suggested action
- Connection with the migration (address now? document as
remaining debt?)"
Example:
## Pattern Analysis
| Pattern | Where | Consistency |
|---------|-------|-------------|
| Repository (via ORM) | models/* | ✅ Consistent |
| Validation | utils/validators.py | ⚠️ Partial (50% of handlers use it) |
| Service Layer | — | ❌ Absent |
| Centralized Error Handler | — | ❌ Absent (each handler handles its own errors) |
## Anti-Patterns Found
| # | Anti-Pattern | Location | Severity | Action |
|---|-------------|-----------|-----------|--------|
| 1 | Logic in handlers | routes/orders.py:50-150 | HIGH | Extract to service (capsule 04) |
| 2 | God class | routes/admin.py:230-380 | HIGH | Split into 3-4 handlers (capsule 04) |
| 3 | Duplication | utils/notifications.py:1-200 | MEDIUM | Refactor to an interface (capsule 04) |
| 4 | Hardcoded secrets | config.py:45 | CRITICAL | Move to env vars (capsule 03) |
| 5 | Generic except Exception | various | MEDIUM | Specific exceptions (M7 capsule 03) |
| 6 | Dead code appearance | utils/legacy.py | LOW | Verify dynamic dispatch first |
Deliverable: Architecture Analysis Document
Combine onboarding + Explore findings + architecture map into a single document:
# Architecture Analysis: [Project]
> Combined output of Onboarding (M1) + Exploration (M2) + Architecture Map (M3)
> Applied to the project from the capsule 01 assessment
---
## 1. Onboarding Summary
[The 5 questions answered with references to files]
## 2. Deep Exploration (Explore)
[Findings from the 4 additional questions]
## 3. Dependency Map
[Mermaid diagram + comments on critical modules]
## 4. Flow Analysis
[Trace of the main flow — typically the "money path" or "critical data"]
[Trace of at least 1 important secondary flow]
## 5. Pattern Analysis
[Table of observed patterns with consistency]
## 6. Anti-Patterns Found
[Table of anti-patterns with severity and suggested action]
## 7. Architecture Map: BEFORE
[Diagram of the current state]
## 8. Key Findings
1. [Most important finding with evidence]
2. [Second finding with evidence]
3. [Third finding with evidence]
## 9. Implications for the Migration
- What to refactor first (high severity + low risk)
- Where to put regression tests (critical flow points)
- What to document as remaining tech debt (not addressable in this scope)
This document is the direct input for capsule 03 (Migration Planning). Each decision in the migration plan is going to reference specific findings from here.
Connection with the Next Capsule
The Architecture Map you produce here is the direct input for capsule 03 (Migration Planning):
- The anti-patterns inform what to refactor (the order for capsule 04)
- The dependency maps inform the order of the changes (what to touch first to minimize ripple)
- The flow traces inform where to put regression tests (capsule 03)
- The absent patterns (service layer, error handler) inform what to introduce vs what to improve
Traps to Avoid in This Capsule
Five common mistakes when executing onboarding + architecture on a real project.
1. Skipping onboarding "because I already read the assessment"
The assessment (capsule 01) gives you scores and categories. The onboarding gives you the real map. Without onboarding, the refactoring decisions are educated guesses. Invest the time here — it's recovered 5× in the execution.
2. Doing "general" Explore instead of specific questions
Explore works best with targeted questions. "Explore the code" produces vague answers. "How is authentication handled end-to-end with file and line?" produces actionable answers. Module 2 capsule 02 gave you the difference — here you apply it.
3. Including everything in the Architecture Map and overloading the document
The Architecture Map is selective. Include the important modules (high fan-out, high criticality) and the severe anti-patterns. If your diagram has 80 nodes, it's not useful — it's raw. The rule: "can a colleague understand the project by reading ONLY this doc in 15 minutes?"
4. Not connecting findings with migration actions
Each anti-pattern in your list must end with a suggested action: "extract to a service layer in capsule 04", "document as remaining debt", "verify before removing". Without an action, the findings are empty criticism. With an action, they're the plan you execute in capsules 03-05.
5. Confusing "dead code" with "code with no apparent use"
Before marking something as dead, verify dynamic dispatch (Module 7 trap #3): registered callbacks, routes with strings, dynamic imports. If your Architecture Map says "dead code: legacy.py", check one more time. Removing live callbacks in capsule 04 is the most expensive bug of this project.
Diagnosis: Is Your Architecture Analysis Ready?
Five questions to verify before moving on to capsule 03.
Question 1: Does your Onboarding Summary have file:line references or only general descriptions?
If it has references: you're on the right track. The plan's decisions can be traced.
If only descriptions: go back to Step 1 — without references, the plan's decisions are vague.
Question 2: Does your Dependency Map identify the 2-3 modules with the highest fan-in and fan-out?
If yes: you know where to touch and where not to touch.
If no: the red/yellow nodes of the diagram should be marked — they're the ones that most impact refactoring.
Question 3: Does the Flow Analysis of the main flow identify at least 5 regression test points?
If yes: capsule 03 (safety nets) has its input.
If no: dig deeper into the flow analysis — without identified points, the tests will be insufficient.
Question 4: Does your Anti-Patterns list have severity and a suggested action for each one?
If yes: capsule 03 (plan) and 04 (execution) have their roadmap.
If no: complete the action column — without it, the anti-patterns don't translate into migration.
Question 5: Could you give this document to a colleague and have them understand the project in 15 minutes?
If yes: it's at the professional level.
If no: edit. There's probably too much detail or missing executive summaries at the start of each section.
If you hesitated on 2 or more: iterate the document before moving on to capsule 03. The quality of the Architecture Analysis determines the quality of the plan, and the quality of the plan determines the quality of the migration. It's the highest-leverage capsule of the project.
Troubleshooting
The project is too large to analyze completely
Use context management (M6): analyze by modules, generate a CLAUDE.md to give persistent context, and apply a chunking strategy (feature, layer, or module). Document only the modules in the scope of the migration — not the whole codebase.
There are no clear patterns
Document it. "Organic architecture without clear patterns" is a valid finding that informs the refactoring strategy (probably: introduce a simple pattern like a service layer instead of maintaining consistency with a nonexistent pattern).
The dependency map is a mess (many circular dependencies)
It's normal in legacy code. Document it as is — the circular dependencies and the high coupling are exactly what you're going to refactor. Mark the cycles in the diagram as high priority for capsule 04.
The "money path" or "critical flow" isn't obvious
Ask someone on the team (or, if it's open-source, read historical issues and PRs). If nobody knows, document the 2-3 most likely candidates and mark all 3 for a safety net. Better to over-cover the critical flow than to assume which one it is.
Summary
- This capsule applies M1+M2+M3 to the assessment project, in sequence
- The output is an integrated Architecture Analysis Document
- Without this document, the migration is an educated guess
- Connect each anti-pattern with a specific migration action
- Dynamically verify before marking code as dead
- The doc must be readable by a colleague in 15 minutes
Next capsule: 03 — Migration Planning + Safety Nets — you use this Architecture Analysis to create the migration plan with phases, checkpoints, and the regression tests that protect the changes. Without this doc well done, capsule 03 can't be executed correctly.
Additional Resources
- Software Architecture: The Hard Parts - Neal Ford et al. - Architectural analysis in distributed systems and monoliths
- C4 Model - A framework for architecture diagrams (Context, Containers, Components, Code)
- Mermaid Documentation - Syntax for diagrams in markdown (used in this module)
- Building Evolutionary Architectures - Ford, Parsons, Kua - Architectures that evolve, a framework for legacy
- Working Effectively with Legacy Code - Michael Feathers - Chapters 7-10: how to understand legacy code
- Claude Code Documentation - Official reference
Module 8, Capsule 02 — Refactoring & Legacy Code with Claude Code Guide