Módulo 8: Proyecto Integrador

Fase Final: Entrega y Retrospectiva

Fase Final: Entrega y Retrospectiva

Descripción de la cápsula

Has completado las tres fases del proyecto: code review, debugging, y corrección. Ahora viene la parte que cierra el loop de aprendizaje: organizar tu entrega y escribir la retrospectiva. La retrospectiva no es un add-on burocrático — es donde el aprendizaje se consolida. Los mejores developers no solo arreglan bugs, reflexionan sobre su proceso para ser mejores la próxima vez.

Esta cápsula te da el checklist exacto de lo que debes entregar, la rúbrica de auto-evaluación con 100 puntos, las preguntas guía para la retrospectiva, y ejemplos de entregas excelentes para que calibres tu trabajo.


Checklist de Entrega

Tu entrega debe contener exactamente estos 4 documentos:

Documento 1: Findings Document

# TaskFlow API — Findings Document

## Información del Reviewer
- Nombre: [Tu nombre]
- Fecha: [Fecha]
- Tiempo total invertido: [Horas]
  - Code review estático: [Tiempo]
  - Debugging: [Tiempo]
  - Corrección: [Tiempo]
  - Documentación: [Tiempo]

## Resumen Ejecutivo
[2-3 oraciones sobre el estado del codebase]

## Findings

| # | Severidad | Categoría | Archivo | Línea(s) | Descripción | Requisito | Impacto |
|---|-----------|-----------|---------|----------|-------------|-----------|---------|
| 1 | | | | | | | |
| 2 | | | | | | | |
[...todos los findings...]

## Estadísticas
| Severidad | Encontrados | Total esperado |
|-----------|-------------|----------------|
| Critical  |             | 3-4            |
| High      |             | 4-5            |
| Medium    |             | 5-6            |
| Low       |             | 3-4            |
| **Total** |             | **15-20**      |

## Notas del Proceso
[Observaciones sobre el codebase, la experiencia del review, 
qué fue fácil y qué fue difícil]

Documento 2: Código Corregido

El codebase completo con todas las correcciones aplicadas. Puede ser:

  • Un directorio con todos los archivos corregidos
  • Un archivo con las secciones de código corregidas y las líneas que cambiaron

Cada archivo corregido debe incluir al inicio:

# CORRECCIONES EN ESTE ARCHIVO:
# - [Línea X]: [Descripción breve del fix]
# - [Línea Y]: [Descripción breve del fix]

Documento 3: Justificaciones

# Justificaciones de Correcciones — TaskFlow API

## Fix #1: [Título]
**Finding:** #[número]
**Severidad:** [nivel]
**Archivo:** [nombre]

### Qué cambié
[Descripción del cambio]

### Por qué era incorrecto
[Requisito violado y explicación]

### Por qué mi fix es correcto
[Explicación y verificación]

### Decisión regenerar/editar
[Decisión y justificación]

---
[Repetir para cada fix]

Documento 4: Retrospectiva

Documento de 300-500 palabras. Formato detallado más adelante en esta cápsula.


Rúbrica de Auto-evaluación (100 puntos)

Sección 1: Findings (40 puntos)

Cantidad de findings (20 puntos)

Findings encontradosPuntos
16-18 de 1820
14-15 de 1817
12-13 de 1814
10-11 de 1811
8-9 de 188
< 8 de 185

Severidad correcta (10 puntos)

CriterioPuntos
Severidad correcta en 90%+ de los findings10
Severidad correcta en 75-89%7
Severidad correcta en 60-74%5
Severidad correcta en menos del 60%2

Guía para evaluar la severidad:

  • ¿Los security holes están marcados como Critical?
  • ¿Los problemas de lógica de negocio están marcados como High?
  • ¿Los edge cases están marcados como Medium?
  • ¿Las hallucinations sin impacto directo están marcadas como Low?

Calidad de la documentación (10 puntos)

CriterioPuntos
Cada finding tiene: descripción clara, archivo, línea, impacto, requisito violado10
La mayoría tiene toda la información, algunos incompletos7
Información parcial en la mayoría de los findings4
Findings con solo descripción, sin contexto2

Sección 2: Correcciones (30 puntos)

Correcciones correctas (15 puntos)

CriterioPuntos
Todos los fixes de Critical y High son correctos15
La mayoría de Critical y High son correctos, alguno parcial12
Algunos fixes son correctos, otros incorrectos o parciales8
La mayoría de los fixes son incorrectos o no implementados4

Cómo evaluar si un fix es "correcto":

  • ✅ Resuelve el problema identificado
  • ✅ No introduce nuevos problemas
  • ✅ Cumple con el requisito funcional
  • ✅ Pasa la verificación de runtime

Justificaciones (10 puntos)

