Modèle FHIR de la prescription
Introduction
La modélisation du résultat du scan d’ordonnance repose sur l’utilisation des ressources FHIR Bundle
, RequestGroup
, MedicationRequest
, DocumentReference
, Patient
et Practitioner
.
Rappel de la documentation FHIR
Un seul objet RequestGroup
est généré. Il contient directement les autres ressources nécessaires et ne dépend pas d’un système externe, il est ainsi complètement autonome.
Différents jeux de valeurs et terminologies sont utilisées et documentés. En l’absence de mention explicite, les jeux de valeurs suggérés par HL7 sont utilisés.
Attention !
Le contenu exact de la ressource FHIR de la prescription évoluera en fonction des avancées sur la reconnaissance de posologie. Vous serez prévenu en avance si le format venait à évoluer.
Description des objets
Objet RequestGroup
Cet objet représente l’ordonnance en tant que telle
Exemple de RequestGroup
{
"resourceType": "RequestGroup",
// unique identifier for the whole prescription
"identifier": [
{
"system": "id://posos",
"value": "aca3fb04-dc8c-4091-b7f9-c907eea05d1d"
}
],
// Raw prescription as read by our scanner and converted in very basic html
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><ul><li>CELLCEPT 500<br/>1 comprimé matin et soir pendant 15 jours</li><li>CORDANCYL 20<br/>60 mg par jour le matin au petit-déjeuner pendant 3 semaines puis 50 mg par jour le matin pendant 3 semaines puis 40 mg par jour le matin pendant 3 semaines puis 30 mg par jour le matin pendant 3 semaines</li></ul></div>"
},
"contained": [
// List of all embedded Medications, MedicationRequest(s), Patient and Practitioner resources
],
// if it can be read, the date of authoring
"authoredOn": "2022-04-01T12:32:00.000Z",
"status": "draft", // POSOS will always push prescriptions as draft
"intent": "order",
// This represent the Patient entity to link the prescription to
"subject": {
"reference": "urn:uuid:68ff0a08-89f5-408b-9d78-1106cba4c44d"
},
// Beware we're sending here who is scanning the prescription, not its original author
"author": {
"reference": "urn:uuid:a3e2ce74-ff1f-443f-86b0-f9c53417749b"
},
// Each action is a reference to a MedicationRequest
"action": [
{
"resource": {
"reference": "#511e1fa4-2aed-4cd9-a64e-2c652a266ddc"
}
},
{
"resource": {
"reference": "#5e9eadf9-7730-47f9-bbe2-a87216db252c"
}
}
]
}
Objet inclus - MedicationRequest
Une ligne de prescription, concerne souvent un seul médicament et des instructions de dosage.
Exemple de MedicationRequest
{
"resourceType": "MedicationRequest",
// Unique identifier for the prescription line
"id": "511e1fa4-2aed-4cd9-a64e-2c652a266ddc",
"text": {
"status": "generated",
// Raw text as read by our scanner
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Cellcept 500mg<br/>1 comprimé matin et soir pendant 15 jours</div>"
},
"status": "draft", // same as in RequestGroup
"intent": "order", // same as in RequestGroup
// should be same as in RequestGroup
"subject": {
"reference": "urn:uuid:68ff0a08-89f5-408b-9d78-1106cba4c44d"
},
// The prescribed medication, a reference to the Medication resource defined in `contained` field
"medicationReference": {
"reference": "#93bd1aa2-7a85-47e1-b332-e3caccdf5cb9"
},
// Dosage conforms to FHIR Dosage resource
"dosageInstruction": [
{
// There is always at least a text representation.
// For complex dosages where no model could be infered, only text will be present
"text": "1 comprimé matin et soir pendant 15 jours, NS MTE",
// "1 comprimé matin et soir pendant 15 jours"
// "for 15 days, take 2 times per 1 day during breakfast and dinner"
"timing": {
"repeat": {
"boundsDuration": {
"system": "http://hl7.org/fhir/ValueSet/duration-units",
"unit": "day",
"value": 15
}, // for 15 days
"frequency": 2, // take 2 times
"period": 1, // per 1
"periodUnit": "d", // day
"when": ["CM", "CV"] // during breakfast and dinner
// when values are from http://hl7.org/fhir/valueset-event-timing.html
}
},
// By default all possible routes for this drug. Filtered if a route is identified by the scan
"route": {
"coding": [
{
"system": "https://standardterms.edqm.eu",
"code": "ROA-20053000",
"display": "Voie orale"
}
]
},
// DEPRECATED use ROUTE object instead
"site": {
"coding": [
{
"system": "https://terminology.posos.co/pathway",
"code": "Voie orale",
"display": "Voie orale"
},
{
"system": "http://posos.on.fhir/pathway",
"code": "Voie orale",
"display": "Voie orale"
}
]
},
// for each take, take 1 tablet
"doseAndRate": [
{
"doseQuantity": {
"unit": "comprimé(s)",
"value": 1,
"system": "http://snomed.info/sct",
"code": "428673006"
}
}
]
}
],
// true by default, coding following french "assurance maladie" rules
"substitution": {
"allowedBoolean": false,
"reason": {
"coding": [
{
"system": "https://terminology.posos.co/substitution",
"code": "MTE",
"display": "MTE"
}
]
}
},
"extension": [
// French "affection longue durée" system, returned as a boolean
{
"url": "https://terminology.posos.co/fhir-extension/medicationrequest/isPrescribedAsALD",
"valueBoolean": false
},
// A reliability class for the structuration of the posology (high,medium or low),
// For more details on this score see https://www.posos.care/docs/apis/guides/integration-scan#score-de-confiance
{
"url": "https://terminology.posos.co/fhir-extension/medicationrequest/structurationReliability",
"valueCoding": {
"system": "https://terminology.posos.co/dosageStructurationScore",
"code": "high"
}
}
]
}
Objet inclus - Medication
Un médicament en lien avec une MedicationRequest
.
Exemple de Medication
{
"resourceType": "Medication",
"id": "da084efc-01ad-4614-a92a-2573120664b7",
// Different coding of this drug in different terminologies
// There should always be at least a DCI or ATC code
"code": {
"coding": [
{
"system": "http://posos.on.fhir/shortname",
"code": "cortancyl",
"display": "cortancyl"
},
{
"system": "http://posos.on.fhir/dci",
"code": "prednisone",
"display": "Prednisone"
},
{
"system": "http://www.whocc.no/atc",
"code": "H02AB",
"display": "GLUCOCORTICOIDES"
}
]
},
// Active ingredient of the medication
// Substance is coded with DCI
"ingredient": [
{
"itemCodeableConcept": {
"coding": {
"system": "http://posos.on.fhir/dci",
"code": "prednisone",
"display": "Prednisone"
}
},
// Strength is a bit cumbersome for tablets
// It must be read as "20mg per 1 tablet"
"strength": {
"numerator": {
"value": 20,
"system": "http://unitsofmeasure.org",
"code": "mg"
},
"denominator": {
"value": 1,
"system": "http://terminology.hl7.org/CodeSystem/v3-orderableDrugForm",
"code": "TAB"
}
}
}
]
}
Objet Patient
Le patient concerné par la prescription : il doit être défini pour attacher la prescription au bon dossier patient dans le système de destination.
Exemple de Patient
{
"resourceType": "Patient",
"id": "urn:uuid:68ff0a08-89f5-408b-9d78-1106cba4c44d",
// Patient are just identified by an identifier coming from destination system
"identifier": [
{
"system": "id://partner",
"value": "38fd36cc-2148-4ee5-852a-4f0533d0c375"
}
]
}
Objet Practitioner
Le practicien qui a scanné la prescription.
Exemple de Practitioner
{
"resourceType": "Practitioner",
"id": "urn:uuid:a3e2ce74-ff1f-443f-86b0-f9c53417749b",
// Practitioner are identified in both destination system and POSOS
"identifier": [
{
"system": "id://partner",
"value": "9e3f7b92-6ca3-4466-b970-abae9b56b4fa"
},
{
"system": "id://posos",
"value": "3e71ff9a-221b-497b-983a-f546cf8b9ea4"
}
]
}
Objet Observation
Les éventuelles observations patient détectées par le scan. Inclut le poids, la taille, l’IMC et l’âge.
Exemple de Observation
{
"resourceType": "Observation",
"id": "647d6030-5600-4a31-b1d7-bc854b95a53f",
"status": "preliminary",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs",
"display": "Vital Signs"
}
],
"text": "Vital Signs"
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "21612-7",
"display": "Age - Reported"
}
],
"text": "Age"
},
"subject": {
"reference": "urn:uuid:f7d09973-4677-4fb5-822d-35f63566f4ea"
},
"valueQuantity": {
"value": 46,
"unit": "a",
"system": "http://unitsofmeasure.org",
"code": "a"
}
}
Objet DocumentReference
Les informations relatives pour retrouver le document de l’ordonnance scannée au format PDF sont précisées dans un objet DocumentReference, lui même référencé par le RequestGroup dans une extension. L’objet DocumentReference est placé au niveau du Bundle, comme une entry à part entière et a le format suivant:
Exemple de DocumentReference
{
"resourceType": "DocumentReference",
"id": "f7d09973-4677-4fb5-822d-35f63566f4ea",
"identifier": [
{
"use": "usual",
"system": "https://terminology.posos.co/storage-path",
"value": "https://urlinterneposos/423132123.pdf"
}
],
"status": "current",
"content": [
{
"attachment": {
"url": "https://urlpubliquetemporaire/9123891.pdf",
"data": "efc2b..."
}
}
]
}
- Le champ
identifier[0].value
contient une URL interne POSOS pour le document et qui n’est pas accessible pour consultation - Le champ status contient soit la valeur “current” si le document a été correctement sauvegardé, soit “entered-in-error” si une erreur a eu lieu lors de sa génération. En cas d’erreur, l’objet
content[0].attachment
sera vide - Le champ content contient systématiquement un seul objet et
content[0].attachment.url
contient l’URL publique pour récupérer le PDF dynamiquement (valable pendant 24h après le scan). L champ “data” peut contenir le document PDF en base64 selon la configuration
En complément, ce DocumentReference est référencé par une extension dans le RequestGroup :
Exemple de RequestGroup contenant l'extension
{
...,
"extension": [
...,
{
"url": "https://terminology.posos.co/fhir-extension/requestgroup/prescriptionDocumentReference",
"valueReference": { "reference": "urn:uuid:f7d09973-4677-4fb5-822d-35f63566f4ea" }
}
]
}
Format v1 (dépréciée)
Ce format de réponse est déprécié et ne doit plus être utilisé. Il est conservé afin d’assurer la rétro-compatibilité. Il peut être activé en passant le paramètre shouldSimplify=true
à l’API de scan d’ordonnance.
Interface
type ScanOrdoApiResponse = {
patientObservations?: {
age?: number;
weight?: number;
height?: number;
};
drugs: {
entity: string;
dci: string[];
boundingPolyVertices?: [
{ x: number; y: number },
{ x: number; y: number },
{ x: number; y: number },
{ x: number; y: number }
];
strength?: string;
isStrengthInMedicalDB?: boolean;
posology?: string;
structuredPosology?: PosologyInstruction[];
form?: string;
}[];
};
Exemple
{
"patientObservations": {
"age": 45,
"weight": 73,
"height": 175
},
"drugs": [
{
"entity": "inexium",
"dci": ["ésoméprazole"],
"boundingPolyVertices": [
{ "x": 133, "y": 173 },
{ "x": 251, "y": 172 },
{ "x": 251, "y": 194 },
{ "x": 133, "y": 195 }
],
"strength": "20 mg",
"isStrengthInMedicalDB": true,
"posology": "Prendre 1 comprimé le soir, pendant 1 mois.",
"structuredPosology": [
{
"frequency": 1,
"period": 1,
"period_unit": "day",
"bounds_duration": {
"value": 1,
"unit": "month"
},
"when": ["EVE"],
"frequency_texts": ["le soir"],
"duration_text": "pendant 1 mois"
}
]
}
]
}
L’objet contient un champ patientObservations
contenant :
Attribut | Description |
---|---|
age | l’âge du patient en années si il existe |
weight | le poids du patient en kg si il existe |
height | la taille du patient en cm si elle existe |
Un champ drugs
contenant la liste des médicaments reconnus. Chaque médicament est à minima décrit par 2 concepts :
Attribut | Description |
---|---|
dci | un champ tableau contenant une unique chaine de caractère correspondant libellé de la dénomination commune du médicament reconnu |
entity | le shortname du médicament s’il est reconnu, sinon sa dci. |
Les champs suivants ne sont pas toujours présents:
Attribut | Description |
---|---|
boundingPolyVertices | les coordonnées du texte qui a servi à reconnaître le médicament. Si l’image envoyée est un PDF, ces coordonnées seront normalisée (entre 0 et 1). Sinon, elles seront en pixels. |
strength | la quantité de substance active (couramment appelée dosage); si aucune n’a pu être reconnue, la valeur est à null . |
isStrengthInMedicalDB | flag valant true si la strength est reconnue ET a été identifiée et validée dans notre base d’information sur les médicaments, false sinon. |
form | la forme prescrite si reconnue ET dans notre base d’information sur les médicaments. Absent sinon. |
posology | la posologie sous forme textuelle non structurée telle qu’écrite dans l’ordonnance. Absent si aucune indication de posologie n’a pu être détectée. |
structuredPosology | la posologie sous forme structurée (une liste de PosologyInstruction ), c’est un tableau de différentes informations extraites de la valeur de posology . Les concepts et syntaxe utilisés se rapprochent des ressources Dosage et Timing de FHIR |
PosologyInstruction
Attribut | Description |
---|---|
frequency | fréquence de prise du médicament (si frequency_max existe, frequency correspond à la fréquence minimale) |
frequency_max | fréquence maximale |
period | correspond à la période pendant laquelle frequency prises ont lieu |
period_unit | unité de la période |
period_max | correspond à la période maximale |
bounds_duration | durée du traitement |
time_of_day | tableau de string , heures de la journée où le traitement doit être pris (8h, 12h30, …) |
day_of_week | tableau de string , jours de la semaine où le traitement doit être pris (mon, tue, wed, thur, fri, sat, sun) |
when | tableau de string , moments de la journée auxquels ont lieu le traitement (les significations des codes sont expliquées dans ce site https://www.hl7.org/fhir/valueset-event-timing.html#definition |
offset | intervalle de temps entre la prise et when, en minutes |
sequence | chiffre commençant à 0 indiquant la succession des posologies (2 cpr pendant une semaine puis 1 cpr pendant 1 mois) |
frequency_texts | tableau de string , liste des différents textes correspondant aux fréquences |
bounds_duration_text | string , texte correspondant à la durée du traitement |
quantity_and_rate | QuantityAndRate , information sur la quantité de médicament par prise/par unité de temps |
BoundsDuration
Attribut | Description |
---|---|
unit | unité de la durée du traitement |
value | durée (minimale) du traitement |
max_value | durée maximale du traitement |
QuantityAndRate
Attribut | Description |
---|---|
value | quantité d’unités détecté |
unit | unité normalisée (parmi une liste d’entités) |
type | “QUANTITY ”, “DOSE ” ou “STRENGTH ”. |
rate | Rate Lorsqu’une fraction est détectée, l’attribut rate est ajouté à l’attribut value avec les valeurs et unités des numérateur et dénominateur. |
Rate
Attribut | Description |
---|---|
numerator | quantité du numérateur |
denominator | quantité du dénominateur |
numerator_unit | unité du numérateur |
denominator_unit | unité du dénominateur |
Exemple d’ordonnance
Fichier original
Réponse structurée de l’API
full-bundle.json
{
"fhirBundle": {
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"resource": {
"resourceType": "Patient",
"identifier": [
{
"system": "id://partner"
}
]
},
"fullUrl": "urn:uuid:68ff0a08-89f5-408b-9d78-1106cba4c44d",
"request": {
"method": "POST",
"url": "Patient"
}
},
{
"resource": {
"resourceType": "Practitioner",
"identifier": [
{
"system": "id://partner",
"value": "partner-id"
},
{
"system": "id://posos"
}
]
},
"fullUrl": "urn:uuid:a3e2ce74-ff1f-443f-86b0-f9c53417749b",
"request": {
"method": "POST",
"url": "Practitioner"
}
},
{
"resource": {
"resourceType": "RequestGroup",
"identifier": [
{
"system": "id://posos",
"value": "145e8b78-8757-4b06-9fdc-a695b0d96add"
}
],
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><ul><li>cellcept - 1 cp matin et soir pendant 15 jours</li><li>cortancyl - 60 mg par jour le matin au petit déjeuner pendant 3 semaines puis 50 mg/jour le matin pendant 3 semaines puis 40 mg/jour le matin pendant 3 semaines puis 30 mg/jour le matin pendant 3 semaines</li></ul></div>"
},
"authoredOn": "2023-01-31",
"status": "draft",
"intent": "order",
"subject": {
"reference": "urn:uuid:68ff0a08-89f5-408b-9d78-1106cba4c44d"
},
"author": {
"reference": "urn:uuid:a3e2ce74-ff1f-443f-86b0-f9c53417749b"
},
"contained": [
{
"resourceType": "Medication",
"id": "2af172dd-77e9-4f97-979f-c570c09abc57",
"code": {
"coding": [
{
"system": "http://posos.on.fhir/dci",
"code": "acide mycophénolique",
"display": "acide mycophénolique"
},
{
"system": "http://www.whocc.no/atc",
"code": "L04AA06",
"display": "MYCOPHENOLIQUE ACIDE"
},
{
"system": "http://posos.on.fhir/form",
"code": "comprimé pelliculé",
"display": "comprimé pelliculé"
}
]
},
"ingredient": [
{
"itemCodeableConcept": {
"coding": [
{
"system": "http://posos.on.fhir/dci",
"code": "acide mycophénolique",
"display": "acide mycophénolique"
}
]
}
}
],
"extension": [
{
"url": "http://fhir.posos.co/extensions/medication/isStrengthInMedicalDb",
"valueBoolean": false
}
]
},
{
"resourceType": "Medication",
"id": "0f6aa3bb-11c7-482e-ae68-034064ef0974",
"code": {
"coding": [
{
"system": "http://posos.on.fhir/shortname",
"code": "cortancyl",
"display": "cortancyl"
},
{
"system": "http://posos.on.fhir/dci",
"code": "prednisone",
"display": "prednisone"
},
{
"system": "http://www.whocc.no/atc",
"code": "H02AB07",
"display": "PREDNISONE"
},
{
"system": "http://bdpm/cis",
"code": "62390849",
"display": "CORTANCYL 20 mg, comprimé sécable"
},
{
"system": "http://posos.on.fhir/dose",
"code": "20 mg",
"display": "20 mg"
}
]
},
"ingredient": [
{
"itemCodeableConcept": {
"coding": [
{
"system": "http://posos.on.fhir/dci",
"code": "prednisone",
"display": "prednisone"
}
]
}
}
],
"extension": [
{
"url": "http://fhir.posos.co/extensions/medication/isStrengthInMedicalDb",
"valueBoolean": true
}
]
},
{
"resourceType": "MedicationRequest",
"id": "f9d47860-9f29-4c09-b458-f5bdf0e10a6b",
"subject": {
"reference": "urn:uuid:68ff0a08-89f5-408b-9d78-1106cba4c44d"
},
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">cellcept - 1 cp matin et soir pendant 15 jours</div>"
},
"status": "draft",
"intent": "order",
"medicationReference": {
"reference": "#2af172dd-77e9-4f97-979f-c570c09abc57"
},
"dosageInstruction": [
{
"timing": {
"repeat": {
"boundsDuration": {
"unit": "day",
"value": 15
},
"frequency": 2,
"period": 1,
"periodUnit": "d",
"when": ["EVE", "MORN"]
}
},
"doseAndRate": [
{
"doseQuantity": {
"unit": "comprimé(s)",
"value": 1
}
}
],
"asNeededBoolean": false,
"text": "1 cp matin et soir pendant 15 jours"
}
]
},
{
"resourceType": "MedicationRequest",
"id": "dbbd4fb9-d331-48bb-9bfc-3d22d9355318",
"subject": {
"reference": "urn:uuid:68ff0a08-89f5-408b-9d78-1106cba4c44d"
},
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">cortancyl - 60 mg par jour le matin au petit déjeuner pendant 3 semaines puis 50 mg/jour le matin pendant 3 semaines puis 40 mg/jour le matin pendant 3 semaines puis 30 mg/jour le matin pendant 3 semaines</div>"
},
"status": "draft",
"intent": "order",
"medicationReference": {
"reference": "#0f6aa3bb-11c7-482e-ae68-034064ef0974"
},
"dosageInstruction": [
{
"timing": {
"repeat": {
"boundsDuration": {
"unit": "week",
"value": 3
},
"frequency": 1,
"period": 1,
"periodUnit": "d",
"when": ["CM"]
}
},
"doseAndRate": [
{
"doseQuantity": {
"unit": "mg",
"value": 60
}
}
],
"asNeededBoolean": false,
"text": "60 mg par jour le matin au petit déjeuner pendant 3 semaines puis 50 mg/jour le matin pendant 3 semaines puis 40 mg/jour le matin pendant 3 semaines puis 30 mg/jour le matin pendant 3 semaines"
},
{
"timing": {
"repeat": {
"boundsDuration": {
"unit": "week",
"value": 3
},
"frequency": 1,
"period": 1,
"periodUnit": "d",
"when": ["MORN"]
}
},
"doseAndRate": [
{
"doseQuantity": {
"unit": "mg",
"value": 50
}
}
],
"asNeededBoolean": false,
"text": "60 mg par jour le matin au petit déjeuner pendant 3 semaines puis 50 mg/jour le matin pendant 3 semaines puis 40 mg/jour le matin pendant 3 semaines puis 30 mg/jour le matin pendant 3 semaines"
},
{
"timing": {
"repeat": {
"boundsDuration": {
"unit": "week",
"value": 3
},
"frequency": 1,
"period": 1,
"periodUnit": "d",
"when": ["MORN"]
}
},
"doseAndRate": [
{
"doseQuantity": {
"unit": "mg",
"value": 40
}
}
],
"asNeededBoolean": false,
"text": "60 mg par jour le matin au petit déjeuner pendant 3 semaines puis 50 mg/jour le matin pendant 3 semaines puis 40 mg/jour le matin pendant 3 semaines puis 30 mg/jour le matin pendant 3 semaines"
},
{
"timing": {
"repeat": {
"boundsDuration": {
"unit": "week",
"value": 3
},
"frequency": 1,
"period": 1,
"periodUnit": "d",
"when": ["MORN"]
}
},
"doseAndRate": [
{
"doseQuantity": {
"unit": "mg",
"value": 30
}
}
],
"asNeededBoolean": false,
"text": "60 mg par jour le matin au petit déjeuner pendant 3 semaines puis 50 mg/jour le matin pendant 3 semaines puis 40 mg/jour le matin pendant 3 semaines puis 30 mg/jour le matin pendant 3 semaines"
}
]
}
],
"action": [
{
"resource": {
"reference": "#f9d47860-9f29-4c09-b458-f5bdf0e10a6b"
}
},
{
"resource": {
"reference": "#dbbd4fb9-d331-48bb-9bfc-3d22d9355318"
}
}
]
},
"fullUrl": "urn:uuid:64b96df4-774b-47ab-a8f2-7075f211dbee",
"request": {
"method": "POST",
"url": "RequestGroup"
}
}
]
}
}