Módulo 1: Onboarding con AI — 5-10x Más Rápido

Crear Mental Model — Architecture, Layers, Entry Points

Crear Mental Model — Architecture, Layers, Entry Points

Descripción de la capsula

Exploraste el codebase. Hiciste las 5 preguntas. Tienes hallazgos sueltos: "usa FastAPI", "hay un directorio services/", "el entry point es main.py", "parece que usa el repository pattern". Pero hallazgos sueltos no son comprension. Comprension es cuando puedes predecir que pasa si cambias algo — y aciertas.

Eso es un mental model: una representacion interna de como funciona el sistema. No es un diagrama bonito ni un documento formal. Es tu capacidad de responder "si modifico esta función, que se rompe?" sin ejecutar los tests. Los developers senior navegan codebases grandes porque tienen mental models robustos. Los juniors se pierden porque no los tienen — no porque sean menos inteligentes, sino porque nadie les enseno a construirlos sistematicamente.

En esta capsula vas a aprender a construir un mental model en tres niveles (high-level, mid-level, low-level) usando Claude Code como acelerador. El proceso que a un developer senior le toma 1-2 semanas de lectura, lo vas a completar en 1-2 horas con las tecnicas correctas. No porque omitas pasos — sino porque Claude Code lee y conecta información orders of magnitude mas rápido que un humano.


Que es un Mental Model de un Codebase

Definición practica

Un mental model de un codebase es tu representacion interna de:

  1. Que componentes existen — modulos, servicios, modelos, utilidades
  2. Como se relacionan — quien llama a quien, quien depende de quien
  3. Como fluyen los datos — de donde entran, como se transforman, donde se almacenan
  4. Que patterns gobiernan las decisiones — convenciones, estilos, reglas implicitas
  5. Donde estan las trampas — acoplamiento oculto, side effects, inconsistencias

Por que no basta con "leer el código"

Leer código sin un framework mental es como leer un diccionario de la A a la Z para aprender un idioma. Tecnicamente posible, practicamente inutil. El código es un grafo — no una secuencia lineal. Los archivos se referencian entre si, las dependencias son circulares a veces, y el flujo real de ejecución rara vez sigue el orden de los archivos en el directorio.

Un mental model te da el mapa. Sin mapa, caminas a ciegas. Con mapa, navegas con confianza.

El test del mental model

Como sabes si tu mental model es bueno? Hazte esta pregunta:

"Si cambio la firma de la función process_payment(), que archivos se rompen y por que?"

Si puedes responder con confianza y verificar que acertaste, tu mental model es funcional. Si no puedes, hay gaps.

Mental Model Debil:
─────────────────────
"El proyecto tiene archivos de Python.
 Hay una carpeta de tests.
 Usa una base de datos."

→ No puedes predecir nada.
  Cada cambio es un experimento.

Mental Model Funcional:
──────────────────────────
"FastAPI app con 3 layers: routes → services → repositories.
 Routes en api/v1/, cada archivo es un dominio (users, orders, payments).
 Services contienen business logic, nunca acceden a DB directamente.
 Repositories usan SQLAlchemy, cada modelo tiene su repository.
 Si cambio process_payment() en services/payments.py,
 se rompe api/v1/payments.py (lo llama en POST /payments)
 y tests/test_payments.py (lo testea directo)."

→ Puedes predecir consecuencias.
  Cada cambio es informado.

Los 3 Niveles del Mental Model

Un mental model completo tiene tres niveles de profundidad. Cada nivel responde preguntas diferentes y requiere tecnicas diferentes para construirlo.

Nivel 1: High-Level — Architecture y Layers

Que responde: "De que esta hecho este sistema y como se organiza?"

Este es el nivel de vista de pajaro. Identifica:

  • Layers de la aplicación — Presentacion, negocio, datos, infraestructura
  • Componentes principales — Los "bloques grandes" del sistema
  • Boundaries — Donde termina un componente y empieza otro
  • Entry points — Por donde entran los requests al sistema
  • Exit points — Por donde sale información (DB, APIs externas, archivos)

Como construirlo con Claude Code:

# Prompt 1: Vista general de la arquitectura
claude "Analiza la estructura de directorios de este proyecto y describe
la arquitectura en layers. Identifica:
1. Cuales son los layers principales (presentacion, negocio, datos)
2. Que directorio corresponde a cada layer
3. Cuales son los entry points del sistema
4. Cuales son las dependencias externas principales"

Output esperado:

El proyecto sigue una arquitectura de 3 layers:

LAYER 1 - Presentacion (api/)
├── api/v1/routes/     → Endpoints HTTP (FastAPI routers)
├── api/middleware/     → Auth middleware, CORS, logging
└── api/dependencies/  → Dependency injection para FastAPI