CriterioPuntos
Cada fix tiene justificación completa con referencia a requisitos10
La mayoría tiene justificación, algunas superficiales7
Justificaciones presentes pero genéricas4
Sin justificaciones o con solo "lo arreglé"1

Decisiones regenerar/editar (5 puntos)

CriterioPuntos
Cada fix documenta la decisión con justificación razonable5
La mayoría documenta la decisión3
Pocas decisiones documentadas1

Sección 3: Proceso (20 puntos)

Proceso sistemático (10 puntos)

CriterioPuntos
Siguió las fases en orden (review → debug → fix), documentando cada paso10
Siguió un proceso razonable, documentación parcial7
Proceso ad-hoc pero completó las tareas4
Sin evidencia de proceso sistemático1

Evidencia de proceso sistemático:

  • ¿Completó el code review antes de empezar a corregir?
  • ¿Documentó los debugging steps?
  • ¿Priorizó los fixes por severidad?
  • ¿Verificó cada corrección?

Uso de herramientas (10 puntos)

CriterioPuntos
Uso estratégico de Claude Code: preguntas específicas, verificación de respuestas, documentación del uso10
Buen uso de Claude Code, verificación parcial7
Uso de Claude Code sin verificación o sin documentar4
No usó Claude Code o lo usó de forma indiscriminada2

Evidencia de buen uso de herramientas:

  • ¿Las preguntas a Claude Code son específicas y verificables?
  • ¿Verificó las respuestas de Claude Code antes de aceptarlas?
  • ¿Documentó cuándo Claude Code ayudó y cuándo no?
  • ¿Usó debugging manual cuando era más apropiado?

Sección 4: Retrospectiva (10 puntos)

CriterioPuntos
Reflexiva, específica, con ejemplos concretos y actionables10
Reflexiva y con algunos insights específicos7
Presente pero genérica ("aprendí mucho", "fue difícil")4
Superficial, corta, o ausente1

Una retrospectiva de 10/10 tiene:

  • Ejemplos específicos de qué fue difícil y por qué
  • Identificación de qué mental model o técnica fue más útil
  • Reflexión honesta sobre errores o cosas que haría diferente
  • Acciones concretas para mejorar tu proceso en el futuro

Tabla de Calificación Final

RangoCalificaciónDescripción
90-100ExcelenteDemuestra dominio profesional del proceso completo
75-89BuenoSólido en la mayoría de áreas, con espacio para mejorar
60-74AceptableCompletó el proyecto pero con gaps significativos
< 60Necesita refuerzoRevisar módulos anteriores y reintentar

Guía para la Retrospectiva

Por qué la retrospectiva importa

La retrospectiva no es un reporte de lo que hiciste. Es una reflexión sobre cómo lo hiciste y qué aprendiste del proceso. Los mejores developers no solo resuelven problemas — mejoran su proceso de resolución. La retrospectiva es donde eso sucede.

Preguntas guía

Responde estas preguntas en tu retrospectiva (300-500 palabras). No necesitas responder todas, pero tu retrospectiva debe cubrir al menos 4 de estos temas:

Sobre lo que encontraste

1. ¿Qué fue lo más difícil de encontrar? ¿Por qué?

Reflexiona sobre los findings que te costaron más. ¿Fue una hallucination sutil? ¿Un error de lógica que se veía correcto? ¿Un edge case que no se te ocurrió probar? Entender por qué algo fue difícil te ayuda a mejorar.

2. ¿Qué te sorprendió encontrar?

¿Hubo algún problema que no esperabas? ¿El código se veía bien en la primera lectura pero escondía algo? ¿Encontraste algo que no está en las categorías que anticipabas?

3. ¿Hubo falsos positivos? ¿Reportaste algo como problema que resultó no serlo?

Los falsos positivos son normales y valiosos. Si pensaste que algo era un bug y después descubriste que no lo era, reflexiona sobre por qué te confundiste.

Sobre tu proceso

4. ¿Qué mental model te ayudó más?

De los tres mental models del Módulo 2 (Managing an Intern, Circuit Breaker, Trust Calibration), ¿cuál aplicaste más? ¿Cuál fue más útil en la práctica? ¿Hay alguno que no aplicaste?

5. ¿Tu proceso de review fue efectivo? ¿Qué cambiarías?

¿Encontraste los problemas en las primeras pasadas o necesitaste volver? ¿El orden de review (seguridad → lógica → edge cases → calidad) fue útil? ¿Pasaste demasiado tiempo en una categoría y poco en otra?

6. ¿Cómo usaste Claude Code? ¿Fue efectivo?

¿Le hiciste preguntas específicas? ¿Verificaste sus respuestas? ¿Hubo momentos donde fue muy útil y otros donde no sirvió? ¿Lo usarías diferente la próxima vez?

