Large Codebase Management with AI
Codebase Navigation Patterns
5 min read
The Navigation Problem
In large codebases, finding relevant code is half the battle. AI assistants need efficient strategies to locate:
- Where a feature is implemented
- How data flows through the system
- What depends on what
- Where to make changes
Search-First Navigation
Semantic Search with AI
claude "Find where user authentication happens in this codebase.
I need to understand the full auth flow."
AI performs intelligent search:
Searching for authentication patterns...
Authentication flow identified:
1. Entry Point: src/app/login/page.tsx
- Login form submission
- Calls /api/auth/login
2. API Route: api/src/routes/auth.ts
- POST /login - Credential validation
- POST /register - New user creation
- POST /logout - Session termination
3. Service Layer: api/src/services/auth.ts
- validateCredentials()
- createSession()
- hashPassword()
4. Middleware: api/src/middleware/auth.ts
- authenticateRequest()
- requireRole()
5. Database: packages/database/schema.prisma
- User model
- Session model
Would you like me to read any of these files?
Pattern-Based Search
claude "Find all API endpoints that handle payments.
Look for route definitions, not just 'payment' in strings."
# AI uses intelligent grep patterns
grep -r "router\.(get|post|put|delete).*payment" api/src/
grep -r "@(Get|Post|Put|Delete).*payment" api/src/ # Decorators
grep -r "app\.(get|post|put|delete).*pay" api/src/
Tracing Data Flow
Following a Request
claude "Trace what happens when a user clicks 'Place Order':
1. Frontend event handler
2. API request
3. Backend processing
4. Database operations
5. Response handling"
AI produces a flow diagram:
User Clicks "Place Order"
│
▼
┌─────────────────────────┐
│ OrderButton.tsx:45 │
│ onClick → placeOrder() │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ useOrder.ts:23 │
│ mutation.mutate() │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ POST /api/orders │
│ routes/orders.ts:67 │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ OrderService.create() │
│ services/order.ts:112 │
├─────────────────────────┤
│ 1. Validate cart items │
│ 2. Check inventory │
│ 3. Process payment │
│ 4. Create order record │
│ 5. Update inventory │
│ 6. Queue confirmation │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ prisma.order.create() │
│ database/orders.ts:45 │
└─────────────────────────┘
Dependency Tracing
claude "What calls the sendEmail function?
Trace all callers up to the entry points."
sendEmail() call hierarchy:
services/notification.ts:sendEmail()
├── Called by: services/notification.ts:sendOrderConfirmation()
│ └── Called by: services/order.ts:create()
│ └── Called by: routes/orders.ts:POST /orders
│ └── Entry: OrderButton.tsx → useOrder.ts
│
├── Called by: services/notification.ts:sendPasswordReset()
│ └── Called by: routes/auth.ts:POST /forgot-password
│ └── Entry: ForgotPasswordForm.tsx
│
└── Called by: services/notification.ts:sendWelcome()
└── Called by: services/auth.ts:register()
└── Called by: routes/auth.ts:POST /register
└── Entry: RegisterForm.tsx
Understanding Code Structure
Generate Architecture Maps
claude "Create a dependency graph of our service layer.
Show which services depend on which."
Service Layer Dependencies:
OrderService
├── PaymentService (process payments)
├── InventoryService (check/update stock)
├── NotificationService (send confirmations)
└── UserService (get customer details)
PaymentService
├── StripeService (payment processing)
└── OrderService (update order status) ⚠️ Circular!
InventoryService
├── ProductService (get product info)
└── WarehouseService (location data)
NotificationService
├── EmailService (send emails)
├── SmsService (send texts)
└── PushService (push notifications)
⚠️ Circular dependency detected:
OrderService → PaymentService → OrderService
Module Boundaries
claude "Analyze the boundaries between our modules.
Find cases where modules are too tightly coupled."
Module Coupling Analysis:
✅ Well-bounded modules:
- auth ↔ user (clean interface via UserService)
- notification ↔ * (pure output, no incoming deps)
⚠️ Concerning coupling:
- order ↔ payment (circular, 12 cross-references)
- inventory ↔ product (15 direct imports, no interface)
❌ Boundary violations:
- routes/orders.ts directly imports prisma client
(should go through service layer)
- components/Cart.tsx imports from api/src/types
(should use packages/types)
Recommendations:
1. Extract payment state machine to break circular dep
2. Create ProductRepository interface for inventory
3. Move prisma imports to service layer only
Quick Navigation Commands
Find by Responsibility
claude "Where do we handle inventory reservations?"
claude "Which component renders the user profile?"
claude "What validates credit card numbers?"
Find by Pattern
claude "Find all React hooks in this project"
claude "Show me all database migrations"
claude "List all environment variables used"
Find by Convention
claude "Based on our naming conventions, where would
the tax calculation logic be?"
AI infers from patterns:
Based on your project conventions:
Business logic → services/
Tax is finance-related → services/finance/ or services/tax/
Checking...
Found: api/src/services/tax.ts
- calculateTax()
- getTaxRate()
- validateTaxId()
Also related:
- api/src/services/checkout.ts:applyTax() (uses TaxService)
- packages/types/src/tax.ts (type definitions)
Building Mental Models
Request AI Explanations
claude "Explain how our caching layer works.
I'm new to this codebase and need to understand
the caching strategy."
AI provides conceptual overview:
# Caching Architecture
## Strategy: Read-Through with TTL
Request
│
▼
┌────────────────┐
│ API Route │
└───────┬────────┘
│
▼
┌────────────────┐
│ CacheService │
│ cache.get(key) │
└───────┬────────┘
│
┌──────────┴──────────┐
│ │
Cache Hit Cache Miss
│ │
▼ ▼
Return data Query database
│
▼
cache.set(key)
│
▼
Return data
## Cache Layers
1. In-memory (LRU, 1000 items) - lib/cache/memory.ts
2. Redis (distributed) - lib/cache/redis.ts
## TTL Strategy
- User profiles: 5 minutes
- Product data: 1 hour
- Static content: 24 hours
## Invalidation
- On write: Immediate invalidation
- Broadcast: Redis pub/sub to all instances
Next Steps
In the final lesson of this module, we'll cover managing legacy code and technical debt with AI assistance. :::