Resposta breve: como evitar a duplicação de registos?
Atribua a cada trabalho de inspeção uma identidade de origem imutável; execute a transferência para o ERP de forma idempotente com essa identidade, imponha a unicidade na base de dados e ligue à contabilidade apenas o documento de destino verificado.
Não basta que uma integração funcione no fluxo normal. Quando a resposta de rede se perde, quando a mensagem da fila chega repetida ou quando dois workers recebem o mesmo trabalho, o resultado também deve ser um único cliente, uma única ordem e uma única ligação de faturação.
Porque é que surge a duplicação?
Resposta breve: a maioria das duplicações não surge por o utilizador carregar duas vezes no botão, mas por um retry incontrolado no momento ambíguo em que o primeiro pedido teve sucesso mas a resposta se perdeu.
O sistema de inspeção envia ao ERP um pedido de abertura de ordem. O ERP cria o registo, mas a ligação fecha-se e a integração não recebe a resposta. Se o worker reenviar o pedido como se fosse novo, pode abrir-se uma segunda ordem. Riscos semelhantes surgem na entrega pelo menos uma vez nas filas, workers paralelos, repetição manual após tempo limite e sincronização em lote.
O IETF RFC 9110 define a operação idempotente como aquela em que aplicar o mesmo pedido várias vezes tem o efeito pretendido de uma única aplicação. O PUT tem essa característica; a criação de novos recursos com POST deve ser protegida adicionalmente. A conceção técnica não deve assumir que a rede entrega exatamente uma vez.

