> ## Documentation Index
> Fetch the complete documentation index at: https://wiki.vivla.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sincronización con Zendesk

> Import, webhook, comentarios y los CLIs de backfill del módulo de tickets

# Sincronización con Zendesk

Zendesk fue la fuente de verdad de los tickets. En la transición, **Vivla Tools** pasa a ser la herramienta principal con **sincronización bidireccional**: Zendesk alimenta el inbound (import + webhook) y recibe el write-back de lo que se edita en Tools.

<Note>
  Las opciones de los desplegables (equipo, zona, categoría, etc.) ya las
  gobierna Vivla Tools desde config — ver [Campos](/tickets/fields). El
  write-back de esos valores requiere que la opción exista también en Zendesk.
</Note>

## Modelo de sincronización

| Dirección                      | Qué                                                | Cómo                                              |
| ------------------------------ | -------------------------------------------------- | ------------------------------------------------- |
| **Inbound** (Zendesk → Tools)  | Tickets, custom fields, comentarios, transiciones  | Import diario (Windmill) + webhook en tiempo real |
| **Outbound** (Tools → Zendesk) | título / estado / prioridad + adjuntos (como nota) | `syncTicketToZendesk()` en cada update            |

El proveedor de Zendesk vive en `apps/backend/src/chat/integrations/ticketing/` (`zendesk.provider.ts`, `zendesk-import.service.ts`, `zendesk-mappings.config.ts`).

## Import

`zendesk-import.service` hace **UPSERT** de tickets por `zendesk_ticket_id`:

* Mapea los custom fields de Zendesk a columnas nativas según `zendesk-mappings.config.ts` (cada campo tiene su `zendeskFieldId` ↔ `column`).
* Importa los comentarios a `chat_ticket_comments`.
* Registra las transiciones de estado en `chat_ticket_status_history` y mantiene `resolved_at` / `reopened_count`.

El import se dispara desde **Windmill** (job `sync_tickets`, dentro de `sync_full`). Ver [Windmill](/platform/windmill).

## Webhook

`zendesk-webhook.handler` procesa eventos en tiempo real:

| Evento             | Efecto                                                                              |
| ------------------ | ----------------------------------------------------------------------------------- |
| `status_changed`   | Actualiza estado + registra transición + recomputa `resolved_at` / `reopened_count` |
| `priority_changed` | Actualiza prioridad + registra transición                                           |
| `assigned`         | Actualiza agente asignado + registra transición                                     |
| `comment_added`    | Upsert del comentario (`upsertFromZendesk`)                                         |

## Comentarios

La tabla `chat_ticket_comments` (migración 105) guarda los comentarios. `upsertFromZendesk` los sincroniza de forma idempotente (por `zendesk_comment_id`). Los adjuntos de los comentarios **apuntan a URLs de Zendesk** y se sirven a través del proxy con autenticación + transcodificación HEIC — ver [Adjuntos](/tickets/attachments).

## CLIs de backfill

Comandos para poblar datos históricos. Usan el contexto de Nest (`CliModule`) y respetan `APP_STAGE` (dev/prod).

| Comando                               | Qué hace                                                                           |
| ------------------------------------- | ---------------------------------------------------------------------------------- |
| `pnpm backfill:closed-tickets`        | Importa tickets cerrados / históricos de Zendesk                                   |
| `pnpm backfill:ticket-comments`       | Importa los comentarios históricos                                                 |
| `pnpm backfill:ticket-history`        | Trae los audits de Zendesk → historial; recomputa `resolved_at` / `reopened_count` |
| `backfill-ticket-teams` *(follow-up)* | Recategoriza con IA el equipo de tickets cerrados al set nuevo (estadística)       |

```bash theme={null}
# Ejemplos
APP_STAGE=development pnpm backfill:ticket-history --dry-run --limit=5
APP_STAGE=development pnpm exec ts-node -r tsconfig-paths/register \
  src/cli/backfill-ticket-teams.command.ts --dry-run --limit=10
```

<Warning>
  Las migraciones SQL en `apps/backend/src/database/migrations/` se aplican
  **manualmente** (no hay runner automático en este repo). Aplicar en dev y
  luego en prod.
</Warning>

## Migraciones del módulo

| Migración | Descripción                                           |
| --------- | ----------------------------------------------------- |
| `103`     | Tablas base de tickets                                |
| `104`     | Campos nativos (custom fields promovidos a columnas)  |
| `105`     | `chat_ticket_comments`                                |
| `107`     | `chat_ticket_status_history` (historial/actividad)    |
| `108`     | `resolved_at` / `reopened_count` / `last_reopened_at` |
| `134`     | `estimated_cost_range` (rangos de coste)              |
| `135`     | Soft-delete (`invalid` + metadatos)                   |
| `136`     | `improvement_plan` (plan de mejora IA)                |
| `137`     | `chat_ticket_attachments` (adjuntos en Cloudinary)    |
| `138`     | Tickets abiertos → equipo Properties (remap de CX)    |
