registro-productivo-avicola

Registro Productivo Avícola

Sistema de registro diario de producción para gallinas ponedoras.
Autor: Andrés Lazo Escobar, Médico Veterinario · avivet.cl


📖 Manual de usuario (para productores)

Guía paso a paso en lenguaje simple para quienes usan la app:


Documentación para Claude Code

Este repositorio incluye un CLAUDE.md en la raíz con el stack, la arquitectura y comportamientos no obvios del proyecto. Claude Code lo carga automáticamente al trabajar en el repo, reduciendo el contexto necesario en cada sesión.


Estado actual de la migración

El sistema está en transición de Google Apps Script (GAS) + Google Sheets a una arquitectura centralizada en Supabase.

Etapa Estado
Nueva app Supabase (src/supabase/) ✅ Lista
Schema + RLS en Supabase ✅ Activo desde 2026-04-29
Migración historial Avícola GH ⏳ Pendiente
Migración historial Avícola Clarita ⏳ Pendiente
Migración historial Praderas de Ranco ⏳ Pendiente
Migración historial Reinhard ⏳ Pendiente
Productores usando nueva app ⏳ En proceso

Por qué migramos

Problema actual (GAS) Solución nueva (Supabase)
Un Sheet y una URL por productor → deploy manual de 15–20 min Una URL para todos, crear productor = 2 min en Supabase Auth
Sin autenticación real (URL pública con ?productor=X) Login email/contraseña con Row Level Security
Cada productor ve solo su propio Sheet pero no hay restricción técnica RLS garantiza aislamiento a nivel de base de datos
Escalar requiere copiar y configurar archivos Nuevo productor = crear usuario, no tocar código
Datos históricos atrapados en Sheets individuales Todo en PostgreSQL, consultable centralmente

Nueva arquitectura (src/supabase/)

src/shared.js             ← Código común a producción y módulo: cliente Supabase, sesión,
                            cuenta compartida (resolverOwner) y helpers (hoy, fmtFecha, toast)
src/supabase/
├── index.html            ← App de producción (todos los productores)
└── supabase-schema.sql   ← Esquema base SOLO para instalación nueva (tiene DROP TABLE)
src/ventas/
└── index.html            ← App de bodega, alimento, pedidos y ventas (opcional por productor)
migrations/               ← Migraciones SQL numeradas (000…009) + README.md (ledger).
                            Cada una es idempotente, exige la anterior y se registra en schema_migrations
supabase/functions/       ← Edge Functions: alerta-produccion, aviso-invitacion (index.ts)

URLs:

Supabase project: xewujmpycclqjhlmiica.supabase.co (mismo proyecto que pesaje-pollitas)

Producción es la base; bodega/pedidos/ventas son módulos que nacen de ella. La app de producción enlaza a este módulo (nav → 📦 Bodega) y el módulo enlaza de vuelta a producción, con las mismas cuentas y proyecto Supabase. Es opcional: solo la usan los productores que venden. Tiene 3 pestañas, en orden de importancia (abre en Bodega):

Tablas

Tabla Descripción
productores Nombre legible del plantel por usuario; lectura pública (autenticados) para el dashboard
ubicaciones Catálogo de espacios físicos por usuario (Carro 1, Pabellón 2, etc.)
lotes Lotes por usuario (nombre, fecha nac, n° aves, línea genética, ubicación opcional)
pesajes Pesaje semanal en crianza (semanas 1–19)
registros Un registro por día por lote (producción + clasificación + KPIs)
ventas Ventas de huevos por usuario (bandejas, huevos, precio, total) — cuadra contra registros
pedidos Pedidos/reservas de clientes por usuario, con estado (pendiente/entregado/anulado); al entregar enlaza la ventas.id generada. Incluye tamano y cajas
ajustes_stock Movimientos de bodega por usuario (merma, autoconsumo, regalo, entrada, ajuste); huevos es un delta con signo. Incluye tamano
proveedores Proveedores de alimento por usuario (nombre, teléfono); alta rápida desde el módulo Alimento
alimento_recepciones Compras/entradas de alimento por usuario (fecha, proveedor, lote, kg, sacos, precio/kg, N° documento)
alimento_ajustes Mermas/correcciones del stock de alimento por usuario; kg es un delta con signo
user_config Preferencias por usuario en JSONB (no vendibles, alertas, correcciones de nombres del asesor)
equipo Acceso compartido: dueno_id → email_invitado activo/inactivo. Un correo invitado ve y edita la cuenta del dueño (Etapa 1: rol editor)