Sobre lo que cambiarás

7. ¿Qué harías diferente la próxima vez?

Si tuvieras que hacer el mismo proyecto de nuevo, ¿qué cambiarías en tu proceso? ¿Empezarías por otro lugar? ¿Usarías herramientas diferentes? ¿Te enfocarías más en alguna categoría?

8. ¿Cómo cambiará esto tu workflow diario?

Esta guía te enseñó a revisar código generado por AI. ¿Cómo aplicarás esto en tu trabajo diario? ¿Adoptarás el checklist? ¿Cambiarás tu nivel de confianza en AI code? ¿Hay una práctica específica que incorporarás?

Formato de la retrospectiva

# Retrospectiva — Proyecto Integrador TaskFlow API

## Fecha: [fecha]
## Tiempo total del proyecto: [horas]

---

[300-500 palabras respondiendo las preguntas guía.
Usa primera persona. Sé específico. Da ejemplos.
No necesitas subtítulos — puede ser un texto fluido.]

---

## Acciones concretas para mi workflow

1. [Acción específica que tomarás en tu trabajo diario]
2. [Acción específica que tomarás en tu trabajo diario]
3. [Acción específica que tomarás en tu trabajo diario]

Ejemplo de Entrega Excelente

Ejemplo de Findings Document (extracto)

# TaskFlow API — Findings Document

## Información del Reviewer
- Nombre: María García
- Fecha: Marzo 15, 2026
- Tiempo total: 3.5 horas
  - Code review: 1.5 hrs
  - Debugging: 45 min
  - Corrección: 50 min
  - Documentación: 25 min

## Resumen Ejecutivo

El codebase de TaskFlow API implementa la funcionalidad 
básica de CRUD de tareas y autenticación, pero contiene 
múltiples vulnerabilidades de seguridad críticas 
(SQL injection, password en plaintext, secret hardcoded) 
que lo hacen inseguro para producción. Además, tiene 
problemas de lógica de negocio que violan 6 de los 
requisitos funcionales, y edge cases que causan crashes 
con inputs legítimos. Requiere correcciones significativas 
antes de cualquier deploy.

## Findings

| # | Severidad | Categoría | Archivo | Línea(s) | Descripción | Requisito | Impacto |
|---|-----------|-----------|---------|----------|-------------|-----------|---------|
| 1 | Critical | Security | config.py | 12 | JWT_SECRET_KEY tiene fallback hardcoded "super-secret-key-taskflow-2026". Cualquier persona con acceso al código puede forjar tokens válidos. | RF-02.3, RF-06.1 | Compromiso total de autenticación |
| 2 | Critical | Security | routes/auth.py | 18-20 | register() inserta user.password directamente sin hashear. Las contraseñas se almacenan en texto plano. | RF-01.2 | Exposición de todas las contraseñas si la DB es comprometida |
| 3 | Critical | Security | routes/users.py | 28-30 | search_users() usa f-string para construir query SQL: f"...WHERE name LIKE '%{query}%'". Vulnerable a SQL injection. | RF-06.2 | Un atacante puede extraer todos los datos de la DB |
| 4 | Critical | Security | routes/users.py | 25-30 | search_users() no requiere autenticación. Cualquier persona puede buscar usuarios sin estar logueado. | RF-02.4 | Exposición de datos de usuarios sin autorización |
| 5 | High | Logic | services/task_service.py | 98-101 | delete_task() ejecuta DELETE FROM (hard delete) en vez de UPDATE status = 'deleted' (soft delete). | RF-03.6 | Datos perdidos permanentemente, imposible recuperar |
| 6 | High | Logic | services/task_service.py | 23-28 | get_task_by_id() no filtra por user_id. Cualquier usuario autenticado puede ver cualquier tarea. | RF-03.7, RF-05.6 | Exposición de datos entre usuarios |
| 7 | High | Logic | services/task_service.py | 107-120 | get_user_stats() incluye tareas eliminadas en el conteo y porcentaje. | RF-04.2 | Estadísticas incorrectas |
| 8 | High | Validation | models.py | 14-16 | validate_password() acepta contraseñas de 4+ caracteres. RF-01.4 requiere 8 mínimo. | RF-01.4 | Contraseñas débiles aceptadas |
| 9 | Medium | Security | services/task_service.py | 47-51 | get_tasks() usa f-strings para insertar status y priority en la query SQL. | RF-06.2 | SQL injection a través de filtros |
| 10 | Medium | Edge Case | services/task_service.py | 118 | completion_percentage divide por total sin verificar que no sea 0. ZeroDivisionError para usuarios sin tareas. | RF-04.1 | Crash del endpoint con error 500 |
| 11 | Medium | Edge Case | services/task_service.py | 55 | offset = page * size. Para page=1, offset=10, saltando la primera página completa. | RF-03.2 | La primera página nunca muestra resultados |
| 12 | Medium | Validation | models.py | 37-40 | validate_title() acepta títulos de 1+ carácter. RF-05.1 requiere 3-100. | RF-05.1 | Títulos inválidos aceptados |
| 13 | Medium | Validation | models.py | — | No hay validación de priority ni status contra valores permitidos. | RF-05.2, RF-05.3 | Valores arbitrarios aceptados |
| 14 | Medium | Edge Case | routes/tasks.py | 30 | page=Query(default=1, ge=0) acepta page=0. | RF-05.4 | Paginación con valores inválidos |
| 15 | Low | Hallucination | main.py | 3 | from pydantic_settings import BaseSettings. El paquete pydantic-settings no está en requirements.txt ni instalado. | — | ModuleNotFoundError al arrancar |
| 16 | Low | Hallucination | services/auth_service.py | 7 | from bcrypt import verify_hash. La función verify_hash no existe en bcrypt. Las funciones reales son hashpw, gensalt, checkpw, kdf. | — | ImportError al arrancar |
| 17 | Low | Hallucination | services/task_service.py | 62 | cursor.fetchall(as_dict=True). fetchall() de sqlite3 no acepta parámetros. | — | TypeError al listar tareas |
| 18 | Low | Security | main.py | 16-21 | CORS permite todos los orígenes (allow_origins=["*"]). No es un problema de funcionalidad pero es mala práctica para producción. | — | Potencial CSRF en producción |

