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?
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. :::

Quiz

Module 3: Large Codebase Management with AI

Take Quiz
FREE WEEKLY NEWSLETTER

Stay on the Nerd Track

One email per week — courses, deep dives, tools, and AI experiments.

No spam. Unsubscribe anytime.