Cuenta compartida (equipo): la función tiene_acceso(owner) centraliza la regla de acceso: un dato con user_id = X es visible/editable si auth.uid() = X o tu correo está invitado y activo en la cuenta X. Todas las tablas de datos usan tiene_acceso(user_id) en sus políticas RLS. Es retrocompatible: sin invitaciones, equivale a user_id = auth.uid(). Las apps calculan al entrar el ownerId (mi cuenta, o la de quien me invitó) y trabajan sobre ella. El dueño gestiona los correos en Producción → Lotes → 👥 Equipo.

Todas las tablas tienen Row Level Security activado: cada usuario ve y modifica solo sus propios datos. Excepción: productores permite a cualquier usuario autenticado leer los nombres (solo el nombre, sin datos productivos), para que el dashboard del asesor identifique a cada productor.

Funcionalidades de la nueva app

Cómo activar Supabase (una sola vez)

  1. SQL Editor de Supabase → pegar y ejecutar src/supabase/supabase-schema.sql (solo proyecto vacío), luego migrations/000_ledger.sql y las migraciones 001 → 009 en orden (ver migrations/README.md)
  2. Authentication → Users → Add user → email + contraseña por productor
  3. El productor entra a la URL de la app, crea sus lotes e importa su historial

Cómo migrar el historial de un productor

  1. Abrir su Google Sheet → ir a la pestaña del lote
  2. Archivo → Descargar → Valores separados por coma (.csv)
  3. En la nueva app: tab Lotes → seleccionar lote destino → subir CSV
  4. Repetir por cada pestaña de lote

Validación automática (CI)

Cada PR y cada push a main corre scripts/validar-apps.py mediante GitHub Actions (.github/workflows/validar.yml). Revisa las tres apps (src/supabase/index.html, src/ventas/index.html, dashboard.html):

Para correrlo localmente antes de subir: python3 scripts/validar-apps.py. No usa npm ni dependencias.


Arquitectura anterior (GAS) — referencia

Las carpetas src/avicolas/ se mantienen como archivo histórico. Cada una tiene:

src/avicolas/<nombre>/
├── code.gs      ← Backend GAS (doGet, guardarDatos, getDashboard…)
├── index.html   ← App móvil con gráficos y exportar PDF
└── NOTAS.md     ← URL del Sheet, URL web app, contacto del productor

Productores en GAS (activos al momento de la migración)

Productor Carpeta Línea genética
Avícola GH src/avicolas/avicola-gh/ ver Sheet
Avícola Clarita src/avicolas/avicola-clarita/ ver Sheet
Praderas de Ranco src/avicolas/praderas-de-ranco/ ver Sheet
Reinhard src/avicolas/reinhard/ ver Sheet
Roberto Santelices src/avicolas/roberto-santelices/ ver Sheet
Vicente Abogabir src/avicolas/Vicente-Abogabir/ ver Sheet
Copihue Real src/avicolas/Copihue real/ ver Sheet

Cómo actualizar un productor en GAS (mientras no se migra)

  1. Google Sheet → Extensiones → Apps Script
  2. Actualizar Código.gs y/o index.html
  3. Implementar → Gestionar implementaciones → editar → Nueva versión → Implementar

📊 Monitor de Producción (dashboard del asesor)

dashboard.html en la raíz del repo, publicado en http://avivet.cl/registro-productivo-avicola/dashboard.html. Lee directo de Supabase con la cuenta del asesor (política RLS vet_admin_* que permite ver los lotes y registros de todos los productores; cada productor sigue viendo solo lo suyo en su app).


💾 Respaldos


Registro de cambios