## Estadísticas
| Severidad | Encontrados | Total esperado |
|-----------|-------------|----------------|
| Critical  | 4           | 3-4            |
| High      | 4           | 4-5            |
| Medium    | 6           | 5-6            |
| Low       | 4           | 3-4            |
| **Total** | **18**      | **15-20**      |

Ejemplo de Retrospectiva Excelente

# Retrospectiva — Proyecto Integrador TaskFlow API

## Fecha: Marzo 15, 2026
## Tiempo total: 3.5 horas

---

Lo más difícil de encontrar fue la contraseña almacenada 
en texto plano en routes/auth.py. Suena contradictorio 
porque debería ser obvio, pero el archivo importa 
hash_password desde auth_service.py — la función existe 
y funciona. El problema es que register() nunca la llama. 
Pasé por ese archivo dos veces antes de notar que user.password 
se pasa directamente al INSERT sin transformación. Lo que me 
enseñó es que importar una función no significa usarla, y que 
mi code review estaba enfocado en "¿qué funciones existen?" 
cuando debería enfocarse en "¿qué funciones se llaman?"

El mental model que más me ayudó fue Trust Calibration. 
Al principio del review, mi instinto era revisar todo con 
la misma intensidad. Pero cuando apliqué Trust Calibration 
— baja confianza en auth y security, alta confianza en 
boilerplate — encontré los problemas críticos mucho más 
rápido. Los primeros 30 minutos enfocados en config.py, 
auth_service.py, y routes/auth.py me dieron 4 de los 
findings Critical. Si hubiera empezado por main.py 
o models.py, habría perdido tiempo en problemas de 
severidad baja.

Me sorprendió que el SQL injection en los filtros de 
tareas (services/task_service.py) fuera más sutil que 
el de búsqueda de usuarios. La búsqueda usa un f-string 
evidente: f"...WHERE name LIKE '%{query}%'". Pero los 
filtros en get_tasks() también usan f-strings para status 
y priority, y eso lo noté hasta la segunda pasada. 
Me enseñó que el SQL injection no siempre es un f-string 
en un WHERE — puede estar en cualquier parte de la query 
donde se inserta input del usuario.

Claude Code fue útil para verificar que el import 
de pydantic_settings no existía en la versión instalada. 
Le pregunté "¿BaseSettings está en pydantic 2.9 o necesita 
pydantic-settings separado?" y confirmó que es un paquete 
separado. También me ayudó a entender el offset de 
paginación — le pasé la fórmula y me confirmó que 
page * size salta la primera página. En ambos casos, 
verifiqué su respuesta contra la documentación.

Lo que haría diferente: dedicaría los primeros 5 minutos 
a trazar el flujo completo de cada operación antes de 
buscar bugs. Hice el review archivo por archivo, y eso 
me hizo perder la conexión entre capas. El bug de 
contraseña en plaintext lo habría encontrado antes si 
hubiera trazado el flujo register → hash → insert → DB 
de principio a fin.

---

## Acciones concretas para mi workflow

1. Siempre trazar el flujo de datos completo antes de 
   revisar archivos individuales, especialmente para auth 
   y operaciones con datos sensibles.
