Files
seguidorDeLotes/README.md
josedario87 a395dcbd62
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m5s
Fix: Usar host único de Postgres para evitar conflictos en red compartida
Cambio de 'postgres' a 'lotes-postgres' para evitar errores 28P01 causados
por resolución de DNS a instancias incorrectas en la red principal.
2025-11-22 01:35:27 -06:00

13 KiB

Seguidor de Lotes - Sistema de Trazabilidad de Café

Sistema completo de trazabilidad para café, desde ingreso de uva hasta secado final, implementando un modelo de grafo (DAG) para rastrear transformaciones, divisiones y combinaciones de lotes.

🌐 URL: https://lotes.nucleoriofrio.com

🎯 Características Principales

  • Trazabilidad Completa: Rastreo desde ingreso de uva hasta café secado
  • Modelo de Grafo (DAG): Soporta divisiones (1→N), combinaciones (N→1) y transformaciones (1→1)
  • API REST Completa: 11 endpoints para gestión de lotes y operaciones
  • Frontend Interactivo: Interfaz con Nuxt UI para visualización y gestión
  • Función Recursiva de Trazabilidad: Consulta SQL que recorre todo el historial
  • PostgreSQL sin ORM: Queries directas con driver pg
  • Autenticación Authentik: Protección mediante Proxy Outpost
  • CI/CD Automático: Gitea Actions para build y deploy

📊 Modelo de Datos

Estructura del Grafo

El sistema usa 3 tablas principales que forman un grafo dirigido acíclico (DAG):

┌─────────────┐      ┌──────────────────┐      ┌─────────────┐
│   LOTES     │◄─────│ OPERACION_LOTES  │─────►│ OPERACIONES │
│             │      │                  │      │             │
│ - id        │      │ - operacion_id   │      │ - id        │
│ - codigo    │      │ - lote_id        │      │ - tipo      │
│ - tipo      │      │ - rol (in/out)   │      │ - fecha     │
│ - cantidad  │      │ - cantidad_kg    │      │ - meta      │
└─────────────┘      └──────────────────┘      └─────────────┘

Tipos de Operaciones Soportadas

  • Ingreso: Recepción de uva del productor
  • Despulpado: 1→3 (genera primera, segunda, rechazos)
  • Oreado: 1→1 (reducción de humedad en patio)
  • Presecado: 1→1 (reducción adicional de humedad)
  • Reposo: 1→1 (estabilización en bodega)
  • Secado: N→1 (combinación de lotes para secado final)
  • Ajustes: Corrección de mermas o tipos

Ejemplo de Flujo

UVA-001 (2086kg)
    │
    ├─[Despulpado]─┬─► PRIM-001 (1500kg)
    │              ├─► SEG-001 (400kg)
    │              └─► RECH-001 (150kg)
    │
    └─[Oreado]────► ORE-001 (1500kg)
         │
         ├─[Ajuste merma]────► ORE-001A (1480kg)
         │
         ├─[Ajuste tipo]─────► PRE-001 (1480kg)
         │
         └─[Reposo]──────────► REP-001 (1480kg)
                                   │
                                   ├─[Secado]─► SEC-001 (2000kg)
                                   │
                              REP-002 (520kg)

🚀 Inicio Rápido

Requisitos Previos

  • Docker y Docker Compose
  • Gitea con Actions habilitado
  • Traefik con red traefik-network
  • Authentik con Proxy Outpost configurado

Despliegue Automático

  1. Fork/Clone del repositorio en tu Gitea

  2. Configurar variables en Gitea (Settings > Actions):

    Secrets:

    • REGISTRY_USERNAME - Usuario del registro Docker
    • REGISTRY_PASSWORD - Contraseña del registro
    • POSTGRES_PASSWORD - Contraseña de PostgreSQL

    Variables:

    • REGISTRY_URL - gitea.nucleoriofrio.com
    • APP_NAME - lotes
    • APP_DOMAIN - lotes.nucleoriofrio.com
    • NUXT_PUBLIC_APP_URL - https://lotes.nucleoriofrio.com
    • NUXT_POSTGRES_URL - postgres://seguidor:seguidor_password@lotes-postgres:5432/seguidor_lotes
    • POSTGRES_USER - seguidor
    • POSTGRES_DB - seguidor_lotes
    • POSTGRES_PORT - 5432
  3. Push al repositorio - El workflow automáticamente:

    • Construye la imagen Docker
    • Sube la imagen al registro
    • Despliega con docker-compose
    • Inicializa PostgreSQL (solo primera vez)
    • Carga datos de ejemplo (solo primera vez)