LAYER 2 - Negocio (services/)
├── services/user_service.py      → Logica de usuarios
├── services/order_service.py     → Logica de pedidos
├── services/payment_service.py   → Logica de pagos
└── services/notification.py      → Emails, webhooks

LAYER 3 - Datos (repositories/ + models/)
├── repositories/user_repo.py     → Queries de usuarios
├── repositories/order_repo.py    → Queries de pedidos
├── models/                       → SQLAlchemy models
└── database.py                   → Conexion y sesion

Entry points:
- api/main.py → FastAPI app, mount de routers
- cli/manage.py → Comandos de administracion

Dependencias externas:
- PostgreSQL (via SQLAlchemy)
- Redis (via redis-py, para cache)
- Stripe API (para pagos)
- SendGrid (para emails)
# Prompt 2: Diagrama de layers
claude "Genera un diagrama de texto que muestre los layers de este
proyecto y como se comunican entre si. Incluye la direccion
de las dependencias (quien depende de quien)."

Output esperado:

┌─────────────────────────────────────────────────┐
│                  ENTRY POINTS                    │
│         main.py (HTTP)  │  manage.py (CLI)       │
└───────────┬─────────────┴──────────┬────────────┘
            │                        │
            ▼                        ▼
┌─────────────────────────────────────────────────┐
│              LAYER 1: PRESENTACION               │
│  api/v1/routes/  │  middleware/  │ dependencies/ │
│  (FastAPI)       │  (auth,CORS)  │ (DI)         │
└───────────────────────┬─────────────────────────┘
                        │ llama a
                        ▼
┌─────────────────────────────────────────────────┐
│              LAYER 2: NEGOCIO                    │
│  services/user_service.py                        │
│  services/order_service.py                       │
│  services/payment_service.py                     │
│  services/notification.py                        │
└───────────────────────┬─────────────────────────┘
                        │ llama a
                        ▼
┌─────────────────────────────────────────────────┐
│              LAYER 3: DATOS                      │
│  repositories/  │  models/  │  database.py       │
└───────────┬─────┴───────────┴──────┬────────────┘
            │                        │
            ▼                        ▼
     ┌──────────┐           ┌──────────────┐
     │PostgreSQL│           │ Redis/Stripe/ │
     │          │           │ SendGrid      │
     └──────────┘           └──────────────┘

Regla de dependencia: Layer N solo llama a Layer N+1.
Nunca al reves. Repositories nunca llaman a Services.

Nivel 2: Mid-Level — Modules y Dependencies

Que responde: "Como se conectan los modulos entre si?"

Este nivel mapea las dependencias concretas entre archivos y modulos. No basta saber que "services llama a repositories" — necesitas saber cuales y como.

Como construirlo con Claude Code:

# Prompt 3: Mapa de dependencias entre modulos
claude "Analiza los imports de este proyecto y genera un mapa de
dependencias. Para cada modulo principal, lista:
1. De que modulos depende (imports)
2. Que modulos dependen de el (quien lo importa)
3. Si hay dependencias circulares"

Output esperado:

MAPA DE DEPENDENCIAS:

services/order_service.py
  ├── DEPENDE DE:
  │   ├── repositories/order_repo.py (queries)
  │   ├── repositories/user_repo.py (validar usuario existe)
  │   ├── services/payment_service.py (procesar pago)
  │   └── services/notification.py (enviar confirmacion)
  │
  └── DEPENDIDO POR:
      ├── api/v1/routes/orders.py (endpoint POST/GET/PUT)
      └── cli/manage.py (comando create-test-order)

services/payment_service.py
  ├── DEPENDE DE:
  │   ├── repositories/payment_repo.py (guardar transaccion)
  │   └── core/stripe_client.py (API de Stripe)
  │
  └── DEPENDIDO POR:
      ├── services/order_service.py (procesar pago de orden)
      └── api/v1/routes/payments.py (endpoint de webhook)

⚠️ DEPENDENCIA CIRCULAR DETECTADA:
  services/order_service.py → services/notification.py
  services/notification.py → services/order_service.py
  (notification importa order_service para obtener datos del pedido)
# Prompt 4: Profundizar en un modulo especifico
claude "Analiza services/order_service.py en detalle:
1. Que funciones expone (API publica del modulo)
2. Que hace cada funcion en una linea
3. Que side effects tiene (DB writes, API calls, emails)
4. Que excepciones puede lanzar"

Output esperado:

services/order_service.py — API Publica:

create_order(user_id, items) -> Order
  → Valida usuario, calcula total, crea orden en DB
  → Side effects: DB write, Stripe charge, email
  → Raises: UserNotFoundError, PaymentFailedError, InsufficientStockError

get_order(order_id) -> Order
  → Lee orden de DB, incluye items
  → Side effects: ninguno (read-only)
  → Raises: OrderNotFoundError