2. Aplicar Trust Calibration al inicio de cada code review: 
   marcar los archivos como "alta confianza" o "baja confianza" 
   y empezar por los de baja confianza.
3. Buscar SQL injection en TODOS los lugares donde se construyen 
   queries, no solo en los obvios. Crear un grep para f-strings 
   cerca de execute/cursor.

Ejemplo de Justificación Excelente

Para que calibres la calidad esperada, aquí hay un ejemplo completo de justificación para un fix:

## Fix #3: SQL Injection en Búsqueda de Usuarios

**Finding:** #3 — El endpoint search_users() usa f-string para 
construir la query SQL
**Severidad:** Critical
**Archivo:** routes/users.py
**Líneas afectadas:** 28-30

### Qué cambié
Reemplacé la query con f-string:
  f"SELECT id, email, name FROM users WHERE name LIKE '%{query}%'"
por una query con parámetro:
  "SELECT id, email, name FROM users WHERE name LIKE ?"
  con parámetro (f"%{query}%",)

También agregué Depends(get_current_user) al endpoint para 
requerir autenticación.

### Por qué el código original era incorrecto
La query construida con f-string es vulnerable a SQL injection 
(RF-06.2). Un atacante puede enviar como query:

  test' UNION SELECT password, email, name FROM users--

Esto modifica la query SQL para extraer contraseñas de todos 
los usuarios. Además, el endpoint no requiere autenticación 
(RF-02.4), permitiendo que cualquier persona ejecute el ataque 
sin siquiera tener una cuenta.

### Por qué mi corrección es correcta
1. Los parámetros SQL (?) son escapados automáticamente por 
   SQLite, previniendo la inyección de SQL arbitrario
2. El LIKE pattern se construye en Python (f"%{query}%") 
   y se pasa como parámetro, no se concatena en la query
3. Verifiqué ejecutando el mismo payload de SQL injection:
   la query ahora busca literalmente el string del ataque 
   como nombre, retornando 0 resultados
4. Depends(get_current_user) asegura que solo usuarios 
   autenticados pueden buscar

### Decisión regenerar/editar
- **Decisión:** Editar
- **Justificación:** Los cambios son dos: parameterizar la query 
  (2 líneas) y agregar el dependency de auth (1 línea). El 
  resto de la función está bien. Regenerar sería desproporcionado 
  para 3 líneas de cambio.

### Verificación
- **Método:** Ejecuté curl con payload de SQL injection
- **Resultado antes del fix:** 
  Retornó todos los usuarios con sus passwords
- **Resultado después del fix:** 
  Retornó lista vacía (búsqueda literal, sin inyección)
- **Método adicional:** Probé sin token de auth
- **Resultado:** 401 Unauthorized (correcto)

Contraste: Justificación insuficiente

## Fix #3: SQL Injection

Cambié la query para usar parámetros. 
También agregué autenticación.

La diferencia es evidente. La primera justificación demuestra que entiendes el problema, la solución, y verificaste que funciona. La segunda solo dice qué hiciste sin explicar por qué.


Cómo Escribir una Buena Retrospectiva

La estructura que funciona

Una retrospectiva efectiva tiene tres partes:

  1. Observaciones: Qué pasó durante el proyecto (hechos, no opiniones)
  2. Reflexiones: Qué aprendiste de lo que pasó
  3. Acciones: Qué vas a hacer diferente en el futuro

Señales de una retrospectiva superficial

Estas frases indican falta de reflexión:

  • ❌ "Aprendí mucho con este proyecto" — ¿Qué aprendiste exactamente?
  • ❌ "Fue muy interesante" — ¿Por qué? ¿Qué te interesó?
  • ❌ "Los bugs eran difíciles" — ¿Cuáles? ¿Por qué eran difíciles para ti?
  • ❌ "Usé Claude Code y me ayudó" — ¿En qué? ¿Cómo verificaste?
  • ❌ "Todo salió bien" — ¿No hubo nada que mejorar?

Señales de una retrospectiva reflexiva

Estas frases indican reflexión genuina:

  • ✅ "No detecté el SQL injection en los filtros hasta la segunda pasada porque estaba enfocado en los f-strings obvios"
  • ✅ "El mental model de Trust Calibration me hizo empezar por auth_service.py, donde encontré 3 de los 4 findings Critical"
  • ✅ "Claude Code me confirmó que pydantic_settings es un paquete separado, pero yo debería haber verificado requirements.txt primero"
  • ✅ "La próxima vez, voy a trazar el flujo de datos completo antes de revisar archivos individuales"

Preguntas Frecuentes

¿Qué pasa si no encontré todos los problemas?

