Entrega 1 Deuda tecnica - JuanVargas0325/Prueba GitHub Wiki

Entrega 1 – Reporte de deuda técnica

Grupo N° completar · Integrantes

Deudas identificadas durante la construcción, el análisis de SonarQube y las pruebas de carga, con su estado y su prioridad (lineamientos, sección 8).

Deudas identificadas

DT-01 – Pruebas de integración de los repositorios SQL

Campo Detalle
Descripción Las consultas de internal/repositorio no tenían pruebas automáticas contra una base de datos real.
Componente Capa de datos (internal/repositorio, internal/basedatos)
Origen Se priorizaron primero las pruebas unitarias de la lógica de negocio.
Impacto Pruebas y confiabilidad
Prioridad Alta
Riesgo Regresiones en la persistencia que el pipeline no detectaría.
Acción tomada Se agregaron pruebas de integración (-tags integracion) contra PostgreSQL, incluida una prueba de concurrencia de las reglas de horas. Se ejecutan en CI con un contenedor de PostgreSQL, junto con una prueba de punta a punta (Newman sobre Docker Compose).
Estado Resuelta

DT-02 – Almacenamiento de archivos en un volumen local

Campo Detalle
Descripción Los PDF y adjuntos se guardan en un volumen de Docker que solo existe en una máquina.
Componente internal/almacenamiento, volumen archivos
Origen Decisión deliberada para la Entrega 1 (despliegue local).
Impacto Escalabilidad y disponibilidad: con varias instancias en distintas máquinas (Entrega 3), los archivos no estarían compartidos.
Prioridad Media (alta para la Entrega 2 o 3)
Riesgo Reportes o adjuntos registrados cuyo archivo no está en la instancia que atiende la descarga.
Acción propuesta Implementar Cloud Storage como otro tipo de almacenamiento: almacenamiento/gcs.go y un caso más en almacenamiento.Nuevo (ALMACENAMIENTO_TIPO).
Estado Identificada. Preparada: la API y el worker ya crean el almacenamiento con almacenamiento.Nuevo, así que el cambio no toca los servicios ni los main.

DT-03 – Envío de datos de estudiantes a un proveedor externo de IA

Campo Detalle
Descripción Las descripciones y observaciones de las tareas se envían al servicio LLM configurado. Se excluyen el nombre y el correo, pero el texto libre podría contener datos personales.
Componente internal/ia
Origen Requerimiento RF-14 con un proveedor externo.
Impacto Seguridad y privacidad
Prioridad Media
Riesgo Exposición de información personal a un tercero según sus políticas de retención.
Acción propuesta Documentar el proveedor elegido y sus políticas; evaluar un modelo local (Ollama) o anonimizar el texto libre.
Estado Parcialmente resuelta (se excluyen nombre, correo y horas contratadas)

DT-04 – Tokens JWT sin revocación ni renovación

Campo Detalle
Descripción Los tokens son válidos hasta que expiran (JWT_EXPIRACION, 8 h). No hay cierre de sesión en el servidor. Si el administrador cambia los roles de un usuario, el cambio aplica en su siguiente inicio de sesión.
Componente internal/auth, internal/handler/middleware.go
Origen Simplificación deliberada; el enunciado pide autenticación local básica (RNF-03).
Impacto Seguridad
Prioridad Baja
Riesgo Un token filtrado o un rol retirado siguen siendo válidos hasta la expiración.
Acción propuesta Expiraciones cortas con refresh token, o una versión de sesión por usuario verificada en cada petición.
Estado Identificada

DT-05 – Sin límite de intentos de inicio de sesión

Campo Detalle
Descripción /api/v1/auth/login no limita los intentos fallidos por IP o por usuario.
Componente Nginx / internal/handler
Origen Fuera del alcance mínimo de la Entrega 1.
Impacto Seguridad (fuerza bruta)
Prioridad Media
Riesgo Adivinación de contraseñas.
Acción propuesta limit_req en Nginx para la ruta de login o un limitador en la API.
Estado Identificada

