Reconciliação de documentos e eventos NFS-e
Os endpoints de documentos (/inbound/documentos) e eventos (/inbound/eventos) operam de forma independente. O client consome cada um em seu próprio loop de…
How-to Guide — Este documento orienta o integrador na construção da lógica de reconciliação entre documentos e eventos NFS-e inbound consumidos via API REST.
1. Introdução
Os endpoints de documentos (/inbound/documentos) e eventos (/inbound/eventos) operam de forma independente. O client consome cada um em seu próprio loop de polling, com tokens e filtros separados. No entanto, documentos e eventos estão relacionados: um evento de cancelamento, por exemplo, só faz sentido quando associado ao documento que ele cancela.
A reconciliação é a lógica no lado do client que conecta esses dois fluxos. Como a ordem de chegada é imprevisível — um evento pode chegar antes do documento correspondente, e vice-versa — o client precisa lidar com ambos os cenários de forma resiliente.
2. Pré-requisitos
- O client já implementa o loop de sincronização incremental para o endpoint de documentos (conforme o guia de sincronização de documentos NFS-e inbound).
- O client já implementa o loop de sincronização incremental para o endpoint de eventos (conforme o guia de sincronização de eventos NFS-e inbound).
- O client possui uma base de dados local onde documentos e eventos são persistidos à medida que são consumidos.
3. Visão geral do modelo
O client mantém dois loops de polling independentes, cada um com seu próprio nextToken e filtros. Ambos os loops gravam os registros recebidos na base local. A reconciliação acontece após cada gravação, usando a chave de acesso como elo de ligação.
┌──────────────────────┐ ┌──────────────────────┐
│ Loop de Documentos │ │ Loop de Eventos │
│ /inbound/documentos │ │ /inbound/eventos │
└────────┬─────────────┘ └────────┬─────────────┘
│ │
▼ ▼
Salva documento Salva evento
na base local na base local
│ │
▼ ▼
Busca eventos pendentes Busca documento
pela chave de acesso pela chave de acesso
│ │
▼ ▼
Encontrou? Encontrou?
├─ Não → fim ├─ Não → fim
└─ Sim → reconcilia └─ Sim → reconcilia
Chave de acesso
A chave de acesso é o identificador que conecta um documento ao(s) seu(s) evento(s):
| Origem | Campo |
|---|---|
Documento (/inbound/documentos) | id (raiz do item) |
Evento (/inbound/eventos) | infEvento.id |
O client deve indexar sua base local por esse campo para permitir buscas eficientes durante a reconciliação.
4. Ao receber um documento
Quando o loop de documentos retorna um novo item:
- Salvar o documento na base local, independentemente de já existirem eventos associados.
- Buscar na base local todos os eventos cujo
infEvento.idcorresponda aoiddo documento recém-salvo. - Se nenhum evento for encontrado, encerrar o processamento deste item. Os eventos podem ainda não ter chegado — serão reconciliados quando o loop de eventos os consumir.
- Se um ou mais eventos forem encontrados, associar cada evento ao documento e executar a ação correspondente ao tipo de evento. Por exemplo, se um evento de cancelamento for encontrado, marcar o documento como cancelado na base local.
5. Ao receber um evento
Quando o loop de eventos retorna um novo item:
- Salvar o evento na base local, independentemente de o documento associado já existir.
- Buscar na base local o documento cujo
idcorresponda aoinfEvento.iddo evento recém-salvo. - Se o documento não for encontrado, encerrar o processamento deste item. O documento pode ainda não ter chegado — será reconciliado quando o loop de documentos o consumir.
- Se o documento for encontrado, associar o evento ao documento e executar a ação correspondente ao tipo de evento. Por exemplo, se for um evento de cancelamento, marcar o documento como cancelado na base local.
6. Considerações
Ordem de chegada imprevisível
Não há garantia de que o documento chegará antes dos seus eventos, nem o contrário. O client deve tratar ambos os cenários com a mesma lógica: salvar primeiro, reconciliar depois.
Idempotência
A lógica de reconciliação deve ser idempotente. Se o mesmo par documento-evento for reconciliado mais de uma vez (por exemplo, após uma reinicialização do client), o resultado final deve ser o mesmo. Isso significa que marcar um documento como cancelado duas vezes não deve gerar efeitos colaterais indesejados.
Eventos sem documento
É possível que um evento permaneça sem documento associado por um período prolongado — por exemplo, se o documento ainda não foi processado pela API ou se o client iniciou o consumo de eventos com um createdFrom anterior ao dos documentos. O client deve tratar eventos não reconciliados como estado normal, não como erro.
Documentos sem evento
Nem todo documento terá eventos associados. Um documento que nunca foi cancelado, manifestado ou sofreu qualquer ação posterior simplesmente não terá eventos. A ausência de eventos para um documento é o cenário padrão.