Proyecto compartido. En el taller de Intermodular que abre esta semana has trabajado la defensa del proceso. En Servidor continúas la implementación del mismo producto.
Se explica
25 minutos · explicación y demostración
Ya has revisado los criterios del primer trimestre. Hoy defenderás cómo funciona el backend y comprobarás que otra persona puede verificarlo. En Servidor explicarás código, reglas, persistencia y pruebas; en Intermodular se evalúa el flujo seguido para publicar esa versión.
Esta demostración es común con Intermodular 14. Relaciona la explicación técnica con las evidencias de proceso del mismo producto. El bloque de cinco minutos descrito abajo corresponde a la parte técnica, no a una segunda defensa independiente.
La revisión de código no es buscar erratas
En muchas empresas novatas la revisión de código se limita a mirar si faltan espacios o si los nombres de variables son bonitos. Eso es una pérdida de tiempo que debería resolver un formateador automático.
Un Code Review de ingeniería de software audita la salud estructural y la viabilidad técnica del sistema a través de cinco vectores críticos:
- 1. Arquitectura (capas desacopladas)
- 2. Persistencia (LAZY, N+1, transacciones)
- 3. Seguridad y Contrato (validación DTOs)
- 4. Manejo de Errores (códigos semánticos)
- 5. Calidad de Tests (sin mocks en BD)
| Vector de auditoría | Qué debes buscar activamente en el código ajeno |
|---|---|
| 1 · Arquitectura y Capas | ¿Se cuelan entidades @Entity en las respuestas de los controladores? ¿Hay llamadas a repositorios desde el controlador sin pasar por el servicio? ¿El servicio conoce clases web o códigos HTTP? |
| 2 · Persistencia y Rendimiento | ¿Hay relaciones con FetchType.EAGER? ¿Se usa List en @ManyToMany? ¿Están los métodos de escritura cubiertos por @Transactional(rollbackFor = Exception.class)? ¿Hay riesgo evidente de problema N+1? |
| 3 · Validación y Contrato | ¿Tienen los DTOs anotaciones Bean Validation (@NotBlank, @NotNull, @Size)? ¿Lleva el controlador @Valid en los @RequestBody? ¿Se devuelven cabeceras Location en los POST? |
| 4 · Manejo de Errores | ¿La API devuelve códigos de estado coherentes (404 para no encontrado, 409 para conflicto de unicidad, 400 para validación)? ¿Se evitan errores 500 con trazas de pila expuestas al cliente? |
| 5 · Batería de Pruebas | ¿La suite compila y pasa al 100 % con ./mvnw test? ¿Los tests de repositorio usan TestEntityManager con flush() y clear() para evitar falsos positivos de caché? |
Los niveles de severidad en la revisión de código
Para que la revisión sea profesional, constructiva y trazable, clasificamos cada observación según su nivel de severidad (ya sea como comentarios en la Pull Request de GitHub o en las notas de revisión del aula):
- 🔴 Bloqueante (Blocker)
- Fallos graves de integridad, corrupción de datos, consultas N+1 masivas, exposición de secretos o ausencia de validación que provoca errores 500 no capturados. El código no puede fusionarse hasta que se resuelva.
- 🟡 Mayor (Major)
- Violación de separación de capas (ej: DTOs dentro del servicio), ausencia de
rollbackFor = Exception.classo tests con aserciones frágiles. - 🟢 Sugerencia (Nitpick)
- Oportunidades de simplificación con streams, nombres de métodos más expresivos o mejoras en el README.
Ejemplo de observación técnica bien formulada:
### [🔴 Bloqueante] Riesgo de problema N+1 en GET /tareas
* **Ubicación:** `TareaService.java`, línea 42.
* **Problema:** Se llama a `tareaRepo.findAll()` y en el bucle del mapper se accede a `t.getProyecto().getNombre()`. Al estar configurado `FetchType.LAZY`, esto provocará una consulta SQL adicional a PostgreSQL por cada tarea devuelta.
* **Propuesta de solución:** Añadir en `TareaRepository` un método con `@Query("SELECT t FROM Tarea t JOIN FETCH t.proyecto")` para recuperar la relación en una única sentencia SQL unificada.
Se trabaja
140 minutos · implementación guiada sobre el proyecto propio
Paso 1 · Retomar el proyecto y preparar la comprobación
- Abre el repositorio y la URL del backend. Identifica el mismo commit en las evidencias de la versión que vas a defender.
- Prepara datos de demostración y selecciona una operación completa, una regla rechazada y una consulta con relaciones.
- Localiza el controlador, servicio, repositorio y test de esa operación para poder recorrerlos sin buscar durante la explicación.
Paso 2 · El protocolo de la defensa técnica individual (5 minutos cronometrados)
Prepara una secuencia breve en tu colección: consulta correcta, escritura válida, regla rechazada y una consulta que use relaciones. Abre también los métodos que las atienden. Ensaya con un compañero: uno ejecuta y explica; el otro comprueba que la respuesta y la versión corresponden al repositorio entregado. Si aparece un fallo, registra la petición exacta y corrige su causa antes de volver a ensayar. No memorices respuestas sobre una arquitectura distinta de la tuya.
El tiempo se reparte con precisión militar:
[ Minuto 1 ] Visión general: arquitectura de capas y modelo relacional en PostgreSQL.
[ Minuto 2 ] La decisión técnica más difícil: qué problema tuviste y cómo lo resolviste.
[ Minuto 3 ] Evidencia de bitácora: muestra un bloqueo técnico real que superaste y su solución.
[ Minuto 4 ] Demostración en vivo: ejecución de ./mvnw test y petición real en Bruno con SQL.
[ Minuto 5 ] Pregunta sorpresa del tribunal: respuesta conceptual y justificación teórica.
El principio de honestidad técnica
Si el tribunal te señala un error o limitación en tu diseño, jamás inventes una excusa ni intentes taparlo.
Un ingeniero profesional responde: «Tienes razón; en esta versión priorizamos X y aceptamos ese compromiso técnico. Para solucionarlo en producción implementaríamos Y mediante este cambio...». Esa respuesta demuestra madurez y dominio real de la materia.
Paso 3 · Auditoría cruzada y refactorización
Clona la versión de otro equipo en otra carpeta y utiliza una base de desarrollo propia, configurada como indica su README. Ejecuta primero los tests y después la colección, con el backend encendido. Para cada observación escribe requisito, archivo o petición, resultado esperado y observado. Corrige después tu propio proyecto con esos mismos criterios, una observación cada vez, y actualiza el registro de la sesión en GitHub.
-
Clona el repositorio de tus compañeros en una carpeta independiente.
-
Ejecuta
./mvnw testpara verificar si su suite pasa en verde a la primera. -
Abre su código y revisa los cinco vectores de auditoría con la tabla anterior.
-
Deja al menos un aspecto positivo bien resuelto y tres observaciones técnicas justificadas categorizadas por severidad (como comentarios en su Pull Request de GitHub o en la sesión de revisión de aula).
-
Revisa las observaciones que te han dejado tus revisores.
-
Aplica las correcciones a las observaciones bloqueantes y mayores.
-
Vuelve a ejecutar
./mvnw testpara asegurar que nada se ha roto. -
Haz un commit de entrega final:
git commit -m "refactor(review): resolver observaciones de auditoria tecnica".
Prepara tu guion de 5 minutos asegurándote de tener la terminal lista con PostgreSQL arrancado, el proyecto corriendo y las peticiones preparadas en pestañas.
Estructura el guion en cuatro bloques breves, y para cada uno ten preparado qué vas a enseñar en pantalla mientras hablas:
| Tiempo | Qué cuentas | Qué enseñas mientras |
|---|---|---|
| 0–1 min | El modelo: qué entidades hay y cómo se relacionan | El diagrama y las clases @Entity |
| 1–3 min | El camino feliz completo | La colección ejecutándose: alta, consulta y borrado |
| 3–4 min | Un caso de error de verdad | Un 400 de validación y un 404, con su cuerpo RFC 7807 |
| 4–5 min | Qué no está terminado | La lista de deuda técnica |
Las tres preguntas que caen casi siempre en esta primera defensa, y que conviene llevar preparadas:
- «Enséñame dónde está la regla de negocio.» No se contesta con palabras: se abre el
servicey se señala el método. - «¿Por qué este endpoint devuelve 404 y este otro 409?» Es la pregunta que comprueba si entendiste la UD3 o si copiaste los códigos.
- «Si te pido cambiar de PostgreSQL a otra base de datos, ¿qué tendrías que tocar?» La respuesta correcta señala que el
serviceno cambia, y es la prueba de que la arquitectura de la UD4 sirvió para algo.
- Cómo saber que lo has terminado
- Tu proyecto arranca desde cero en la máquina del equipo revisor; has dejado y recibido observaciones categorizadas por severidad; las bloqueantes están corregidas y la suite sigue en verde; y has ensayado la defensa entera con el cronómetro delante al menos una vez.
Paso 4 · Comprobar y registrar el resultado del proyecto
- Reproduce el caso permitido y el rechazado, y explica qué capa decide cada resultado y qué datos quedan almacenados.
- Haz que otra persona siga el README y registre cualquier paso que falte. Incorpora la corrección y deja el commit final de la revisión identificado.
Ampliación si has completado el trabajo
Primero termina y verifica los pasos anteriores. Estos retos profundizan en el mismo contenido; no sustituyen la entrega ni obligan a iniciar otro proyecto.
Reto · El simulador de preguntas de tribunal técnico
Ensaya tu respuesta a estas tres preguntas típicas de tribunal de evaluación y entrevistas técnicas:
-
Pregunta del tribunal: «Veo que en tus consultas de lectura pones
@Transactional(readOnly = true). ¿Qué optimización concreta hace Hibernate y el driver JDBC con esa anotación?» -
(Respuesta esperada: Hibernate desactiva el dirty checking sobre las entidades leídas, ahorrando ciclos de CPU y memoria RAM al no tener que mantener copias de comparación para actualización).
-
Pregunta del tribunal: «Si mañana el equipo de frontend te pide que en la respuesta de
GET /proyectos/{id}el campoactivose llameestaHabilitado, ¿cuántos archivos de tu aplicación tendrías que modificar?» -
(Respuesta esperada: Únicamente el DTO
ProyectoResponsey elProyectoMapper. La entidad JPA, la base de datos PostgreSQL y las reglas del servicio permanecen 100 % inalteradas gracias a la arquitectura desacoplada). -
Pregunta del tribunal: «¿Qué ocurriría si dos peticiones HTTP intentan crear simultáneamente un proyecto con el mismo nombre en el mismo milisegundo?»
-
(Respuesta esperada: Ambas pasarían la validación del servicio
existsByNombre, pero la restricción físicaUNIQUEde PostgreSQL abortaría una de ellas conDataIntegrityViolationException, garantizando la integridad de datos).
Ver respuestas
1 · Bloqueante (Blocker: impide la fusión hasta solucionarse), Mayor (Major: problema de arquitectura o robustez importante) y Sugerencia (Nitpick: mejora de estilo o simplificación menor).
2 · Porque acopla el contrato público de la API al esquema físico de la base de datos, puede provocar bucles infinitos de serialización JSON (StackOverflowError) y expone datos internos no deseados.
3 · Desactiva el mecanismo de Dirty Checking (Hibernate no toma una instantánea en memoria de la entidad para comparar cambios al cerrar la transacción, ahorrando memoria y tiempo de CPU).
4 · Reconociendo con sinceridad el límite del conocimiento puntual, explicando qué hipótesis técnica tiene y describiendo cómo investigaría o verificaría la solución en la documentación oficial.
Cierre
15 minutos · resultado comprobable y explicación individual
Al terminar la sesión:
Se entrega la misma versión en ambos módulos: aquí se evalúan código y funcionamiento; en Intermodular, workflow, CI, revisión y puesta en producción.
Cada integrante explica una decisión del código apoyándose en una de las comprobaciones realizadas.