Es normal. El proyecto tiene 15-20 problemas y encontrar 12-14 es un resultado sólido. Lo importante no es la perfección — es el proceso y la reflexión. Si encontraste 10 de 18, reflexiona en la retrospectiva sobre por qué te faltaron 8 y qué harías diferente.

¿Puedo volver a las fases anteriores?

Sí. El proceso no es estrictamente lineal. Si durante la corrección descubres un nuevo finding, agrégalo al findings document. Si durante la retrospectiva te das cuenta de que te saltaste algo, menciónalo. El proceso iterativo es más realista que el lineal.

¿Qué tan largo debe ser el findings document?

La tabla de findings debe tener tantas filas como problemas encontraste (idealmente 12-18). El resumen ejecutivo debe ser 2-3 oraciones. Las notas del proceso son opcionales pero recomendadas.

¿Las justificaciones deben ser largas?

No. Cada justificación debe ser concisa pero completa: qué cambió (1-2 oraciones), por qué era incorrecto (1-2 oraciones con referencia al requisito), por qué tu fix es correcto (1-2 oraciones), decisión regenerar/editar (1 oración). Entre 4 y 8 oraciones por fix.

¿La retrospectiva puede ser más larga que 500 palabras?

Sí, pero no necesita serlo. Una retrospectiva concisa y reflexiva de 350 palabras es mejor que una de 800 que repite los mismos puntos. Busca profundidad, no longitud.


Lista Completa de Problemas del Codebase

Después de completar tu entrega, puedes comparar tus findings contra esta lista completa. No la leas antes de terminar tu proyecto.

Ver lista completa de problemas (SPOILERS — solo después de entregar)

Problemas Critical (4)

  1. JWT Secret Hardcoded — config.py, línea 12. JWT_SECRET_KEY tiene fallback "super-secret-key-taskflow-2026". Categoría: Security.

  2. Password en Plaintext — routes/auth.py, línea 18-20. register() inserta user.password sin hashear. La función hash_password se importa pero nunca se llama. Categoría: Security.

  3. SQL Injection en Búsqueda — routes/users.py, línea 28-30. search_users() usa f-string: f"...WHERE name LIKE '%{query}%'". Categoría: Security.

  4. Endpoint sin Autenticación — routes/users.py, línea 25-30. search_users() no tiene Depends(get_current_user). Categoría: Security.

Problemas High (4)

  1. Hard Delete en vez de Soft Delete — services/task_service.py, línea 98-101. delete_task() usa DELETE FROM en vez de UPDATE ... SET status = 'deleted'. Viola RF-03.6. Categoría: Logic.

  2. No verifica propiedad de tarea — services/task_service.py, línea 23-28. get_task_by_id() no filtra por user_id. Cualquier usuario puede ver cualquier tarea. Viola RF-03.7. Categoría: Logic.

  3. Estadísticas incluyen tareas eliminadas — services/task_service.py, línea 107-120. get_user_stats() no excluye tareas con estado "deleted". Viola RF-04.2. Categoría: Logic.

  4. Validación de password insuficiente — models.py, línea 14-16. Acepta 4+ caracteres, RF-01.4 requiere 8+. Categoría: Logic.

Problemas Medium (6)

  1. SQL Injection en filtros de tareas — services/task_service.py, línea 47-51. Usa f-strings para insertar status y priority en la query. Viola RF-06.2. Categoría: Security.

  2. División por cero en estadísticas — services/task_service.py, línea 118. completion_percentage = by_status.get("completed", 0) / total * 100 crashea si total = 0. Categoría: Edge Case.

  3. Paginación off-by-one — services/task_service.py, línea 55. offset = page * size. Para page=1, offset=10, saltando la primera página. Debería ser (page - 1) * size. Categoría: Edge Case.

  4. Validación de título insuficiente — models.py, línea 37-40. Acepta títulos de 1+ carácter. RF-05.1 requiere 3-100. Categoría: Validation.

  5. Sin validación de prioridad — models.py. No hay validador que restrinja prioridad a low/medium/high. Acepta cualquier string. Viola RF-05.2. Categoría: Validation.

  6. Paginación acepta page=0 — routes/tasks.py, línea 30. ge=0 debería ser ge=1. Viola RF-05.4. Categoría: Edge Case.