DT-06 – Reportes de lotes anteriores sin limpieza

Campo Detalle
Descripción Cada nuevo lote de la misma semana genera PDF nuevos. Los anteriores se conservan para trazabilidad, sin una política de retención.
Componente Módulo de reportes, almacenamiento
Origen Decisión provisional.
Impacto Operación y costo de almacenamiento
Prioridad Baja
Riesgo Crecimiento indefinido del volumen.
Acción propuesta Conservar solo el último lote por semana o aplicar reglas de ciclo de vida en Cloud Storage.
Estado Identificada

DT-07 – Adjuntos validados solo por extensión

Campo Detalle
Descripción Los adjuntos se aceptan según su extensión (lista blanca), sin inspeccionar el contenido. Un archivo renombrado pasaría la validación.
Componente internal/dominio/tarea.go, internal/servicio/tareas.go
Origen Simplificación de la primera versión.
Impacto Seguridad. Mitigado: se descargan siempre como adjunto con nosniff, así el navegador no los ejecuta.
Prioridad Baja
Riesgo Almacenamiento de contenido no deseado.
Acción propuesta Verificar la firma del archivo (magic bytes) y, en la nube, analizarlo con un antivirus.
Estado Identificada

DT-08 – Seguimiento semanal calculado en cada consulta

Campo Detalle
Descripción El estado "sin reporte" y los consolidados se calculan en memoria en cada consulta, a partir de vinculaciones y tareas. No se guardan.
Componente internal/dominio/seguimiento.go, internal/servicio/seguimiento.go
Origen Diseño deliberado: el estado es derivado (RN-36) y así siempre es consistente.
Impacto Rendimiento. Medido en las pruebas de carga (escenario E2): la vista principal del profesor se estabilizaba en ~765 peticiones/s sin saturar la CPU, y con ~3.000 tareas adicionales en la semana caía a 51 peticiones/s con 10 usuarios.
Causa encontrada Al revisar el código: (1) el servicio entregaba al cálculo semanal de cada persona las tareas de todas las personas del profesor, que se reagrupaban una vez por persona (con 40 personas y 3.000 tareas, ~120.000 operaciones por petición); (2) la consulta traía con cada tarea datos de usuario, espacio y adjuntos que el seguimiento no usa.
Prioridad Media (subió de Baja después de medirla)
Riesgo Latencia alta en /seguimiento/personas para profesores con muchas personas o mucha actividad semanal.
Acción aplicada Las tareas se reparten por persona una sola vez (tareasPorPersona en servicio/seguimiento.go) y el seguimiento usa una consulta que lee solo la tabla tareas (selectTareaPropia en repositorio/tareas.go, con su prueba de integración). El estado se sigue calculando en cada consulta (RN-36). Resultado, medido con ambas versiones el mismo día: con 200 usuarios, de 1.378 a 4.063 peticiones/s y p95 de 173 a 57 ms; con 3.000 tareas extra, de 46 a 423 peticiones/s (Pruebas de carga, sección 3).
Pendiente Si en la nube volviera a ser un cuello de botella: agregar en SQL las horas y conteos por persona y semana, y ajustar pool_max_conns en DATABASE_URL según los núcleos de la VM.
Estado Resuelta

DT-09 – Notificaciones internas pendientes

Campo Detalle
Descripción El recordatorio de los viernes y el centro de notificaciones (RF-13) no están implementados.
Componente Nuevo módulo
Origen Fuera del alcance de la Entrega 1 según el enunciado.
Impacto Funcionalidad
Prioridad Media (según el alcance de las siguientes entregas)
Riesgo Ninguno para la Entrega 1.
Acción propuesta Implementarlo como un módulo nuevo con el patrón documentado en el README y un scheduler de Asynq para el recordatorio de los viernes.
Estado Identificada

DT-10 – Hallazgos de SonarQube

El pipeline analiza el código con SonarQube (Community Build 26.9, perfil "Sonar way" para Go) en cada push. El reporte completo de cada ejecución queda en el artefacto reporte-sonarqube de GitHub Actions.

