Skip to main content

Panel de tickets

El Panel de tickets es la vista de analytics del sistema de tickets de soporte. Agrega métricas de actividad, cumplimiento de SLA, antigüedad del backlog y distribución por tipo, calculadas en tiempo real desde chat_tickets (sin tabla precomputada en v1). Las reglas de negocio (objetivos de SLA, mapeos de tipo, umbral de dormido) viven en apps/backend/src/chat/tickets/config/sla.config.ts como única fuente de verdad. Los campos derivados (slaStatus, ticketType, daysSinceCreated) se calculan al leer cada ticket — el frontend no reimplementa las reglas.

KPIs

GET /chat/tickets/kpis — admite filtros por ventana de fechas (dateFrom/dateTo), equipo (team / resolution_team) y prioridad. Los tickets marcados como invalid no cuentan.
MétricaCampoDescripción
Tickets abiertostotalOpenTickets en estado abierto ahora mismo (cualquier prioridad)
Resueltos en rangototalResolvedInRangeTickets resueltos/cerrados dentro de [dateFrom, dateTo]
Críticos sin resolvercriticalUnresolvedNowTickets abiertos con prioridad urgent o high
Backlog por cohortesbacklogOverDaysAbiertos con antigüedad > 1, > 3 y > 7 días
% backlogbacklogPercentageProporción (0-1) de abiertos con más de 3 días sobre totalOpen
FCR %fcrPercentageFirst Contact Resolution: resueltos con ≤ 1 comentario público y sin reaperturas
Tasa de reaperturasreopenRateProporción (0-1) de resueltos en rango que se reabrieron al menos una vez
Tiempo medio de respuestaavgResponseTimeMinutesMinutos medios de creación → first_response_at, por prioridad
Tiempo medio de resoluciónavgResolutionTimeMinutesMinutos medios de creación → resolved_at, por prioridad
Cumplimiento SLA respuestaslaResponseComplianceProporción (0-1) que cumple el SLA de 1ª respuesta, por prioridad
Cumplimiento SLA resoluciónslaResolutionComplianceProporción (0-1) que cumple el SLA de resolución, por prioridad
El FCR cruza chat_tickets con chat_ticket_comments: una consulta agrupada cuenta los comentarios públicos por ticket resuelto. Pasa el FCR quien tiene commentCount ≤ 1 y reopenedCount === 0.
Estados considerados abiertos: created, assigned, in_progress. Estados resueltos: resolved, closed.
El estado improvement_proposal era un estado falso ya migrado a la dimensión propia ticket_kind (ver Campos). Sigue en el CHECK de status durante la transición two-phase, pero las propuestas ya cuentan como abiertas por su lifecycle real (created/assigned). Excluir las propuestas de los KPIs (si CX lo pide) es un follow-up de producto.

SLAs

Objetivos en minutos (wall-clock 24/7), definidos en sla.config.ts:
Prioridad1ª respuestaResolución
urgent30 min6 h (360 min)
high30 min24 h (1440 min)
normal2 h (120 min)7 días (10080 min)
low24 h (1440 min)30 días (43200 min)
computeSlaStatus(ticket) devuelve el estado de la etapa actual del SLA:
  • Tickets resueltos → siempre ok.
  • Antes de la 1ª respuesta → se compara el tiempo transcurrido contra el SLA de respuesta.
  • Tras la 1ª respuesta → se compara contra el SLA de resolución.
EstadoCondición
okTranscurrido < 80 % del objetivo
warningTranscurrido ≥ 80 % del objetivo
breachedTranscurrido ≥ 100 % del objetivo
Por ahora el cálculo usa tiempo de reloj 24/7. La flag SLA_USE_BUSINESS_HOURS está reservada para una futura utilidad de horario laboral (zona horaria + festivos españoles + fines de semana) que podrá enchufarse sin tocar los servicios.

Tipos de ticket

resolveTicketType(ticket) deriva uno de cuatro tipos: Casa, Experiencia, Administrativo o Dormido. Regla híbrida, en orden:
  1. Override Dormido — si el ticket está abierto y sin actividad (updatedAt / lastCommentAt) durante ≥ 30 días (DORMIDO_THRESHOLD_DAYS), el tipo es dormido, ignorando el resto.
  2. Equipo primarioresolution_teamTICKET_TYPE_BY_TEAM.
  3. Categoría (fallback)categoryTICKET_TYPE_BY_CATEGORY, cuando el equipo no resuelve un tipo.
  4. Defaultadministrativo (TICKET_TYPE_DEFAULT).