Problemas Low (5-6)

  1. Import de paquete inexistente — main.py, línea 3. from pydantic_settings import BaseSettings. El paquete no está instalado. No se usa la clase. Categoría: Hallucination.

  2. Import de función inexistente — services/auth_service.py, línea 7. from bcrypt import verify_hash. La función verify_hash no existe en bcrypt. Las funciones reales son hashpw, gensalt, checkpw, kdf. Categoría: Hallucination.

  3. Parámetro inventado en fetchall() — services/task_service.py, línea 62. cursor.fetchall(as_dict=True). El método fetchall() de sqlite3 no acepta parámetros. Causa TypeError al listar tareas. Categoría: Hallucination.

  4. Sin validación de estado — models.py. No hay validador para restrictar estado a pending/in_progress/completed. Viola RF-05.3. Categoría: Validation.

  5. CORS permisivo — main.py, línea 16-21. allow_origins=["*"]. No es un bug funcional pero es mala práctica de seguridad. Categoría: Security (Low).

  6. DEBUG hardcoded True — config.py, línea 8. DEBUG: bool = True. En producción expondría stack traces. Viola RF-06.3. Categoría: Security (Low).


Auto-evaluación Detallada

Después de completar tu entrega, usa esta guía para calcular tu puntuación:

Paso 1: Cuenta tus findings

Compara tu findings document contra la lista completa de problemas (en la sección de spoilers más arriba). Para cada finding:

  • ✅ Encontrado y correcto: Lo identificaste y la descripción es precisa → cuenta como finding
  • ⚠️ Encontrado pero incompleto: Lo identificaste pero la descripción es vaga o la severidad es incorrecta → cuenta como 0.5
  • ❌ No encontrado: No aparece en tu findings document → no cuenta
  • ❌ Falso positivo: Reportaste algo que no es un problema real → resta 0.5

Paso 2: Evalúa tus correcciones

Para cada fix que implementaste:

  • ✅ Fix correcto y verificado: El fix resuelve el problema sin introducir otros → full credit
  • ⚠️ Fix parcial: Resuelve parte del problema o la verificación es incompleta → half credit
  • ❌ Fix incorrecto: Introduce nuevos problemas o no resuelve el original → no credit

Paso 3: Evalúa tu proceso

Hazte estas preguntas honestamente:

  1. ¿Seguiste las fases en orden o saltaste entre ellas?
  2. ¿Documentaste el debugging en tiempo real o al final?
  3. ¿Priorizaste por severidad o por conveniencia?
  4. ¿Verificaste cada fix antes de pasar al siguiente?
  5. ¿Usaste Claude Code de forma estratégica o indiscriminada?

Paso 4: Evalúa tu retrospectiva

Lee tu retrospectiva y pregúntate:

  • ¿Tiene ejemplos específicos o solo generalidades?
  • ¿Menciona qué mental models usaste?
  • ¿Identifica áreas de mejora concretas?
  • ¿Las acciones son implementables en tu trabajo diario?

Qué Hacer Después de Entregar

Si obtuviste 90+

Excelente. Tienes un proceso profesional sólido. Los próximos pasos:

  • Aplica el checklist en tus PRs diarios
  • Enseña el proceso a un compañero de equipo
  • Contribuye con items adicionales al checklist basados en tu experiencia

Si obtuviste 75-89

Buen trabajo. Tienes las bases pero hay áreas para mejorar. Recomendaciones:

  • Revisa los findings que te faltaron — ¿por qué no los viste?
  • Practica con otro codebase aplicando el mismo proceso
  • Refuerza el módulo que corresponde a tu categoría más débil

Si obtuviste 60-74

Completaste el proyecto pero hay gaps significativos. Recomendaciones:

  • Revisa los módulos 3, 4, y 5 con atención especial a los ejercicios
  • Practica el checklist de code review con código más simple primero
  • Haz el proyecto una segunda vez después de revisar los módulos

Si obtuviste menos de 60

No te desanimes — esto indica que necesitas más práctica con los módulos individuales antes del proyecto integrador:

  • Revisa y completa todos los ejercicios de los módulos 3-6
  • Asegúrate de entender cada item del checklist del módulo 4
  • Repite el proyecto después de completar los módulos

Conexión con la Siguiente Guía

Lo que aprendiste en esta guía

Con este proyecto completado, tienes un proceso profesional demostrado para manejar código generado por AI:

  • ✅ Awareness: Sabes que AI code necesita validación rigurosa (Módulo 1)
  • ✅ Mental models: Tienes frameworks para decidir qué revisar y cuándo (Módulo 2)
  • ✅ Detección: Puedes identificar hallucinations sutiles (Módulo 3)
  • ✅ Code review: Tienes un checklist profesional de 20 items (Módulo 4)
  • ✅ Patrones: Reconoces los errores más comunes en AI code (Módulo 5)
  • ✅ Debugging: Puedes diagnosticar bugs de runtime con Claude Code (Módulo 6)
  • ✅ Decisiones: Sabes cuándo regenerar vs editar (Módulo 7)
  • ✅ Integración: Puedes aplicar todo junto en un codebase real (Módulo 8)

Lo que viene después

