Risposta breve: come prevenire la doppia registrazione?
Assegnate a ogni lavoro di ispezione un identificativo di origine immutabile; eseguite il trasferimento all'ERP in modo idempotente con questo identificativo, imponete l'unicità nel database e collegate alla contabilità solo il documento di destinazione verificato.
Non basta che un'integrazione funzioni nel flusso normale. Quando la risposta di rete si perde, quando il messaggio in coda arriva duplicato o quando due worker prendono lo stesso lavoro, il risultato deve comunque essere un unico cliente, un unico ordine e un unico collegamento di fatturazione.
Perché si crea la doppia registrazione?
Risposta breve: la maggior parte delle doppie registrazioni nasce non perché l'utente preme due volte il pulsante, ma da un retry incontrollato eseguito nel momento ambiguo in cui la prima richiesta è riuscita ma la sua risposta si è persa.
Il sistema di ispezione invia all'ERP la richiesta di apertura di un ordine. L'ERP crea il record, ma la connessione si chiude e l'integrazione non riceve la risposta. Se il worker reinvia la stessa richiesta come se fosse una nuova transazione, può aprirsi un secondo ordine. Rischi analoghi si presentano con la consegna at-least-once in coda, worker paralleli, ripetizioni manuali dopo timeout e sincronizzazioni batch.
La IETF RFC 9110 definisce il metodo idempotente come uno per cui l'applicazione ripetuta della stessa richiesta più volte produce l'effetto desiderato di una singola applicazione. PUT ha questa proprietà; la creazione di nuove risorse con POST va invece protetta ulteriormente. La progettazione tecnica non deve presumere che la rete consegni esattamente una volta.

