Campos y automatizaciones del ticket
El módulo de tickets sincroniza con Zendesk pero define sus propios campos y desplegables. Esta página documenta las columnas del ticket, de dónde salen las opciones de cada desplegable, cómo se mapean con Zendesk y las automatizaciones del formulario de alta/edición.Campos del ticket
Columnas nativas de la tablachat_tickets (más allá de identificadores y timestamps de sistema):
estimated_cost (numérico) se conserva por compatibilidad. Se añadió estimated_cost_range para capturar el coste como rango: <50, 50–100, 100–500, 500–1.000, 1.000–5.000, >5.000 €.Desglose del coste real (cuota vs extra).
actual_cost sigue siendo el total. Cuando ambas columnas están informadas se cumple actual_cost = cost_covered_by_fee + cost_extra (ambas validan >= 0 en el DTO). En los tickets históricos actual_cost puede estar informado con las dos columnas nuevas a NULL: eso significa desglose desconocido y debe tratarse como tal en todas partes —nunca inventar ceros. Migración aditiva 223_ticket_cost_maintenance_fee.sql (columnas nullable, sin CHECK ni backfill).Coste pendiente vs sin coste.
cost_pending = true significa “resuelto, coste real aún desconocido” (se cierra el ticket sin escribir actual_cost y se completa cuando llega la factura). No confundir con actual_cost = 0, que es “comprobado, sin coste”. El flag se limpia solo en cuanto se escribe un actual_cost real —salvo que el propio update lo esté fijando de forma explícita en el mismo payload—. Migración aditiva 227_add_cost_pending_to_tickets.sql (columna NOT NULL DEFAULT false + índice parcial sobre las filas true).Tipo (
ticket_kind) vs Segmento (ticket_type). No confundir: ticket_kind es una columna persistida con la naturaleza del ticket (incidencia | propuesta de mejora). ticket_type (etiquetado Segmento en la lista) es una dimensión derivada de SLA (casa/experiencia/administrativo/dormido) que se computa al leer y no es una columna.Desplegables: Vivla Tools es la fuente de verdad
Las opciones de equipo de resolución, zona, categoría, estado de reparación y pagador se sirven desdeticket-options.config.ts (TICKET_OPTION_SETS), no en vivo de Zendesk. CX decidió el set final aquí, de forma que es editable sin tocar Zendesk y resiliente si la API de Zendesk falla.
El destino sí sigue viniendo en vivo de Zendesk (vía ZendeskProvider.getTicketFields()), igual que el resto de enums no cubiertos por la config.
Todo se expone en un único endpoint:
Valores finales
Equipo de resolución (resolution_team)
Zona (
zone): General, Salón, Comedor, Cocina, Dormitorio, Baños, Exterior, Lockers, Garaje.
Categoría (category): Llaves y acceso, Inventario, Electrodomésticos, Amenities o accesorios, Iluminación, Wifi, Limpieza, Fontanería, Electricidad, Daños estructurales, Daños menores, Carpintería, Diseño y estilismo (label corregida), Climatización, Mantenimiento preventivo (plagas). Se eliminó “Reservas y estancias”.
Estado de reparación (repair_status): En evaluación, En ejecución, Comunicado a propietario. Se eliminó “Programado”.
Pagador (payer): Capex, Vivla, Mejora o daño propietario, Cuota de mantenimiento, Comunidad de vecinos, Promotora, Seguro, Derrama.
Mapeo con Zendesk
Elvalue (slug) almacenado en chat_tickets es el mismo en Vivla Tools y en Zendesk. Los slugs históricos de Zendesk se preservan tal cual para que las filas antiguas sigan resolviendo. El contrato de mapeo vive en zendesk-mappings.config.ts:
Sin write-back a Zendesk (desde agosto 2026). Los valores de estos campos
—incluidas las opciones propias de Tools (
manitas, promotora, seguro,
garaje, climatizacion, mantenimiento_preventivo_plagas) y los destinos
nuevos (mallorca, asturias, etc.)— se guardan solo en chat_tickets y ya
no se propagan a Zendesk, así que no hace falta que existan como opciones
allí. El mapeo zendesk-mappings.config.ts se conserva porque lo siguen usando
el CLI de import manual y el catálogo de campos (GET /chat/zendesk/fields,
ahora servido de config local desde ticket-options.config.ts). Antes la
creación mandaba todos los campos nativos a Zendesk y la actualización solo
re-sincronizaba título/estado/prioridad (syncTicketToZendesk); ese camino ya
no existe.Automatizaciones del formulario
Casa → Destino
Al elegir (o preseleccionar) la propiedad en el alta de un ticket, el destino se autocompleta derivandoproperty.location → location.slug → destino (mapa LOCATION_SLUG_TO_DESTINATION). Solo aplica a creaciones futuras; no remapea tickets existentes.
{ propertyId → destino } que el formulario usa para el autocompletado.
Pagador automático según equipo
Al cambiar el equipo de resolución, si no se envía un pagador explícito, el sistema lo presugiere (suggestPayerForTeam / PAYER_BY_TEAM). El agente siempre puede sobrescribirlo.
derrama nunca se autosugiere: es una elección exclusivamente manual.Categoría obligatoria al crear (solo ruta de CX)
El formulario de alta de la herramienta de CX exige categoría para poder enviar (marca el campo con asterisco y bloquea el botón). La validación vive solo en esa ruta, no en elCreateTicketDto compartido: por ahí también crean tickets el agente de IA, las propuestas de mejora del portal y los borradores de encuestas, y hacerlo obligatorio a ese nivel las rompería a todas.
Estado de reparación derivado del estado
El estado del ticket manda sobre el de la reparación. Al cambiar elstatus, si no se envía un repair_status explícito, se deriva (REPAIR_STATUS_BY_TICKET_STATUS):
Campos eliminados
Los siguientes campos se retiraron de la UI; sus columnas se conservan en la base de datos como histórico:- Aprobación de propietarios (
owner_approval) - Aprobación de finanzas (
finance_approval) - Causa de la incidencia (
incident_cause) - Causa del bloqueo (
blocking_cause) - Nº de horas