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 encontrados | Puntos |
|---|---|
| 16-18 de 18 | 20 |
| 14-15 de 18 | 17 |
| 12-13 de 18 | 14 |
| 10-11 de 18 | 11 |
| 8-9 de 18 | 8 |
| < 8 de 18 | 5 |
Severidad correcta (10 puntos)
| Criterio | Puntos |
|---|---|
| Severidad correcta en 90%+ de los findings | 10 |
| 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)
| Criterio | Puntos |
|---|---|
| Cada finding tiene: descripción clara, archivo, línea, impacto, requisito violado | 10 |
| La mayoría tiene toda la información, algunos incompletos | 7 |
| Información parcial en la mayoría de los findings | 4 |
| Findings con solo descripción, sin contexto | 2 |
Sección 2: Correcciones (30 puntos)
Correcciones correctas (15 puntos)
| Criterio | Puntos |
|---|---|
| Todos los fixes de Critical y High son correctos | 15 |
| La mayoría de Critical y High son correctos, alguno parcial | 12 |
| Algunos fixes son correctos, otros incorrectos o parciales | 8 |
| La mayoría de los fixes son incorrectos o no implementados | 4 |
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)
| Criterio | Puntos |
|---|---|
| Cada fix tiene justificación completa con referencia a requisitos | 10 |
| La mayoría tiene justificación, algunas superficiales | 7 |
| Justificaciones presentes pero genéricas | 4 |
| Sin justificaciones o con solo "lo arreglé" | 1 |
Decisiones regenerar/editar (5 puntos)
| Criterio | Puntos |
|---|---|
| Cada fix documenta la decisión con justificación razonable | 5 |
| La mayoría documenta la decisión | 3 |
| Pocas decisiones documentadas | 1 |
Sección 3: Proceso (20 puntos)
Proceso sistemático (10 puntos)
| Criterio | Puntos |
|---|---|
| Siguió las fases en orden (review → debug → fix), documentando cada paso | 10 |
| Siguió un proceso razonable, documentación parcial | 7 |
| Proceso ad-hoc pero completó las tareas | 4 |
| Sin evidencia de proceso sistemático | 1 |
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)
| Criterio | Puntos |
|---|---|
| Uso estratégico de Claude Code: preguntas específicas, verificación de respuestas, documentación del uso | 10 |
| Buen uso de Claude Code, verificación parcial | 7 |
| Uso de Claude Code sin verificación o sin documentar | 4 |
| No usó Claude Code o lo usó de forma indiscriminada | 2 |
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)
| Criterio | Puntos |
|---|---|
| Reflexiva, específica, con ejemplos concretos y actionables | 10 |
| Reflexiva y con algunos insights específicos | 7 |
| Presente pero genérica ("aprendí mucho", "fue difícil") | 4 |
| Superficial, corta, o ausente | 1 |
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
| Rango | Calificación | Descripción |
|---|---|---|
| 90-100 | Excelente | Demuestra dominio profesional del proceso completo |
| 75-89 | Bueno | Sólido en la mayoría de áreas, con espacio para mejorar |
| 60-74 | Aceptable | Completó el proyecto pero con gaps significativos |
| < 60 | Necesita refuerzo | Revisar 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:
- Observaciones: Qué pasó durante el proyecto (hechos, no opiniones)
- Reflexiones: Qué aprendiste de lo que pasó
- 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)
-
JWT Secret Hardcoded —
config.py, línea 12.JWT_SECRET_KEYtiene fallback"super-secret-key-taskflow-2026". Categoría: Security. -
Password en Plaintext —
routes/auth.py, línea 18-20.register()insertauser.passwordsin hashear. La funciónhash_passwordse importa pero nunca se llama. Categoría: Security. -
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. -
Endpoint sin Autenticación —
routes/users.py, línea 25-30.search_users()no tieneDepends(get_current_user). Categoría: Security.
Problemas High (4)
-
Hard Delete en vez de Soft Delete —
services/task_service.py, línea 98-101.delete_task()usaDELETE FROMen vez deUPDATE ... SET status = 'deleted'. Viola RF-03.6. Categoría: Logic. -
No verifica propiedad de tarea —
services/task_service.py, línea 23-28.get_task_by_id()no filtra poruser_id. Cualquier usuario puede ver cualquier tarea. Viola RF-03.7. Categoría: Logic. -
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. -
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)
-
SQL Injection en filtros de tareas —
services/task_service.py, línea 47-51. Usa f-strings para insertarstatusypriorityen la query. Viola RF-06.2. Categoría: Security. -
División por cero en estadísticas —
services/task_service.py, línea 118.completion_percentage = by_status.get("completed", 0) / total * 100crashea sitotal = 0. Categoría: Edge Case. -
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. -
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. -
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. -
Paginación acepta page=0 —
routes/tasks.py, línea 30.ge=0debería serge=1. Viola RF-05.4. Categoría: Edge Case.
Problemas Low (5-6)
-
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. -
Import de función inexistente —
services/auth_service.py, línea 7.from bcrypt import verify_hash. La funciónverify_hashno existe en bcrypt. Las funciones reales sonhashpw,gensalt,checkpw,kdf. Categoría: Hallucination. -
Parámetro inventado en fetchall() —
services/task_service.py, línea 62.cursor.fetchall(as_dict=True). El métodofetchall()de sqlite3 no acepta parámetros. CausaTypeErroral listar tareas. Categoría: Hallucination. -
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. -
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). -
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:
- ¿Seguiste las fases en orden o saltaste entre ellas?
- ¿Documentaste el debugging en tiempo real o al final?
- ¿Priorizaste por severidad o por conveniencia?
- ¿Verificaste cada fix antes de pasar al siguiente?
- ¿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
| Habilidad | Dónde la demostraste |
|---|---|
| Detectar hallucinations en imports y APIs | Findings de pydantic_settings, verify_hash, fetchall(as_dict) |
| Identificar SQL injection | Findings en routes/users.py y services/task_service.py |
| Verificar manejo de contraseñas | Finding de password en plaintext en routes/auth.py |
| Evaluar configuración de seguridad | Finding de JWT secret hardcoded |
| Detectar lógica de negocio incorrecta | Findings de delete, autorización, estadísticas |
| Encontrar edge cases | Findings de paginación, división por cero |
| Debugging sistemático | Reproducir y confirmar runtime bugs |
| Corrección justificada de código | Fixes con explicación y verificación |
Habilidades de proceso
| Habilidad | Dónde la demostraste |
|---|---|
| Priorización por severidad | Orden de correcciones (Critical → Low) |
| Documentación profesional | Findings document con formato completo |
| Uso estratégico de herramientas AI | Preguntas específicas a Claude Code con verificación |
| Decisiones informadas | Framework regenerar vs editar aplicado |
| Reflexión y mejora continua | Retrospectiva con acciones concretas |
Habilidades de comunicación
| Habilidad | Dónde la demostraste |
|---|---|
| Reportar findings con contexto | Tabla de findings con severidad e impacto |
| Justificar decisiones técnicas | Documento de justificaciones |
| Comunicar riesgo | Clasificación de severidad correcta |
| Reflexión escrita | Retrospectiva 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