12 — Dettaglio: Riconciliazione Manuale¶
Approfondimento del capitolo 10 — Monitoraggio e Riconciliazione. Per il dettaglio dei report scambiati, vedi 11 — Dettaglio: Monitoraggio.
Architettura complessiva¶
Ogni giorno alle 06:00 gt4medServices invia a T4MED il report sintetico (situazione complessiva dall'inizio dell'integrazione) e il report analitico (dettaglio delle ultime due settimane). Il report aggregato consente di verificare rapidamente l'andamento generale del servizio — la sua stessa assenza è un segnale di anomalia. Il report analitico consente a T4MED di effettuare il controllo puntuale degli appuntamenti e dei relativi referti.
Il controllo e il confronto sono eseguiti da T4MED; la gestione delle eventuali discrepanze segue il meccanismo di riconciliazione manuale:
- un referente T4MED confronta i report ricevuti con i propri dati e individua le discrepanze;
- il referente segnala al servizio assistenza di SINED cosa risulta mancante o discordante;
- il servizio assistenza di SINED attiva le procedure di riconciliazione per risolverle.
La responsabilità operativa della riconciliazione resta quindi sempre in carico al servizio assistenza di SINED, unico soggetto con visibilità completa sui propri tentativi di chiamata (incluse le mancate risposte). T4MED resta responsabile del controllo, del confronto e della segnalazione.
Punto aperto: il canale concreto (telefono, e-mail, ticket...) con cui il referente T4MED comunica la segnalazione al servizio assistenza di SINED è da definire con T4MED/TESI.
Endpoint ipotizzati per l'invio dei report¶
T4MED non ha ancora pubblicato una specifica per l'invio dei report di monitoraggio. Gli endpoint che seguono sono un'ipotesi di lavoro, costruita per analogia con gli endpoint T4MED già noti.
Endpoint T4MED già noti (riferimento)¶
Base URL: https://biocaretest.evisus.it/api/fhir
| Flusso | Endpoint T4MED | Conformità R4 |
|---|---|---|
| A | POST {base-url} — Bundle transaction |
CONFORMI |
| B | PUT {base-url}/Appointment/{id} |
CONFORMI |
| C | DELETE {base-url}/Appointment/{id} |
CONFORMI |
| D | POST {base-url}/Patient/{cfisc}/$generate-pdf |
CONFORMI |
| E | POST {base-url} — Bundle transaction; PUT {base-url}/DocumentReference/{id} (solo metadati) |
CONFORMI |
Da questo elenco emergono due pattern già in uso, entrambi candidati per analogia: CRUD REST standard su risorse note (Flussi A, B, C, E) e operazione FHIR custom $nome-operazione (Flusso D).
Opzione 1 — Operazione FHIR custom (per analogia col Flusso D)¶
Report Sintetico
POST https://biocaretest.evisus.it/api/fhir/$submit-monitoring-summary
Content-Type: application/fhir+json
Authorization: ApiKey <api-key>
Body: la risorsa MeasureReport (vedi 11 — Dettaglio: Monitoraggio).
Report Analitico
POST https://biocaretest.evisus.it/api/fhir/$submit-monitoring-detail
Content-Type: application/fhir+json
Authorization: ApiKey <api-key>
Body: la risorsa Parameters, oppure il Bundle di Task (vedi 11 — Dettaglio: Monitoraggio).
Varianti di risposta¶
Per entrambi gli endpoint si ipotizzano quattro varianti di risposta.
a) Ricezione semplice
{
"resourceType": "OperationOutcome",
"issue": [
{ "severity": "information", "code": "informational", "diagnostics": "Report sintetico ricevuto correttamente." }
]
}
b) Dettagliata, senza discrepanze
{
"resourceType": "OperationOutcome",
"issue": [
{ "severity": "information", "code": "informational", "diagnostics": "Report sintetico ricevuto e confrontato con i dati T4MED per il periodo 2026-10-01T00:00:00+02:00 - 2027-03-15T00:00:00+01:00. Nessuna discrepanza rilevata." },
{ "severity": "information", "code": "informational", "details": { "text": "Prenotazioni CUP televisita ricevute" }, "diagnostics": "Dichiarate da SINED: 1500. Confermate da T4MED: 1500." }
]
}
c) Dettagliata, con discrepanze
{
"resourceType": "OperationOutcome",
"issue": [
{ "severity": "information", "code": "informational", "diagnostics": "Report analitico ricevuto: 14 record nel periodo 2027-03-01T00:00:00+01:00 - 2027-03-15T00:00:00+01:00, di cui 12 confermati e 2 con discrepanza." },
{
"severity": "warning",
"code": "not-found",
"details": {
"coding": [{ "system": "urn:t4med:error-code", "code": "DISC-002", "display": "Record non pervenuto a T4MED" }],
"text": "26B001958 / REPO-481207"
},
"diagnostics": "SINED dichiara t4medOutcome=success, ma la richiesta non risulta mai ricevuta da T4MED."
},
{
"severity": "warning",
"code": "conflict",
"details": {
"coding": [{ "system": "urn:t4med:error-code", "code": "DISC-003", "display": "Disallineamento di stato" }],
"text": "26B001960 / REPO-481209"
},
"diagnostics": "SINED dichiara reportStatus=signed, mentre la prenotazione risulta a T4MED ancora in attesa di referto."
},
{
"severity": "warning",
"code": "business-rule",
"details": {
"coding": [{ "system": "urn:t4med:error-code", "code": "DISC-004", "display": "Referto fermo in uno stadio intermedio della pipeline" }],
"text": "26B001962"
},
"diagnostics": "SINED dichiara reportStatus=pending da oltre 5 giorni (referto prodotto ma non ancora firmato)."
}
]
}
Questo riscontro sincrono è un primo segnale automatico utile per un controllo rapido lato gt4medServices, ma non sostituisce il canale ufficiale: resta cura del referente T4MED confermare al servizio assistenza di SINED le discrepanze da risolvere, attivando la riconciliazione manuale.
d) Failure
Si riusa lo stesso formato di OperationOutcome di errore già definito da T4MED per i Flussi A-H (vedi 06-response-failure.md):
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "error",
"code": "required",
"details": {
"coding": [{ "system": "urn:t4med:error-code", "code": "PR-002", "display": "Campo obbligatorio mancante" }],
"text": "Il parametro 'documentId' è obbligatorio per ogni item del report analitico."
},
"diagnostics": "transactionId=3b77e0f1-3c2a-4e9b-8a4e-9b0c1d2e3f4a",
"expression": ["Parameters.parameter[3].part[1]"]
}
]
}
Dizionario dei codici per la risposta OperationOutcome¶
issue.severity (value set standard FHIR R4):
| Codice | Significato |
|---|---|
fatal |
Errore bloccante: elaborazione interrotta completamente |
error |
Errore: l'elemento segnalato non è stato elaborato |
warning |
Avviso: elaborato, ma con una condizione da verificare |
information |
Informazione: nessun problema, solo un riscontro o conferma |
issue.code — IssueType (sottoinsieme standard FHIR R4 usato):
| Codice | Significato | Usato in |
|---|---|---|
informational |
Messaggio puramente informativo | varianti a/b/c |
business-rule |
Violazione di una regola di business (discrepanza conteggi) | variante c (sintetico) |
not-found |
Riferimento a un elemento che non risulta esistere | variante c (analitico) |
conflict |
Conflitto di stato fra due versioni dello stesso dato | variante c (analitico) |
required |
Elemento obbligatorio mancante nel body inviato | variante d (failure) |
System: urn:t4med:error-code (custom, in issue.details.coding):
| Codice | Significato | Severity / code tipici |
|---|---|---|
DISC-001 |
Discrepanza sui conteggi aggregati (sintetico) | warning / business-rule |
DISC-002 |
Record dichiarato da SINED ma non pervenuto a T4MED | warning / not-found |
DISC-003 |
Disallineamento di stato fra SINED e T4MED | warning / conflict |
DISC-004 |
Referto fermo in uno stadio intermedio della pipeline (not-produced/pending/not-sent) oltre una soglia di tempo ragionevole |
warning / business-rule |
PR-001 |
Formato del report non valido (proposto) | error / invalid |
PR-002 |
Campo o identifier obbligatorio mancante | error / required |
MR-001 |
Periodo di reporting non valido (proposto) | error / invalid |
I codici
DISC-*qualificano un warning che non blocca la ricezione (HTTP 200, varianti b/c); i codiciPR-*/MR-*qualificano un errore che blocca la richiesta (HTTP 4xx/5xx, variante d).
Pro/contro dell'Opzione 1: stesso pattern già usato da T4MED per il Flusso D, con riscontro graduale e formato di errore già standardizzato. Manca però un precedente diretto per un'operazione di "invio dati" (il Flusso D è una lettura/generazione, non un submit).
Opzione 2 — Creazione REST standard (per analogia coi Flussi A, B, C, E)¶
POST https://biocaretest.evisus.it/api/fhir/MeasureReport
POST https://biocaretest.evisus.it/api/fhir/Parameters
Stesso pattern REST già usato per Appointment e DocumentReference, ma con due perplessità:
- Tipi di risorsa: tutti gli endpoint noti di T4MED sono limitati a un insieme chiuso (Appointment, Patient, DocumentReference, Binary). Non è noto se il server accetti genericamente
POSTsu qualunque resourceType, inclusoMeasureReport. Parameterscome involucro di operazione: lo standard FHIR R4 definisceParameterscome "involucro di input/output di un'operazione" — il contenitore usato per impacchettare i parametri di una chiamata a un'operazione custom (come la lista di argomenti di una funzione), non come risorsa con un proprio significato di business. Non ha quindi un'identità "di business", non ha parametri di ricerca standard, e molti server FHIR non supportano unacreatesu questo tipo. UnaPOST /Parameterssarebbe un utilizzo atipico, con comportamento non garantito.
Raccomandazione¶
Per il report sintetico (MeasureReport, risorsa "normale" pensata per essere creata e conservata) entrambe le opzioni sono plausibili. Per il report analitico in formato Parameters, l'Opzione 1 è preferibile sul piano concettuale. Usando invece un Bundle di Task (vedi 11 — Dettaglio: Monitoraggio) la perplessità si risolve a monte, e anche l'Opzione 2 diventa una scelta solida quanto l'Opzione 1. Resta comunque necessario verificare con T4MED/TESI quale soluzione il loro server sia in grado di supportare.