Sincronizar fila offline

POST/api/offline/sync

Aplica no servidor as ações (finalizar visita / registrar observação) feitas em campo sem internet. Cada item da fila é processado individualmente: um item com erro não impede os demais de serem aplicados.

Exemplos de uso

Rota interna do próprio app (a fila offline é montada e reenviada automaticamente pelo PWA) — exige o cookie de sessão do usuário logado, não um token separado. Os exemplos abaixo mostram como chamar essa mesma rota fora do app, reaproveitando o cookie de uma sessão de navegador já autenticada (ex.: pra depurar um item que ficou preso na fila).

curl -X POST "https://empresa.primevisita.com.br/api/offline/sync" \
  -H "Content-Type: application/json" \
  -H "Cookie: $COOKIE_DE_SESSAO" \
  -d '{
    "actions": [
      { "id": "a1", "type": "finalize", "appointmentId": "6a4d18dcc56c1026a5d0c138", "capturedStatus": "AGENDADO", "data": { "status": "REALIZADO", "result": "JA_E_PARCEIRO" } }
    ]
  }'

Parâmetros

Cookie de sessãoHeaderstringobrigatório

Descrição

Mesmo cookie criado no login (/auth/login) da própria UI. Exige permissão appointment:update.

Como encontrar

Definido automaticamente pelo navegador após o login — não é algo que se obtém manualmente; chamar esta rota fora do app significa reenviar o cookie já existente na sessão do navegador.

actionsCorpo (body)OutboxAction[]obrigatório

Descrição

Lista de ações capturadas offline. Cada item tem id, type (finalize | observation), appointmentId, capturedStatus e data (status/result/observations conforme o tipo).

Como encontrar

Montado automaticamente pelo app durante o uso offline (fila local no dispositivo) — não é algo digitado manualmente.

Exemplos de saída

200 — resultado por item

200

Sempre 200, mesmo com itens em erro/conflito — o status de cada ação vem dentro do array results.

{
  "results": [
    { "id": "a1", "status": "applied" },
    { "id": "a2", "status": "conflict", "message": "Esta visita já foi finalizada no servidor por outra pessoa." },
    { "id": "a3", "status": "error", "message": "Agendamento não encontrado." }
  ]
}

Exemplos de erro

401 — sem sessão

401

Cookie ausente ou usuário inativo.

{ "error": "unauthorized" }

403 — sem permissão

403

Usuário autenticado, mas sem appointment:update (ex.: cargo ANALISTA).

{ "error": "forbidden" }

400 — corpo inválido

400

JSON malformado, ou actions não é um array.

{ "error": "invalid_body" }