Que identidade deve ser dona do registo?
O trabalho de inspeção, a ordem no ERP, o lançamento contabilístico e o documento eletrónico não são a mesma identidade. No início da cadeia deve existir um UUID do trabalho de origem imutável; as identidades geradas pelos outros sistemas devem ser guardadas em campos separados como correspondências desta.
| Identidade | Dono | Quando é criada? | Utilização |
|---|---|---|---|
| UUID do trabalho de origem | Sistema de inspeção | Quando o trabalho é aberto pela primeira vez | Chave fixa do trabalho para todas as transferências e retries |
| UUID do evento | Sistema de inspeção | Quando é gerada a versão pronta a faturar | Mensagem da fila e verificação de eventos processados |
| ID de cliente/ordem no ERP | ERP | Quando o registo de destino é aceite | Atualizações seguintes e consulta de estado |
| ID do documento contabilístico | Sistema contabilístico | Quando é criado o rascunho/registo do documento | Ciclo de vida financeiro |
| UUID/número do documento eletrónico | Processo de documento eletrónico | Quando o documento é emitido | Identidade técnica própria do documento |
A OASIS UBL 2.4 Invoice define campos de referência entre a fatura e a ordem e outros documentos. O guia do Portal e-Fatura da GİB também indica que faturas com o mesmo UUID e número de fatura não podem ser carregadas novamente. A consequência prática não é substituir a identidade da inspeção de origem pelo número do documento eletrónico; é manter as identidades separadas numa tabela de ligação bidirecional.
Como gerar a idempotency key?
A chave não deve ser regerada aleatoriamente a cada retry; deve permanecer a mesma em todas as tentativas do mesmo efeito comercial. Um âmbito exemplo pode derivar-se da combinação canónica das seguintes partes:
tenant + hedef_sistem + işlem_türü + kaynak_iş_uuid + kaynak_sürümü
A versão de origem é relevante. Reenviar a mesma versão do relatório deve devolver o resultado existente; se uma revisão autorizada criar um novo efeito comercial, deve ser um evento separado com uma regra de negócio explícita. O registo de idempotência deve guardar, junto à chave, o resumo do payload, a hora da primeira ocorrência, o estado e a identidade da resposta de destino.
A referência atual da API da Stripe documenta que, após uma falha de ligação, um pedido create/update pode ser repetido em segurança com a mesma idempotency key e que, se os parâmetros mudarem com a mesma chave, o pedido é rejeitado. Este comportamento específico do fornecedor é também um exemplo de contrato útil para o adaptador ERP interno: se a mesma chave chegar com cliente, valor ou mapeamento de imposto diferentes, não sobrescreva silenciosamente; encaminhe o conflito para análise.
Porque não basta o controlo na aplicação?
Na abordagem “verificar primeiro se existe, senão inserir”, dois workers podem ver em simultâneo que não existe. A unicidade deve também ser imposta na base de dados.
Na tabela de ligação da integração, estabeleça tenant_id + target_system + document_type + source_job_uuid um unique constraint composto. A documentação atual do INSERT do PostgreSQL, com unique constraint ON CONFLICT explica que a sua utilização pode produzir um insert/update atómico sob corrida. Se a sua regra de negócio não permitir atualizações, devolva o ID de destino existente em caso de conflito; se os dados forem diferentes, abra um registo de análise fail-closed.
UNIQUE (tenant_id, target_system, document_type, source_job_uuid)
aynı anahtar + aynı payload özeti -> mevcut sonucu döndür
aynı anahtar + farklı payload -> çakışma, otomatik belge açmaComo deve ser configurado o fluxo de outbox e de fila?
Escrever separadamente a marcação do relatório de inspeção como “pronto para faturação” e a mensagem para o ERP pode gerar estados incompletos. O estado do trabalho e o evento de integração devem ser commitados na mesma transação local.
- O utilizador autorizado aprova a versão do relatório e o âmbito de faturação.
- A aplicação atualiza o estado do trabalho na mesma transação e adiciona uma linha de outbox com o UUID do evento.
- O worker envia o evento do outbox para o adaptador de destino com uma chave de idempotência fixa.
- Na resposta bem-sucedida, o ID de destino do ERP e o resumo da resposta são registados na tabela de ligação.
- Se o ACK se perder, o mesmo evento volta a chegar; o consumidor verifica o UUID do evento e a ligação ao trabalho e devolve o resultado existente.
- Um erro de dados permanente não entra em ciclo de retry; é encaminhado para análise/dead-letter queue.
O guia Transactional Outbox da Microsoft recomenda armazenar o objeto de negócio e o evento na mesma transação; o guia do Service Bus recomenda que o consumidor seja idempotente com base em MessageId ou identidade comercial, devido a ACK perdido e reentrega. A deteção de duplicados no lado do emissor não substitui o controlo de unicidade no recetor.
Como efetuar em segurança a correspondência de cliente, serviço e imposto?
Evitar registos duplicados não é apenas um problema técnico de retry. Reabrir o mesmo cliente com uma grafia de denominação diferente ou faturar o mesmo serviço com um código diferente também gera duplicação operacional.
- Cliente: efetue a correspondência com VKN/TCKN validado no âmbito do tenant ou com a chave mestra da entidade; não utilize a denominação isoladamente como chave.
- Serviço: ligue o método de inspeção à tabela aprovada de códigos de stock/serviço do ERP; não abra automaticamente códigos sem correspondência como texto livre.
- Imposto e moeda: aplique uma correspondência com versões à lista de códigos do sistema de destino; interrompa a produção de documentos em caso de correspondência em falta ou inválida.
- Valor: fixe as linhas calculadas, os descontos e o imposto com o resumo da versão de origem; encaminhe qualquer alteração após aprovação para um novo fluxo de revisão.
- Autorização: gere separadamente, com trilhos de auditoria distintos, as funções de criação de clientes, alteração de correspondências e produção de documentos financeiros.
Uma correspondência ambígua não deve escolher o “resultado mais próximo”. A transferência deve aguardar até a análise humana estar concluída; deve registar-se quem decidiu, quando, os valores anterior/novo e a justificação da decisão.
Como monitorizar o estado da transferência?
Um único campo “com sucesso/sem sucesso” esconde ambiguidade. A máquina de estados deve indicar qual o passo que pode ser repetido.
| Estado | Significado | Operação permitida |
|---|---|---|
| Em preparação | Correspondência e payload em validação | Corrigir lacunas |
| Pronto para envio | Identidade, versão e resumo do payload bloqueados | Colocar no outbox |
| Indeterminado | Houve timeout, pode existir resultado no destino | Consultar/repetir com a mesma chave |
| Transferido | ID de destino e prova da resposta registados | Consultar estado, criar cópia |
| Análise necessária | Conflito de chaves ou erro de correspondência de dados | Aguardar decisão do responsável autorizado |
| A aguardar cancelamento/registo inverso | Necessária correção financeira | Processo separado segundo a regra do sistema de destino |
Eliminar o registo de transferência bem-sucedida e reenviar não é um método de correção. Se já foi criado um documento financeiro, o cancelamento, o reembolso ou o registo inverso devem ser executados com a sua própria identidade e fluxo de aprovação.
Que controlos deve fazer a reconciliação?
A reconciliação diária deve comparar os registos de origem e de destino ao nível da identidade, em vez de limitar-se a contar o registo de erros.
- Trabalhos prontos para faturação sem ligação ao destino.
- Vários documentos de destino ligados ao mesmo UUID de trabalho de origem.
- Documentos encontrados no destino sem correspondência na tabela de ligação da origem.
- Registos cujo resumo do payload enviado não coincide com a versão de origem.
- Tentativas que permanecem em estado indeterminado além do tempo definido.
- Faltas de aprovação/prova em correspondências manuais, cancelamentos e registos inversos.
O resultado da reconciliação não deve efetuar eliminação automática nem fusão em massa. Deve apresentar ao utilizador autorizado os registos suspeitos, as identidades nos dois sistemas e a operação segura recomendada.
Como pilotar a integração da VizyonTech?
Vizyon Periyodik na transição para o ERP a partir de fluxos de inspeção deste tipo, teste os cenários de erro antes do cenário normal. Devem ser testados o duplo clique no mesmo trabalho, o ERP criar o registo sem responder, a mesma mensagem de fila chegar a dois workers, a mesma chave com payload diferente, a correspondência de cliente inválida e a revisão do relatório.
O critério de sucesso do piloto não é “a integração funcionou”. Em cada cenário deve demonstrar-se quantos registos foram criados no destino, se a ligação origem-destino foi estabelecida, se o retry devolve o mesmo resultado, se a ambiguidade permanece visível e se a operação financeira não autorizada foi bloqueada. Para proteger a cadeia de decisão do relatório de inspeção, guia de fluxo de trabalho de assinatura eletrónica pode também ser considerado em conjunto.
Fontes
- IETF — RFC 9110, Semântica de HTTP: Métodos Idempotentes (junho de 2022; consultado a 21 de julho de 2026).
- Stripe — Pedidos idempotentes, Referência da API (documentação online atual; consultado a 21 de julho de 2026).
- Microsoft Learn — Evitar a perda de mensagens e o processamento duplicado no Azure Service Bus (atualização de 29 de junho de 2026).
- Microsoft Learn — Implementar o padrão Transactional Outbox (2026; consultado a 21 de julho de 2026).
- PostgreSQL — INSERT e ON CONFLICT, documentação atual (consultado a 21 de julho de 2026).
- OASIS — Resumo do modelo de fatura UBL 2.4 (2024).
- Presidência da Administração Fiscal — Guia de Utilização do Portal e-Fatura v1.5 (novembro de 2013; para identidade técnica e regra de recarregamento, consultado a 21 de julho de 2026).
As regras de campos/códigos de ERP, contabilidade e e-Documento do fornecedor utilizado devem ser verificadas em separado através da documentação técnica atual do fornecedor e dos processos financeiros da organização.