Skip to content

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, biomasaLb y fcr = 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 fcr no 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 usa biomasa + libras de raleo a 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 alimentacion en el catálogo, clients ["web","mobile"].
  • Defaults: Administrador todo; Técnico ver/crear/editar; Bodeguero ver. 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 con canVerAlimentacion (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.