Skip to content

0060. Sobrevivencia estimada: censo por consumo con el factor crudo, no kgSugeridosDia

Estado

Aceptada

Contexto

Filas 13-14 de la hoja Consolidado del Excel v4: % Sob. estimada / % Sob. real. El sistema ya tenía una sola sobrevivencia (survivalPct, la real de muestreo de campo / aguaje). La estimada es el censo por consumo de la guía de campo: la tabla teórica de alimentación invertida — en vez de "con esta densidad, comer X kg/día", se pregunta "comieron X kg/día, ¿qué densidad hay?" (referencia/guia-campo-ab.md → "C/m² a cosecha implícito por el consumo real", ya implementado en computeGuide()).

Al implementarla en weekly-report.calc.ts (computeWeeklyRow), el punto de entrada natural parecía ser kgSugeridosDia — el service (reportes.service.ts) ya lo calcula y ya viaja a computeWeeklyRow para la desviación (kgReferencialSemana). Pero kgSugeridosDia = computeGuide({ cM2, ... }).kgSugeridos, y ese cM2 sale de deriveCM2(survivalPct, larvaeCount, hectares) — es decir, ya depende de la real. Calcular la estimada como censo(kgReales, kgSugeridosDia) habría dado:

% estimada = % real × (kgReales ÷ kgSugeridos)

La real multiplicada por el ratio de consumo real/sugerido — no una segunda fuente independiente, sino la real deformada por cuánto se desvió el alimentador del plan. Una columna así no aporta información nueva y viola el propósito de la fila del Excel (dos fuentes que Winston compara para detectar discrepancias).

Decisión

La estimada se calcula con el factor crudo de la curva (ya buscado en el service vía lookupFactor(points, pesoActG), línea previa a kgSugeridosDia), no con kgSugeridosDia:

kgRealesDia = feedWeekKg / 7
cM2Est      = kgRealesDia / hectares / factor
animalesEst = cM2Est * hectares * 10_000
% estimada  = animalesEst / larvaeCount * 100

factor se agregó a WeeklyRowInputs como campo separado de kgSugeridosDia, con un comentario explícito en el código marcando por qué no se reusa el sugerido. Un test de regresión (weekly-report.calc.spec.ts, "la estimada es independiente de la sobrevivencia real...") fija el comportamiento: cambiar survivalPct (o populationOverride, que tampoco interviene) no debe mover survivalEstimadaPct.

Base diaria: feedWeekKg / 7, no el registro del último día ni el acumulado del ciclo. El factor está expresado en kg/día y la sábana solo guarda el acumulado semanal; promediar la semana del corte no requiere queries nuevas al agregador y su tramo de peso (pesoActG de esa misma semana) es coherente con el factor buscado. El acumulado del ciclo se descartó: el factor cambia con el peso, y el acumulado mezcla tramos con factores distintos — la fórmula deja de ser válida fuera de una ventana de peso estable.

Sin recorte a 100%: si la piscina está sobrealimentada respecto a su densidad real, la estimada puede superar 100%. Es información válida (señal de desperdicio de alimento), no un error de cálculo — no se clampea en ningún punto (cálculo, DTO, ni gauge del admin, que solo clampea el arco visual, nunca el texto).

Consecuencias

  • La estimada es puramente informativa: no participa en animalesVivos, biomasaLb, lbPorHaActual/Total, fcr ni ningún semáforo/índice/prioridad del motor de scoring (kpi-scoring.ts, sin cambios). Toda la cadena de negocio sigue con survivalPct (la real) — es una asunción documentada en el backlog (Winston confirmó la distinción real/estimada pero no dijo explícitamente que la biomasa siga con la real; es lo que el sistema ya hacía).
  • Si el ciclo no tiene curva propia ni la organización tiene una isDefault, o el peso está fuera de rango de la curva, la estimada da null — igual semántica que kgSugeridosDia/desviacionKg para "sin guía".
  • Un cambio futuro que necesite la estimada dependa del alimento real consumido (no del sugerido) para cualquier otro cálculo debe seguir este mismo criterio: no mezclar kgSugeridosDia (que depende de la real) con derivados que se quieren independientes de ella.

Referencias

  • Tarea sobrevivencia-estimada-vs-real (2026-08-05).
  • camaroneras_backend/src/modules/reportes/weekly-report.calc.ts (computeWeeklyRow).
  • camaroneras_backend/src/modules/reportes/dashboard.calc.ts (survivalEstimadaPct agregado, mismo criterio de ponderación que survivalPct).
  • camaroneras_docs/modulos/08-reporte-semanal-flow.md → "Sobrevivencia: real vs. estimada".
  • camaroneras_docs/referencia/guia-campo-ab.md (fórmula del censo por consumo).
  • ADR-0042 (semántica del factor de la curva).