Skip to content

0044. Reporte semanal: ventana móvil de 7 días (no pestañas de calendario), sin export en v1

Estado

Aceptada

Contexto

La sábana del Excel del socio es una pestaña nueva por fecha de reporte (ej. 11-01-2026): cada semana el socio copia la pestaña anterior y la completa a mano. El módulo reportes la reemplaza generándola a demanda (GET /reports/weekly), pero el backend no tiene (ni necesita) una tabla de "snapshots semanales" — los datos ya viven en Sampling, Population, Feeding, Harvest con su fecha real de captura.

Dos decisiones de diseño no obvias quedaron pendientes de registrar:

  1. Qué significa "la semana" cuando no hay pestañas fijas de calendario.
  2. Si la v1 debía incluir export (el Excel original "es exportable" por naturaleza: vive en Google Sheets).

Decisión

Ventana móvil, no semana de calendario. GET /reports/weekly?date= recibe una fecha de corte (default hoy) y calcula todo relativo a ella: la "semana" es (corte − 7 días, corte]. Esto permite generar el reporte a cualquier fecha histórica (no solo "hoy" o "el lunes pasado"), reutilizando el historial real de cada módulo:

  • pesoAnt/pesoAct y los últimos 4 incrementos se derivan buscando el muestreo vigente en cada corte de 7 días hacia atrás (weekly-report.aggregate.ts), en vez de leerlos de una fila fija de pestaña.
  • Alternativa descartada: semana de calendario (lunes-domingo). Se descartó porque el socio no factura ni cierra en ciclos de calendario — cada piscina tiene su propio ritmo de muestreo/aguaje, y anclar a lunes-domingo hubiera forzado a alinear datos que no calzan con esa cadencia real.

Sin export en v1. El alcance se acotó a la vista web (GET /reports/weekly + página admin). La acción reportes:exportar se sembró en el catálogo RBAC (Administrador la tiene por default) para no romper compatibilidad cuando se agregue el endpoint, pero no hay endpoint de export todavía — decisión del dueño del producto al planificar la tarea (2026-07-16): reducir alcance del primer corte y validar la sábana generada con el socio antes de invertir en xlsx/csv.

Consecuencias

  • El reporte es idempotente respecto al historial: pedir la misma fecha de corte dos veces da el mismo resultado (no depende de "qué pestaña se guardó"), y sirve para reconstruir el estado de cualquier semana pasada con los datos ya cargados.
  • diasVacio mira todos los ciclos de la piscina (no solo el activo) para encontrar la cosecha final ejecutada más reciente anterior al corte — necesario porque la "semana" ya no es una fila fija que arrastra ese dato de la pestaña anterior.
  • Costo de performance: cada corte recalcula todo desde las tablas base (sin cache). Al volumen actual (decenas de piscinas por organización) es despreciable; si se vuelve un problema, cachear por (organizationId, date) es el camino natural sin cambiar el contrato.
  • Export queda como ítem de backlog («export de la sábana (xlsx) — acción reportes:exportar ya sembrada en RBAC»), no bloquea el resto del módulo.

Referencias

  • Tarea reporte-semanal (2026-07-16).
  • camaroneras_backend/src/modules/reportes/ (weekly-report.calc.ts, weekly-report.aggregate.ts, reportes.service.ts).
  • camaroneras_docs/modulos/08-reporte-semanal-flow.md.
  • camaroneras_docs/referencia/sabana-calculos.md — fórmulas de la sábana real.
  • ADR-0030 — precedente de acoplar un derivado (FCR) al muestreo disponible más reciente en vez de exigir sincronía perfecta; el reporte semanal extiende ese mismo criterio a toda la fila.