📁 Estructura del Proyecto

.
├── nuxt4/
│   ├── app/
│   │   ├── components/
│   │   │   ├── lotes/          # Componentes de lotes
│   │   │   ├── operaciones/    # Componentes de operaciones
│   │   │   └── auth/           # Componentes de autenticación
│   │   ├── composables/
│   │   │   ├── useLotes.ts     # Lógica de negocio
│   │   │   └── useAuthentik.ts # Autenticación
│   │   └── app.vue             # Aplicación principal (con botones debug)
│   ├── server/
│   │   ├── api/
│   │   │   ├── lotes/          # Endpoints de lotes (6)
│   │   │   ├── operaciones/    # Endpoints de operaciones (3)
│   │   │   └── debug/          # ⚠️ Endpoints debug temporales (2)
│   │   ├── utils/
│   │   │   ├── db.ts           # Pool de PostgreSQL
│   │   │   └── queries.ts      # Funciones SQL
│   │   └── database/
│   │       ├── 01_schema.sql         # Esquema DB
│   │       └── 02_seed.sql           # Datos de ejemplo
│   └── package.json
├── docker-compose.yml          # Servicios (app + postgres)
├── .gitea/workflows/
│   └── build-and-deploy.yml   # CI/CD
└── README.md

🔌 API Endpoints

Lotes

  • GET /api/lotes - Listar lotes (con filtros)
  • POST /api/lotes - Crear lote
  • GET /api/lotes/:id - Obtener lote específico
  • PATCH /api/lotes/:id - Actualizar lote
  • DELETE /api/lotes/:id - Eliminar lote
  • GET /api/lotes/:id/trazabilidad - Obtener trazabilidad completa

Operaciones

  • GET /api/operaciones - Listar operaciones
  • POST /api/operaciones - Crear operación con lotes
  • GET /api/operaciones/:id - Obtener operación específica

Debug (⚠️ Temporales)

  • POST /api/debug/reset-database - Elimina todas las tablas (DROP)
  • POST /api/debug/seed-database - Carga datos de ejemplo

Nota: Estos endpoints están marcados como temporales. No eliminar sin consultar.

Ejemplo de Respuesta - Trazabilidad

{
  "success": true,
  "data": {
    "historial": [
      {
        "lote_id": "...",
        "codigo": "SEC-001",
        "tipo": "secado",
        "profundidad": 0,
        "operacion_tipo": "secado",
        "fecha_operacion": "2025-11-20T01:12:19.489Z"
      },
      // ... historial completo hasta origen
    ],
    "estadisticas": {
      "total_ancestros": 7,
      "profundidad_maxima": 6,
      "kg_iniciales": "2086.00"
    }
  }
}

🗄️ Base de Datos

Persistencia

  • Los datos persisten entre deploys (volumen Docker lotes_postgres_data)
  • Scripts de inicialización solo se ejecutan si no existen tablas
  • Configuración de autenticación (md5) se aplica automáticamente

Reiniciar BD a Estado Inicial

Para volver a los datos de ejemplo:

# Detener y eliminar volumen
docker compose --project-name lotes down -v

# Próximo deploy reinicializará todo
git commit --allow-empty -m "Trigger redeploy" && git push

Consultas Útiles

-- Ver todos los lotes
SELECT * FROM lotes ORDER BY fecha_creado DESC;

-- Ver trazabilidad completa de un lote
SELECT * FROM get_trazabilidad('id-del-lote');

-- Ver estadísticas de un lote
SELECT * FROM get_estadisticas_lote('id-del-lote');

🎨 Frontend

Tecnologías

  • Nuxt 4 - Framework Vue.js
  • Nuxt UI - Componentes basados en Tailwind
  • TypeScript - Tipado estático

Componentes Principales

  • LotesTable - Tabla con filtros y acciones
  • LoteForm - Formulario crear/editar lote
  • TrazabilidadTree - Árbol de trazabilidad con estadísticas
  • OperacionForm - Wizard de 3 pasos para crear operaciones

Modo Debug

El sistema incluye varios botones de debug para desarrollo:

Botones de Prueba de API (azules)

  1. Abre https://lotes.nucleoriofrio.com
  2. Abre consola del navegador (F12)
  3. Usa los botones "Probar GET /api/lotes", "Probar GET /api/operaciones", "Probar Trazabilidad"
  4. Verifica resultados en consola

⚠️ Botones de Gestión de BD (rojos) - TEMPORALES

