---
{
  "title": "$purge : Effacer définitivement les données d'un patient en un seul appel FHIR",
  "description": "Aidbox 2602 implémente l'opération FHIR R6 $purge — supprimez définitivement un patient et l'intégralité de son compartiment, y compris tout l'historique, en un seul appel traçable.",
  "date": "2026-04-03",
  "author": "Evgeny Mukha",
  "reading-time": "6 min read",
  "tags": ["FHIR Standard", "Aidbox", "Compliance"],
  "tldr": "L'opération FHIR R6 $purge supprime définitivement un patient et toutes les ressources de son compartiment — y compris l'historique des versions. Aidbox 2602 l'implémente avec des modes synchrone et asynchrone, des définitions de compartiment personnalisées et la journalisation des audits."
}
---
Le `DELETE` standard de FHIR est une suppression logicielle. La ressource est marquée comme supprimée, mais son historique de versions demeure intact — chaque état passé reste accessible via `_history`. Pour la plupart des flux cliniques, c'est exactement ce que l'on souhaite : une piste d'audit immuable.

Mais les réglementations ne sont pas toujours du même avis.

L'article 17 du RGPD accorde aux personnes le « droit à l'effacement ». Les politiques de conservation des données ont des dates d'expiration — même si elles s'étendent sur 100 ans après le décès. Lorsque vient le moment de supprimer véritablement les données d'un patient, une suppression logicielle ne suffit pas. Les données doivent être effacées définitivement de chaque version de chaque ressource.

C'est cet écart — entre la sémantique de suppression logicielle par défaut de FHIR et les exigences réglementaires de suppression définitive — que l'opération `$purge` a été conçue pour combler.

## De la discussion sur Zulip à la normalisation dans FHIR R6

L'opération `$purge` est issue de plusieurs années de [discussions au sein de la communauté](https://chat.fhir.org/#narrow/stream/179166-implementers/topic/GDPR.20and.20hard.20delete) sur FHIR Zulip, amorcées en 2018.

La question centrale : comment FHIR devrait-il gérer l'effacement définitif des données? Plusieurs noms ont été proposés — `$erase`, `$expunge`, `$gdpr-delete` — et différentes implémentations existaient déjà. HAPI FHIR disposait de `$expunge`, mais celui-ci ne supprimait que les ressources ayant déjà fait l'objet d'une suppression logicielle.

La décision de conception clé portait sur la portée : `/Patient/1/$purge` devrait-il effacer uniquement la ressource Patient elle-même, ou tout le contenu du compartiment du patient? La communauté a convergé vers la seconde option — le serveur devrait prendre en charge la complexité de la recherche et de la suppression de toutes les ressources du compartiment.

