# Contrato — API Sincronização Tickets Desk ↔ FOSS **Spec:** [044](../spec.md) **VM122:** Desk API · **VM123:** FOSSBilling Admin API **Status:** 📋 Especificado — implementação pendente --- ## 1. Desk → FOSS — criar espelho **Quando:** ticket Desk criado ou escalado **e** `external_customer_id` disponível. ### `foss_client.create_support_ticket()` (novo módulo VM122) ``` POST https://financeiro.ligbox.com.br/api/admin/support/ticket_create Auth: Basic admin@ligbox.com.br:{FOSS_ADMIN_API_KEY} Content-Type: application/x-www-form-urlencoded ``` | Campo FOSS | Origem Desk | |------------|-------------| | `client_id` | `billing_accounts.external_customer_id` | | `subject` | `tickets.subject` | | `content` | Primeira nota + link Desk + OB- se existir | | `helpdesk` | `Ligbox Ops` (departamento default) | | `priority` | mapa Desk priority → FOSS | **Resposta esperada:** `{ "result": { "id": 42 } }` → gravar `foss_ticket_id=42`. **Idempotência:** antes de criar, `GET ticket by desk_ticket_id` em cache local ou custom field FOSS `desk_ticket_id`. --- ## 2. FOSS → Desk — webhook inbound ### `POST /api/v1/webhooks/foss/support` **Auth:** header `X-Foss-Webhook-Secret: {FOSS_WEBHOOK_SECRET}` **Content-Type:** `application/json` ### Payload ```json { "event": "ticket.reply", "foss_ticket_id": 42, "client_id": 17, "domain": "empresa.com.br", "subject": "Problema DNS", "status": "open", "message": "Cliente respondeu: ainda não resolveu", "author": "client", "created_at": "2026-07-01T18:05:00Z" } ``` | `event` | Acção Desk | |---------|------------| | `ticket.opened` | Criar ticket Desk se não existir (cliente abriu no FOSS) | | `ticket.reply` | Append nota interna + notificar assignee | | `ticket.closed` | `UPDATE tickets SET status='closed'` | | `ticket.reopened` | `status='open'` | ### Response 200 ```json { "ok": true, "desk_ticket_id": 45, "handled": true, "duplicate": false } ``` ### Erros | HTTP | Condição | |------|----------| | 401 | Secret inválido | | 404 | `foss_ticket_id` sem correlação e `client_id` desconhecido | | 409 | Evento duplicado (idempotência) | --- ## 3. Desk — API staff (fase E) ### `POST /api/v1/support/tickets` **Auth:** JWT Desk · roles: `technician+`, `sales_support+` ```json { "domain": "empresa.com.br", "subject": "Webmail inacessível", "body": "Cliente reporta erro 502", "mirror_foss": true, "wizard_ticket_id": null } ``` **Fluxo:** 1. Resolve `billing_accounts` por `domain` 2. INSERT `tickets` 3. Se `mirror_foss=true` e `external_customer_id` → `foss_client.create_support_ticket()` 4. Return `{ desk_ticket_id, foss_ticket_id, tracking_url }` ### `GET /api/v1/support/tickets/{id}/sync-status` Retorna estado sync FOSS + links. --- ## 4. Portal VM112 — sem alteração v1 Endpoints existentes mantidos: | Método | Path | Notas | |--------|------|-------| | `POST` | `/api/onboarding/support/ticket` | Cria OB- + webhook Desk | | `GET` | `/api/onboarding/support/ticket/{OB-}/public` | Portal cliente Spec 026 | **Extensão fase E:** resposta inclui `desk_ticket_id` quando sync completo (opcional, não bloqueia cliente). --- ## 5. FOSS — configuração webhook (VM123) Opções (escolher uma na implementação): | Opção | Prós | Contras | |-------|------|---------| | **A** Hook PHP FOSS custom | Tempo real | Requer patch container | | **B** Cron Desk poll `support/ticket_get_list` | Sem patch FOSS | Latência 1–5 min | | **C** Traefik + sidecar notifier | Desacoplado | Mais infra | **Recomendação v1:** Opção **B** (poll) + Opção **A** quando estável. --- ## 6. Variáveis ambiente (VM122) | Variável | Descrição | |----------|-----------| | `FOSSBILLING_URL` | `https://financeiro.ligbox.com.br` | | `FOSS_ADMIN_EMAIL` | Conta M2M admin | | `FOSS_ADMIN_API_KEY` | API key FOSS (Spec 027) | | `FOSS_WEBHOOK_SECRET` | Validação inbound FOSS→Desk | | `FOSS_TICKET_SYNC_ENABLED` | `true` / `false` feature flag | --- ## 7. Testes curl ```bash # Webhook simulado FOSS → Desk curl -s -X POST https://desk.ligbox.com.br/api/v1/webhooks/foss/support \ -H "X-Foss-Webhook-Secret: $FOSS_WEBHOOK_SECRET" \ -H "Content-Type: application/json" \ -d '{ "event": "ticket.reply", "foss_ticket_id": 42, "client_id": 17, "domain": "empresa.com.br", "message": "Teste sync Spec 044" }' ``` --- ## Histórico | Versão | Data | Notas | |--------|------|-------| | 1.0 | 2026-07-01 | Contrato inicial Spec 044 |