ELGA Core (R4) DRAFT
0.1.0 - ci-build

Transaktionen

Listen

Im Folgenden werden standardisierte Interaktionen für den lesenden und schreibenden Zugriff auf persistierte Listen beschrieben. Die Interaktionen definieren einen einheitlichen Mechanismus für das Lesen, Bearbeiten und Schreiben von Listen auf Basis der FHIR-Ressource List und sind unabhängig vom fachlichen Inhalt der Liste.

Die beschriebenen Abläufe können für unterschiedliche Anwendungsfälle verwendet werden.

Grundkonzept

Für jeden fachlichen Listentyp existiert pro Patient bzw. Patientin höchstens eine aktuelle Liste. Die Zuordnung erfolgt über das Element List.code, welches den fachlichen Typ einer Liste eindeutig kennzeichnet (z.B. Medikationsplan, Diagnosenliste oder Problemliste).

Alle in diesem Kapitel beschriebenen Interaktionen beziehen sich auf diejenige Liste, deren List.code dem angeforderten Listentyp entspricht.

Existiert für einen Patienten bzw. eine Patientin noch keine Liste mit dem angeforderten List.code, wird diese – sofern durch die jeweilige Interaktion vorgesehen – neu angelegt. Listen mit unterschiedlichen List.code-Werten werden unabhängig voneinander verwaltet und versioniert.

List-History-Read

Beim List-History-Read stellt die Fachanwendung die aktuelle oder historische Version(en) der Liste inkl. aller referenzierten Ressourcen (persistiertes Listen-Collection-Bundle) unverändert bereit.

Ablauf
  1. Der Client führt ein GET auf das persistierte Listen-Collection-Bundle aus.
  2. Die Fachanwendung prüft, ob für den Patienten bzw. die Patientin eine Liste mit dem angeforderten List.code existiert.
  3. Ist keine Liste mit diesem List.code vorhanden, wird ein leeres Ergebnis zurückgegeben.
  4. Ist eine Liste mit diesem List.code vorhanden, wird das zuletzt persistierte Listen-Collection-Bundle zurückgeliefert. Das Collection Bundle enthält:
    • die List-Ressource
    • alle referenzierten Ressourcen vollständig (inline).

Beim List-History-Read erfolgt keine Veränderung von Flags, Status oder Inhalten. Der Zugriff dient ausschließlich der Anzeige aktueller oder historischer Listenversionen.

Sequenzdiagramm List-History-Read


List-History-ReadGDA 1GDA 1FachanwendungFachanwendung1POST /$history-read2Prüfung auf bestehendeCollection-Bundlesalt: Collection-Bundles gefunden?[Collection-Bundles entsprechend der Parameter vorhanden]3Bundle (type=searchset) mit zumindest einem Collection-Bundle[kein Collection-Bundle entsprechend der Parameter vorhanden]4Bundle (type=searchset) ohne Einträge[Fehler]5OperationOutcome


Beispiele für Zugriffe mittels Suchparameter: In Arbeit. <!– * Aktuelle Planversion mit dem Suchparameter Patient abrufen: GET [base]/Bundle?type=collection&_count=1&_sort=-timestamp&List.subject={bPK-GH}

  • Alle Planversionen mit dem Suchparameter Patient abrufen: GET [base]/Bundle?type=collection&_sort=-timestamp&List.subject={bPK-GH}
  • Abfrage aller historischen Medikationsplan-Versionen eines Patienten, die nach dem angegebenen Datum gespeichert wurden und Plan-Einträge enthalten, die als storniert, beendet oder abgesetzt gekennzeichnet sind: GET [base]/Bundle?type=collection&_sort=-timestamp&timestamp=ge2025-01-01&List.subject={bPK-GH}&List.entry.flag=removed –>

List-Read

List-Read dient dem Abruf einer Liste und der Vorbereitung einer nachfolgenden Änderung.

