13 — Dettaglio: Riconciliazione Automatica¶
Approfondimento del capitolo 10 — Monitoraggio e Riconciliazione.
Principio generale¶
A differenza della riconciliazione manuale (12 — Dettaglio: Riconciliazione Manuale), qui è gt4medServices stesso, periodicamente, a interrogare T4MED, confrontare l'esito con i propri archivi e reinviare automaticamente quanto risultasse mancante — senza alcun intervento umano, né un referente T4MED né un servizio assistenza SINED.
Per ogni intervallo [X, Y) (es. finestra mobile delle ultime N settimane, come per il report analitico), gt4medServices:
- interroga T4MED per ottenere l'elenco delle prenotazioni nel periodo (Query 1);
- interroga T4MED per ottenere l'elenco dei referti pubblicati nel periodo (Query 2);
- confronta entrambi gli elenchi con i propri archivi interni;
- per ogni elemento presente nei propri archivi ma assente nella risposta di T4MED, ripete automaticamente l'invio.
Le due query usano ricerche FHIR R4 standard (GET con parametri di ricerca) su risorse che T4MED già espone — Appointment e DocumentReference — senza richiedere alcuna nuova operazione custom (a differenza del meccanismo "push" della riconciliazione manuale). Resta da verificare con T4MED se il loro server supporta effettivamente la ricerca standard su questi tipi di risorsa: la specifica nota oggi documenta solo POST/PUT/DELETE e $generate-pdf.
Base URL: https://biocaretest.evisus.it/api/fhir
Riconciliazione degli Appuntamenti¶
Query 1 — Elenco prenotazioni in un intervallo¶
GET https://biocaretest.evisus.it/api/fhir/Appointment?date=ge2026-10-01&date=lt2026-10-15
Accept: application/fhir+json
Authorization: ApiKey <api-key>
{
"resourceType": "Bundle",
"type": "searchset",
"total": 2,
"entry": [
{
"resource": {
"resourceType": "Appointment",
"id": "T00450",
"identifier": [{ "system": "urn:local:cup:id-prenotazione", "value": "26B001956" }],
"status": "booked",
"start": "2026-10-05T09:00:00+02:00",
"end": "2026-10-05T09:30:00+02:00",
"participant": [{ "actor": { "reference": "Patient/4578934" }, "status": "accepted" }]
}
},
{
"resource": {
"resourceType": "Appointment",
"id": "T00451",
"identifier": [{ "system": "urn:local:cup:id-prenotazione", "value": "26B001957" }],
"status": "booked",
"start": "2026-10-07T11:00:00+02:00",
"end": "2026-10-07T11:30:00+02:00",
"participant": [{ "actor": { "reference": "Patient/4578935" }, "status": "accepted" }]
}
}
]
}
Ogni Appointment restituito porta entrambi i codici necessari al confronto: il T4MED Appointment ID (id, es. T00450) e il codice CUP (identifier, system urn:local:cup:id-prenotazione, già usato nei Flussi A/B).
Ricerca puntuale per T4MED Appointment ID¶
Per verificare lo stato di una singola prenotazione già nota (es. prima di un reinvio, per escludere falsi negativi):
GET https://biocaretest.evisus.it/api/fhir/Appointment/T00450
Accept: application/fhir+json
Authorization: ApiKey <api-key>
Risposta: la singola risorsa Appointment (non un Bundle) — 200 OK se presente, 404 Not Found se l'id non esiste su T4MED.
Chiavi di confronto¶
Il confronto si basa sul T4MED Appointment ID e/o sul codice CUP, entrambi presenti in ogni Appointment restituito, confrontati con l'elenco delle prenotazioni che gt4medServices risulta aver inviato per lo stesso periodo, già mappate CUP Appointment ID ↔ T4MED Appointment ID.
Logica di reinvio¶
Per ogni prenotazione nota a gt4medServices nel periodo e non presente nella risposta T4MED: gt4medServices ripete automaticamente l'invio (Flusso A, trattandosi per definizione di una prenotazione mai arrivata a destinazione).
Idempotenza e rischio di duplicati¶
Il rischio è basso: un reinvio per una prenotazione già nota userebbe sempre una PUT sull'id T4MED esistente (Flusso B), non una nuova POST. Il reinvio automatico scatta solo quando la prenotazione risulta del tutto assente, cioè quando non esiste ancora un T4MED Appointment ID — si tratterebbe quindi sempre di una nuova POST (Flusso A).
Caso limite: se gt4medServices avesse perso la mappatura per un errore interno, potrebbe generare un duplicato pur essendo la prenotazione già presente a T4MED. Si raccomanda, prima del reinvio, un controllo puntuale per identifier (
GET Appointment?identifier=urn:local:cup:id-prenotazione|<id-CUP>) per escludere falsi negativi della Query 1 (es. per paginazione).
Riconciliazione dei Referti¶
Query 2 — Elenco referti pubblicati in un intervallo¶
GET https://biocaretest.evisus.it/api/fhir/DocumentReference?date=ge2026-10-01&date=lt2026-10-15
Accept: application/fhir+json
Authorization: ApiKey <api-key>
{
"resourceType": "Bundle",
"type": "searchset",
"total": 1,
"entry": [
{
"resource": {
"resourceType": "DocumentReference",
"id": "DR-9001",
"status": "current",
"date": "2026-10-05T15:00:00+02:00",
"identifier": [
{ "system": "urn:local:sined:codice-fiscale", "value": "RSVDMN11A41H620X" },
{ "system": "urn:ietf:rfc:3986", "value": "urn:uuid:e7c3f91b-8a42-4d5e-9f16-3b8c7a2e5d41" }
],
"subject": { "reference": "Patient/4578934" }
}
}
]
}
Ogni DocumentReference restituito porta entrambi i codici necessari al confronto: il T4MED DocumentReference ID (id, es. DR-9001), assegnato da T4MED alla ricezione (Flusso E), e l'UUID assegnato da gt4medServices al momento della spedizione (identifier, system urn:ietf:rfc:3986, value urn:uuid:<GUID>) — la chiave che risolve l'ambiguità del solo codice fiscale (un paziente può avere più referti nello stesso periodo).
Come per le prenotazioni, gt4medServices dovrebbe mantenere una mappatura UUID referto ↔ T4MED DocumentReference ID.
Ricerca puntuale per id referto¶
Se è già noto il T4MED DocumentReference ID:
Se si dispone solo dell'UUID assegnato da gt4medServices:
GET https://biocaretest.evisus.it/api/fhir/DocumentReference?identifier=urn:ietf:rfc:3986|urn:uuid:e7c3f91b-8a42-4d5e-9f16-3b8c7a2e5d41
(risposta: Bundle searchset con 0 o 1 entry, essendo l'UUID per definizione univoco.)
Chiavi di confronto¶
Il confronto si basa sull'identifier UUID assegnato da gt4medServices al momento della spedizione (Flusso E), confrontato con l'elenco dei referti che gt4medServices risulta aver spedito per lo stesso periodo.
Vanno considerati solo i referti che hanno effettivamente raggiunto lo stadio "spedito a T4MED" della pipeline descritta in 11 — Dettaglio: Monitoraggio (
reportStatus = signederepositoryOutcome = success). Un referto ancoranot-produced,pendingo non spedito a REPO (repositoryOutcome = not-sent) non è mai stato pronto per l'invio a T4MED: la sua assenza in T4MED non è una discrepanza, ma lo stato normale di un referto non ancora arrivato a quello stadio.
Logica di reinvio¶
Per ogni referto già firmato e spedito a REPO (reportStatus = signed, repositoryOutcome = success) noto a gt4medServices nel periodo e non presente nella risposta T4MED: gt4medServices ripete automaticamente l'invio (Flusso E). I referti in stadi precedenti della pipeline vengono esclusi dal confronto, perché per essi non esiste ancora nulla da spedire.
Idempotenza e rischio di duplicati¶
Grazie all'UUID univoco, il rischio è basso quanto quello delle prenotazioni: prima di un reinvio, gt4medServices può eseguire una ricerca puntuale per identifier per escludere falsi negativi della Query 2 dovuti a paginazione o altri problemi transitori.
Considerazioni operative¶
- Paginazione: le Query 1 e 2 possono restituire Bundle paginati (
Bundle.linkconrelation: next); vanno seguiti tutti i link prima di considerare completa la risposta, altrimenti si rischiano falsi negativi. - Frequenza: non richiedendo coordinamento umano, può essere eseguita con cadenza giornaliera o più frequente (es. ogni poche ore).
- Scope: serve un nuovo scope di lettura
system/Appointment.read(oggi non previsto, solo.write); perDocumentReferencelo scope di lettura è già previsto (usato per$generate-pdf). - Capacità del server: va verificato con T4MED se il loro server supporta la ricerca standard con parametro
datee la paginazione dei Bundle searchset — non documentate nella specifica nota. - Volumi: valutare con T4MED l'uso di
_counte_sortper intervalli ampi.
Raccomandazioni per T4MED¶
| # | Punto da discutere |
|---|---|
| A1 | Conferma del supporto a ricerca standard (date), lettura puntuale per id e ricerca per identifier su Appointment/DocumentReference, inclusa la paginazione |
| A2 | Concessione dello scope di lettura system/Appointment.read |
| A3 | Conferma che il T4MED DocumentReference ID sia stabile e recuperabile insieme all'identifier UUID lato SINED |
| A4 | Frequenza di esecuzione delle query (proposta iniziale: stessa cadenza giornaliera dei report) |
| A5 | Conferma che questo meccanismo sia complementare, e non sostitutivo, della riconciliazione manuale (12 — Dettaglio: Riconciliazione Manuale) |