Base de datos
PostgreSQL 18. 38 tablas · 34 tipos enumerados · 23 triggers · 153 índices · 3 vistas, en 13 migraciones.
Los enums son el contrato
Los mismos valores viven en tres sitios:
| Capa | Forma |
|---|---|
| Base | snake_case — en_proceso |
| GraphQL | SCREAMING_SNAKE — EN_PROCESO |
| Tokens de diseño | camelCase — enProceso |
En Rust se declaran una sola vez con una macro que deriva a la vez
sqlx::Type y async_graphql::Enum, de modo que las dos representaciones no
pueden divergir. En el front, la traducción existe una sola vez en
enumToTokenKey.
Añadir un estado nuevo obliga a tocar los tres. Eso es deliberado.
Los triggers que hacen el trabajo
| Trigger | Qué hace |
|---|---|
tickets_set_sla | Fija los vencimientos al crear, y los recalcula al cambiar la prioridad |
tickets_status | Cierra tiempos al resolver, marca el FCR, gestiona reaperturas |
ticket_events_apply | La primera respuesta pública fija el TPA |
work_logs_accumulate | Acumula el tiempo de atención operativa |
sales_refresh_customer | Recalcula valor de vida, segmento y estado del cliente |
warranties_sync | Deriva la fecha de fin y sincroniza el estado |
messages_touch_conversation | Resumen de la bandeja y ventana de 24 h |
Las vistas
v_tickets_enriched— tickets con SLA en vivo, para que web y móvil no calculen «le quedan 40 minutos» cada una a su manerav_customers_enriched— resumen para la ficha 360°v_agent_workload— carga por asesor, alimenta el reparto automático
Un fallo real que enseña algo
La migración 0009 asignaba literales sin tipo a una columna de tipo
enumerado. PostgreSQL resolvía la expresión como text y el UPDATE fallaba.
Estaba latente: el trigger sólo corre al insertar una venta, y el esquema se validó sin ninguna. Con eso, registrar la primera venta era imposible — habría aparecido el primer día de uso real.
Corregido en 0012, con la corrección en una migración nueva y no editando la
0009, porque cambiar una migración ya aplicada altera su checksum.