Appearance
Infraestrutura & Auditoria
Estes quatro recursos são a espinha dorsal operacional do módulo — todos somente leitura: os logs de auditoria respondem "quem fez o quê, quando e de onde"; as chaves de idempotência garantem que o reenvio de uma operação offline não duplica vendas; os eventos outbox são a fila interna que alimenta os workers assíncronos; e os checkpoints de sincronização monitoram a saúde dos dispositivos POS que operam offline.
Nenhum destes recursos aceita escrita pela API: os registros nascem dos próprios fluxos do sistema (mutações, sincronizações e workers) e existem aqui para consulta, suporte e auditoria.
Headers obrigatórios
Todas as requisições devem incluir o header X-Tour-Id (UUID) com o tokenHeader da instância e Authorization: Bearer {token} com o token de um usuário staff (guard toursUser). Como são recursos somente leitura, basta estar autenticado na instância.
Logs de Auditoria
Cada mutação sensível do módulo grava um log imutável: a action (ex.: create, update, delete), a entidade afetada (entityType + entityId), o usuário staff autor (tourUserId), os dados antes e depois (beforeData/afterData) e a origem da requisição (ipAddress + userAgent), sempre com occurredAt.
Listar Logs
http
GET /v1/tours/user/audit-logsParâmetros de Query
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
page | number | Não | O número da página (mínimo: 1). |
perPage | number | Não | Itens por página (entre 1 e 100). |
action | string | Não | Filtra pela ação (máx. 150 caracteres). |
entityType | string | Não | Filtra pela entidade (ex.: tours_users). |
entityId | number | Não | Filtra pelo ID da entidade. |
tourUserId | number | Não | Filtra pelo usuário staff autor da ação. |
from | string | Não | Início do período por occurredAt (ISO 8601). |
to | string | Não | Fim do período por occurredAt (ISO 8601). |
orderBy | enum | Não | id ou occurredAt. |
orderDirection | enum | Não | asc ou desc. |
Exemplo de Requisição
bash
curl -X GET "https://api.us.basis.tavares.in/v1/tours/user/audit-logs?entityType=tours_users&action=create" \
-H "X-Tour-Id: 123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"Respostas
200 OK
Retorna a página de logs no formato meta/data.
json
{
"meta": {
"currentPage": 1,
"perPage": 10
},
"data": [
{
"id": 1,
"tourId": 1,
"tourUserId": 1,
"action": "create",
"entityType": "tours_users",
"entityId": null,
"beforeData": null,
"afterData": null,
"ipAddress": "291c:ceae:c9ed:6b5f:3ac4:18f3:deef:9bcd",
"userAgent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_15_7) AppleWebKit/588.52.84 (KHTML, like Gecko) Chrome/127.1.3.6 Safari/592.73.89",
"occurredAt": "2026-10-07T11:56:15.725-03:00",
"toursUser": {
"id": 1,
"displayName": "Bruno Demo"
}
}
]
}Obter Log por ID
http
GET /v1/tours/user/audit-logs/:idRespostas
200 OK
Retorna o log com o usuário autor da ação.
json
{
"id": 1,
"tourId": 1,
"tourUserId": 1,
"action": "create",
"entityType": "tours_users",
"entityId": null,
"beforeData": null,
"afterData": null,
"ipAddress": "291c:ceae:c9ed:6b5f:3ac4:18f3:deef:9bcd",
"userAgent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_15_7) AppleWebKit/588.52.84 (KHTML, like Gecko) Chrome/127.1.3.6 Safari/592.73.89",
"occurredAt": "2026-10-07T11:56:15.725-03:00",
"toursUser": {
"id": 1,
"displayName": "Bruno Demo"
}
}404 Not Found
Ocorre quando o log não existe na instância.
Chaves de Idempotência
Quando um dispositivo envia uma operação sensível à reconexão (pedido, pagamento, comanda) com clientRef, a plataforma registra a chave e o requestHash do payload. Se o mesmo clientRef chegar de novo — o dispositivo reenviou após uma queda de conexão — a API devolve a resposta congelada (responseBody + statusCode) em vez de executar a operação duas vezes.
O ciclo de vida: a chave é travada (lockedAt) enquanto a operação original processa, concluída (completedAt) com a resposta gravada, e expira em expiresAt — após a expiração, a chave pode ser reutilizada.
Listar Chaves
http
GET /v1/tours/user/idempotency-keysParâmetros de Query
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
page | number | Não | O número da página (mínimo: 1). |
perPage | number | Não | Itens por página (entre 1 e 100). |
key | string | Não | Busca pela chave (máx. 250 caracteres). |
orderBy | enum | Não | id, createdAt ou expiresAt. |
orderDirection | enum | Não | asc ou desc. |
Exemplo de Requisição
bash
curl -X GET "https://api.us.basis.tavares.in/v1/tours/user/idempotency-keys?key=093f6339-9fb7-4b91-bbf4-5753edc0b305" \
-H "X-Tour-Id: 123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"Respostas
200 OK
Retorna a página de chaves no formato meta/data.
json
{
"meta": {
"currentPage": 1,
"perPage": 10
},
"data": [
{
"id": 1,
"tourId": 1,
"key": "093f6339-9fb7-4b91-bbf4-5753edc0b305",
"requestHash": "B06d8c3dbD53Ecd3d0F59C7FC738AfA41B14ac2BbD9e1622eaE6B0D08f9d3822",
"responseBody": null,
"statusCode": null,
"lockedAt": null,
"completedAt": null,
"expiresAt": "2026-10-08T11:56:15.771-03:00",
"createdAt": "2026-10-07T11:56:15.771-03:00"
}
]
}Obter Chave por ID
http
GET /v1/tours/user/idempotency-keys/:idRespostas
200 OK
Retorna a chave com a resposta congelada (quando já concluída).
json
{
"id": 1,
"tourId": 1,
"key": "093f6339-9fb7-4b91-bbf4-5753edc0b305",
"requestHash": "B06d8c3dbD53Ecd3d0F59C7FC738AfA41B14ac2BbD9e1622eaE6B0D08f9d3822",
"responseBody": null,
"statusCode": null,
"lockedAt": null,
"completedAt": null,
"expiresAt": "2026-10-08T11:56:15.771-03:00",
"createdAt": "2026-10-07T11:56:15.771-03:00"
}404 Not Found
Ocorre quando a chave não existe na instância.
Eventos Outbox
O módulo usa o padrão transactional outbox: na mesma transação de uma operação (ex.: atualizar um pedido), um evento é gravado nesta fila interna. Os workers consomem a fila de forma assíncrona para disparar os efeitos colaterais — promoção da waitlist, alertas para a equipe, tarefas pós-checkout — sem risco de o efeito se perder se o processo cair no meio do caminho.
Cada evento tem um topic (ex.: order.updated), o payload JSON, o momento em que fica disponível (availableAt), o número de attempts, o lastError da última tentativa e o processedAt quando concluído. O filtro pending retorna apenas o que ainda não foi processado.
Listar Eventos
http
GET /v1/tours/user/outbox-eventsParâmetros de Query
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
page | number | Não | O número da página (mínimo: 1). |
perPage | number | Não | Itens por página (entre 1 e 100). |
topic | string | Não | Filtra pelo tópico (máx. 150 caracteres). |
pending | boolean | Não | true lista apenas eventos não processados. |
from | string | Não | Início do período (ISO 8601). |
to | string | Não | Fim do período (ISO 8601). |
orderBy | enum | Não | id, availableAt ou createdAt. |
orderDirection | enum | Não | asc ou desc. |
Exemplo de Requisição
bash
curl -X GET "https://api.us.basis.tavares.in/v1/tours/user/outbox-events?pending=true&topic=order.updated" \
-H "X-Tour-Id: 123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"Respostas
200 OK
Retorna a página de eventos no formato meta/data.
json
{
"meta": {
"currentPage": 1,
"perPage": 10
},
"data": [
{
"id": 1,
"tourId": 1,
"topic": "order.updated",
"payload": {
"ref": "613abf9a-93a4-45fc-ae4b-88f39e872c3d"
},
"availableAt": "2026-10-07T11:56:15.803-03:00",
"attempts": 0,
"lastError": null,
"processedAt": null,
"createdAt": "2026-10-07T11:56:15.804-03:00"
}
]
}Obter Evento por ID
http
GET /v1/tours/user/outbox-events/:idRespostas
200 OK
Retorna o evento com o payload completo.
json
{
"id": 1,
"tourId": 1,
"topic": "order.updated",
"payload": {
"ref": "613abf9a-93a4-45fc-ae4b-88f39e872c3d"
},
"availableAt": "2026-10-07T11:56:15.803-03:00",
"attempts": 0,
"lastError": null,
"processedAt": null,
"createdAt": "2026-10-07T11:56:15.804-03:00"
}404 Not Found
Ocorre quando o evento não existe na instância.
Checkpoints de Sincronização
Cada dispositivo POS que opera offline reporta um checkpoint de telemetria por usuário/dispositivo (deviceId + tourUserId): quando foi o último pull (lastPullAt) e o último push (lastPushAt), o número do último lote sincronizado (lastBatchSequence — um salto na sequência revela lotes perdidos), o intervalo de heartbeat configurado (heartbeatIntervalMinutes), quantos itens o dispositivo ainda reporta como pendentes (reportedPendingCount, em reportedAt) e a versão do app (appVersion). É o painel de saúde da frota offline.
Listar Checkpoints
http
GET /v1/tours/user/sync-checkpointsParâmetros de Query
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
page | number | Não | O número da página (mínimo: 1). |
perPage | number | Não | Itens por página (entre 1 e 100). |
deviceId | string | Não | Filtra pelo dispositivo (máx. 150 caracteres). |
tourUserId | number | Não | Filtra pelo usuário staff do dispositivo. |
orderBy | enum | Não | id ou updatedAt. |
orderDirection | enum | Não | asc ou desc. |
Exemplo de Requisição
bash
curl -X GET "https://api.us.basis.tavares.in/v1/tours/user/sync-checkpoints?deviceId=8a9ab472-593a-48ed-871b-34254669ff82" \
-H "X-Tour-Id: 123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"Respostas
200 OK
Retorna a página de checkpoints no formato meta/data.
json
{
"meta": {
"currentPage": 1,
"perPage": 10
},
"data": [
{
"id": 1,
"tourId": 1,
"tourUserId": 1,
"deviceId": "8a9ab472-593a-48ed-871b-34254669ff82",
"lastPullAt": null,
"lastPushAt": null,
"lastBatchSequence": null,
"heartbeatIntervalMinutes": 5,
"reportedPendingCount": 0,
"reportedAt": null,
"appVersion": "1.0.0",
"updatedAt": "2026-10-07T11:56:15.831-03:00"
}
]
}Obter Checkpoint por ID
http
GET /v1/tours/user/sync-checkpoints/:idRespostas
200 OK
Retorna o checkpoint do dispositivo.
json
{
"id": 1,
"tourId": 1,
"tourUserId": 1,
"deviceId": "8a9ab472-593a-48ed-871b-34254669ff82",
"lastPullAt": null,
"lastPushAt": null,
"lastBatchSequence": null,
"heartbeatIntervalMinutes": 5,
"reportedPendingCount": 0,
"reportedAt": null,
"appVersion": "1.0.0",
"updatedAt": "2026-10-07T11:56:15.831-03:00"
}404 Not Found
Ocorre quando o checkpoint não existe na instância.