Problema:
- Al enviar parámetros con valores vacíos (""), Metabase los expandía
- Filtros opcionales [[AND ...]] se convertían en filtros obligatorios
- Resultado: queries retornaban 0 registros en lugar de aplicar filtros opcionales
Solución:
- Solo enviar parámetros si son requeridos O tienen valor no vacío
- Verificar que el valor no sea null, "", undefined o array vacío
- Los parámetros opcionales sin valor no se incluyen en el request
Afecta: MetabaseCardDisplay.vue executeQuery() líneas 345-360
Problema:
- Metabase rechazaba queries cuando se enviaba null para parámetros text/date
- Error: "faltan los parámetros necesarios: fecha_desde, fecha_hasta"
- Los parámetros usados fuera de [[...]] son considerados requeridos
Solución:
- Cambiar || null a || '' para parámetros de tipo text y date
- Ahora envía string vacío que es compatible con NULLIF() en la query SQL
Afecta: MetabaseCardDisplay.vue líneas 333 y 342
Problema:
- Las queries de Metabase fallaban con error 500 al ejecutarse desde metabase-debug
- Metabase rechazaba los parámetros porque usaban tipos simples en lugar de tipos con operadores
Solución:
- Actualizar mapeo de tipos de parámetros en MetabaseCardDisplay.vue
- boolean → boolean/=
- date → date/single
- number → number/=
- text → string/=
Esto corrige el error "Tipo de parámetro no válido :text para el parámetro 'cliente_ids'"
Cambios realizados:
- Eliminar cards innecesarias que envolvían componentes de métricas
(TotalesMonetarios, TotalesIngresoCompra, TotalesVerde ya son cards)
- Actualizar estilo del contenedor de filtros al estilo de panorama facturador:
* Usar clase 'brand-card' y bordes transparentes
* Header con título y subtítulo estilizados
* Checkbox 'Incluir anulados' en header
* Inputs con variables CSS de brand
* Footer con botón 'Actualizar' estilizado
* Layout consistente con gap-8
Resultado: diseño más limpio, sin duplicación de cards y
estilo consistente entre páginas.
Cambios realizados:
- Alerta más compacta con variant 'soft' en lugar de 'solid'
- Eliminado botón 'Actualizar ahora' redundante de la alerta
- Eliminado emoji de advertencia del botón 'Actualizar'
- Simplificado borde del card (solo borde amarillo sutil)
- Eliminadas sombras y rings del card
- Eliminada animación pulse del botón
- Mantenido punto amarillo pulsante en la alerta
El indicador ahora es más discreto pero sigue siendo evidente.
Implementación de sistema de tracking para detectar cuando los filtros
han cambiado pero no se han aplicado a los datos mostrados.
Indicadores visuales implementados:
- Alerta amarilla prominente con animación pulse y ping
- Borde y sombra amarilla en el card de filtros
- Botón 'Actualizar' cambia a amarillo con emoji de advertencia
- Botón rápido 'Actualizar ahora' dentro de la alerta
- Animaciones llamativas para captar la atención
El sistema compara los filtros actuales con los últimos aplicados
y muestra indicadores visuales evidentes cuando hay diferencias.
Cambios implementados:
- Eliminada la llamada automática a loadData() en onMounted
- Añadido estado inicial con mensaje de bienvenida
- El usuario debe hacer clic explícito en 'Actualizar' para cargar datos
- Mejora la experiencia evitando queries automáticas pesadas a Metabase
Ahora la página muestra:
- Estado inicial: filtros + mensaje invitando a actualizar
- Estado con datos: filtros + todas las secciones de datos
La sidebar ahora detecta el tamaño de pantalla al inicializar:
- En móvil (< 1024px): cerrada por defecto
- En desktop (>= 1024px): abierta por defecto
Esto mejora la experiencia en dispositivos móviles evitando que
la sidebar tape el contenido al cargar la página.
Cambios realizados:
- Mover botón "Actualizar" al footer del card de Filtros
- Implementar guard para prevenir peticiones simultáneas
- Eliminar watcher automático de fechas
- Deshabilitar recarga automática al cambiar "incluir anulados"
- Usuario debe hacer clic explícito en "Actualizar" para cargar datos
Esto garantiza que solo una petición a Metabase esté activa a la vez
y da control total al usuario sobre cuándo recargar los datos.
Cambios en TotalesIngresoCompra:
- Mover botón toggle del header principal al header de sección 'Uva'
- Mejor posicionamiento: solo afecta la sección donde se aplica
Cambios en TotalesMonetarios:
- Agregar toggle de unidades en 'Precios Promedio Ponderados' para Uva
- 3 estados: LB, QQ, Ambos (muestra ambos precios en un contenedor)
- Unificar visualización de 'Uva por LB' y 'Uva por QQ' en un solo contenedor
- Grid cambia de 5 a 4 columnas para mejor layout
Ambos toggles funcionan independientemente y mantienen el mismo patrón
de diseño con iconos dinámicos.
- Agregar botón toggle de 3 estados: LB, QQ Seco, Ambos
- Por defecto muestra valores en LB
- Al cambiar a QQ Seco muestra: QQ Seco Ingresado, Pagado, en Depósito
- Al cambiar a Ambos muestra ambas unidades en el mismo contenedor
- Calcular QQ Seco en Depósito para Uva (ingresado - pagado)
- Iconos dinámicos según el modo seleccionado
- Cambiar tipo de parámetros boolean de 'category' a 'boolean' para que funcione el UToggle
- Detectar campos de fecha por nombre aunque sean tipo text en Metabase
- Renderizar inputs de fecha con date picker para campos que contienen 'fecha'
- Mejorar inicialización de parámetros text que representan fechas
Resuelve el problema donde incluir_anulados no aparecía y fecha_desde/fecha_hasta
se mostraban como text inputs en lugar de date pickers
Cambios principales:
- Refactorizar todos los componentes de panorama para recibir datos directos de Metabase
* TotalesMonetarios.vue: cambiar de props.metrics a props.data
* TotalesIngresoCompra.vue: cambiar de props.metrics a props.data
* TotalesVerde.vue: cambiar de props.metrics a props.data
* SecosVendidos.vue: cambiar de props.metrics a props.data
- Eliminar fechas hardcodeadas en panorama.post.ts
* Pasar valores null directamente a Metabase para usar sus defaults
- Marcar composables obsoletos para Panorama Facturador
* useIngresosMetrics.ts: agregar advertencia de no uso en Panorama
* useRechazosMetrics.ts: agregar advertencia de no uso en Panorama
Resultado: Todos los cálculos (agregaciones, promedios ponderados) se hacen en Metabase mediante SQL. Los componentes Vue solo renderizan valores ya calculados.
- Agregar icono de la app perfil al botón Inicio
- Implementar sistema de fallback para iconos (local → remoto → favicon)
- Aplicar gradientes y estilos inspirados en la app perfil
- Agregar transiciones suaves y efectos hover mejorados
Cambios en AppSidebar.vue:
- Cambiar link de /profile a https://inicio.nucleoriofrio.com
- Actualizar texto de 'Mi Perfil' a 'Inicio'
- Cambiar icono de user a home
- Actualizar colores de azul a verde
El botón ahora navega a la PWA de inicio usando scope extensions.
- Remover badge de mantenimiento del sidebar
- Eliminar endpoints de debug temporales
- Panorama funcionando con todas las secciones:
* Totales Financieros
* Café Seco - Inventario y Proyecciones
* Totales de Ingreso y Compra
* Totales Monetarios
* Café Verde
* Rechazos y Subproductos
- Todas las 9 queries de Metabase ejecutándose correctamente
- Datos reales mostrados en tiempo real
- Crear endpoint /api/metabase/panorama.post.ts que ejecuta las 9 queries en paralelo
- Restaurar y adaptar panorama.vue para usar el nuevo endpoint
- Crear componentes auxiliares: SecosVendidos, TotalesIngresoCompra, TotalesMonetarios, TotalesVerde, MetricBox, RechazosRechazoCard
- Adaptar RechazosSubproductos para recibir data directamente de Metabase
- Toda la transformación de datos ocurre en las queries SQL de Metabase
- Sin uso de stores ni composables de métricas
- Agregar documentación de queries en archivos MD
- Mover foco al sidebar cuando se abre en móvil
- Mover foco al panel principal cuando sidebar se cierra
- Evita warning de accesibilidad: aria-hidden con elemento enfocado
- Cambiar estructura de columnas de {key, label} a {accessorKey, header, id}
- Cambiar prop :rows a :data en componente UTable
- Actualizar referencias en selector de columnas
- Agregar selector de límite de registros (10 a 10,000)
- Implementar paginación client-side con UPagination
- Mostrar información detallada de registros cargados y filtrados
- Usar límite seleccionado en lugar de hardcoded 1000
- Resetear página al cambiar búsqueda o cargar datos
- Indicar cuando hay más datos disponibles (limitado)
- Mejorar UX con paginación de 50 filas por página por defecto
- Agregar sección expandible para configurar parámetros antes de ejecutar
- Inputs dinámicos según tipo: toggle para boolean, date picker para fechas, text para otros
- Inicialización automática con valores por defecto de template-tags
- Botón para restablecer parámetros a valores originales
- Usar valores del formulario al ejecutar queries
- Mejorar UX con labels legibles y estilos consistentes
- Extraer valores por defecto de template-tags de la card
- Construir parámetros dinámicamente basados en la configuración
- Soportar tipos: date, boolean, text
- Resolver error de parámetros faltantes en queries con fechas
- Agregar tabla estructurada para mostrar resultados de queries
- Agregar botón de copiar JSON profesional con feedback visual
- Agregar formato automático de números y fechas según tipo de columna
- Mantener vista JSON colapsable para ver datos completos
- Mejorar UX con tabla responsive y estilos consistentes
Soluciona dos problemas en la ejecución de queries de Metabase:
1. Error de parámetros faltantes:
- Las queries requieren parámetros (incluir_anulados, fecha_desde, fecha_hasta)
- Agregado valores por defecto a todas las llamadas POST:
* incluir_anulados: false
* fecha_desde: null (sin filtro)
* fecha_hasta: null (sin filtro)
2. Estado vacío poco amigable:
- Cuando rows y cols están vacíos mostraba solo JSON
- Agregado EmptyState visual con:
* Icono de tabla vacía
* Mensaje "No hay datos"
* Descripción explicativa
Cambios en:
- MetabaseCardDisplay.vue: executeQuery() con parámetros y EmptyState
- MetabaseCardsTable.vue: executeCard() con parámetros y EmptyState en modal
El contenido de los tabs no se mostraba porque faltaba la propiedad
'slot' en cada item del array tabs. Nuxt UI UTabs requiere esta
propiedad para vincular los slots nombrados con sus respectivos tabs.
Cambios:
- Agregar propiedad 'slot' a cada item en el array tabs
- Ahora los slots nombrados (#table, #cards, #panorama, #detail) se
vinculan correctamente con sus tabs correspondientes
Corrección del bug visual donde todos los tabs se mostraban simultáneamente.
El problema era el uso incorrecto del slot #default en UTabs que causaba
que todos los contenidos se renderizaran a la vez, creando elementos duplicados.
Cambios:
- Cambiar de #default a slots nombrados específicos (#table, #cards, #panorama, #detail)
- Ahora solo se muestra el contenido del tab activo
- Elimina la duplicación de elementos
- Mejora la legibilidad y organización visual
Ajustes realizados:
Components:
- MetabaseCardDisplay: grid responsive, queries con wrap, botones apilables
- MetabaseCardsTable: filtros verticales en móvil, acciones con wrap
Page:
- Header responsive con elementos apilados
- Stats en grid 2x2 para móvil, 4 columnas en desktop
- Tamaños de fuente adaptados con breakpoints
Todas las queries SQL y JSON ahora usan whitespace-pre-wrap y break-words
para aprovechar el espacio vertical en lugar de scroll horizontal.
- Crear componente MetabaseCardDisplay para mostrar detalles de queries
- Crear componente MetabaseCardsTable para listar todas las queries
- Crear página /metabase-debug con vistas de tabla, cards y queries Panorama
- Agregar API routes para cards de Metabase (GET, POST, export)
- Actualizar metabase.ts para soportar API Key authentication
- Agregar configuración de Metabase API Key en nuxt.config.ts
- Documentar todos los endpoints disponibles en METABASE_API_ENDPOINTS.md
- Add support for 'db' and 'table' query parameters
- Automatically preselect database and table from URL
- Auto-load data when both params are provided
- Update URL when user changes selection manually
- Example: /explorer?db=facturador+supabase&table=Ingresos
- Change from object binding to string-based selection
- Add computed properties to transform data to string arrays
- Add reverse lookup to get IDs from selected strings
- Improves compatibility with USelectMenu component
- Fixes dropdown not showing options correctly
- Change from ID-based selection to full object binding
- Add custom label templates to display proper text
- Simplify computed properties and watchers
- Improve user experience with proper label display
- Change from USelect to USelectMenu for database and table selection
- Add value-attribute and option-attribute props for proper rendering
- Improves dropdown functionality and user experience
- Replace maintenance mode with functional data explorer
- Connect to Metabase API for database and table listing
- Implement raw data viewer with search and column filtering
- Add support for querying tables directly from Metabase
- Limit queries to 1000 records by default for performance
Add complete integration with Metabase API to fetch data from
'facturador supabase' database.
Features:
- Server-side Metabase authentication using session tokens
- Utility functions for Metabase API requests with auto-retry
- API endpoints to proxy Metabase requests
- GET /api/metabase/databases - List all databases
- GET /api/metabase/tables/:databaseId - Get tables and metadata
- POST /api/metabase/query - Execute queries against tables
- useMetabase() composable for frontend consumption
- getDatabases() - Fetch available databases
- getDatabaseMetadata() - Get tables and fields info
- queryTable() - Execute queries with filters and limits
- resultToObjects() - Helper to convert results to objects
Session tokens are cached and auto-refreshed when expired.
This enables the application to display real data from the
facturador database without using embeds or iframes.
The tableStores.client.ts plugin was importing from the deleted
stores directory, causing build failures. This plugin initialized
Pinia stores for table data caching which is no longer needed.
Remove all client-side state management and data caching as the
application no longer needs to manage data analysis features.
Changes:
- Remove Pinia store system (app/stores/ directory)
- metadata.ts: Store for table metadata
- tableDataFactory.ts: Factory for creating table data stores
- README.md: Comprehensive store documentation
- Remove IndexedDB storage utility (app/utils/storage.ts)
- Remove Pinia dependencies from package.json
- @pinia/nuxt
- pinia
- Remove Pinia module from nuxt.config.ts
- Remove vendor-pinia chunk configuration
- Remove server services (server/services/ directory)
- table-service.ts: Supabase-dependent table operations
- query-parser.ts: Query parsing utilities
- query-runner.ts: Query execution utilities
The application now operates as a stateless authentication portal
without client-side data caching or state management.
Restore all data analysis pages but display them in maintenance mode.
Users can see these pages in the navigation and access them, but they
show a maintenance message instead of trying to fetch data.
Changes:
- Create MaintenanceMode component for reusable maintenance UI
- Restore all deleted pages: explorer, metadatos, rawExplorer, panorama,
comparativa-cosechas, informe-ingresos
- Replace complex data-fetching logic with MaintenanceMode component
- Add "Mantenimiento" badges to navigation menu items
- Pages show clear maintenance message with technical details
- Users can still navigate to these pages without errors
This approach:
- Keeps the UI structure intact
- Shows users what features exist
- Provides clear communication about maintenance status
- Prevents confusion about missing features
- Easy to re-enable when data sources are reconnected
BREAKING CHANGE: Remove all data analysis features
This commit removes all database-dependent functionality and simplifies
the application to focus on authentication and user management only.
Changes:
- Remove all /api/data and /api/metadata server endpoints
- Remove Supabase configuration from nuxt.config.ts and .env.example
- Remove @supabase/supabase-js dependency from package.json
- Delete data analysis pages: explorer, metadatos, rawExplorer, panorama,
comparativa-cosechas, informe-ingresos
- Simplify sidebar navigation to show only "Inicio"
- Update home page to focus on authentication and profile management
- Remove "Supabase" and "Solo lectura" badges from navbar
- Keep only auth-related API endpoints: /api/auth/status and /api/auth/check-group
The application now serves as an authentication-protected portal with:
- Authentik SSO integration
- User profile management
- Settings and notifications pages (coming soon)
- No database or data analysis features