Ablauf
  1. Der GDA führt ein POST $list-read auf das Collection Bundle aus, das die Liste mit allen zugehörigen relevanten Ressourcen enthält.
  2. Die Fachanwendung prüft, ob für den Patienten bzw. die Patientin bereits eine Liste mit dem angeforderten List.code existiert.
  3. Ist keine Liste mit diesem List.code vorhanden, wird eine neue Liste angelegt.
  4. Anschließend wird eine leere Liste mit dem entsprechenden List.code und List.emptyReason = notstarted zurückgeliefert.
  5. Existiert bereits eine Liste mit diesem List.code, erstellt die Fachanwendung daraus ein Auslieferungs-Collection-Bundle Auslieferungs-Collection-Bundle bereitgestellt. Die Inhalte werden von der Fachanwendung wie folgt aufbereitet:
    • Falls der vorherige GDA neue Listeneinträge hinzugefügt oder bestehende geändert hat (List.entry.flags haben den Wert new oder changed), werden diese auf unchanged gesetzt.
    • Falls der vorherige GDA Listeneinträge beendet hat (deren List.entry.flags haben den Wert removed), werden diese Einträge aus der Liste entfernt.
    • Falls der vorherige GDA alle vorhandenen Listeneinträge mit removed gekennzeichnet hat, wird List.emptyReason auf nilknown gesetzt. Dadurch wird nachfolgenden GDA signalisiert, dass die Liste bewusst leer ist und dieser Zustand fachlich beabsichtigt ist (z.B. keine aktuelle Medikation, keine bekannten Diagnosen oder keine vorhandenen Einträge des jeweiligen Listentyps).
  6. Die Fachanwendung liefert das Auslieferungs-Collection-Bundle an den GDA:
    • inkl. ETag für Optimistic Locking
    • inkl. List und aller referenzierten Ressourcen (inline)
    • Ziel ist ein neutraler, weiterbearbeitbarer Zustand für den abrufenden GDA
  7. Der GDA bearbeitet die Liste (er fügt Einträge hinzu, ändert bestehende oder entfernt diese).
Custom Operations

$plan-read

Sequenzdiagramm List-Read


Liste und zugehörige Ressourcen abrufen ($read)GDA 1GDA 1FachanwendungFachanwendung1POST /$read2Prüfen, ob Liste bestehtalt: Liste vorhanden?[Liste vorhanden]3Prüfen, ob List.emptyReason vorhanden istalt: List.emptyReason vorhanden?[nein]4Flag der Listeneinträge aufbereitennew|changed → unchangedremoved → entfernen5Zählen der Listeneinträgealt: Anzahl Einträge?[zumindest ein Eintrag]6Collection-Bundle (nicht leer)+ ETag für Optimistic Locking[Liste leer]7List.emptyReason = nilknown setzen8Collection-Bundle (leer)+ ETag für Optimistic Locking[ja]List.emptyReason kann den Wert "notstarted" oder"nilknown" haben.9Collection-Bundle (leer)+ ETag für Optimistic Locking[Liste nicht vorhanden]10Leere Liste mit List.emptyReason = notstarted erzeugen11Collection-Bundle (leer)+ ETag für Optimistic Locking


List-Write

List-Write ist eine eigenständige Operation, die ausschließlich im Kontext eines zuvor ausgeführten List-Read erfolgen darf.

Ablauf
  1. Der GDA übermittelt via POST $list-write die aktualisierte Liste als List-Transaction-Bundle inkl. ETag für Optimistic Locking:
    • alle neuen und geänderten und zu entfernenden Ressourcen sind inline im Bundle enthalten,
    • alle unveränderten Ressourcen werden nur referenziert.
  2. Die Fachanwendung prüft, ob der im Header übermittelte ETag mit dem ETag der Fachanwendung übereinstimmt (d.h. es wurde zwischenzeitlich keine Liste mit diesem List.code gespeichert).
  3. Stimmt der ETag nicht überein, lehnt die Fachanwendung das Speichern der Liste ab. Es muss erneut ein List-Read ausgeführt werden und die Aktualisierungen übernommen werden bzw. Fehler behoben werden, bevor ein neuerlicher Speicherversuch vorgenommen werden kann.
  4. Wenn kein Fehler auftritt, validiert die Fachanwendung die neue Liste und stellt sicher, dass keine unzulässigen Zustandsübergänge vorgenommen wurden.
  5. Bei erfolgreicher Prüfung werden die übermittelten Änderungen übernommen und auf Basis der aktualisierten Ressourcen ein neues Listen-Collection-Bundle mit demselben List.code erstellt und als neue Version dieser Liste persistiert.
  6. Der GDA erhält eine Meldung, dass die Liste erfolgreich aktualisiert wurde.
