Los componentes LotesTable y OperacionesTable usan UTable de Nuxt UI,
que internamente usa @tanstack/table-core. Esta librería no puede
renderizarse en el servidor (SSR), causando error 500.
Solución: Envolver los componentes en <ClientOnly> para que solo se
rendericen en el navegador.
- Crear plugin error-handler.ts para capturar todos los errores
- Captura errores de app:error, vue:error y errorHandler
- Agregar logs en script setup de componentes
- Logs antes y después de llamar a useLotes()
- Esto nos mostrará exactamente dónde crashea la app
- Logs en useLotes() para ver cuándo se llama
- Logs en fetchLotes() para rastrear el flujo
- Logs en API /api/lotes para ver requests del servidor
- Todos los logs con emojis para fácil identificación:
🔵 = Cliente/Composable
🟦 = Servidor/API
❌ = Errores
El problema era que useToast() no funciona en Server-Side Rendering.
Cuando los componentes se renderizaban en el servidor, crasheaba con error 500.
Cambios:
- Hacer que toast sea opcional: process.client ? useToast() : null
- Cambiar todos toast.add() a toast?.add()
- Ahora el composable funciona tanto en servidor como en cliente
- Agregar try-catch en loadLotes/loadOperaciones
- Agregar try-catch en onMounted y watch
- Agregar estado de error y mostrar mensaje en UI
- Agregar console.log detallados para debug
- Mostrar errores en tarjeta roja sin crashear la app
- Restaurar LotesTable completo con onMounted y watch
- Habilitar carga automática de datos
- Base de datos recreada con credenciales correctas
- Conexión PostgreSQL funcionando correctamente
- Cambiar selectedTab de ref(0) a ref('lotes') para usar string
- Agregar propiedad value explícita a cada tab item
- Crear documento nuxt-ui-tips.md con documentación de cambios
- Los valores deben ser strings según API de v4
- Cambiar v-model a v-model:open según API de v4
- Agregar slot #content requerido en todos los modales
- Corregir prop :ui para anchos personalizados (content en lugar de width)
- Aplicar clases correctas del tema para max-w-3xl y max-w-4xl
- Agregar sección completa sobre autenticación md5 vs scram-sha-256
- Documentar race condition entre app y PostgreSQL con retry logic
- Explicar idempotencia de scripts (schema vs seed)
- Documentar persistencia de datos y volúmenes Docker
- Incluir troubleshooting detallado de errores comunes
- Agregar diagramas de arquitectura de inicialización
- Documentar endpoints de debug temporales
- Tabla de decisiones técnicas con alternativas descartadas
- Queries útiles y comandos de backup/restore
- Endpoint seed-database ahora ejecuta 01_schema.sql primero
- Luego ejecuta 02_seed.sql
- Resuelve error cuando se presiona seed después de borrar BD
- Schema tiene CREATE TABLE IF NOT EXISTS (idempotente)
Flujo correcto:
1. Borrar BD → DROP TABLE de todo
2. Cargar datos → Crea tablas + inserta datos
- Implementar 5 reintentos con 2s de delay entre cada uno
- Resolver error de autenticación en primera carga
- PostgreSQL necesita tiempo para ejecutar 00_configure_auth.sh
- App ahora espera automáticamente hasta que auth esté configurado
Esto resuelve el error 28P01 (password authentication failed)
que ocurría solo en la primera conexión después del deploy.
Soluciones implementadas:
1. Copiar archivos SQL al contenedor Docker
- Agregar COPY de server/database/ en Dockerfile
- Permite que endpoint seed-database encuentre 02_seed.sql
2. Aumentar timeout de conexión PostgreSQL
- connectionTimeoutMillis: 2000 -> 10000 (10 segundos)
- Evita errores de autenticación en primera carga
3. Reducir logs en producción
- Solo mostrar 'Nueva conexión' en desarrollo
- Reduce ruido en logs de producción
Problema: Al hacer TRUNCATE, las tablas quedaban vacías pero existían,
entonces el workflow pensaba que ya estaba inicializada y no recreaba
los datos de ejemplo.
Solución: Ahora hace DROP TABLE (eliminar completamente) para que el
próximo deploy detecte que no existen tablas y las recree con el seed.
Ahora el flujo correcto es:
1. Click en 'BORRAR TODA LA BD' → DROP de todas las tablas
2. Push o redeploy → Workflow detecta que no hay tablas
3. Workflow ejecuta 01_schema.sql y 02_seed.sql automáticamente
⚠️ CÓDIGO TEMPORAL - NO ELIMINAR SIN CONSULTAR ⚠️
Backend:
- POST /api/debug/reset-database - Borra todos los datos
- POST /api/debug/seed-database - Carga datos de ejemplo
Frontend:
- Card rojo con advertencias notorias
- Botones: 🗑️ BORRAR TODA LA BD y 🌱 CARGAR DATOS DE EJEMPLO
- Confirmación antes de resetear
- Estados de loading
- Alertas de éxito/error
Todos los archivos marcados con comentarios muy visibles:
⚠️⚠️⚠️ NO ELIMINAR SIN CONSULTAR A DARIO/DRAGANEL/NUCLEO000 ⚠️⚠️⚠️
Útil para desarrollo y debugging del sistema de trazabilidad.
- Script 00_configure_auth.sh configura pg_hba.conf para usar md5
- Se ejecuta automáticamente en inicializaciones de BD
- Soluciona permanentemente problemas de autenticación con driver pg de Node.js
- Botones simples para probar GET /api/lotes, /api/operaciones y trazabilidad
- Resultados se muestran en console.log del navegador
- Facilita debugging de la API desde el frontend
- Agregar PostgreSQL 16 con esquema completo
- Crear API endpoints para lotes y operaciones
- Implementar UI con Nuxt UI (tablas, formularios, trazabilidad)
- Agregar datos de ejemplo del flujo completo
- Documentar sistema en PLAN_TRAZABILIDAD.md
This commit implements a comprehensive, reusable group verification system:
Components:
- GroupCheckButton: Base component for group verification
- 7 specialized buttons: 3 real groups (authentik Admins, grupo-prueba, lvl0), 1 public access test, 2 system verification buttons
- All buttons support both frontend and backend verification modes
Backend:
- New API endpoint /api/auth/check-group for server-side group validation
- Reads Authentik headers and validates group membership
Frontend:
- Enhanced useAuthentik composable with hasGroup() and checkGroupBackend() methods
- Toast notifications for all verification results
- Smooth animations and color-coded visual feedback
UI Improvements:
- Organized layout with cards for different verification types
- Grid layout for group buttons
- Professional styling with hover effects and shadows
- Clear visual distinction between frontend/backend checks
- Update AuthentikUser interface to include appSlug and outpostName
- Capture x-authentik-meta-app and x-authentik-meta-outpost headers
- Improve UserMetadata component to display connection information
- Filter empty groups from groups array
- Add documentation about available Authentik headers
- Add AuthentikUser and AuthStatusResponse interfaces
- Fix toast color from 'gray' to 'neutral' (valid color)
- Remove invalid 'timeout' property from toast.add()
- Fix toast action from 'click' to 'onClick'
- Add proper type annotations for error handling
- Replace process.server with import.meta.server
- Make email, name, uid optional in AuthentikUser interface
- Revert CacheFirst strategy back to NetworkFirst
- Add clear technical explanation in offline.html
- Explain that full offline mode requires no-auth or SPA
- Note that UI remains functional if app is already open
- Create offline.html with user-friendly offline message
- Auto-redirect when connection is restored
- Use offline.html as navigateFallback instead of root
- Include offline.html in PWA assets for precaching
This ensures users see a proper offline page when opening the app without connection, instead of a browser error.
- Add navigateFallbackDenylist to exclude API and auth routes
- Enhanced urlPattern to match document destination and root path
- Increase cache entries to 50 and duration to 7 days
- Add cacheableResponse for better cache control
This should enable the app to open offline after being loaded once.
This enables offline navigation by caching HTML documents generated by SSR.
When offline, users can now navigate to cached pages using the service worker.
- Enable navigateFallback for offline navigation support
- Add JSON files to glob patterns for heroicons support
- Change Authentik API caching from NetworkFirst to NetworkOnly to prevent stale session data
- Add offline detection in checkSessionStatus with proper user feedback
- Add no-cache headers to /api/auth/status endpoint to prevent browser caching
- Show "Modo Offline" toast when user tries to check session while offline
Change button layout to show all 4 buttons at the same time:
- Estado de Sesión (info/blue)
- Ver Perfil (primary/blue)
- Cerrar Sesión (error/red)
- Iniciar Sesión (success/green) - NEW: always visible
This allows users to force a re-authentication by clicking 'Iniciar
Sesión' even when already authenticated, triggering Authentik login flow.
Replace 'Ver Perfil' and 'Cerrar Sesión' buttons with a prominent
'Iniciar Sesión' button when user is not authenticated. The button
reloads the page to trigger Authentik login redirect.
This provides a more accessible way to log in compared to the toast
button, which can be difficult to click.
Button layout:
- Authenticated: [Estado de Sesión] [Ver Perfil] [Cerrar Sesión]
- Not authenticated: [Estado de Sesión] [Iniciar Sesión]
Add 'Iniciar Sesión' button to toasts when session is not active.
Clicking the button reloads the page, triggering Authentik redirect
to login flow.
Also increased toast timeout from 5s to 10s to give users more time
to see and click the login button.
- Detect CORS/redirect errors from Authentik and interpret them as
"no session" instead of generic error
- When session expires, Authentik returns 302 redirect to login which
causes CORS error in fetch requests
- Add /api/_nuxt_icon/ to public routes to prevent icon load failures
after logout
This fixes the issue where logout in Authentik showed "Error" instead
of "Sin Sesión" when checking session status.
Remove /api/auth/status from public routes so it receives Authentik headers.
Remove logic that was clearing local auth state, which caused the page to
show "No autenticado" even when user was authenticated.
Now the button only displays session status without modifying the UI state.
Move /api/auth/status endpoint from app/server/ to server/ directory.
Nuxt expects server API routes to be in /server/api/, not /app/server/api/.
This fixes the issue where the endpoint was returning HTML instead of JSON.
Create real-time session verification against Authentik:
- Add /api/auth/status endpoint that reads Authentik headers live
- Modify checkSessionStatus() to fetch from API instead of local state
- Show "Verifying..." toast while checking
- Sync local state with actual Authentik session status
- Handle connection errors gracefully
This ensures the status check reflects the current Authentik session,
not just the cached local state.