Apariencia
Flujo Alimentación — Registro diario + FCR + guía de campo
Base URL: /api/v1. Backend: camaroneras_backend (módulo alimentacion) ✅. Admin: camaroneras_admin ✅. Mobile: camaroneras_mobile ✅. Cuarto módulo de negocio; depende de ciclos y (para el FCR) de muestreos. Fórmulas del registro diario en referencia/sabana-calculos.md; fórmulas de la guía en referencia/guia-campo-ab.md (ver también ADR-0042).
Requests y responses 2xx: bodies (tipos, opcionales, enums) y el shape de las respuestas exitosas están en la API Reference, generada desde el spec OpenAPI. Acá quedan solo las respuestas de error (4xx/5xx) y las reglas de negocio/flujo.
El módulo tiene 3 partes: registro diario (núcleo original), curvas de alimentación (catálogo editable por org) y guía de alimentación (deriva kg sugeridos/desviación/proyección a cosecha combinando muestreos + alimentación + curva).
Modelo
Cycle ──< Feeding (registro diario de balanceado)
Organization ──< FeedingCurve ──< FeedingCurvePoint (curvas peso→factor)
Cycle >── FeedingCurve (feedingCurveId, opcional; null = default de la org)- Feeding:
date,brand(marca),pelletType(0.6/0.8/1.2/2/2.2, string),kg,notes. - FeedingCurve:
name,isDefault(una sola por org);points:weightG(g) →factor. - Cycle (campos agregados):
feedingCurveId?,populationOverride?(c/m² manual).
Derivados del registro diario (calculados en service)
- por registro:
acumuladoKg(Σ kg del ciclo hasta esa fecha),kgHa(kg ÷ hectáreas). - por ciclo (
summary):totalKg,biomasaLbyfcr=totalKg × 2.2046 / biomasaLb.biomasaLb= biomasa del último muestreo con biomasa del ciclo (peso × (sobrev%/100 × cantidad sembrada) ÷ 454; requiere población del mismo día). Si no hay →fcr = null.
⚠️ Este
fcrno es el mismo que el de la sábana. Acá el denominador es la biomasa del último muestreo con biomasa, sin sumar raleo; en 08 · Reporte semanal y 09 · Dashboard el FCA usabiomasa + libras de raleoa la fecha de corte (ver Sábana de cálculos §4). En un ciclo con raleos ejecutados los dos valores difieren, y el que alimenta el semáforo de FCA es el de la sábana, no éste.
Derivados de la guía (por ciclo; ver referencia/guia-campo-ab.md)
kgSugeridos, desviacionKg, cM2Cosecha (censo por consumo), librasCosecha, bines, rendimientoSaco, porcentajeRendimiento, lbHaActuales. Cada uno es null si falta el dato fuente (muestreo, población/override, o registro de alimentación) — igual que las celdas en blanco del Excel del socio.
RBAC
- Módulo
alimentacionen el catálogo, clients["web","mobile"]. - Defaults: Administrador todo; Técnico
ver/crear/editar; Bodeguerover. Backfill automático. - Las curvas y la guía usan el mismo módulo
alimentacion(no uno propio): crear/editar curva →alimentacion:crear/editar; ajustar guía →alimentacion:editar.
Endpoints (protegidos: AccessJwtGuard + PermissionGuard; tenant del JWT)
Registro diario
GET /cycles/:cycleId/feedings — (alimentacion:ver)
Lista la alimentación del ciclo (más reciente primero) con derivados y un summary.
Nota: fcr (y biomasaLb) son null si el ciclo aún no tiene un muestreo con biomasa.
POST /cycles/:cycleId/feedings — (alimentacion:crear)
Registra la alimentación de un día. Devuelve la lista + summary recalculados.
json
// response 404 (ciclo no existe / de otra org)
{ "error": "...", "message": "Ciclo no encontrado", "statusCode": 404 }PATCH /feedings/:id — (alimentacion:editar)
Edita un registro (campos parciales).
DELETE /feedings/:id — (alimentacion:eliminar)
json
// response 404 (no existe o de otra organización)
{ "error": "...", "message": "Registro de alimentación no encontrado", "statusCode": 404 }Curvas de alimentación
Seed automático (idempotente) de las 4 curvas del Excel del socio al crear la organización (FeedingCurvesService.seedDefaultCurvesForOrg, enganchado en AuthService.onboarding, mismo patrón que seedDefaultRolesForOrg).
GET /feeding-curves — (alimentacion:ver)
Lista las curvas de la organización con sus puntos.
POST /feeding-curves — (alimentacion:crear)
Crea una curva. Marcar isDefault: true desmarca la curva default anterior.
json
// response 409 (nombre duplicado)
{ "error": "...", "message": "Ya existe una curva con ese nombre", "statusCode": 409 }json
// response 400 (peso repetido en los puntos)
{ "error": "...", "message": "Peso duplicado en los puntos de la curva: 15", "statusCode": 400 }PATCH /feeding-curves/:id — (alimentacion:editar)
Edita nombre/default/puntos (parcial). Si envía points, reemplaza todos los puntos (mismo error 400 de peso duplicado que el POST).
DELETE /feeding-curves/:id — (alimentacion:eliminar)
No se puede eliminar la curva marcada default de la organización (rompería la guía de todo ciclo sin curva propia asignada): hay que marcar otra como default primero.
json
// response 400 (es la curva default)
{ "error": "...", "message": "No se puede eliminar la curva default; marca otra curva como default primero", "statusCode": 400 }json
// response 404 (no existe o de otra organización)
{ "error": "...", "message": "Curva no encontrada", "statusCode": 404 }Guía de alimentación
GET /feeding-guide — (alimentacion:ver)
Una fila por ciclo activo de la organización (estilo la hoja del socio), ordenadas por código de piscina.
GET /cycles/:cycleId/feeding-guide — (alimentacion:ver)
Guía de un ciclo puntual.
PATCH /cycles/:cycleId/feeding-guide — (alimentacion:editar)
Ajusta feedingCurveId y/o populationOverride del ciclo (cualquiera de los dos, o ambos; null explícito limpia el valor). Devuelve la fila recalculada.
json
// response 400 (curva de otra organización, o inexistente)
{ "error": "...", "message": "Curva no encontrada", "statusCode": 400 }json
// response 404 (ciclo no existe / de otra org)
{ "error": "...", "message": "Ciclo no encontrado", "statusCode": 404 }Flujo admin (camaroneras_admin, feature alimentacion)
- Ruta:
/guia-alimentacion— protegida (alimentacion:ver). - Tabla estilo la hoja del socio: Piscina · Ha · Curva · Peso · C/m² (con badge de fuente: muestreo/manual) · Kg reales · Kg sugeridos · Desviación (color por signo) · C/m² cosecha · Lb cosecha · Bines · Rendimiento/saco · % Rendimiento · Lb/ha.
- "Ajustar" (
alimentacion:editar): diálogo con selector de curva (o "default de la organización") y override numérico de c/m². - "Gestionar curvas" (visible con
alimentacion:editar): diálogo con la lista de curvas (nombre, # puntos, badge Default), acciones marcar-default/editar/eliminar, y "Nueva curva" con editor dinámico de puntos peso→factor.
Flujo mobile (camaroneras_mobile, feature alimentacion)
- Ruta:
/guia-alimentacion. Card en Home concanVerAlimentacion(mismo permiso que el registro diario). - Offline-first: tabla Drift
FeedingGuideRows(schema v10) cachea la guía completa (una fila por ciclo); las curvas no se cachean (el ajuste requiere red de todos modos para escribirse). - Tarjetas por piscina (no tabla, por espacio): ha/curva/peso, y 3 métricas por fila (C/m², Kg reales, Kg sugeridos / Desviación, Lb cosecha, Bines).
- Ajuste (
canEditarAlimentacion): sheet con selector de curva + override de c/m², online.