- Fix error de sintaxis SQL en cálculo de tickets 'at risk' - Fix error de timezone (offset-naive vs offset-aware datetimes) - Implementado sistema completo de SLA Management - Agregados endpoints: /sla/dashboard, /sla/violations, /sla/at-risk - Creadas vistas frontend para dashboard, violaciones y tickets en riesgo - Actualizado sistema de Celery para monitoreo automático de SLAs - Mejorada configuración de categorías con tiempos SLA personalizables - Corregidos problemas de proxy en configuración de Vite - Agregado troubleshooting guide en README Archivos principales modificados: - backend/app/api/v1/endpoints/sla.py (nuevo) - backend/app/api/schemas/sla.py (nuevo) - frontend-internal/src/routes/sla/ (nuevo módulo completo) - workers/app/tasks/sla_tasks.py (queries async mejoradas) Documentación: docs/changelog-2026-02-17.md
4.4 KiB
Changelog - 17 de Febrero 2026
Versión 1.7.0 - Corrección Sistema de SLA Dashboard
🐛 Bugs Corregidos
Error 500 en Endpoint /api/v1/sla/dashboard
Problema Identificado: El endpoint de SLA Dashboard estaba generando errores 500 (Internal Server Error) al intentar cargar las métricas. Se identificaron dos problemas críticos en las queries SQL:
-
Error de Sintaxis SQL - "missing FROM-clause entry for table 'ticket'"
- Causa: Uso incorrecto de
text()con referencias al modelo SQLAlchemy dentro de expresiones SQL sin formato - Ubicación: Cálculo de tickets "at risk" en queries de Response y Resolution SLA
- Expresión problemática:
text("INTERVAL '20%' * (Ticket.sla_response_due - Ticket.created_at)")
- Causa: Uso incorrecto de
-
Error de Timezone - "can't subtract offset-naive and offset-aware datetimes"
- Causa: Comparación entre
datetime.now(timezone.utc)(timezone-aware) y campos de base de datosTIMESTAMP WITHOUT TIME ZONE(timezone-naive) - Ubicación: Todas las comparaciones temporales en queries SLA
- Causa: Comparación entre
✅ Solución Implementada
Archivo Modificado:
backend/app/api/v1/endpoints/sla.py
Cambios Realizados:
-
Eliminación de SQL Crudo con
text()- Se reemplazaron todas las expresiones
text()con funciones nativas de SQLAlchemy - Se utilizó
func.extract('epoch', ...)para cálculos temporales seguros
- Se reemplazaron todas las expresiones
-
Corrección de Timezone
- Se introdujo
db_now = func.now()para usar la funciónNOW()de PostgreSQL directamente now = datetime.now(timezone.utc)se mantiene solo para cálculos en Python (ej:period_start)- Se reemplazaron todas las comparaciones
now > Ticket.sla_response_duepordb_now > Ticket.sla_response_due
- Se introdujo
-
Cálculo de Tickets "At Risk" Mejorado
- Lógica: Un ticket está "en riesgo" cuando ha consumido más del 80% del tiempo disponible
- Nueva expresión segura:
func.extract('epoch', db_now - Ticket.created_at) > (func.extract('epoch', Ticket.sla_response_due - Ticket.created_at) * 0.8)
Secciones del Código Corregidas:
-
Dashboard Principal (líneas 93-280)
- Query de Response SLA
- Query de Resolution SLA
- Contadores de violaciones activas
-
Lista de Violaciones (líneas 355-395)
- Filtro por tipo de SLA (response/resolution)
- Queries con timezone corregido
-
Tickets en Riesgo (líneas 505-540)
- Cálculo del umbral de riesgo
- Filtrado de tickets según porcentaje de tiempo consumido
🧪 Validación
Pruebas Realizadas:
- ✅ Endpoint
/api/v1/sla/dashboard?days=30responde correctamente (200 OK) - ✅ Backend reiniciado sin errores de sintaxis
- ✅ Logs del backend sin excepciones de SQLAlchemy
- ✅ Frontend carga el dashboard de SLA sin errores 500
Estado del Servicio:
servicemanager-backend: Up and healthy
servicemanager-db: Up and healthy
servicemanager-redis: Up and healthy
📊 Impacto
Alta Prioridad: Este fix desbloquea una funcionalidad crítica del sistema de gestión de SLAs, permitiendo a los equipos de soporte visualizar:
- Métricas de cumplimiento de Response SLA
- Métricas de cumplimiento de Resolution SLA
- Tickets en riesgo de violar SLA
- Violaciones activas
- Tendencias por categoría y prioridad
🔍 Detalles Técnicos
Stack Tecnológico:
- Python 3.11
- FastAPI (async)
- SQLAlchemy 2.0 (async ORM)
- PostgreSQL
- Docker
Patrón de Solución:
- Uso de funciones SQL nativas a través de SQLAlchemy ORM
- Separación entre datetime Python (timezone-aware) y SQL timestamps (timezone-naive)
- Eliminación de strings SQL dinámicos en favor de expresiones type-safe
📝 Notas para Desarrollo Futuro
Lecciones Aprendidas:
- Siempre usar
func.now()para comparaciones temporales en queries SQL - Evitar
text()cuando sea posible; preferir funciones SQLAlchemy - Los campos
TIMESTAMP WITHOUT TIME ZONEen PostgreSQL deben compararse con valores timezone-naive o funciones SQL
Recomendaciones:
- Considerar migración de campos timestamp a
TIMESTAMP WITH TIME ZONEen futuras versiones - Agregar tests de integración para endpoints SLA
- Implementar monitoreo de queries SQL lentas
Desarrollador: GitHub Copilot
Fecha: 17 de Febrero 2026
Tipo: Bug Fix
Severidad: Alta
Branch: main
Versión: 1.7.0