josedario87 599a7999c9
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m6s
Feat: agregar creación de lotes de input en formulario de operación
Ahora el formulario de crear operación permite crear nuevos lotes de
entrada directamente desde el paso 2, sin necesidad de salir del modal.

Cambios:
- Agregar botón "Nuevo lote de entrada" en el paso 2
- Mostrar formulario inline para crear lote con código, tipo y cantidad
- Al crear el lote, se agrega automáticamente a la lista de disponibles
- Se selecciona automáticamente como input de la operación
- Importar createLote del composable useLotes
- Agregar estado showCreateInputForm y creatingInput
- Implementar funciones cancelCreateInput y handleCreateInput

Beneficios:
- Flujo más ágil sin interrupciones
- Consistencia con la creación de lotes de output
- Mejor experiencia de usuario
2025-11-22 03:33:19 -06:00

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

Description
No description provided
Readme 6.5 MiB
Languages
Vue 45.8%
TypeScript 42.9%
PLpgSQL 5.2%
Shell 4.5%
HTML 1.2%
Other 0.4%