Quale identificativo deve essere titolare del record?
Il lavoro di ispezione, l'ordine ERP, il registro contabile e il documento elettronico non condividono lo stesso identificativo. All'inizio della catena deve esserci un UUID del lavoro di origine immutabile; gli identificativi generati dagli altri sistemi vanno conservati separatamente in campi di corrispondenza.
| Identificativo | Titolare | Quando viene generato? | Utilizzo |
|---|---|---|---|
| UUID del lavoro di origine | Sistema di ispezione | Alla prima apertura del lavoro | Chiave fissa del lavoro per tutti i trasferimenti e i retry |
| UUID dell'evento | Sistema di ispezione | Quando si genera la versione pronta per la fatturazione | Messaggio in coda e controllo degli eventi elaborati |
| ID cliente/ordine ERP | ERP | Quando il record di destinazione è accettato | Aggiornamenti successivi e interrogazione di stato |
| ID del documento contabile | Sistema contabile | Quando si genera la bozza/il record del documento | Ciclo di vita finanziario |
| UUID/numero del documento elettronico | Processo del documento elettronico | All'emissione del documento | Identificativo tecnico proprio del documento |
OASIS UBL 2.4 Invoice definisce campi di riferimento tra fattura e ordine e altri documenti. Anche la guida del portale GİB e-Fatura indica che fatture con lo stesso UUID e lo stesso numero di fattura non possono essere caricate nuovamente. La conseguenza pratica non è sostituire l'identificativo di ispezione di origine con il numero del documento elettronico, ma mantenere gli identificativi separati in una tabella di correlazione bidirezionale.
Come generare la chiave di idempotenza?
La chiave non deve essere rigenerata casualmente a ogni retry; deve rimanere la stessa in tutti i tentativi dello stesso effetto commerciale. Un ambito esemplare può derivare dalla combinazione canonica delle seguenti parti:
tenant + hedef_sistem + işlem_türü + kaynak_iş_uuid + kaynak_sürümü
La versione di origine è determinante. Reinviare la stessa versione del report deve restituire il risultato esistente; se una revisione autorizzata crea un nuovo effetto commerciale, deve costituire un evento separato con una regola di business esplicita. Il registro di idempotenza deve conservare, accanto alla chiave, il digest del payload, l'orario della prima occorrenza, lo stato e l'identificativo della risposta di destinazione.
L'attuale riferimento API di Stripe documenta che, dopo un errore di connessione, una richiesta create/update può essere ripetuta in sicurezza con la stessa idempotency key e che la richiesta viene rifiutata se, a parità di chiave, i parametri sono cambiati. Questo comportamento specifico del fornitore è un utile esempio di contratto anche per l'adattatore ERP interno: se la stessa chiave arriva con un cliente, importo o mapping fiscale diverso, non sovrascrivete silenziosamente; mettete il conflitto in revisione.
Perché il controllo applicativo da solo non basta?
Nell'approccio "prima verifica se esiste, altrimenti inserisci" due worker possono vedere contemporaneamente l'esito negativo. L'unicità deve essere imposta anche nel database.
Nella tabella di correlazione dell'integrazione tenant_id + target_system + document_type + source_job_uuid istituite un vincolo unique composito. L'attuale documentazione INSERT di PostgreSQL spiega che, con un vincolo unique e ON CONFLICT si può ottenere un risultato insert/update atomico anche in condizioni di competizione. Se la regola di business non consente l'aggiornamento, in caso di conflitto restituite l'ID di destinazione esistente; se i dati differiscono, aprite un record di revisione 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çmaCome impostare il flusso outbox e coda?
Contrassegnare il report di ispezione come "pronto per la fatturazione" e scrivere separatamente il messaggio ERP può produrre stati incompleti. Lo stato del lavoro e l'evento di integrazione devono essere sottoposti a commit nella stessa transazione locale.
- L'utente autorizzato approva la versione del report e l'ambito di fatturazione.
- L'applicazione, nella stessa transazione, aggiorna lo stato del lavoro e inserisce la riga outbox con l'UUID dell'evento.
- Il worker invia l'evento outbox all'adattatore di destinazione con la idempotency key fissa.
- In caso di risposta positiva, l'ID di destinazione ERP e il riepilogo della risposta vengono registrati nella tabella di correlazione.
- Se l'ACK si perde, lo stesso evento arriva di nuovo; il consumer vede l'UUID dell'evento e il collegamento al lavoro e restituisce il risultato esistente.
- Un errore persistente sui dati non va messo in un ciclo di retry; va instradato a una coda di revisione/dead-letter.
La guida al Transactional Outbox di Microsoft raccomanda di salvare l'oggetto di business e l'evento nella stessa transazione; la guida a Service Bus raccomanda che il consumer sia idempotente tramite MessageId o identificativo commerciale, a causa di ACK persi e riconsegne. Il duplicate detection lato mittente non sostituisce il controllo di unicità lato ricevente.
Come rendere sicuro il mapping di clienti, servizi e imposte?
Prevenire la doppia registrazione non è solo un problema tecnico di retry. Riaprire lo stesso cliente in base alla grafia della ragione sociale o fatturare lo stesso servizio con un codice diverso genera anch'esso duplicazioni operative.
- Cliente: correlatelo nell'ambito del tenant con VKN/TCKN verificato o con la chiave master aziendale; non usare la sola ragione sociale come chiave.
- Servizio: collegate il metodo di ispezione alla tabella approvata di codici ERP per articoli/servizi; non aprite automaticamente codici non corrispondenti come testo libero.
- Imposte e valuta: applicate un mapping versionato alle liste di codici del sistema di destinazione; in caso di mapping mancante o non valido, interrompete la generazione del documento.
- Importo: bloccate le righe calcolate, gli sconti e l'imposta con il digest della versione di origine; dopo l'approvazione, ogni modifica passa per un flusso di nuova revisione.
- Autorizzazioni: gestite con tracce di controllo separate i ruoli di creazione cliente, modifica mapping e produzione di documenti finanziari.
Una corrispondenza ambigua non deve scegliere "il risultato più simile". Il trasferimento deve attendere il completamento della revisione umana; della decisione vanno registrati chi, quando, valore precedente/nuovo e motivazione.
Come monitorare lo stato del trasferimento?
Un unico campo "successo/fallimento" nasconde l'ambiguità. La macchina a stati deve indicare quale passo è ripetibile.
| Stato | Significato | Operazione consentita |
|---|---|---|
| In preparazione | Verifica di mapping e payload | Correggere le carenze |
| Pronto all'invio | Identificativo, versione e digest del payload bloccati | Mettere in outbox |
| Ambiguo | Timeout presente, il risultato può esistere a destinazione | Interrogare/riprovare con la stessa chiave |
| Trasferito | ID di destinazione e prova della risposta registrati | Interrogare lo stato, non duplicare |
| Revisione necessaria | Conflitto di chiave o errore di mapping dei dati | Attendere la decisione autorizzata |
| In attesa di annullamento/registrazione inversa | Necessaria correzione finanziaria | Transazione separata secondo la regola del sistema di destinazione |
Eliminare il record del trasferimento riuscito e reinviare non è un metodo di correzione. Se il documento finanziario è già stato creato, annullamento, rimborso o registrazione inversa devono seguire un proprio identificativo e flusso di approvazione.
Quali controlli deve eseguire la riconciliazione?
La riconciliazione giornaliera, invece di limitarsi a contare i log di errore, deve confrontare a livello di identificativo i record di origine e di destinazione.
- Lavori pronti per la fatturazione senza collegamento di destinazione.
- Più documenti di destinazione collegati allo stesso UUID di lavoro di origine.
- Documenti presenti a destinazione ma senza corrispondenza nella tabella di correlazione di origine.
- Record in cui il digest del payload inviato non corrisponde alla versione di origine.
- Tentativi che permangono in stato ambiguo oltre il termine definito.
- Carenze di approvazione/prova in mapping manuali, annullamenti e registrazioni inverse.
L'esito della riconciliazione non deve eseguire cancellazioni automatiche o fusioni batch. Deve mostrare all'utente autorizzato i record sospetti, gli identificativi nei due sistemi e l'operazione sicura proposta.
Come predisporre il progetto pilota dell'integrazione VizyonTech?
Vizyon Periyodik come nel passaggio all'ERP da flussi di ispezione, prima dello scenario normale provate gli scenari di errore. Vanno testati il doppio clic sullo stesso lavoro, l'ERP che crea il record senza rispondere, lo stesso messaggio in coda consegnato a due worker, la stessa chiave con payload diverso, un mapping cliente non valido e la revisione del report.
La metrica di successo del pilota non è "l'integrazione funziona". Per ogni scenario va provato quanti record si sono formati a destinazione, se il collegamento origine-destinazione è stato stabilito, se il retry ha restituito lo stesso risultato, se l'ambiguità è rimasta visibile e se l'operazione finanziaria non autorizzata è stata bloccata. Per preservare la catena decisionale del report di ispezione la guida al flusso di lavoro della firma elettronica può essere valutata anch'essa congiuntamente.
Fonti
- IETF — RFC 9110, HTTP Semantics: Idempotent Methods (giugno 2022; accesso 21 luglio 2026).
- Stripe — Idempotent requests, API Reference (documentazione online aggiornata; accesso 21 luglio 2026).
- Microsoft Learn — Prevent message loss and duplicate processing in Azure Service Bus (aggiornamento del 29 giugno 2026).
- Microsoft Learn — Implement the Transactional Outbox pattern (2026; accesso 21 luglio 2026).
- PostgreSQL — INSERT e ON CONFLICT, documentazione aggiornata (accesso 21 luglio 2026).
- OASIS — sintesi del modello UBL 2.4 Invoice (2024).
- Amministrazione fiscale turca — Guida utente del portale di fatturazione elettronica v1.5 (novembre 2013; per l'identificativo tecnico e la regola di ricaricamento, accesso 21 luglio 2026).
Le regole di campi/codici per ERP, contabilità e documenti elettronici vanno verificate separatamente sulla documentazione tecnica aggiornata del fornitore utilizzato e sui processi finanziari dell'organizzazione.