cancel_order(order_id, reason) -> Order
  → Cambia status a cancelled, refund si ya se cobro
  → Side effects: DB write, Stripe refund, email
  → Raises: OrderNotFoundError, OrderAlreadyCancelledError

update_order_status(order_id, new_status) -> Order
  → Valida transicion de status, actualiza en DB
  → Side effects: DB write, email si status es "shipped"
  → Raises: OrderNotFoundError, InvalidStatusTransitionError

Nivel 3: Low-Level — Key Functions y Data Structures

Que responde: "Como funcionan las piezas criticas internamente?"

Este nivel es selectivo. No mapeas todas las funciones — solo las criticas: las que manejan dinero, autenticación, transformaciones de datos complejas, o las que tienen mas dependencias.

Como construirlo con Claude Code:

# Prompt 5: Analisis de funcion critica
claude "Analiza la funcion create_order() en services/order_service.py.
Traza el flujo completo paso a paso:
1. Que recibe como input
2. Que validaciones hace
3. En que orden llama a otros servicios/repositorios
4. Que pasa si falla en cada paso (error handling)
5. Que retorna al final
Incluye el happy path y los error paths."

Output esperado:

create_order(user_id: int, items: list[OrderItem]) -> Order

HAPPY PATH:
──────────────────────────────────────────────
1. user = user_repo.get_by_id(user_id)
   └── Si no existe → raise UserNotFoundError

2. for item in items:
   │   product = product_repo.get_by_id(item.product_id)
   │   └── Si no existe → raise ProductNotFoundError
   │   if product.stock < item.quantity:
   │       └── raise InsufficientStockError
   └── Calcula subtotal por item

3. total = sum(subtotales) + calculate_tax(subtotales)

4. payment = payment_service.charge(user, total)
   └── Si falla Stripe → raise PaymentFailedError

5. order = order_repo.create(
       user_id=user_id,
       items=items,
       total=total,
       payment_id=payment.id,
       status="confirmed"
   )

6. for item in items:
       product_repo.decrease_stock(item.product_id, item.quantity)

7. notification.send_order_confirmation(user, order)
   └── Si falla email → log warning (NO raise, non-critical)

8. return order

ERROR PATHS:
──────────────────────────────────────────────
- Paso 1 falla → UserNotFoundError (no side effects aun)
- Paso 2 falla → ProductNotFoundError o InsufficientStockError (no side effects)
- Paso 4 falla → PaymentFailedError (Stripe no cobro, no side effects en DB)
- Paso 5 falla → DB error → ⚠️ PROBLEMA: Stripe ya cobro pero orden no se creo
                 No hay rollback de Stripe en este path. BUG POTENCIAL.
- Paso 6 falla → DB error → Orden existe pero stock no se actualizo. BUG.
# Prompt 6: Data structures principales
claude "Identifica las 5 data structures mas importantes de este
proyecto (modelos de DB, DTOs, config objects). Para cada una:
1. Nombre y ubicacion
2. Campos principales
3. Relaciones con otras data structures
4. Donde se crea y donde se consume"

Output esperado:

DATA STRUCTURES PRINCIPALES:

1. Order (models/order.py)
   ├── Campos: id, user_id, status, total, created_at, payment_id
   ├── Relaciones: belongs_to User, has_many OrderItems, has_one Payment
   ├── Se crea en: services/order_service.py (create_order)
   └── Se consume en: api/v1/routes/orders.py, services/notification.py

2. User (models/user.py)
   ├── Campos: id, email, name, hashed_password, is_active, created_at
   ├── Relaciones: has_many Orders, has_one Profile
   ├── Se crea en: services/user_service.py (register_user)
   └── Se consume en: api/v1/routes/users.py, middleware/auth.py

3. OrderItem (models/order_item.py)
   ├── Campos: id, order_id, product_id, quantity, unit_price
   ├── Relaciones: belongs_to Order, belongs_to Product
   ├── Se crea en: services/order_service.py (dentro de create_order)
   └── Se consume en: services/order_service.py (calculos), api (display)

4. Product (models/product.py)
   ├── Campos: id, name, description, price, stock, category_id
   ├── Relaciones: belongs_to Category, has_many OrderItems
   ├── Se crea en: cli/manage.py (seed data), admin routes
   └── Se consume en: services/order_service.py, api/v1/routes/products.py

5. PaymentResult (services/payment_service.py — dataclass)
   ├── Campos: id, stripe_id, amount, status, error_message
   ├── Relaciones: asociado a Order via payment_id
   ├── Se crea en: payment_service.charge()
   └── Se consume en: order_service.create_order()

Construir el Mental Model con Claude Code — Proceso Completo

Paso 1: Nivel 1 en 10 minutos

Abre tu terminal en la raiz del proyecto y ejecuta estos prompts en secuencia:

# Paso 1a: Estructura general
claude "Dame un overview de la arquitectura de este proyecto.
Que layers tiene, como se organizan los directorios,
y cuales son los entry points principales."

# Paso 1b: Diagrama de layers
claude "Genera un diagrama ASCII mostrando los layers del proyecto
y la direccion de las dependencias entre ellos."

# Paso 1c: Dependencias externas
claude "Que dependencias externas usa este proyecto?
Analiza requirements.txt (o pyproject.toml) y agrupa por categoria:
framework, base de datos, APIs externas, utilidades."

Tiempo estimado: 10-15 minutos. Al terminar tienes el mapa de alto nivel.

Paso 2: Nivel 2 en 20 minutos

# Paso 2a: Mapa de dependencias
claude "Genera un mapa de dependencias entre los modulos principales.
Para cada archivo en services/, muestra de que depende
y que depende de el."

# Paso 2b: Dependencias circulares
claude "Hay dependencias circulares en este proyecto?
Analiza todos los imports y reporta cualquier ciclo."

# Paso 2c: Modulos mas conectados
claude "Cuales son los 5 archivos con mas dependencias
(tanto entrantes como salientes)? Estos son los 'hubs'
del proyecto — los mas riesgosos de modificar."

Tiempo estimado: 15-20 minutos. Al terminar tienes el mapa de conexiones.

Paso 3: Nivel 3 en 30 minutos (selectivo)

# Paso 3a: Funciones criticas
claude "Cuales son las 5 funciones mas criticas de este proyecto?
Criterios: manejan dinero, autenticacion, o tienen mas de
5 dependencias. Para cada una, describe el flujo paso a paso."

# Paso 3b: Data structures
claude "Cuales son los modelos de datos principales?
Para cada uno: campos, relaciones, donde se crea, donde se consume."

# Paso 3c: Error handling
claude "Como maneja errores este proyecto?
Hay un patron consistente? Donde hay gaps en el error handling?"

Tiempo estimado: 25-30 minutos. Al terminar tienes profundidad en las areas criticas.

Total: ~60 minutos para un mental model funcional de un codebase de 5K-10K lineas.


Visualizar el Mental Model

Los hallazgos que genera Claude Code son utiles pero efimeros si no los persistes. Estas son tres tecnicas para hacer tu mental model visible y compartible.

Tecnica 1: Diagrama ASCII (rápido, inline)

claude "Genera un diagrama ASCII que muestre:
1. Los 3 layers del proyecto
2. Los modulos dentro de cada layer
3. Las flechas de dependencia entre modulos
Usa caracteres box-drawing (┌ ─ └ │ → ▼)"

Ventaja: Se puede poner en cualquier README, comment, o Slack message. Limitacion: Se vuelve ilegible con mas de 10-15 componentes.

Tecnica 2: Mermaid Diagram (profesional, renderizable)

claude "Genera un diagrama Mermaid que muestre la arquitectura
del proyecto. Usa graph TD para mostrar la jerarquia de layers
y las dependencias entre modulos."

Output esperado:

graph TD
    subgraph "Layer 1: Presentacion"
        ROUTES[api/v1/routes/]
        MIDDLEWARE[middleware/]
        DEPS[dependencies/]
    end

    subgraph "Layer 2: Negocio"
        USER_SVC[user_service]
        ORDER_SVC[order_service]
        PAYMENT_SVC[payment_service]
        NOTIFICATION[notification]
    end

    subgraph "Layer 3: Datos"
        USER_REPO[user_repo]
        ORDER_REPO[order_repo]
        PAYMENT_REPO[payment_repo]
        MODELS[models/]
    end

    subgraph "Externo"
        DB[(PostgreSQL)]
        REDIS[(Redis)]
        STRIPE[Stripe API]
        SENDGRID[SendGrid]
    end

    ROUTES --> USER_SVC
    ROUTES --> ORDER_SVC
    MIDDLEWARE --> USER_SVC
    ORDER_SVC --> ORDER_REPO
    ORDER_SVC --> PAYMENT_SVC
    ORDER_SVC --> NOTIFICATION
    PAYMENT_SVC --> PAYMENT_REPO
    PAYMENT_SVC --> STRIPE
    USER_SVC --> USER_REPO
    NOTIFICATION --> SENDGRID
    USER_REPO --> MODELS
    ORDER_REPO --> MODELS
    MODELS --> DB

Ventaja: Se renderiza en GitHub, Notion, documentación. Profesional. Limitacion: Requiere que tu plataforma soporte Mermaid.

Tecnica 3: Lista de dependencias (exhaustiva, greppable)

claude "Genera una lista plana de todas las dependencias del proyecto
en formato 'A → B (razon)'. Una linea por dependencia.
Ordena por modulo origen."

Output esperado:

LISTA DE DEPENDENCIAS:

api/v1/routes/orders.py → services/order_service.py (business logic)
api/v1/routes/orders.py → api/dependencies/auth.py (JWT validation)
api/v1/routes/users.py → services/user_service.py (business logic)
api/v1/routes/payments.py → services/payment_service.py (webhook handler)
services/order_service.py → repositories/order_repo.py (DB queries)
services/order_service.py → repositories/user_repo.py (user validation)
services/order_service.py → services/payment_service.py (charge)
services/order_service.py → services/notification.py (email)
services/payment_service.py → repositories/payment_repo.py (DB queries)
services/payment_service.py → core/stripe_client.py (Stripe API)
services/notification.py → services/order_service.py (get order data) ⚠️ CIRCULAR

Ventaja: Fácil de buscar con grep/ctrl+f. Completa. Limitacion: No muestra la estructura visual.


Validar el Mental Model

Construir un mental model sin validarlo es como escribir tests sin ejecutarlos. La validación es el paso mas importante y el mas omitido.

Tecnica 1: Predecir y verificar

Elige una función y predice que pasa si la modificas:

# Paso 1: Haz tu prediccion ANTES de preguntar a Claude Code
# Tu prediccion: "Si renombro create_order() a place_order(),
# se rompen: orders.py (route), manage.py (CLI), test_orders.py"

# Paso 2: Verifica con Claude Code
claude "Si renombro la funcion create_order() en
services/order_service.py a place_order(),
que archivos se rompen y por que?"

Si tu prediccion acerto: Tu mental model del Nivel 2 es correcto para ese módulo. Si tu prediccion fallo: Encontraste un gap. Actualiza tu mental model.

Tecnica 2: Hacer un cambio pequeno real

# Haz un cambio inofensivo para verificar que entiendes el flujo
claude "Agrega un log message al inicio de create_order() que diga
'Creating order for user {user_id} with {len(items)} items'.
Usa el logger que ya existe en el proyecto."

Si Claude Code lo hace correctamente y los tests pasan, confirms que:

  • ✅ Tu mental model de donde esta la función es correcto
  • ✅ Tu mental model de como se llama es correcto
  • ✅ El proyecto tiene logging configurado donde pensabas

Si algo falla, tu mental model tiene un gap específico que puedes corregir.

Tecnica 3: Trazar un request end-to-end

claude "Traza el flujo completo de un request POST /orders
desde que llega al server hasta que retorna la respuesta.
Incluye cada funcion que se ejecuta en orden, cada modulo
que se toca, y cada side effect (DB, API, email)."

Compara el resultado con tu mental model. Los puntos donde difiere son tus gaps.


Comparacion: Mental Model Completo vs Parcial

CriterioMental Model ParcialMental Model Completo
Tiempo de construccion15-20 minutos45-60 minutos
CoberturaSolo Nivel 1 (layers)Niveles 1, 2 y 3
Predecir consecuencias"Probablemente se rompe algo en services""Se rompen estos 3 archivos especificos"
Hacer cambiosCon miedo, muchos tests manualesCon confianza, verificaciones dirigidas
Encontrar bugsCuando se manifiestan en producciónAntes de hacer el cambio (en el análisis)
Útil para otrosDifícil de comunicar ("es complicado")Documentable y compartible
MantenimientoSe desactualiza rápido (no tienes base)Fácil de actualizar (ajustas el mapa)

Cuando basta un mental model parcial?

  • ✅ Vas a hacer UN cambio específico y pequeno
  • ✅ El codebase es pequeno (<2K lineas)
  • ✅ Hay documentación actualizada que puedes consultar

Cuando necesitas un mental model completo?

  • ✅ Vas a hacer cambios significativos o refactoring
  • ✅ El codebase es mediano-grande (5K+ lineas)
  • ✅ No hay documentación confiable
  • ✅ Vas a trabajar en el proyecto por semanas/meses

Trade-off: Los 30 minutos extra que inviertes en completar el mental model se pagan 10x la primera vez que evitas un bug porque predijiste correctamente una consecuencia.


Conexión con Proyecto

En el Proyecto del Módulo: Onboarding a Codebase Open-Source (proyecto de este módulo):

  • Usaras los 3 niveles del mental model para documentar tu comprension del proyecto open-source que elijas
  • El Nivel 1 te dara la estructura general del proyecto para tu onboarding doc
  • El Nivel 2 te mostrara como los modulos se conectan — información critica para tu primer cambio
  • El Nivel 3 (selectivo) te ayudara a identificar las funciones criticas donde hacer tu cambio de validación
  • La tecnica de "predecir y verificar" es exactamente como validaras tu comprension en el entregable

Todo lo que aprendes aquí se aplica directamente en el proyecto del módulo.


Troubleshooting

Problema 1: Claude Code genera un mental model demasiado superficial