ADVERTENCIA: Estos botones son para desarrollo/debugging y están marcados como TEMPORALES.

🗑️ BORRAR TODA LA BD:

  • Elimina completamente todas las tablas (DROP TABLE)
  • Requiere confirmación antes de ejecutar
  • Después de usar, hacer un push para que el workflow recree la BD con datos de ejemplo

🌱 CARGAR DATOS DE EJEMPLO:

  • Ejecuta el script de seed (10 lotes, 7 operaciones, 16 relaciones)
  • Útil para cargar datos después de un reset

Flujo recomendado para resetear completamente:

# 1. Click en "🗑️ BORRAR TODA LA BD" en la web
# 2. Trigger redeploy para que se recree automáticamente
git commit --allow-empty -m "Trigger reinit DB" && git push

# Alternativa rápida (sin redeploy):
# 1. Click en "🗑️ BORRAR TODA LA BD"
# 2. Click en "🌱 CARGAR DATOS DE EJEMPLO"
# 3. Recargar la página

⚠️ IMPORTANTE: Estos botones y endpoints están marcados con advertencias en el código:

  • NO ELIMINAR sin consultar a Dario/Draganel/nucleo000
  • Son temporales pero útiles durante desarrollo
  • Ver comentarios en el código antes de modificar

🔐 Autenticación

Sistema protegido con Authentik Proxy Outpost:

  • Forward Auth: Authentik intercepta todas las peticiones
  • Headers automáticos: Usuario inyectado en cada request SSR
  • Sin OAuth: No requiere configuración OAuth en la app
  • Rutas públicas: PWA assets accesibles sin auth

Ver configuración detallada en la sección de Traefik al final del README.

🛠️ Desarrollo Local

Nota: El desarrollo local tiene limitaciones debido a la dependencia de Authentik Proxy.

Opción 1: Desarrollo con PostgreSQL local

cd nuxt4
npm install

# Configurar PostgreSQL local
export NUXT_POSTGRES_URL=postgres://seguidor:seguidor_password@localhost:5432/seguidor_lotes

# Ejecutar scripts SQL
psql -U seguidor -d seguidor_lotes < server/database/01_schema.sql
psql -U seguidor -d seguidor_lotes < server/database/02_seed.sql

# Iniciar dev server
npm run dev

Opción 2: Desarrollo contra servidor

cd nuxt4
npm install

# Apuntar a BD de producción
export NUXT_POSTGRES_URL=postgres://seguidor:seguidor_password@server.interno.com:5432/seguidor_lotes

npm run dev

📈 Próximos Pasos

Objetivo Actual: Visualización del Grafo

Meta: Mostrar correctamente el grafo de trazabilidad creado con los datos de ejemplo.

Tareas pendientes:

  • Componente de visualización de grafo (D3.js, vis.js, o similar)
  • Layout de árbol o grafo dirigido
  • Interactividad (zoom, pan, click en nodos)
  • Mostrar metadatos al hacer hover
  • Indicadores visuales de tipos de operación

Mejoras Futuras

  • Exportar trazabilidad a PDF
  • Búsqueda avanzada de lotes
  • Dashboard con estadísticas
  • Alertas de mermas excesivas
  • Integración con básculas IoT
  • App móvil con PWA
  • Reportes personalizables

📚 Documentación Adicional


🔧 Configuración de Traefik y Authentik

Arquitectura de Autenticación

Usuario → Traefik → Authentik Forward Auth → App Nuxt
                         ↓ (sin sesión)
                    Redirect a Login

Configuración de Middleware (Traefik)

# dynamic/middlewares.yml
http:
  middlewares:
    authentik-forward-auth:
      forwardAuth:
        address: http://authentik-server:9000/outpost.goauthentik.io/auth/traefik
        trustForwardHeader: true
        authResponseHeaders:
          - X-authentik-username
          - X-authentik-groups
          - X-authentik-email
          - X-authentik-name
          - X-authentik-uid

Configuración de Proxy Provider (Authentik)

  1. Crear Proxy Provider:

    • Type: Forward auth (single application)
    • External host: https://lotes.nucleoriofrio.com
  2. Crear Application:

    • Name: Seguidor de Lotes
    • Slug: lotes
    • Provider: (el creado arriba)
  3. Vincular a Outpost:

    • Agregar la aplicación al Outpost existente

Headers Disponibles en la App

Header Descripción
X-authentik-username Nombre de usuario
X-authentik-email Email
X-authentik-name Nombre completo
X-authentik-groups Grupos (separados por |)
X-authentik-uid ID único

📄 Licencia

MIT