Vai al contenuto

Flusso A — Nuova prenotazione televisita

Operazione: POST {base-url} — Bundle FHIR R4 transaction Flusso: A — CUP → gt4medServices → T4MED


Dati del caso di esempio

Campo Valore
Paziente ROSAVIOLA DALMINA (nome di fantasia)
Codice fiscale RSVDMN11A41H620X
Data nascita 1911-12-10 — Rovigo
Sesso F
Telefono +39 0323 1234567
Residenza via sconosciuta, 99 — VERBANIA (CAP 28921, prov. VB) — ASL 209, Regione Piemonte (cod. 010), cod. ISTAT comune 103072
Domicilio non specificato → non presente nel Bundle (si invia il solo indirizzo tipizzato dal CUP)
Televisita 2026-06-03T10:30:00+02:0011:00:00+02:00
ASL VCO, cod. ASL 209, regione Piemonte 010
Codice FLS11 010209
Presidio Ospedale di Verbania, cod. STS11 000256
Reparto Nefrologia e Dialisi, cod. NEF001
Ricetta (NRE) 010A900000112233
Prestazione 89.01.B — Visita nefrologica di controllo
ID CUP prenotazione 26B001956
T4MED Appointment ID T00450 (restituito nella risposta)

Conformità allo standard FHIR R4

Il Flusso A aderisce completamente allo standard FHIR R4:

  • la request è un Bundle transaction, inviato all'endpoint base di T4MED (POST {base-url}) — lo stesso endpoint usato dal Flusso E;
  • la response è un Bundle transaction-response;
  • non sussistono deviazioni rispetto allo standard.

Endpoint e autenticazione

POST https://biocaretest.evisus.it/api/fhir
Content-Type: application/fhir+json
X-API-Key: <chiave>

Endpoint di TEST. In PROD: https://biocaresuite.evisus.it/api/fhir. Autenticazione tramite header custom X-API-Key.


Il campo "Reparto"

