Skip to main content

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 tabla chat_tickets (más allá de identificadores y timestamps de sistema):
CampoColumnaTipoDescripción
TítulotitletextoAsunto del ticket
DescripcióndescriptiontextoDetalle de la incidencia
Estadostatusenumcreated, assigned, in_progress, improvement_proposal (deprecado), resolved, closed
Prioridadpriorityenumlow, normal, high, urgent
Tipoticket_kindenumNaturaleza del ticket: incident (incidencia, default) | improvement_proposal (propuesta de mejora)
Propiedadproperty_idrefCasa asociada (UUID de properties)
DestinodestinationenumZona geográfica (Baqueira, Menorca, etc.)
Equipo de resoluciónresolution_teamenumEquipo responsable
ZonazoneenumZona de la propiedad donde ocurre la incidencia
CategoríacategoryenumTipo de incidencia
PagadorpayerenumQuién asume el coste
Estado de reparaciónrepair_statusenumFase de la reparación
Coste estimadoestimated_costnuméricoImporte estimado exacto (se conserva)
Coste estimado (rango)estimated_cost_rangeenumRango de coste estimado (ver abajo)
Coste realactual_costnuméricoImporte final
Notas internasinternal_notestextoComentarios internos sobre la incidencia
Fecha primera respuestafirst_response_attimestampPrimera respuesta al cliente
Fecha resolución previstaexpected_resolution_attimestampFecha estimada de resolución
Resumen IAai_summarytextoGenerado por Zendesk (solo lectura)
estimated_cost (numérico) se conserva por compatibilidad. Se añadió estimated_cost_range para capturar el coste como rango: <100, 100–500, 500–1.000, 1.000–5.000, >5.000 €.
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.
Transición del estado improvement_proposal (two-phase). “Propuesta de mejora” era un estado falso del status. Ahora es su propia dimensión ticket_kind. La migración se aplica a mano en Supabase (dev + prod) en dos fases: 162 (pre-deploy: añade la columna ticket_kind, la indexa y backfillea el kind sin tocar el status) → deploy → 163 (post-deploy: normaliza el status de las propuestas a su lifecycle real assigned/created). improvement_proposal sigue permitido en el CHECK de status hasta un follow-up (retirarlo del CHECK y del enum es la fase 3).

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 desde ticket-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:
GET /chat/tickets/dropdowns

Valores finales

Equipo de resolución (resolution_team)
valuelabel
propiedades_y_mantenimientoProperties
promotoraPromotora
equipo_de_limpiezaLimpieza
manitasManitas
seguroSeguro
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

El value (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:
CampoColumnaZendesk field id
Casaproperty_id17925940459804
Destinodestination18534461108892
Equipo de resoluciónresolution_team17926240467100
Zonazone17926529031708
Categoríacategory17926673594140
Pagadorpayer17926800591004
Estado de reparaciónrepair_status17926767041308
Coste estimadoestimated_cost18458778087068
Coste realactual_cost18458825521180
Notas internasinternal_notes17926789994780
Fecha primera respuestafirst_response_at19667959142428
Fecha resolución previstaexpected_resolution_at19703173032092
Resumen IAai_summary23679986610076 (solo lectura)
Las opciones nuevas introducidas en Vivla Tools (manitas, promotora, seguro, garaje, climatizacion, mantenimiento_preventivo_plagas, y los destinos nuevos como mallorca, asturias, etc.) deben crearse como opciones en los campos correspondientes de Zendesk para que el write-back funcione. Hasta entonces, el valor se guarda en Vivla Tools pero el sync a Zendesk de esa opción falla. Ver docs/internal/specs/tickets-cx-rework/zendesk-options-to-create.md.

Qué se sincroniza en creación vs actualización

El write-back a Zendesk no es simétrico entre crear y actualizar:
  • Creación (POST /chat/tickets): se envían a Zendesk el asunto, la descripción, la prioridad, el estado y todos los campos nativos (destino, equipo, zona, categoría, pagador, costes, etc.) traducidos a sus custom fields.
  • Actualización (PATCH /chat/tickets/:id, syncTicketToZendesk): solo se re-sincronizan subject (título), status y priority. Los campos nativos (category, resolution_team, zone, destination, payer, costes…) se persisten en chat_tickets pero no se re-escriben a Zendesk tras la creación. Editarlos desde el detalle actualiza Vivla Tools pero no propaga a Zendesk.
El estado improvement_proposal nunca se escribe a Zendesk: solo existe en Tools. Si se propagara iría como pending y el eco del webhook lo devolvería como in_progress, revirtiendo el estado. shouldWriteStatusToZendesk() lo excluye del write-back y conserva el último status conocido en Zendesk.
Limitación del espejo hold. Zendesk hold no tiene estado interno propio: se mapea a in_progress (igual que pending). Por tanto, si un ticket está en hold en Zendesk y Tools reescribe su estado, Zendesk aterriza en pending, no en hold. Es una pérdida de fidelidad conocida del espejo.

Automatizaciones del formulario

Casa → Destino

Al elegir (o preseleccionar) la propiedad en el alta de un ticket, el destino se autocompleta derivando property.location → location.slug → destino (mapa LOCATION_SLUG_TO_DESTINATION). Solo aplica a creaciones futuras; no remapea tickets existentes.
GET /chat/tickets/property-destinations
Devuelve un mapa { 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.
EquipoPagador sugerido
Limpieza · Manitas · PropertiesCuota de mantenimiento
PromotoraPromotora
SeguroSeguro
derrama nunca se autosugiere: es una elección exclusivamente manual.

Estado de reparación derivado del estado

El estado del ticket manda sobre el de la reparación. Al cambiar el status, si no se envía un repair_status explícito, se deriva (REPAIR_STATUS_BY_TICKET_STATUS):
Estado del ticketEstado de reparación
created · assignedEn evaluación
in_progressEn ejecución
resolved · closedComunicado a propietario

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