Fecha Cambio
2026-10 Rediseño — Etapa 3b: Historial. La tabla ancha se reemplaza por días agrupados por semana de vida (con promedio de la semana), cada día con barra de postura y la marca de la curva, 📝 si tiene nota, días sin registro en rosado con Completar y Registrar para hoy; tocar un día lo abre para editar. Chips de lote, «Ver semanas anteriores» y botón ⬇ CSV (historial del lote, separador ; para Excel en español)
2026-10 Rediseño — Etapa 3a: Tendencia. La pestaña Gráficos pasa a llamarse Tendencia: período 7 días / 30 días / todo el lote con 4 indicadores (postura vs curva, mortalidad, conversión, no vendibles) y su cambio contra el período anterior; un gráfico principal con selector (Postura, Mortalidad, Tamaños, Distribución, No vend., Acumulado, Semanas); Hitos del lote (mejor semana, días seguidos sin bajas, huevos acumulados y próximo hito de 50 mil); el detalle completo de indicadores y el costo de alimentación quedan plegables. Gráficos con tipografía de la marca, leyenda abajo y eje Y de postura ajustado a los datos
2026-10 Notas por lote y nota general del día. Corregido: al cambiar de lote o de día el formulario conservaba los datos y la nota anteriores, y se guardaban repetidos en otro lote. Ahora cada día sin registro parte en blanco (aves = las del día anterior de ese lote). Nueva nota general del día para todo el plantel (tabla notas_dia, migración 010); la nota del lote sigue en registros.observaciones. El dashboard muestra Notas del productor · últimos 30 días (generales y por lote) en el detalle y en «Todos los lotes»
2026-10 Dashboard — Etapa 2 del rediseño: constancia y WhatsApp. Tarjeta Constancia de registro (últimos 30 días, cuadritos por día: registrado / sin registro / hoy pendiente, «X de Y días», días seguidos y fechas faltantes) en la vista de cada lote y en «Todos los lotes»; columna Constancia 30 d en el Resumen. Sin rankings entre productores. Nuevo periodo Últimos 7 días (hasta ayer; queda por defecto). «Copiar texto» reescrito para WhatsApp: saludo al productor filtrado, 2–3 líneas por lote (huevos, postura vs esperado, bajas vs periodo anterior, consumo en el mes) y cierre con los días registrados del periodo y la racha si es ≥ 7 días
2026-10 Rediseño de la app de producción — Etapa 1 (Registro), estilo minimalista con la misma paleta: barra de navegación inferior (Registro · Tendencia · Historial · Plantel), menú en el avatar (Bodega, Pedidos, Ventas, Manual, salir), saludo que avisa “Faltan los datos de hoy” y, ya registrado, muestra un dato positivo rotativo (huevos del día, días sin bajas, sobre la curva, hitos de 50 mil). Tarjeta de postura con anillo vs curva, tira de 7 días con faltantes y botón Completar, huevos como campo grande con % postura en vivo, aves/mortalidad/alimento con − / +, clasificación con huevos a escala y barra, nota plegable y hoja “¡Día guardado!” al guardar. Al guardar salta al siguiente día pendiente (nunca a una fecha futura). Prototipos en docs/propuesta-rediseno/
2026-09 Migraciones con registro: carpeta migrations/ numerada (000–009) con guarda de orden, auto-registro en schema_migrations y ledger en migrations/README.md; el CI valida numeración/guarda/registro. Edge Functions movidas a supabase/functions/<nombre>/index.ts + scripts/deploy-functions.sh (opcional)
2026-09 Rendimiento del módulo: función SQL stock_resumen(owner, desde, hasta, hoy) (security invoker, RLS intacta) que devuelve en un JSON los agregados de bodega por tamaño, cuadre del periodo y alimento. El módulo deja de descargar el historial de registros (antes 3 veces por acción) y lanza las listas en paralelo. Requiere ejecutar stock-resumen.sql una vez; si falta, la app lo avisa
2026-09 src/shared.js: se extrajo el código duplicado entre producción y módulo (sesión, recuperación de clave, resolverOwner, banner de cuenta, hoy, fmtFecha, toast). De paso se corrigió hoy() en producción, que aún usaba UTC (toISOString) y desde ~21:00 daba el día siguiente. El validador del CI comprueba ahora shared + app juntos
2026-09 CI de validación: GitHub Action (.github/workflows/validar.yml) que corre scripts/validar-apps.py en cada PR y push a main — sintaxis JS, <div> balanceados, IDs duplicados, handlers sin función y getElementById sin elemento. Sin npm
2026-09 Dashboard: revisión de proceso y diseño — fechas en hora local (antes UTC: desde las 21:00 marcaba lotes al día como atrasados), token de sesión que se renueva solo (antes HTTP 401 tras 1 h), carga de lotes en paralelo, «Copiar texto» con los mismos KPIs de la tabla y respetando el productor filtrado, hoja de estilos de impresión para el PDF del resumen, lista de lotes incompletos con días registrados, «Mes cerrado» = último mes completo con gracia, mortalidad «alta» relativa al lote, identidad visual avivet.cl (Fraunces + DM Sans) y layout para pantalla angosta
2026-07 Gráfico de Postura con toggle Diario / Semanal: agrupa por semana de vida (postura = Σhuevos/Σaves; esperado = promedio de la semana)
2026-07 Alertas: el asesor (AviVet, ALERTA_EMAIL) recibe siempre copia de las alertas de todos los productores, aunque el productor haya apagado sus propias alertas. Se quitó el toggle de copia al asesor
2026-07 Gráficos: nueva pestaña ☠️ Mortalidad (por semana + acumulada) y ⚠️ No vendibles (% de sucios/rotos/trizados/sangre y total, por semana de vida; usa los nombres personalizados del productor)
2026-07 Respaldos: Action semanal en repo privado avivet-respaldos (CSV de todas las tablas, historial en git) + botón “⬇ Exportar todo” (ZIP) en el dashboard
2026-07 Aviso de invitación: al dar acceso a un correo en 👥 Equipo, una Edge Function (aviso-invitacion, Resend) avisa al administrador para que cree la cuenta del invitado
2026-07 Unidad docena (12) agregada en Ventas, Pedidos y ajuste de Bodega (junto a cajas 180, bandejas 30 y sueltos). Los huevos se pueden colocar en cajas, docenas o bandejas. Sin cambios de BD (el total se guarda en huevos, empaque canónico)
2026-07 Bodega: el ajuste de stock se ingresa en cajas (180) / bandejas (30) / huevos (antes solo huevos), con su tamaño — para agregar cajas extra, cargar stock inicial o corregir. Muestra el total y el equivalente en cajas
2026-07 Cuenta compartida (equipo) — Etapa 1: el dueño invita correos (Producción → Lotes → 👥 Equipo) que ven y editan la misma información. RLS centralizada en tiene_acceso(user_id); las apps resuelven el ownerId al entrar. Retrocompatible. equipo-schema.sql
2026-07 Módulo 🌾 Alimento en Bodega: stock de alimento = recepciones − consumo diario (registros.kg_alimento) ± ajustes; recepción con proveedor (alta rápida), lote, precio/kg y sacos de 25 kg; autonomía en días, costo/kg y alerta de stock bajo. Tablas proveedores, alimento_recepciones, alimento_ajustes (alimento-schema.sql)
2026-07 Stock por tamaño y cajas de 180: Bodega muestra Físico/Reservado/Libre por tamaño (Chico…Jumbo + Sin especificar); ventas, pedidos y ajustes registran tamaño; se puede ingresar y ver todo en cajas de 180 (= 6 bandejas). Migración migration-tamanos-cajas.sql (columnas tamano, cajas)
2026-07 Dashboard: opción “★ Todos los lotes” al seleccionar un productor — vista combinada con la curva de postura de todos sus lotes por semana de vida y una tabla-resumen por lote (clic en una fila abre su detalle)
2026-07 Dashboard: indicadores del lote agregan Consumo de alimento (g/ave/día + kg/día) y Costo alim/huevo, calculado con el precio del kg de alimento por productor (guardado por productor en el navegador)
2026-07 Dashboard: panel “Comparar por semana de vida” — compara postura de lotes marcables (con “Todos”), agrupados por estación de nacimiento (verano/otoño/invierno/primavera, hemisferio sur) o por avícola, normalizando al eje de semana de vida
2026-07 Navegación entre módulos: la app de Producción enlaza directo a Bodega/Pedidos/Ventas (../ventas/#tab) y el módulo abre en la pestaña del enlace (recuerda el módulo en la URL)
2026-07 App de ventas: pestañas Pedidos (reservas de clientes que al entregarse generan la venta) y Bodega (inventario acumulado con mermas/autoconsumo/ajustes y stock libre). El cuadre pasa a usar huevos vendibles en vez del total clasificado. Tablas pedidos y ajustes_stock
2026-06 Dashboard: agrupación del resumen por 1/4 semanas o mes cerrado, y gráficos de postura bajo demanda (curva por lote y curva combinada de los lotes de un productor)
2026-06 Dashboard: resumen semanal con tarjetas generales, filtro por productor y KPIs por lote (postura vs estándar, mortalidad semanal y anterior, consumo g/ave, huevos)
2026-06 KPI de consumo de alimento (g/ave/día, hoy y promedio 7 días) en la pestaña Gráficos
2026-06 App de ventas (src/ventas/): registra ventas en bandejas y cuadra huevos vendidos vs producidos por periodo, mismo Supabase y cuenta
2026-06 Recuperación de contraseña (¿Olvidaste tu contraseña?) en app y dashboard
2026-06 Nombres de productor en el dashboard (tabla productores): el productor se nombra en su app y el asesor corrige desde el monitor, sin más UUIDs
2026-06 Alertas por email configurables por productor (destino, umbrales, copia al asesor)
2026-06 Rediseño visual alineado a marca avivet.cl (Fraunces + DM Sans, paleta crema/verde/dorado)
2026-06 Selector de lote en tab Gráficos + no vendibles configurables por productor
2026-05 Ubicaciones físicas por lote (carro, pabellón, galpón)
2026-05 Curva Dominat agregada + curvas extendidas a semana 150
2026-05 CLAUDE.md + URL GitHub Pages configurada
2026-04-29 Alerta por email activa y verificada (Resend + Supabase Edge Function → andres.lazomv@outlook.com)
2026-04 Nueva app Supabase + herramienta de importación CSV
2026-04 Inicio migración GAS → Supabase
2026-04 Exportar PDF semanal con gráfico y tabla
2026-04 Dashboard central multi-granja
2025-03 Versión inicial GAS