Apariencia
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 * 100factor 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,fcrni ningún semáforo/índice/prioridad del motor de scoring (kpi-scoring.ts, sin cambios). Toda la cadena de negocio sigue consurvivalPct(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 danull— igual semántica quekgSugeridosDia/desviacionKgpara "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(survivalEstimadaPctagregado, mismo criterio de ponderación quesurvivalPct).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).