Causa: El prompt es demasiado generico ("explicame este proyecto"). Solución: Usa prompts especificos por nivel. En lugar de pedir "un overview", pide:

claude "Identifica los layers de la arquitectura, que directorio
corresponde a cada layer, y cual es la regla de dependencia
entre layers (quien puede llamar a quien)."

Problema 2: El mapa de dependencias tiene demasiada información

Causa: Pediste todas las dependencias de todos los archivos de una vez. Solución: Enfocate en un layer o módulo a la vez:

# En vez de: "mapa de TODAS las dependencias"
# Usa: un modulo a la vez
claude "Mapa de dependencias SOLO de services/order_service.py.
Que importa y quien lo importa."

Problema 3: El Nivel 3 toma demasiado tiempo

Causa: Estas intentando analizar todas las funciones en profundidad. Solución: Se selectivo. Solo profundiza en las 3-5 funciones mas criticas:

claude "Cuales son las 3 funciones de este proyecto que mas
riesgo tienen si se modifican mal? (Criterio: manejan dinero,
datos sensibles, o tienen mas dependencias)"

Problema 4: Los diagramas Mermaid no se renderizan correctamente

Causa: Syntax errors en el Mermaid generado o caracteres especiales. Solución: Pide a Claude Code que valide el diagrama:

claude "Revisa este diagrama Mermaid y corrige cualquier error de sintaxis.
Asegurate de que todos los nodos tienen IDs validos (sin espacios ni
caracteres especiales)."

Problema 5: Tu prediccion fallo pero no sabes por que

Causa: Gap en el mental model que no puedes identificar solo. Solución: Pide a Claude Code que explique la diferencia:

claude "Yo predije que cambiar create_order() romperia 3 archivos:
orders.py, manage.py, test_orders.py. Pero tambien se rompio
notification.py. Explicame por que notification.py depende de
create_order() — yo no veia esa conexion."

Ejercicios

Ejercicio 1: Mental Model Nivel 1 de httpx (Fácil)

Clona el proyecto httpx (pip install httpx y busca su source code o clona desde GitHub). Usa Claude Code para generar el Nivel 1 del mental model: layers, componentes principales, y entry points. Tu entregable es un diagrama ASCII de los layers.

Ver solución
# Clonar httpx
git clone https://github.com/encode/httpx.git
cd httpx

# Generar Nivel 1
claude "Analiza la estructura de este proyecto Python (httpx).
Identifica:
1. Los layers o componentes principales de la arquitectura
2. Que directorio o archivo corresponde a cada componente
3. Cuales son los entry points publicos (lo que un usuario importa)
4. Las dependencias externas principales"

Output esperado (simplificado):

httpx/
├── _client.py          → Entry point principal (Client, AsyncClient)
├── _models.py          → Request, Response, URL, Headers
├── _transports/        → HTTP transport layer (sync y async)
├── _content.py         → Encoding/decoding de content
├── _urls.py            → URL parsing y construccion
├── _auth.py            → Authentication handlers
└── _config.py          → SSL, timeout, proxy config

Layers:
1. API Publica: Client, AsyncClient (_client.py)
2. Models: Request, Response (_models.py)
3. Transport: BaseTransport, HTTPTransport (_transports/)
4. Utilidades: config, auth, urls, content

Entry point para usuarios:
  from httpx import Client, get, post

Explicacion: El Nivel 1 te da la vista de pajaro. httpx tiene una arquitectura relativamente plana — no es un framework web con muchos layers, sino una library HTTP con un API publica clara (_client.py) y componentes internos bien separados.

Ejercicio 2: Mapa de Dependencias de un Módulo (Fácil)

Usando el mismo proyecto httpx, genera el mapa de dependencias del archivo _client.py. Que modulos importa? Quien importa a _client.py?

Ver solución
claude "Analiza httpx/_client.py y genera su mapa de dependencias:
1. Que modulos internos de httpx importa
2. Que dependencias externas usa
3. Quien importa a _client.py (dentro del proyecto)"

Output esperado:

httpx/_client.py — DEPENDENCIAS:

IMPORTA (dependencias internas):
├── _models.py (Request, Response)
├── _transports/ (BaseTransport, HTTPTransport, AsyncHTTPTransport)
├── _config.py (SSLConfig, Timeout, Proxy)
├── _auth.py (Auth)
├── _urls.py (URL)
├── _content.py (encode content)
└── _exceptions.py (HTTPStatusError, etc.)

IMPORTA (dependencias externas):
├── httpcore (transporte HTTP de bajo nivel)
├── typing (type hints)
└── contextlib (context managers)

IMPORTADO POR:
├── __init__.py (re-exporta Client, AsyncClient, get, post, etc.)
└── _api.py (funciones de conveniencia: get(), post(), etc.)