Custom Operations

$list-write

Sequenzdiagramm List-Write


Plan-WriteGDA 1GDA 1FachanwendungFachanwendungVorbedingung: Nach einem $read wurdendie Inhalte bearbeitet.1POST /$write (Transaction-Bundle + ETag)2ETag im Header ==ETag der Fachanwendung?alt: ETag stimmt überein?[ja]3Validierung der Inhalte(keine unzulässigen Zustandsübergänge)alt: Validierung erfolgreich?[ja]4Neue Version persistierenNeue Version der Liste und aller Referenzen gespeichert5HTTP 200 OK[nein]6Fehler (HTTP 4xx)OperationOutcome[nein]7Fehler (HTTP 428 Precondition Required)OperationOutcome


Abgelehntes Plan-Write
Ablauf
  1. GDA 1 möchte eine Liste bearbeiten und führt ein POST auf $list-read aus.
  2. Die Fachanwendung erstellt ein Auslieferungs-Collection-Bundle (siehe List-Read) einschließlich ETag "123" und liefert dieses an GDA 1 zurück. GDA 1 beginnt mit der Bearbeitung der Liste.
  3. Währenddessen führt GDA 2 ebenfalls ein POST auf $list-read für dieselbe Liste (identifiziert durch List.code) aus.
  4. Die Fachanwendung erstellt ein weiteres Auslieferungs-Collection-Bundle einschließlich ETag "123" und liefert dieses an GDA 2 zurück. Beide GDA bearbeiten nun dieselbe Version der Liste parallel.
  5. GDA 2 schließt seine Änderungen zuerst ab und übermittelt mittels POST $list-write ein Listen-Transaction-Bundle einschließlich des ETag "123".
  6. Die Fachanwendung prüft den übermittelten ETag. Da dieser mit dem aktuellen ETag der Fachanwendung übereinstimmt, werden die Änderungen übernommen und eine neue Version der Liste persistiert.
  7. GDA 2 erhält eine Bestätigung, dass die Liste erfolgreich aktualisiert wurde.
  8. Anschließend übermittelt GDA 1 seine Änderungen ebenfalls mittels POST $list-write und verwendet dabei weiterhin den ETag "123".
  9. Die Fachanwendung stellt fest, dass der übermittelte ETag nicht mehr dem aktuellen Stand entspricht, da zwischenzeitlich bereits eine neue Version der Liste gespeichert wurde. Das Speichern wird daher abgelehnt.
  10. GDA 1 erhält eine Fehlermeldung. Vor einem erneuten Schreibversuch muss der GDA ein neues List-Read durchführen, um die aktuelle Version der Liste einschließlich des aktuellen ETag abzurufen und seine Änderungen auf dieser Version erneut anzuwenden.
Sequenzdiagramm Abgelehntes List-Write


Plan-Write-ErrorGDA 1GDA 1FachanwendungFachanwendungGDA 2GDA 2$read durch GDA 11POST /$read2Collection-Bundle + ETag "123"GDA 1 bearbeitet Inhalte$ead durch GDA 23POST /$read4Collection-Bundle + ETag "123"GDA 2 bearbeitet Inhalte$write durch GDA 25POST /$write (Transaction-Bundle + ETag "123")6ETag "123" im Header ==ETag der Fachanwendung "123"Fachanwendung aktualisiert Inhalte.7HTTP 200 OK$write-Error für GDA 18POST /$write (Transaction-Bundle + ETag "123")9ETag im Header "123" stimmt nichtmit ETag der Fachanwendungüberein, da er bereits zum Schreibenverwendet wurdeFachanwendung lehnt Speichern ab.10HTTP 428 FehlerSpeichern der Inhalte wurde abgelehnt,der GDA 1 muss ein neues $read ausführen.