Das Standard-DELETE in FHIR ist ein Soft-Delete. Die Ressource wird als gelöscht markiert, doch ihre Versionshistorie bleibt vollständig erhalten — jeder vergangene Zustand ist weiterhin über _history abrufbar. Für die meisten klinischen Arbeitsabläufe ist das genau das Gewünschte: ein unveränderlicher Prüfpfad.
Regulatorische Anforderungen sehen das jedoch nicht immer so.
Artikel 17 der DSGVO gewährt Einzelpersonen das „Recht auf Löschung". Datenaufbewahrungsrichtlinien haben Verfallsdaten — selbst wenn diese 100 Jahre nach dem Tod liegen. Wenn es darum geht, die Daten eines Patienten wirklich zu entfernen, reicht ein Soft-Delete nicht aus. Die Daten müssen dauerhaft aus jeder Version jeder Ressource gelöscht werden.
Diese Lücke — zwischen der standardmäßigen Soft-Delete-Semantik von FHIR und den regulatorischen Hard-Delete-Anforderungen — ist es, die die Operation $purge schließen soll.
Von der Zulip-Diskussion zur FHIR R6-Standardisierung
Die Operation $purge entstand aus jahrelangen Community-Diskussionen auf FHIR Zulip, die 2018 begannen.
Die zentrale Frage lautete: Wie soll FHIR die dauerhafte Datenlöschung handhaben? Verschiedene Namen wurden vorgeschlagen — $erase, $expunge, $gdpr-delete — und unterschiedliche Implementierungen existierten bereits. HAPI FHIR verfügte über $expunge, das jedoch nur zuvor soft-gelöschte Ressourcen entfernte.
Die wichtigste Designentscheidung betraf den Geltungsbereich: Soll /Patient/1/$purge nur die Patient-Ressource selbst löschen oder alles im Compartment des Patienten? Die Community einigte sich auf Letzteres — der Server soll die Komplexität des Auffindens und Entfernens aller Compartment-Ressourcen übernehmen.
Die formale Spezifikationsarbeit wurde 2023 fortgesetzt und behandelte Antwort-Codes, Semantiken zur Historienbereinigung und SMART-Scopes. Das Ergebnis: $purge wurde als normative Operation in FHIR R6 aufgenommen und ersetzt damit herstellerspezifische Implementierungen durch einen Standard.
Aidbox 2602: $purge in der Praxis
Ab Version 2602 implementiert Aidbox die FHIR R6-Operation $purge. Ein einziger POST löscht die Patient-Ressource und jede Ressource in deren Compartment dauerhaft — Observations, Conditions, Encounters, MedicationRequests und alle ihre Versionshistorien.
Die Operation verwendet die Patient-Compartment-Definition, um zu bestimmen, welche Ressourcen zu einem Patienten gehören. Für jeden Ressourcentyp im Compartment fragt Aidbox die entsprechenden Suchparameter ab, um alle Ressourcen zu finden, die auf Patient/<id> verweisen:
Ein einfaches synchrones Purge ist ein einzelner POST:
POST /fhir/Patient/pt-1/$purge
Content-Type: application/json
Antwort:
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "fatal",
"code": "informational",
"diagnostics": "All resources for Patient/pt-1 were purged"
}
]
}
Nach Abschluss der Operation gibt jede Anfrage nach dem Patienten oder seinen Ressourcen 404 Not Found zurück — nicht 410 Gone. Die Daten existieren nicht mehr.
Asynchroner Modus für große Compartments
Einige Patienten akkumulieren im Laufe jahrelanger Behandlung Tausende von Ressourcen. Das synchrone Löschen aller Ressourcen könnte zu Timeouts führen.
Fügen Sie den Header Prefer: respond-async hinzu, um den Purge im Hintergrund auszuführen:
POST /fhir/Patient/pt-1/$purge
Content-Type: application/json
Prefer: respond-async
Der Patient wird sofort gelöscht. Compartment-Ressourcen werden von Hintergrund-Workern gelöscht. Sie erhalten eine 202 Accepted-Antwort mit einem Content-Location-Header, der auf den Status-Endpunkt verweist:
GET /fhir/$async/<operation-id> # 202 while in progress, 200 when complete
DELETE /fhir/$async/<operation-id> # cancel the operation
Die Anzahl der gleichzeitigen asynchronen Worker wird durch die Einstellung BOX_SCHEDULER_EXECUTORS gesteuert (Standard: 4).
Das Problem gemeinsam genutzter Ressourcen: Warum benutzerdefinierte Compartments wichtig sind
Betrachten Sie eine Group-Ressource, die eine klinische Studienkohorte mit 50 Patienten repräsentiert. Oder eine List-Ressource, die das gemeinsame Patientenpanel eines Pflegeteams verfolgt. Diese Ressourcen verweisen gleichzeitig auf mehrere Patienten. Wenn Sie Patient A bereinigen, soll dann die gesamte Group gelöscht werden — obwohl die Patienten B bis Z noch darin enthalten sind?
Es gibt keine universell richtige Antwort. Das Löschen der gesamten Ressource verletzt die referentielle Integrität für andere Patienten, die noch darauf verweisen. Das Löschen nur eines Teils — etwa das Entfernen eines Mitglieds aus einer Group — wirft eigene Fragen auf: Sollen auch alle historischen Versionen dieser Ressource umgeschrieben werden, um den Patienten zu entfernen? Und bewahrt die geänderte Ressource überhaupt noch ihre ursprüngliche Semantik?
Die FHIR-Kernspezifikation überlässt dieses Verhalten bewusst den Implementierern — und das aus gutem Grund. Die richtige Antwort hängt von Ihrem Datenmodell, Ihrem regulatorischen Kontext und der Verwendung dieser gemeinsam genutzten Ressourcen in Ihrem System ab.
$purge unterstützt einen Parameter compartmentDefinition, mit dem Sie genau steuern können, welche Ressourcentypen in den Purge einbezogen werden. Anstatt die Standard-Patient-Compartment-Definition des Servers zu verwenden (die Group, List und Dutzende anderer Typen umfasst), können Sie eine benutzerdefinierte CompartmentDefinition übergeben, die den Geltungsbereich einschränkt.
Um beispielsweise nur klinische Daten zu bereinigen — und dabei Group und List bewusst auszuschließen:
{
"resourceType": "Parameters",
"parameter": [
{
"name": "compartmentDefinition",
"resource": {
"resourceType": "CompartmentDefinition",
"url": "http://example.com/purge-clinical-only",
"name": "PurgeClinicalOnly",
"code": "Patient",
"status": "active",
"search": true,
"resource": [
{ "code": "Observation", "param": ["subject"] },
{ "code": "Condition", "param": ["subject"] },
{ "code": "Encounter", "param": ["subject"] },
{ "code": "MedicationRequest", "param": ["subject"] }
]
}
}
]
}
Dies bietet explizite Kontrolle: Die individuellen klinischen Daten des Patienten werden bereinigt, während gemeinsam genutzte Ressourcen für eine separate Behandlung durch Ihre Anwendungslogik intakt bleiben.
Die benutzerdefinierte CompartmentDefinition muss code auf Patient gesetzt haben und mindestens einen Ressourceneintrag mit einer nicht leeren param-Liste enthalten.
Integrierte Sicherheitsgarantien
Von Grund auf idempotent. Das Bereinigen eines Patienten, der nicht existiert (oder bereits bereinigt wurde), gibt einen Erfolgsstatus zurück. Sie können $purge nach einem partiellen Fehler sicher erneut ausführen, ohne sich um Fehler sorgen zu müssen.
Prüfpfad. Jeder erfolgreiche Purge erstellt ein AuditEvent mit action: "E" (Execute) und subtype: "$purge". Der Purge entfernt die Daten des Patienten, aber die Tatsache, dass ein Purge stattgefunden hat, wird dauerhaft aufgezeichnet. Informationen zur Einrichtung finden Sie unter Konfiguration des Audit-Logs.
Erste Schritte
$purge ist in Aidbox ab Version 2602 verfügbar. Der Endpunkt folgt der FHIR R6-Spezifikation:
POST /fhir/Patient/<patient-id>/$purge
Es ist keine zusätzliche Konfiguration erforderlich. Vollständige API-Details und eine Parameterreferenz finden Sie in der Aidbox $purge-Dokumentation.