Explicacion: _client.py es el hub central del proyecto. Importa casi todos los modulos internos y es el único archivo que los usuarios finales tocan (indirectamente via init.py). Esto te dice que cualquier cambio en _client.py tiene alto impacto.

Ejercicio 3: Predecir y Verificar (Medio)

Sin preguntar a Claude Code primero, predice: "Si elimino la clase Timeout de _config.py, que archivos se rompen?". Escribe tu prediccion. Luego verifica con Claude Code. Reporta la diferencia entre tu prediccion y la realidad.

Ver solución
# Paso 1: Tu prediccion (escribe antes de ejecutar)
# Prediccion: "_client.py se rompe porque importa Timeout.
#              Probablemente _api.py tambien. Y tests."

# Paso 2: Verificar
claude "Si elimino la clase Timeout de httpx/_config.py,
que archivos del proyecto se rompen y por que?
Lista cada archivo afectado."

Output esperado:

Archivos que se rompen:

1. _client.py — importa Timeout directamente, lo usa en __init__
   y en send() para configurar timeouts por request
2. _api.py — usa Timeout como default en get(), post(), etc.
3. __init__.py — re-exporta Timeout como parte del API publica
4. _transports/default.py — recibe Timeout para configurar httpcore
5. tests/test_config.py — testea Timeout directamente
6. tests/test_timeouts.py — tests especificos de timeout behavior

TOTAL: 6 archivos (posiblemente mas en tests)

Explicacion: Si tu prediccion fue 2-3 archivos y la realidad fueron 6, tu mental model tenia gaps en el Nivel 2 (no sabias que _transports/ y init.py también usaban Timeout directamente). Eso es exactamente lo que este ejercicio revela.

Ejercicio 4: Diagrama Mermaid de Flujo (Medio)

Usa Claude Code para generar un diagrama Mermaid del flujo de un request HTTP en httpx: desde que el usuario llama client.get(url) hasta que recibe un Response. Incluye los modulos por los que pasa el request.

Ver solución
claude "Genera un diagrama Mermaid (sequenceDiagram) que muestre
el flujo de un request HTTP en httpx. Desde que el usuario
llama client.get(url) hasta que recibe un Response.
Muestra cada modulo/clase que participa en el flujo."

Output esperado:

sequenceDiagram
    participant User
    participant Client as _client.Client
    participant Models as _models.Request
    participant Auth as _auth.Auth
    participant Transport as _transports.HTTPTransport
    participant HTTPCore as httpcore

    User->>Client: client.get(url)
    Client->>Client: _build_request(method, url, ...)
    Client->>Models: Request(method, url, headers, content)
    Client->>Auth: auth_flow(request)
    Auth-->>Client: request con auth headers
    Client->>Transport: handle_request(request)
    Transport->>HTTPCore: httpcore.request(...)
    HTTPCore-->>Transport: httpcore.Response
    Transport-->>Client: Response
    Client->>Client: _build_response(transport_response)
    Client-->>User: Response(status=200, ...)

Explicacion: El sequence diagram muestra que un simple get() pasa por al menos 5 modulos. Este es el tipo de insight que el Nivel 3 revela y que es imposible obtener solo con el Nivel 1.

Ejercicio 5: Comparar Mental Model de Dos Proyectos (Difícil)

Clona dos proyectos: httpx y requests (la library HTTP original de Python). Genera el Nivel 1 del mental model para ambos. Compara sus arquitecturas. Cual tiene layers mas claros? Cual tiene mas acoplamiento? Documenta en un parrafo por proyecto.

Ver solución
# httpx
cd httpx
claude "Genera el Nivel 1 del mental model de este proyecto:
layers, componentes, entry points, dependencias externas."

# requests
cd ../requests
git clone https://github.com/psf/requests.git
cd requests
claude "Genera el Nivel 1 del mental model de este proyecto:
layers, componentes, entry points, dependencias externas."

Comparacion esperada:

httpx:
- Arquitectura modular clara: _client, _models, _transports separados
- Dependencias bien definidas (httpcore para transporte)
- Type hints consistentes
- Async support nativo (AsyncClient como ciudadano de primera clase)
- Boundaries claros entre layers

requests:
- Arquitectura mas monolitica: mucha logica en api.py y sessions.py
- urllib3 como dependencia de transporte (mas vieja, mas grande)
- Sin type hints significativos (proyecto legacy)
- No async (requiere library separada: aiohttp o httpx)
- Boundaries menos claros entre "que hace requests" vs "que hace urllib3"

Conclusion: httpx tiene una arquitectura mas moderna y modular.
requests es un proyecto legacy con tech debt acumulado. Esta
comparacion es exactamente el tipo de analisis que haras en los
modulos de refactoring (4-7) de esta guia.