La Guía 7: Git Workflows with Claude Code aplica todo lo que aprendiste aquí al contexto de equipos y control de versiones:

  • Code review en PRs: El checklist que construiste aquí se aplica a Pull Requests reales generados por Claude Code
  • Flujos de branching: Cómo estructurar branches cuando usas AI para generar código
  • Commits con AI: Cómo Claude Code puede generar commits, y cómo validar que los mensajes y cambios son correctos
  • Colaboración: Cómo trabajar en equipo cuando algunos miembros usan AI y otros no
  • Quality gates: Automatizar verificaciones de AI code en el pipeline de CI/CD

El skill que demostraste en este proyecto — recibir código, evaluarlo con criterio, corregirlo, y documentar tu proceso — es exactamente lo que harás todos los días cuando revises PRs de compañeros que usan Claude Code. La diferencia es que ahora tienes un proceso profesional para hacerlo.


Resumen de Habilidades Demostradas

Al completar este proyecto, has demostrado las siguientes habilidades profesionales:

Habilidades técnicas

HabilidadDónde la demostraste
Detectar hallucinations en imports y APIsFindings de pydantic_settings, verify_hash, fetchall(as_dict)
Identificar SQL injectionFindings en routes/users.py y services/task_service.py
Verificar manejo de contraseñasFinding de password en plaintext en routes/auth.py
Evaluar configuración de seguridadFinding de JWT secret hardcoded
Detectar lógica de negocio incorrectaFindings de delete, autorización, estadísticas
Encontrar edge casesFindings de paginación, división por cero
Debugging sistemáticoReproducir y confirmar runtime bugs
Corrección justificada de códigoFixes con explicación y verificación

Habilidades de proceso

HabilidadDónde la demostraste
Priorización por severidadOrden de correcciones (Critical → Low)
Documentación profesionalFindings document con formato completo
Uso estratégico de herramientas AIPreguntas específicas a Claude Code con verificación
Decisiones informadasFramework regenerar vs editar aplicado
Reflexión y mejora continuaRetrospectiva con acciones concretas

Habilidades de comunicación

HabilidadDónde la demostraste
Reportar findings con contextoTabla de findings con severidad e impacto
Justificar decisiones técnicasDocumento de justificaciones
Comunicar riesgoClasificación de severidad correcta
Reflexión escritaRetrospectiva articulada

Estas no son habilidades teóricas — las acabas de ejercitar con código real, problemas reales, y documentación real. La próxima vez que recibas un PR para revisar, estas habilidades estarán ahí.


Checklist Final Antes de Entregar

Usa esta lista para verificar que tu entrega está completa:

Findings Document

  • Tiene información del reviewer (nombre, fecha, tiempo)
  • Tiene resumen ejecutivo (2-3 oraciones)
  • Tabla de findings con todas las columnas: #, severidad, categoría, archivo, líneas, descripción, requisito, impacto
  • Tiene al menos 12 findings documentados
  • Todos los findings Critical tienen severidad correcta
  • Tiene tabla de estadísticas de findings
  • Tiene notas del proceso

Código Corregido

  • Cada archivo corregido tiene comentario de correcciones al inicio
  • Todos los fixes de severidad Critical están implementados
  • Todos los fixes de severidad High están implementados
  • La mayoría de fixes Medium están implementados
  • El codebase corregido se ejecuta sin errores
  • Los endpoints básicos funcionan correctamente

Justificaciones

  • Cada fix tiene justificación escrita
  • Cada justificación incluye: qué cambió, por qué era incorrecto, por qué el fix es correcto
  • Cada justificación referencia el requisito funcional violado
  • Cada justificación documenta la decisión regenerar/editar
  • Las justificaciones incluyen cómo se verificó cada fix

Retrospectiva

  • Tiene entre 300-500 palabras
  • Incluye ejemplos específicos (no solo generalidades)
  • Menciona qué mental models o técnicas fueron más útiles
  • Identifica qué fue difícil y por qué
  • Incluye al menos 3 acciones concretas para el workflow diario
  • Es honesta y reflexiva

Cierre

Este proyecto no es el final de tu aprendizaje — es el comienzo de un hábito. La primera vez que hagas code review de AI-generated code con el checklist del módulo 4, va a ser lento. La quinta vez, va a ser más rápido. La vigésima vez, va a ser automático. Y la centésima vez, vas a encontrar un bug que habría llegado a producción si no hubieras revisado.

Ese es el valor de este proyecto: no el código que corregiste hoy, sino el proceso que internalizaste para corregir todo el código que vas a recibir mañana.

Lo que separa a developers que usan AI de developers que dominan AI no es la herramienta — es el criterio. Y el criterio se construye practicando exactamente lo que hiciste aquí.


Debugging & Code Review with Claude Code — Módulo 8, Cápsula 05 Claude Code Agentic Development Path — Guía #6 de 11