Skip to content

0046. Dashboard de producción: ruta /produccion (no /dashboard) y kpis no filtrables

Estado

Aceptada

Contexto

Al planificar la tarea dashboard-produccion, el nombre natural para la nueva página era "el dashboard" — pero /dashboard ya existe en camaroneras_admin como la página "Inicio": el NavItem fijo HOME, sin gate de permiso, y el destino de <Navigate to="/dashboard" replace /> tanto en la ruta raíz (/) como en el fallback de ProtectedRoute cuando falta un permiso. Recién al implementar se descubrió el choque.

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

  1. Dónde montar la página nueva sin romper el mecanismo de fallback existente.
  2. Si los kpis agregados debían responder a los mismos filtros client-side (año, ciclo, sector, piscina, rango de peso) que el resto de la página.

Decisión

Ruta nueva /produccion, /dashboard intacto. La página de producción se montó en /produccion (ProtectedRoute module="dashboard" action="ver"), con su propio ítem de nav ("Dashboard de producción", sección Operación). /dashboard (Inicio) no se tocó: sigue sin gate de permiso y sigue siendo el fallback de ProtectedRoute y el destino de /. Alternativa descartada: reemplazar el contenido de /dashboard — se descartó porque gatear esa ruta con dashboard:ver habría creado un loop de redirect para cualquier rol sin ese permiso (ProtectedRoute redirige ahí precisamente cuando falta un permiso).

Nota de nomenclatura: el módulo de permiso se llama dashboard (key RBAC), pero protege /produccion, no /dashboard. Se aceptó la colisión de vocabulario por ahora (ver hallazgo del code review de cierre) — si en el futuro se generaliza el fallback de ProtectedRoute (ver Consecuencias), conviene revisar el nombre de este módulo.

Kpis globales, no filtrables. data.kpis (agregados de la organización a la fecha de corte) viene fijo del backend (computeDashboardKpis, dashboard.calc.ts) y no recalcula al aplicar los filtros client-side — solo el donut, las barras, la tabla y el selector de piscina del gráfico de línea responden a los filtros. Alternativa descartada: recalcular los kpis en el frontend sobre filteredPools. Se descartó para no duplicar las fórmulas de agregación (promedio ponderado de sobrevivencia, FCR agregado no promediado) en dos lenguajes/repos con riesgo de que diverjan silenciosamente.

También se simplificó el contrato original: el plan de la tarea sugería un query param year en el backend (GET /reports/dashboard?year=) para acotar qué ciclos se agregan. Se omitió: como todos los filtros (año incluido) son client-side sobre la respuesta ya cargada, un year en el backend no tenía consumidor — decisión tomada durante la implementación, no una instrucción explícita del dueño del producto.

Consecuencias

  • Un usuario sin dashboard:ver sigue teniendo una home funcional (/dashboard); solo pierde el ítem de nav y el acceso a /produccion.
  • Los números de los kpis de arriba de la página no coinciden con la suma manual de las filas visibles si el usuario tiene un filtro activo — es intencional (kpis = organización completa), pero puede confundir si no se explica en la UI. Documentado acá y en modulos/09-dashboard-produccion-flow.md; si genera confusión real con usuarios, considerar una nota visible en la página (ej. "kpis de toda la organización, no del filtro actual").
  • El backend solo acepta date como query param (igual que /reports/weekly); si algún día se necesita acotar por año en el servidor (ej. por volumen), agregarlo entonces con su propio caso de uso concreto, no de antemano.
  • Queda pendiente en el backlog (code review de cierre, 2026-07-17) generalizar el fallback de ProtectedRoute/nav para que features futuras gateadas por permiso no repitan este mismo choque con /dashboard.

Referencias

  • Tarea dashboard-produccion (2026-07-17).
  • camaroneras_admin/src/shared/components/ProtectedRoute.tsx, src/app/router.tsx, src/app/layout/AppLayout.tsx.
  • camaroneras_backend/src/modules/reportes/dashboard.calc.ts (computeDashboardKpis).
  • camaroneras_docs/modulos/09-dashboard-produccion-flow.md.
  • ADR-0044 — mismo módulo reportes, precedente de acotar alcance de v1 (allí export; acá el query param year).