Primer análisis: 0 bugs, 0 vulnerabilidades, 0 security hotspots, calificación A en confiabilidad, seguridad y mantenibilidad, y 15 code smells, que se interpretaron así:

Regla Cantidad Interpretación Decisión
go:S3776 complejidad cognitiva > 15 4 Deuda real: Migrar, ConstruirSemanas, ConstruirConsolidado y una prueba de integración concentraban varias responsabilidades. Se refactorizaron en funciones pequeñas con nombre propio (aplicarMigracion, construirSemana, totalizarTareas, contarSemanas...).
go:S1192 literal repetido 5 Deuda menor: nombres de recursos repetidos en los mensajes de error de los repositorios. Se reemplazaron por constantes en repositorio/comun.go.
go:S1186 función vacía 1 Era intencional (función de cierre sin archivos abiertos), pero no estaba explicada. Se agregó el comentario que la justifica.
go:S1135 comentario "TODO" 5 Falso positivo: la regla interpreta la palabra española "todo" ("todo lo que se necesita") como un pendiente. Se reescribieron los comentarios para evitar la ambigüedad.

Estado actual: 0 hallazgos, 0 bugs, 0 vulnerabilidades, cobertura del 79 %, duplicación del 1 % y Quality Gate aprobado.

Limitación conocida: sin una cuenta de SonarQube Cloud, el pipeline usa un servidor temporal que analiza cada vez desde cero, así que las condiciones sobre código nuevo del Quality Gate no comparan contra el análisis anterior. Para tener historial y medir la evolución entre entregas, se recomienda conectar SonarQube Cloud (el pipeline ya lo soporta con SONAR_TOKEN).

Campo Detalle
Prioridad Baja
Estado Resuelta (los 15 hallazgos se atendieron); la limitación del historial queda identificada

Tabla consolidada de priorización

ID Deuda Prioridad Estado ¿Atender antes de la Entrega 2?
DT-01 Pruebas de integración de repositorios Alta Resuelta —
DT-02 Archivos en volumen local Media Identificada (preparada con almacenamiento.Nuevo) Sí (despliegue en GCP)
DT-03 Datos enviados al proveedor de IA Media Parcialmente resuelta Documentar la decisión
DT-05 Sin límite de intentos de login Media Identificada Recomendable
DT-08 Seguimiento calculado por consulta Media Resuelta (3 veces más throughput, medido) —
DT-09 Notificaciones pendientes Media Identificada Según el alcance de la Entrega 2
DT-04 JWT sin revocación Baja Identificada No
DT-06 Sin retención de PDF antiguos Baja Identificada No
DT-07 Adjuntos validados por extensión Baja Identificada No
DT-10 Hallazgos de SonarQube Baja Resuelta (falta historial en SonarQube Cloud) Opcional

Lectura técnica: la base de calidad es sólida: las pruebas de integración (DT-01) y el análisis de SonarQube (DT-10) quedaron resueltos, con 0 bugs, 0 vulnerabilidades y 0 code smells. Las deudas que más condicionan la siguiente entrega son dos:

  • DT-02, archivos en un volumen local: impide escalar horizontalmente (Entrega 3) y debe resolverse al desplegar en GCP con Cloud Storage, como exige la Entrega 2. almacenamiento.Nuevo ya concentra la elección de la implementación, así que el cambio no toca la lógica.
  • DT-08, seguimiento calculado por consulta: era la única con impacto medido en las pruebas de carga y quedó resuelta en esta entrega: la vista del profesor atiende unas 3 veces más peticiones con un tercio del tiempo de respuesta, medido antes y después en las mismas condiciones.

DT-03 (privacidad del texto enviado al LLM) debe documentarse cuando el equipo elija el proveedor. DT-05 (límite de intentos de login) es recomendable porque, según el escenario E1, el inicio de sesión es la operación más costosa en CPU. Las demás (DT-04, DT-06, DT-07 y DT-09) pueden diferirse sin comprometer la calidad de la Entrega 2.