Explicacion: Comparar mental models de dos proyectos que resuelven el mismo problema es una tecnica poderosa para entender trade-offs arquitecturales. Te muestra que "HTTP client" puede implementarse de formas muy diferentes.

Ejercicio 6: Mental Model Completo en 60 Minutos (Difícil)

Elige un proyecto Python de 5K-10K lineas que NO hayas visto antes (sugerencias: typer, rich, textual). En 60 minutos, construye los 3 niveles del mental model usando Claude Code. Documenta tu resultado en un archivo markdown con: diagrama de layers, mapa de dependencias de los 3 modulos mas conectados, y flujo detallado de una función critica.

Ver solución
# Ejemplo con typer
git clone https://github.com/tiangolo/typer.git
cd typer

# Minutos 0-10: Nivel 1
claude "Analiza este proyecto Python (typer). Dame:
1. Layers/componentes de la arquitectura
2. Entry points publicos
3. Dependencias externas"

# Minutos 10-30: Nivel 2
claude "Genera el mapa de dependencias para los 5 archivos
mas importantes de typer/. Para cada uno: que importa y
quien lo importa."

claude "Hay dependencias circulares? Cuales son los 3 archivos
con mas conexiones (hub files)?"

# Minutos 30-50: Nivel 3
claude "Analiza la funcion principal que ejecuta un comando CLI
en typer. Traza el flujo desde que el usuario escribe un comando
en terminal hasta que se ejecuta la funcion de Python correspondiente."

# Minutos 50-60: Documentar
claude "Genera un documento markdown con:
1. Diagrama Mermaid de la arquitectura de typer
2. Mapa de dependencias de los 3 archivos hub
3. Flujo detallado de ejecucion de un comando"

Explicacion: Este ejercicio simula exactamente el proyecto del módulo. La clave es el time-boxing: 60 minutos es suficiente para un mental model funcional de un proyecto de 5K-10K lineas con Claude Code. Sin AI, este mismo proceso tomaria 1-2 semanas.


Resumen

En esta capsula aprendiste:

  • Un mental model es tu representacion interna de como funciona un codebase. Te permite predecir consecuencias de cambios.
  • Se construye en 3 niveles: high-level (layers, entry points), mid-level (modulos, dependencias), low-level (funciones, data structures).
  • Claude Code acelera la construccion: prompts especificos por nivel generan la información que necesitas en minutos, no dias.
  • Los hallazgos sueltos no son comprension. Necesitas conectarlos con preguntas de integración: historia de un request, boundaries, inconsistencias.
  • Visualizar el mental model (ASCII, Mermaid, listas de dependencias) lo hace persistente y compartible.
  • Validar es el paso mas importante y el mas omitido. Haz predicciones y verificalas. Los errores revelan los gaps.
  • El mental model perfecto no existe. El objetivo es funcional: poder predecir el 80% de las consecuencias de un cambio.

Proxima capsula: Documentar Hallazgos con Claude Code — donde conviertes tu mental model en un artefacto tangible que otros pueden usar.


Recursos Adicionales

  1. "Working Effectively with Legacy Code" — Michael Feathers Capitulo 16: "I Don't Understand the Code Well Enough to Change It." El libro que formalizo la importancia de entender antes de modificar. Relevante para la tecnica de "make a small change to validate understanding."

  2. "Software Architecture in Practice" — Bass, Clements, Kazman Los capitulos sobre architectural views (module view, component-and-connector view, allocation view) formalizan los 3 niveles de mental model que cubrimos.

  3. "Documenting Software Architectures" — Clements et al. Tecnicas para documentar y comunicar arquitectura. Complementa la sección de visualizacion de esta capsula.

  4. Mermaid.js Documentation — https://mermaid.js.org/ Referencia completa para diagramas Mermaid. Útil para generar visualizaciones mas complejas (sequence diagrams, class diagrams, state diagrams).

  5. Claude Code Documentation — Explore Subagent En el Módulo 2 aprenderas a usar el Explore subagent, que es la herramienta especializada para las tecnicas de exploracion que viste aquí. Lo que hiciste manualmente con prompts, Explore lo automatiza.

  6. "A Philosophy of Software Design" — John Ousterhout Los conceptos de "deep modules" y "shallow modules" complementan la idea de mental model por niveles. Un módulo "deep" tiene una interfaz simple pero implementación compleja — exactamente lo que tu Nivel 3 necesita mapear.

  7. "The Pragmatic Programmer" — Hunt, Thomas El concepto de "tracer bullets" (hacer un cambio end-to-end minimo para validar la arquitectura) es exactamente lo que hacemos en la sección de validación del mental model.

  8. C4 Model — https://c4model.com/ Un framework formal para documentar arquitectura de software en 4 niveles (Context, Containers, Components, Code) que se alinea con nuestro enfoque de 3 niveles de mental model.