Il campo Reparto indica il codice del reparto di prenotazione, cioè il reparto presso cui si svolgerà la televisita (nel caso d'esempio: Nefrologia e Dialisi — Ospedale di Verbania, codice NEF001). Questo dato proviene dal messaggio HL7 OMG^O19 ricevuto dal CUP.

Nel Bundle del Flusso A, il Reparto è rappresentato come participant di tipo HealthcareService nella risorsa Appointment:

{
  "actor": {
    "type": "HealthcareService",
    "identifier": {
      "system": "urn:local:asl-vco:reparto",
      "value": "NEF001"
    },
    "display": "Reparto Nefrologia e Dialisi - Ospedale di Verbania"
  },
  "required": "required",
  "status": "accepted"
}

gt4medServices mappa il codice di reparto ricevuto dal CUP nel campo identifier.value di questo participant.


Messaggio di richiesta

Bundle transaction contenente: risorsa Patient con i campi richiesti, risorsa ServiceRequest (ricetta/prestazione) e risorsa Appointment con tutti i partecipanti (paziente, Reparto, Presidio).

POST https://biocaretest.evisus.it/api/fhir
Content-Type: application/fhir+json
X-API-Key: <chiave>
{
  "resourceType": "Bundle",
  "type": "transaction",
  "entry": [

    {
      "fullUrl": "urn:uuid:a3f1c24e-7b82-4d5f-9e16-2c4a8f3b7d91",
      "resource": {
        "resourceType": "Patient",
        "extension": [
          {
            "url": "http://hl7.org/fhir/StructureDefinition/patient-birthPlace",
            "valueAddress": {
              "city": "Rovigo",
              "country": "IT"
            }
          }
        ],
        "identifier": [
          {
            "system": "urn:oid:2.16.840.1.113883.2.9.4.3.2",
            "value": "RSVDMN11A41H620X"
          }
        ],
        "name": [
          {
            "family": "ROSAVIOLA",
            "given": [ "DALMINA" ]
          }
        ],
        "gender": "female",
        "birthDate": "1911-12-10",
        "telecom": [
          {
            "system": "phone",
            "value": "+39 0323 1234567",
            "use": "home"
          }
        ],
        "address": [
          {
            "use": "home",
            "line": [ "via sconosciuta, 99" ],
            "city": "VERBANIA",
            "district": "VB",
            "state": "Piemonte",
            "postalCode": "28921",
            "country": "IT",
            "extension": [
              {
                "url": "http://t4med.it/fhir/StructureDefinition/address-tipo",
                "valueCode": "residenza"
              },
              {
                "url": "http://t4med.it/fhir/StructureDefinition/address-codice-istat-comune",
                "valueString": "103072"
              },
              {
                "url": "http://t4med.it/fhir/StructureDefinition/address-asl",
                "valueString": "209"
              },
              {
                "url": "http://t4med.it/fhir/StructureDefinition/address-codice-regione",
                "valueString": "010"
              }
            ]
          }
        ]
      },
      "request": {
        "method": "POST",
        "url": "Patient",
        "ifNoneExist": "identifier=urn:oid:2.16.840.1.113883.2.9.4.3.2|RSVDMN11A41H620X"
      }
    },

    {
      "fullUrl": "urn:uuid:b7e92c83-1f64-4a3c-8d27-5e9b1a4c8f72",
      "resource": {
        "resourceType": "ServiceRequest",
        "status": "active",
        "intent": "order",
        "identifier": [
          {
            "system": "urn:oid:2.16.840.1.113883.2.9.4.3.8",
            "value": "010A900000112233"
          }
        ],
        "code": {
          "coding": [
            {
              "system": "urn:oid:2.16.840.1.113883.2.9.2.10.6.11",
              "code": "89.01.B",
              "display": "Visita nefrologica di controllo"
            }
          ]
        },
        "subject": {
          "reference": "urn:uuid:a3f1c24e-7b82-4d5f-9e16-2c4a8f3b7d91"
        },
        "authoredOn": "2026-06-03",
        "performer": [
          {
            "identifier": {
              "system": "urn:oid:2.16.840.1.113883.2.9.4.1.1",
              "value": "010209"
            },
            "display": "ASL VCO - Ospedale di Verbania"
          }
        ]
      },
      "request": {
        "method": "POST",
        "url": "ServiceRequest"
      }
    },

    {
      "fullUrl": "urn:uuid:c5d8a619-3e74-4b2d-af38-7d1c9b2e5f84",
      "resource": {
        "resourceType": "Appointment",
        "identifier": [
          {
            "system": "urn:local:cup:id-prenotazione",
            "value": "26B001956"
          }
        ],
        "status": "booked",
        "serviceType": [
          {
            "coding": [
              {
                "system": "urn:oid:2.16.840.1.113883.2.9.2.10.6.11",
                "code": "89.01.B",
                "display": "Visita nefrologica di controllo"
              }
            ]
          }
        ],
        "start": "2026-06-03T10:30:00+02:00",
        "end":   "2026-06-03T11:00:00+02:00",
        "basedOn": [
          {
            "reference": "urn:uuid:b7e92c83-1f64-4a3c-8d27-5e9b1a4c8f72"
          }
        ],
        "participant": [
          {
            "actor": {
              "reference": "urn:uuid:a3f1c24e-7b82-4d5f-9e16-2c4a8f3b7d91",
              "display": "ROSAVIOLA DALMINA"
            },
            "required": "required",
            "status": "accepted"
          },
          {
            "actor": {
              "type": "HealthcareService",
              "identifier": {
                "system": "urn:local:asl-vco:reparto",
                "value": "NEF001"
              },
              "display": "Reparto Nefrologia e Dialisi - Ospedale di Verbania"
            },
            "required": "required",
            "status": "accepted"
          },
          {
            "actor": {
              "type": "Location",
              "identifier": {
                "system": "urn:oid:2.16.840.1.113883.2.9.4.1.3",
                "value": "000256"
              },
              "display": "Presidio Ospedaliero di Verbania"
            },
            "required": "required",
            "status": "accepted"
          }
        ]
      },
      "request": {
        "method": "POST",
        "url": "Appointment"
      }
    }

  ]
}

Nota — residenza e domicilio: il Bundle contiene al massimo un elemento nell'array Patient.address: l'indirizzo il cui tipo è indicato dal CUP, riportato nell'estensione address-tipo ("residenza" oppure "domicilio"). gt4medServices non deduce né replica l'indirizzo mancante: se il tipo di indirizzo non è specificato nei dati di prenotazione, la risorsa Patient viene inviata senza l'elemento address.


Risposta attesa

HTTP/1.1 200 OK
Content-Type: application/fhir+json
{
  "resourceType": "Bundle",
  "type": "transaction-response",
  "entry": [
    {
      "response": {
        "status": "201 Created",
        "location": "Patient/RSVDMN11A41H620X/_history/1",
        "etag": "W/\"1\""
      }
    },
    {
      "response": {
        "status": "201 Created",
        "location": "ServiceRequest/sr001/_history/1"
      }
    },
    {
      "response": {
        "status": "201 Created",
        "location": "Appointment/T00450/_history/1"
      }
    }
  ]
}

Nota: se il Patient esiste già su T4MED (ifNoneExist corrisponde), la prima entry restituisce "status": "200 OK" con la location del paziente esistente, invece di "201 Created".

Azione gt4medServices dopo la risposta

  • Leggere entry[2].response.location"Appointment/T00450/_history/1"
  • Estrarre l'AppointmentId T4MED: split("/")[1]"T00450"
  • Salvare la mappatura 26B001956 → T00450 (CUP Appointment ID → T4MED Appointment ID) negli archivi di SINED
  • Il Patient ID su T4MED coincide con il codice fiscale (RSVDMN11A41H620X): non è necessaria alcuna mappatura aggiuntiva per l'identificativo paziente

Atomicità della risposta

La risposta del Flusso A è atomica: se anche una sola entry del Bundle non può essere registrata (es. il Patient viene censito ma l'Appointment non è valido), l'intera transazione viene annullata — nessuna risorsa viene creata — e T4MED restituisce una singola risorsa OperationOutcome con status HTTP 4xx/5xx, non un Bundle transaction-response parziale. Vedi 06-response-failure.md.


Response di fallimento

Per il formato generale e l'elenco completo degli scenari di errore vedi 06-response-failure.md. Esempi pertinenti al Flusso A:

Campo obbligatorio mancante (Appointment.end)

HTTP/1.1 400 Bad Request
Content-Type: application/fhir+json
{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "required",
      "details": {
        "text": "Appointment.end e' un campo obbligatorio e non e' presente"
      },
      "diagnostics": "Bundle entry[2] (Appointment) - validazione fallita",
      "expression": [ "Bundle.entry[2].resource.end" ]
    }
  ]
}

Identificativo prenotazione duplicato

HTTP/1.1 409 Conflict
Content-Type: application/fhir+json
{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "duplicate",
      "details": {
        "text": "Esiste gia' un Appointment con identifier urn:local:cup:id-prenotazione|26B001956"
      },
      "diagnostics": "Bundle entry[2] (Appointment) - identifier duplicato",
      "expression": [ "Bundle.entry[2].resource.identifier" ]
    }
  ]
}

In entrambi i casi, in base all'atomicità descritta sopra, nessuna risorsa (incluso Patient) viene creata su T4MED.