Mapeo por equipo (TICKET_TYPE_BY_TEAM):
EquipoTipo
propiedades_y_mantenimiento, equipo_de_limpieza, manitas, promotoraCasa
proveedores_externos (histórico)Casa
experiencia_del_cliente (histórico)Experiencia
seguro, diseño (histórico)Administrativo
Mapeo por categoría (TICKET_TYPE_BY_CATEGORY): facturacion / contratos / documentacion → Administrativo; reservas / check_in / check_out → Experiencia.

Aging

GET /chat/tickets/aging — cuenta los tickets abiertos agrupados por antigüedad desde su creación. Admite filtro por team. Cohortes (AGING_COHORTS), con límite inferior inclusivo y superior exclusivo:
CohorteRango
lt1d< 1 día
1to3d1-3 días
3to7d3-7 días
gt7d> 7 días

Stats

GET /chat/tickets/stats?groupBy=... — agrega los tickets por una dimensión, aplicando la misma superficie de filtros que el listado (estado, prioridad, agente, propiedad, fechas y columnas nativas de Zendesk). Cada bucket devuelve count, openCount, resolvedCount y sumas/medias de coste (totalEstimatedCost, totalActualCost, avgEstimatedCost). Valores de groupBy: status, priority, property, resolution_team, zone, category, destination, payer, repair_status, owner_approval, finance_approval, ticket_type. Para property se adjunta el nombre como label; ticket_type es una dimensión derivada (no columna) y se calcula con resolveTicketType.

Paneles del dashboard

La página (TicketsDashboardPage.tsx) abre con una rejilla de 3 columnas de 6 KPI cards: Tickets abiertos, Críticos sin resolver (urgentes + altas abiertas), Resueltos último 30 días, FCR % (objetivo 70-80 %), Reaperturas % y Backlog > 3 días (alerta si supera el umbral del 10 %). Debajo, los paneles van en una rejilla uniforme de 3 columnas (xl:grid-cols-3) para que las cards no se agranden:
PanelContenido
SlaComplianceCardCumplimiento de SLA de respuesta y resolución por prioridad
BacklogAgingChartDistribución del backlog por cohortes de antigüedad
TicketsByTeamChartTickets por equipo de resolución (donut)
TicketsByCategoryChartTickets por categoría (barras horizontales)
TicketsByPayerChartTickets por pagador (donut)
ResponseTimeBarChart / ResolutionTimeBarChartTiempos medios de respuesta / resolución por prioridad
WeeklyTicketsChartVolumen semanal de tickets (últimos 90 días)
TicketsByPropertyTableMétricas por casa — desglose por prioridad (ancho completo)
DormantTicketsPanelTickets dormidos (abiertos sin actividad ≥ 30 días, ancho completo)
Se retiraron dos paneles que perdieron valor con el modelo nuevo de equipos: TicketTypeDistributionChart (con los equipos actuales casi todo cae en “Casa”) y TicketsByPropertyChart (el gráfico era redundante con la tabla TicketsByPropertyTable, que se mantiene).

Filtros de la lista

El listado de tickets (GET /chat/tickets) admite, además de los filtros por columna (estado, prioridad, agente, propiedad, fechas y campos nativos de Zendesk), filtros sobre los campos derivados:
FiltroEfecto
ticketTypeFiltra por tipo derivado (casa / experiencia / administrativo / dormido)
slaStatusFiltra por estado de SLA (ok / warning / breached)
ageCohortFiltra por cohorte de antigüedad (lt1d / 1to3d / 3to7d / gt7d)
isDormantFiltra por la condición de dormido (true/false)
onlyInvalidMuestra solo los tickets marcados como inválidos (soft-delete)
Los filtros derivados dependen de funciones puras (resolveTicketType, computeSlaStatus, isDormant) que no se pueden traducir a SQL sin duplicar las reglas. En v1 el listado trae el conjunto filtrado por columnas, deriva en memoria y pagina localmente — barato para el working set de CX (miles, no decenas de miles).