# CDS Hooks sur Epic et Cerner : patient-view, order-select, order-sign

> Un playbook pour CDS Hooks contre Epic et Oracle Health (Cerner) : patient-view versus order-select versus order-sign, cartes versus suggestions, préchargement et jeux de données synthétiques.

Auteur: Ala Ben Aicha

Page de référence: https://alabenaicha.me/fr/insights/cds-hooks-epic-cerner

Mise à jour: 2026-09-17

## Réponse directe

la patient-view, la order-select et la order-sign sont des points de flux de travail différents. Une carte de guidage s'affiche ; une suggestion est un changement FHIR exploitable. La préchargement correspond aux données que le DSE peut envoyer afin que le service reste rapide.

## Hooks et cartes : contrat d’échange

CDS Hooks est un modèle JSON sur HTTPS : les POST du DSE (client CDS) vers `{baseUrl}/cds-services/{id}` lorsqu'un hook de workflow nommé se déclenche. Fixez la version du [Spécification des CDS Hooks](https://cds-hooks.org/specification/current/) et les pages d'accroche pour [patient-view](https://cds-hooks.org/hooks/patient-view), [order-select](https://cds-hooks.org/hooks/order-select) et [order-sign](https://cds-hooks.org/hooks/order-sign). La découverte est `GET {baseUrl}/cds-services`.

Ce n'est pas le même article que [L'IA dans les flux de travail cliniques](https://alabenaicha.me/fr/insights/healthcare-ai-clinical-workflows) (modèle de comportement à l'intérieur du DSE) ou [Epic contre Cerner](https://alabenaicha.me/fr/insights/epic-vs-cerner-comparison) (particularités des plateformes). Les deux fournisseurs exposent les CDS Hooks ; les noms de hook et le schéma de la carte constituent le contrat portable.

| Hook             | Déclenchement                                                                                | Contexte requis                                             | Réponse typique                                                                                                          |
| ---------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **patient-view** | L'utilisateur ouvre le dossier d'un patient                                                  | `userId`, `patientId`; `encounterId` souvent présent        | Carte d'information/d'avertissement, ou un SMART `link`                                                                  |
| **order-select** | Le clinicien sélectionne une ou plusieurs commandes, toujours en cours de rédaction          | `userId`, `patientId`, `selections[]`, `draftOrders` Bundle | Alternatives, couverture, avertissements d'interaction alors que les détails sont incomplets                             |
| **order-sign**   | Le clinicien est sur le point de signer ; dernière chance avant que le brouillon soit validé | `userId`, `patientId`, plein `draftOrders`                  | Conseils au moment de la signature ; des suggestions qui `create` / `update` / `delete` ressources à l’état de brouillon |

Carte versus suggestion versus lien :

| Retour            | Qu'est-ce que c'est                                                                                                  | Ce que ce n'est pas                                                                                                                                                          |
| ----------------- | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Carte**         | `summary` (<140 caractères), `indicator` (`info` \| `warning` \| `critical`), `source`, facultatif `detail` démarque | Pas une écriture. Un vide `cards: []` est une réponse HTTP 200 valide — « aucune indication »                                                                                |
| **Suggestions**   | Ensemble d'actions étiquetées que l'utilisateur peut accepter ; `actions[]` de FHIR `create` / `update` / `delete`   | Non appliqué automatiquement, sauf si vous envoyez également `systemActions` et le DSE y participe. Si `suggestions` exister, `selectionBehavior` est `at-most-one` ou `any` |
| **Lien**          | URL, éventuellement `type: smart` pour lancer une application SMART                                                  | Ne remplace pas une suggestion lorsque vous avez besoin d'un changement MedicationRequest sur place                                                                          |
| **Préchargement** | Modèles de lecture/recherche FHIR au moment de la découverte, remplis par le DSE et postés en tant que `prefetch`    | Pas une garantie. Le client PEUT honorer zéro, certaines ou toutes les clés                                                                                                  |

Les jetons de préchargement sont `{{context.patientId}}` (et d'autres champs de contexte primitifs de premier niveau). Exemple de fragment de découverte :

```json
{
  "hook": "order-sign",
  "id": "example-pgx",
  "description": "Example pharmacogenomics check on sign (de-identified).",
  "prefetch": {
    "patient": "Patient/{{context.patientId}}",
    "medications": "MedicationRequest?patient={{context.patientId}}"
  }
}
```

Si les données requises ne sont ni en préchargement ni autorisées `fhirServer`, le service répond **412 Échec de la condition préalable**. Ne bloquez pas le DSE pendant quelques secondes pendant que vous parcourez toutes les pages du dossier.

## Pièges d'identification

| Piège                                                      | Symptôme                                                                             | Corriger                                                                                                                                                              |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Traiter `context.patientId` en tant qu'URL Patient         | Préchargement `Patient/{{context.patientId}}` contre `Patient?identifier=` confusion | Le contexte Hook est un FHIR **identifiant**, pas un MRN. Cartographier MRN en préfetch ou via recherche FHIR                                                         |
| Utiliser un contexte imbriqué comme jeton de préchargement | `{{context.draftOrders.entry.0.resource.id}}` n'est pas valide                       | Uniquement les champs de contexte primitif de premier niveau ; les hooks qui ont besoin d'un identifiant de commande l'exposent en tant que champ de niveau supérieur |
| Suggestions sans `selectionBehavior`                       | Le client doit traiter la carte comme une erreur                                     | Toujours réglé `at-most-one` ou `any`                                                                                                                                 |
| Renvoyer des conseils cliniques comme `detail` seulement   | Le clinicien ne développe jamais « voir plus »                                       | Mettez la décision dans `summary`; garder `detail` pour preuve                                                                                                        |
| Préchargement depuis un autre service sur le même hook     | Partage excessif                                                                     | Les clients DOIVENT uniquement envoyer des clés **ceci** service enregistré                                                                                           |
| Formes de ressources préliminaires Oracle Health vs Epic   | Suggestions `update` échoue à la validation                                          | Fixation par DSE : même nom de hook, contraintes MedicationRequest différentes. Ne supposez pas qu'une carte JSON écrit sur les deux                                  |

CDS Hooks est une plomberie d’aide à la décision. Il ne s’agit pas d’une autorisation pour administrer un traitement, un dosage ou un diagnostic. La sortie du modèle qui modifie une ordonnance nécessite toujours un clinicien et, lorsque le logiciel est un dispositif médical, un propriétaire réglementaire - voir le [Guide du logiciel MDR](https://alabenaicha.me/fr/insights/eu-mdr-software-medical-device-guide) si cette question est ouverte.

## Jeux de données de test

Désidentifié. L'identifiant Patient `example-p` n'est pas une personne.

Découverte (tronquée) :

```json
{
  "services": [
    {
      "hook": "patient-view",
      "id": "static-patient-greeter",
      "title": "Static example",
      "description": "Returns a static info card.",
      "prefetch": {
        "patientToGreet": "Patient/{{context.patientId}}"
      }
    }
  ]
}
```

demande de patient-view (tronquée) :

```json
{
  "hookInstance": "d1577c69-dfbe-44ad-ba6d-3e05e953b2ea",
  "hook": "patient-view",
  "fhirServer": "https://ehr.example.org/fhir",
  "context": {
    "userId": "Practitioner/example-pract",
    "patientId": "example-p",
    "encounterId": "example-enc"
  },
  "prefetch": {
    "patientToGreet": {
      "resourceType": "Patient",
      "id": "example-p",
      "gender": "female",
      "birthDate": "1977-04-12",
      "active": true
    }
  }
}
```

Carte d’information (aucune suggestion) :

```json
{
  "cards": [
    {
      "summary": "Example info card — not clinical advice.",
      "indicator": "info",
      "source": { "label": "Example CDS Service" },
      "links": [
        {
          "label": "Open example SMART app",
          "url": "https://app.example.org/launch",
          "type": "smart"
        }
      ]
    }
  ]
}
```

Forme de suggestion sur le order-sign (ressource tronquée, il ne s'agit pas d'une véritable commande de médicament) :

```json
{
  "cards": [
    {
      "summary": "Example: replace the draft order (fixture).",
      "indicator": "warning",
      "source": { "label": "Example CDS Service" },
      "selectionBehavior": "at-most-one",
      "suggestions": [
        {
          "label": "Apply example update",
          "actions": [
            {
              "type": "update",
              "description": "Update the draft ServiceRequest identifier only.",
              "resource": {
                "resourceType": "ServiceRequest",
                "id": "draft-order-1",
                "status": "draft",
                "intent": "order",
                "subject": { "reference": "Patient/example-p" }
              }
            }
          ]
        }
      ]
    }
  ]
}
```

Tests minimaux :

1. patient-view avec préchargement présente : 200, carte d'information ≤ 1, budget de latence que le DSE applique réellement.
2. patient-view avec clé de préchargement omise — soit 200 avec une carte plus étroite, soit 412 ; ne jamais bloquer le parcours.
3. order-select avec deux `selections` — la carte parle uniquement des brouillons sélectionnés.
4. suggestion de order-sign acceptée ou rejetée (API de rétroaction si le DSE l'envoie).
5. Même service enregistré sur un bac à sable Epic et un bac à sable Oracle Health : comparez les champs obligatoires du brouillon MedicationRequest.

## Modes de défaillance et restauration

| Échec                                     | Détection                                                               | Restauration                                                                                                                                                                   |
| ----------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Service lent                              | Carte ouverte bloquée                                                   | Délai d’attente maximal ; retour `cards: []`; ne bloquez pas la signature sur un service indisponible                                                                          |
| Cartes périmées                           | Les cartes de order-select sont toujours affichées lors de la signature | Les clients doivent déposer les cartes précédentes du même `id` quand un nouveau hook se déclenche                                                                             |
| La suggestion écrit la mauvaise ressource | Incompatibilité d'identifiant/identifiant activée `update`              | Les suggestions DOIVENT envoyer la ressource entièrement mise à jour ; désactiver l'application automatique (`systemActions`) jusqu’à la validation des tests de compatibilité |
| Fuite de jeton via `fhirAuthorization`    | Jeton Bearer conservé trop longtemps dans les journaux                  | Traitez le jeton comme transitoire ; Le DSE devrait être révoqué après le hook ; ne persiste pas                                                                               |
| JSON Dual-EHR supposé portable            | Production 400 d'un seul fournisseur                                    | Tests de schéma selon le DSE ; noms de hook partagés, pas charges utiles de ressources partagées                                                                               |

Désactivez un service dangereux lors de sa découverte (supprimez-le de `{baseUrl}/cds-services`) plutôt que de renvoyer des cartes critiques que vous ne pouvez pas prendre en charge. La restauration consiste à : désenregistrer le hook, conserver le flux de travail DSE natif, ne rien rejouer – CDS Hooks est consultatif, sauf si vous l'avez accepté. `systemActions`.

## Service associé

Si vous avez besoin de CDS Hooks connectés à Oracle Health / Cerner (et des mêmes cartes testées contre Epic), c'est-à-dire [Intégration Cerner](https://alabenaicha.me/fr/services/cerner-integration). Pour une étude technique ciblée de CDS Hooks, utilisez [formulaire de contact projet](https://alabenaicha.me/fr/contact?intent=project).

Cette page ne constitue pas un conseil clinique, ni une certification CDS Hooks, ni un partenariat avec un fournisseur de DSE. Les cartes vides sont une réponse réussie.