Les [travaux de spécification formelle](https://chat.fhir.org/#narrow/stream/179166-implementers/topic/Purge.20and.20Delete.20History.20Operations.20.28FHIR-16198.29) se sont poursuivis en 2023, couvrant les codes de réponse, la sémantique de suppression de l'historique et les portées SMART. Résultat : `$purge` a été ajouté à [FHIR R6](https://build.fhir.org/patient-operation-purge.html) en tant qu'opération normative, remplaçant les implémentations propres aux fournisseurs par une norme commune.

## Aidbox 2602 : $purge en pratique

À partir de la version 2602, Aidbox implémente l'opération `$purge` de [FHIR R6](/articles/getting-ready-for-fhir-r6-what-you-need-to-know). Un seul POST supprime définitivement la ressource Patient et chaque ressource de son compartiment — Observations, Conditions, Encounters, MedicationRequests et toutes leurs versions historiques.

L'opération utilise la [définition du compartiment Patient](https://build.fhir.org/compartmentdefinition-patient.html) pour déterminer quelles ressources appartiennent à un patient. Pour chaque type de ressource dans le compartiment, Aidbox interroge les paramètres de recherche correspondants afin de trouver toutes les ressources référençant `Patient/<id>` :

```mermaid
flowchart LR
    A["POST /fhir/Patient/pt-1/$purge"] --> B[Load compartment definition]
    B --> C[Delete Patient/pt-1]
    C --> D[Delete Observations]
    C --> E[Delete Conditions]
    C --> F[Delete Encounters]
    C --> G[Delete ...]
```

Une purge synchrone de base consiste en un seul POST :

```http
POST /fhir/Patient/pt-1/$purge
Content-Type: application/json
```

Réponse :

```json
{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "fatal",
      "code": "informational",
      "diagnostics": "All resources for Patient/pt-1 were purged"
    }
  ]
}
```

Une fois l'opération terminée, toute demande concernant le patient ou ses ressources retourne **404 Not Found** — et non 410 Gone. Les données n'existent plus.

## Mode asynchrone pour les grands compartiments

Certains patients accumulent des milliers de ressources au fil des années de soins. La suppression synchrone de l'ensemble de ces ressources pourrait entraîner des délais d'attente dépassés.

Ajoutez l'en-tête `Prefer: respond-async` pour exécuter la purge en arrière-plan :

```http
POST /fhir/Patient/pt-1/$purge
Content-Type: application/json
Prefer: respond-async
```

Le patient est supprimé immédiatement. Les ressources du compartiment sont supprimées par des travailleurs en arrière-plan. Vous obtenez en retour un `202 Accepted` avec un en-tête `Content-Location` pointant vers le point de terminaison de statut :

```http
GET /fhir/$async/<operation-id>     # 202 while in progress, 200 when complete
DELETE /fhir/$async/<operation-id>   # cancel the operation
```

Le nombre de travailleurs asynchrones simultanés est contrôlé par le paramètre [`BOX_SCHEDULER_EXECUTORS`](https://www.health-samurai.io/docs/aidbox/reference/all-settings#scheduler-executor-threads) (valeur par défaut : 4).

## Le problème des ressources partagées : pourquoi les compartiments personnalisés sont importants

Prenons une ressource `Group` représentant la cohorte d'un essai clinique regroupant 50 patients. Ou une ressource `List` assurant le suivi du groupe de patients partagé par une équipe de soins. Ces ressources font référence à plusieurs patients simultanément. Lorsque vous purgez le patient A, l'intégralité du `Group` devrait-elle être supprimée — même si les patients B à Z y figurent toujours?

Il n'existe pas de réponse universellement correcte. Supprimer l'ensemble de la ressource brise l'intégrité référentielle pour les autres patients qui y font encore référence. N'en supprimer qu'une partie — par exemple, retirer un membre d'un Group — soulève ses propres questions : toutes les versions historiques de cette ressource devraient-elles également être réécrites pour en retirer le patient? Et la ressource modifiée préserve-t-elle même sa sémantique d'origine?

La spécification principale de FHIR laisse délibérément ce comportement à la discrétion des implémenteurs — et pour de bonnes raisons. La bonne réponse dépend de votre modèle de données, de votre contexte réglementaire et de la façon dont votre système utilise ces ressources partagées.

`$purge` prend en charge un paramètre `compartmentDefinition` qui vous permet de contrôler précisément quels types de ressources sont inclus dans la purge. Au lieu d'utiliser le compartiment Patient par défaut du serveur (qui inclut Group, List et des dizaines d'autres types), vous pouvez transmettre une `CompartmentDefinition` personnalisée qui en limite la portée.

Par exemple, pour purger uniquement les données cliniques — en excluant délibérément Group et List :

```json
{
  "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"] }
        ]
      }
    }
  ]
}
```

Cela offre un contrôle explicite : purgez les données cliniques individuelles du patient tout en laissant les ressources partagées intactes pour qu'elles soient traitées séparément par la logique applicative.

La `CompartmentDefinition` personnalisée doit avoir `code` défini à `Patient` et au moins une entrée de ressource avec une liste `param` non vide.

## Garanties de sécurité intégrées

**Idempotent par conception.** La purge d'un patient qui n'existe pas (ou qui a déjà été purgé) retourne un succès. Vous pouvez relancer `$purge` en toute sécurité après un échec partiel sans craindre d'erreurs.

**Piste d'audit.** Chaque purge réussie crée un `AuditEvent` avec `action: "E"` (Execute) et `subtype: "$purge"`. La purge supprime les données du patient, mais le fait qu'une purge ait eu lieu est enregistré de façon permanente. Consultez [comment configurer le journal d'audit](https://docs.aidbox.app/tutorials/security-access-control-tutorials/how-to-configure-audit-log) pour les instructions de configuration.

## Premiers pas

`$purge` est disponible dans Aidbox à partir de la version 2602. Le point de terminaison suit la spécification FHIR R6 :

```http
POST /fhir/Patient/<patient-id>/$purge
```

Aucune configuration supplémentaire n'est requise. Pour les détails complets de l'API et la référence des paramètres, consultez la [documentation Aidbox sur $purge](https://docs.aidbox.app/api/bulk-api/purge).