Données socles des Entrepôts de Données de Santé Hospitalier
0.1.0 - ci-build
FRA
Données socles des Entrepôts de Données de Santé Hospitalier - version de développement local (intégration continue v0.1.0) construite par les outils de publication FHIR (HL7® FHIR® Standard). Voir le répertoire des versions publiées
| Official URL: https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureMap/Q2FSL | Version: 0.1.0 | |||
| Draft as of 2026-05-28 | Computable Name: Q2FSL | |||
Transforms QuestionnaireResponse based on Questionnaire Usage Variables socles into FHIR resources conforming to DM profiles
Le group CreatePatient alimente la ressource Patient à partir des éléments d'informations contenus dans le QR, à savoir :
id : génération d'un uuidname : alimenté à partir des items "Nom patient" (8605698058770) et "Prénom patient" (6214879623503)identifier : plusieurs identifiants peuvent être créé :
birthDate : alimenté à partir de l'item "Date de naissance" (5036133558154)deceased[x] : alimenté à partir de l'item "Date de décès" (5633552097315). La source de cette information peut être renseigné dans l'extension edsh-death-source à partir de l'item "Source de la date de décès" (9098810065693)multipleBirth[x] : alimenté à partir de l'item "Rang gémellaire du bénéficiaire" (6931296968515)gender : alimenté à partir de l'item "Sexe" (3894630481120)address : plusieurs informations peuvent être renseigné :
edsh-pmsi-code-geogeolocation :
iso21090-ADXP-censusTract// Group: Create Patient from QuestionnaireResponse
group CreatePatient(source src : QuestionnaireResponse, target patient : Patient) {
src -> patient.id = uuid() "patient-id";
src -> patient.meta = create('Meta') as meta then {
src -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-patient' "patient-profile";
} "patient-meta";
// Extract patient identity data from linkId 4647259356106 > 2958000860428
src.item as socioDemo where (linkId = '4647259356106') then {
socioDemo.item as identity where (linkId = '2958000860428') then {
// Patient name (linkId 8605698058770 = family, 6214879623503 = given)
identity -> patient.name = create('HumanName') as name then {
identity.item as familyItem where (linkId = '8605698058770') then {
familyItem.answer as ans -> name.family = (%ans.valueString) "set-family";
} "extract-family";
identity.item as givenItem where (linkId = '6214879623503') then {
givenItem.answer as ans -> name.given = (%ans.valueString) "set-given";
} "extract-given";
} "set-name";
// NIR identifier (linkId 5711960356160)
identity.item as nirItem where (linkId = '5711960356160') then {
nirItem.answer as ans -> patient.identifier = create('Identifier') as nir then {
ans -> nir.system = 'urn:oid:1.2.250.1.213.1.4.8' "nir-system";
ans -> nir.value = (%ans.valueString) "nir-value";
ans -> nir.type = cc('http://interopsante.org/fhir/CodeSystem/fr-v2-0203', 'NIR') "nir-type";
} "set-nir";
} "extract-nir";
// INS identifier (linkId 3764723550987)
identity.item as insItem where (linkId = '3764723550987') then {
insItem.answer as ans -> patient.identifier = create('Identifier') as ins then {
ans -> ins.system = 'urn:oid:1.2.250.1.213.1.4.10' "ins-system";
ans -> ins.value = (%ans.valueString) "ins-value";
ans -> ins.type = cc('http://interopsante.org/fhir/CodeSystem/fr-v2-0203', 'INS-C') "ins-type";
} "set-ins";
} "extract-ins";
// Birth date (linkId 5036133558154)
identity.item as birthItem where (linkId = '5036133558154') then {
birthItem.answer as ans -> patient.birthDate = (%ans.valueDate) "set-birthdate";
} "extract-birthdate";
// Death date (linkId 5633552097315)
identity.item as deathItem where (linkId = '5633552097315') then {
deathItem.answer as ans -> patient.deceased = (%ans.valueDate) "set-deceased-date";
// Death source (linkId 9098810065693)
deathItem.item as deathSource where (linkId = '9098810065693') then {
deathSource.answer as sourceAns -> patient.extension = create('Extension') as ext then {
sourceAns -> ext.url = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-death-source' "death-source-url";
sourceAns -> ext.value = (%sourceAns.valueCoding) "death-source-value";
} "set-death-source-ext";
} "extract-death-source";
} "extract-death";
// Multiple birth rank (linkId 6931296968515)
identity.item as multipleItem where (linkId = '6931296968515') then {
multipleItem.answer as ans -> patient.multipleBirth = (%ans.valueInteger) "set-multiple-birth";
} "extract-multiple-birth";
} "process-identity";
// Gender from PMSI data (linkId 3894630481120 within 2825244231605)
src.item as pmsiGroup where (linkId = '2825244231605') then {
pmsiGroup.item as sexItem where (linkId = '3894630481120') then {
sexItem.answer as ans then {
ans.valueString as female where ($this = 'f') -> patient.gender = 'female' "setGenderF";
ans.valueString as female where ($this = 'm') -> patient.gender = 'male' "setGenderM";
} "valueCoding";
} "extract-gender";
// Address from code géographique (linkId 2446369196222)
pmsiGroup.item as codeGeoItem where (linkId = '2446369196222') then {
codeGeoItem.answer as ans -> patient.address = create('Address') as addr then {
ans -> addr.extension = create('Extension') as ext then {
ans -> ext.url = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-pmsi-code-geo' "codegeo-url";
ans.value as val -> ext.value = cast(val, 'code') "codegeo-value";
} "set-codegeo-ext";
// Environnement
socioDemo.item as environnementItem where (linkId = '5491974639955') then {
// geolocation
environnementItem.item as geocodageItem where (linkId = '3816475533472') -> addr.extension = create('Extension') as geolocationExt then {
geocodageItem.item as latItem where (linkId = '3709843054556') -> geolocationExt.url = 'http://hl7.org/fhir/StructureDefinition/geolocation', geolocationExt.extension = create('Extension') as latExt then {
latItem.answer as lat -> latExt.url = 'latitude', latExt.value = (%lat.valueDecimal) then {
geocodageItem.item as longItem where (linkId = '7651448032665') -> geolocationExt.extension = create('Extension') as longExt then {
longItem.answer as long -> longExt.url = 'longitude', longExt.value = (%long.valueDecimal) "setLong";
} "createLongExt";
} "setLat";
} "createLatExt";
} "createGeolocExt";
// IRIS
environnementItem.item as irisItem where (linkId = '7621032273792') -> addr.line as addrLine, addrLine.extension = create('Extension') as irisExt then {
irisItem.answer as ans -> irisExt.url = 'http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-censusTract',
irisExt.valueString = (%ans.valueString) "setIrisExt";
} "navIrisItem";
} "navEnv";
} "set-address";
} "extract-codegeo";
} "extract-pmsi-demographics";
} "process-sociodemographics";
}
map "https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureMap/Q2FSL" = "Q2FSL" // Transforms QuestionnaireResponse based on Questionnaire Usage Variables socles into FHIR resources conforming to DM profiles uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QuestionnaireResponse as source uses "http://hl7.org/fhir/StructureDefinition/Bundle" alias Bundle as target // Main entry point: Transform QuestionnaireResponse to Bundle group QuestionnaireResponseToBundle(source src : QuestionnaireResponse, target bundle : Bundle) { // Initialize Bundle src -> bundle.id = uuid() "bundleid"; src -> bundle.type = 'collection' "bundletype"; src -> bundle.timestamp = (now()) "setTimestamp"; // Create Patient resource src -> bundle.entry as patientEntry then { src -> patientEntry.resource = create('Patient') as patient then { src then CreatePatient(src, patient) "createpatient"; src -> patient.id as patientId, patientEntry.fullUrl = append('urn:uuid:', patientId) "setfullUrl"; // Create Locations from geocoding data // src then CreateLocations(src, patient, bundle) "create-locations"; // Create Encounters from PMSI data src then CreateEncounters(src, patient, bundle) "createencounters"; // Create Laboratory Observations src then CreateLaboratoryObservations(src, patient, bundle) "createlabobservations"; // Create Medication Requests src then CreateMedicationRequests(src, patient, bundle) "createmedicationrequests"; // Create Medication Administrations src then CreateMedicationAdministrations(src, patient, bundle) "createmedicationadministrations"; // Create Vital Sign Observations src then CreateVitalSignObservations(src, patient, bundle) "createvitalsigns"; } "createpatientresource"; } "patiententry"; } // Group: Create Patient from QuestionnaireResponse group CreatePatient(source src : QuestionnaireResponse, target patient : Patient) { src -> patient.id = uuid() "patientid"; src -> patient.meta = create('Meta') as meta then { src -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-patient' "patientprofile"; } "patientmeta"; // Extract patient identity data from linkId 4647259356106 > 2958000860428 src.item as socioDemo where (linkId = '4647259356106') then { socioDemo.item as identity where (linkId = '2958000860428') then { // Patient name (linkId 8605698058770 = family, 6214879623503 = given) identity -> patient.name = create('HumanName') as name then { identity.item as familyItem where (linkId = '8605698058770') then { familyItem.answer as ans -> name.family = (%ans.valueString) "setfamily"; } "extractfamily"; identity.item as givenItem where (linkId = '6214879623503') then { givenItem.answer as ans -> name.given = (%ans.valueString) "setgiven"; } "extractgiven"; } "setname"; // NIR identifier (linkId 5711960356160) identity.item as nirItem where (linkId = '5711960356160') then { nirItem.answer as ans -> patient.identifier = create('Identifier') as nir then { ans -> nir.system = 'urn:oid:1.2.250.1.213.1.4.8' "nirsystem"; ans -> nir.value = (%ans.valueString) "nirvalue"; ans -> nir.type = cc('http://interopsante.org/fhir/CodeSystem/fr-v2-0203', 'NIR') "nirtype"; } "setnir"; } "extractnir"; // INS identifier (linkId 3764723550987) identity.item as insItem where (linkId = '3764723550987') then { insItem.answer as ans -> patient.identifier = create('Identifier') as ins then { ans -> ins.system = 'urn:oid:1.2.250.1.213.1.4.10' "inssystem"; ans -> ins.value = (%ans.valueString) "insvalue"; ans -> ins.type = cc('http://interopsante.org/fhir/CodeSystem/fr-v2-0203', 'INS-C') "instype"; } "setins"; } "extractins"; // Birth date (linkId 5036133558154) identity.item as birthItem where (linkId = '5036133558154') then { birthItem.answer as ans -> patient.birthDate = (%ans.valueDate) "setbirthdate"; } "extractbirthdate"; // Death date (linkId 5633552097315) identity.item as deathItem where (linkId = '5633552097315') then { deathItem.answer as ans -> patient.deceased = (%ans.valueDate) "setdeceaseddate"; // Death source (linkId 9098810065693) deathItem.item as deathSource where (linkId = '9098810065693') then { deathSource.answer as sourceAns -> patient.extension = create('Extension') as ext then { sourceAns -> ext.url = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-death-source' "deathsourceurl"; sourceAns -> ext.value = (%sourceAns.valueCoding) "deathsourcevalue"; } "setdeathsourceext"; } "extractdeathsource"; } "extractdeath"; // Multiple birth rank (linkId 6931296968515) identity.item as multipleItem where (linkId = '6931296968515') then { multipleItem.answer as ans -> patient.multipleBirth = (%ans.valueInteger) "setmultiplebirth"; } "extractmultiplebirth"; } "processidentity"; // Gender from PMSI data (linkId 3894630481120 within 2825244231605) src.item as pmsiGroup where (linkId = '2825244231605') then { pmsiGroup.item as sexItem where (linkId = '3894630481120') then { sexItem.answer as ans then { ans.valueString as female where ($this = 'f') -> patient.gender = 'female' "setGenderF"; ans.valueString as female where ($this = 'm') -> patient.gender = 'male' "setGenderM"; } "valueCoding"; } "extractgender"; // Address from code géographique (linkId 2446369196222) pmsiGroup.item as codeGeoItem where (linkId = '2446369196222') then { codeGeoItem.answer as ans -> patient.address = create('Address') as addr then { ans -> addr.extension = create('Extension') as ext then { ans -> ext.url = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-pmsi-code-geo' "codegeourl"; ans.value as val -> ext.value = cast(val, 'code') "codegeovalue"; } "setcodegeoext"; // Environnement socioDemo.item as environnementItem where (linkId = '5491974639955') then { // geolocation environnementItem.item as geocodageItem where (linkId = '3816475533472') -> addr.extension = create('Extension') as geolocationExt then { geocodageItem.item as latItem where (linkId = '3709843054556') -> geolocationExt.url = 'http://hl7.org/fhir/StructureDefinition/geolocation', geolocationExt.extension = create('Extension') as latExt then { latItem.answer as lat -> latExt.url = 'latitude', latExt.value = (%lat.valueDecimal) then { geocodageItem.item as longItem where (linkId = '7651448032665') -> geolocationExt.extension = create('Extension') as longExt then { longItem.answer as long -> longExt.url = 'longitude', longExt.value = (%long.valueDecimal) "setLong"; } "createLongExt"; } "setLat"; } "createLatExt"; } "createGeolocExt"; // IRIS environnementItem.item as irisItem where (linkId = '7621032273792') -> addr.line as addrLine, addrLine.extension = create('Extension') as irisExt then { irisItem.answer as ans -> irisExt.url = 'http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-censusTract', irisExt.valueString = (%ans.valueString) "setIrisExt"; } "navIrisItem"; } "navEnv"; } "setaddress"; } "extractcodegeo"; } "extractpmsidemographics"; } "processsociodemographics"; } // Group: Create Locations from geocoding and IRIS data group CreateLocations(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) { // Extract geocoding data from linkId 4647259356106 > 5491974639955 > 3816475533472 src.item as socioDemo where (linkId = '4647259356106') then { socioDemo.item as environment where (linkId = '5491974639955') then { // Geocoding locations (repeating group 3816475533472) environment.item as geocodingItem where (linkId = '3816475533472') -> bundle.entry as locationEntry then { geocodingItem -> locationEntry.resource = create('Location') as location then { geocodingItem -> location.id = uuid() "locationid"; geocodingItem -> location.meta = create('Meta') as meta then { geocodingItem -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-location' "locationprofile"; } "locationmeta"; // Position with latitude and longitude geocodingItem -> location.position = create('LocationPosition') as pos then { // Latitude (linkId 3709843054556) geocodingItem.item as latItem where (linkId = '3709843054556') then { latItem.answer as ans -> pos.latitude = (%ans.valueDecimal) "setlatitude"; } "extractlatitude"; // Longitude (linkId 7651448032665) geocodingItem.item as longItem where (linkId = '7651448032665') then { longItem.answer as ans -> pos.longitude = (%ans.valueDecimal) "setlongitude"; } "extractlongitude"; } "setposition"; // Extension for collection date (linkId 1185653257776) // geocodingItem.item as dateItem where (linkId = '1185653257776') then { dateItem.answer as ans -> location.extension = create('Extension') as ext then { ans -> ext.url = 'http://hl7.org/fhir/StructureDefinition/data-collection-date' "date-url"; ans -> ext.value = (%ans.valueDate) "date-value"; } "set-collection-date"; } "extract-collection-date"; location -> locationEntry.request as request then { location -> request.method = 'POST' "setmethod"; location -> request.url = 'Location' "seturl"; } "setrequest"; location.id as locId -> locationEntry.fullUrl = append('urn:uuid:', locId) "setfullUrl"; } "createlocation"; } "geocodinglocationentry"; // IRIS locations (repeating item 7621032273792) environment.item as irisItem where (linkId = '7621032273792') then { irisItem.answer as irisAnswer -> bundle.entry as locationEntry then { irisAnswer -> locationEntry.resource = create('Location') as location then { irisAnswer -> location.id = uuid() "locationid"; irisAnswer -> location.meta = create('Meta') as meta then { irisAnswer -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-location' "locationprofile"; } "locationmeta"; // IRIS code as identifier irisAnswer -> location.identifier = create('Identifier') as identifier then { irisAnswer -> identifier.system = 'urn:oid:2.16.840.1.113883.2.8.1.5.5' "irissystem"; irisAnswer -> identifier.value = (%irisAnswer.valueCoding.code) "irisvalue"; } "setirisidentifier"; // Collection date from nested item (linkId 4999580038872) // irisAnswer.item as dateItem where (linkId = '4999580038872') then { dateItem.answer as ans -> location.extension = create('Extension') as ext then { ans -> ext.url = 'http://hl7.org/fhir/StructureDefinition/data-collection-date' "date-url"; ans -> ext.value = (%ans.valueDate) "date-value"; } "set-collection-date"; } "extract-iris-date"; location -> locationEntry.request as request then { location -> request.method = 'POST' "setmethod"; location -> request.url = 'Location' "seturl"; } "setrequest"; location.id as locId -> locationEntry.fullUrl = append('urn:uuid:', locId) "setfullUrl"; } "createirislocation"; } "irislocationentry"; } "processiris"; } "processenvironment"; } "processsociodemographicslocation"; } // Group: Create Encounters from PMSI data group CreateEncounters(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) { // PMSI data group (linkId 2825244231605) - Note: This can repeat in the structure src.item as pmsiItem where (linkId = '2825244231605') -> bundle.entry as encounterEntry then { pmsiItem -> encounterEntry.resource = create('Encounter') as encounter then { pmsiItem -> encounter.id = uuid() "encounterid"; pmsiItem -> encounter.meta = create('Meta') as meta then { pmsiItem -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-encounter' "encounterprofile"; } "encountermeta"; // status src -> encounter.status = 'finished' "setStatus"; // class src -> encounter.class = c('http://terminology.hl7.org/CodeSystem/v3-ActCode', 'IMP') "setClass"; // Link to patient src -> encounter.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject"; // Encounter period (start: 5991443718282, end: 6114780320846) pmsiItem -> encounter.period = create('Period') as period then { pmsiItem.item as startItem where (linkId = '5991443718282') then { startItem.answer as ans -> period.start = (%ans.valueDate) "setstart"; } "extractstart"; pmsiItem.item as endItem where (linkId = '6114780320846') then { endItem.answer as ans -> period.end = (%ans.valueDate) "setend"; } "extractend"; } "setperiod"; // Mode d'entrée (linkId 6172398101212) pmsiItem.item as modeInItem where (linkId = '6172398101212') then { modeInItem.answer as ans then { ans.valueString as valueString -> encounter.hospitalization as hosp, hosp.admitSource as admitSource, admitSource.coding as admitSourceCoding, admitSourceCoding.code = valueString "setadmitsource"; } "navValue"; } "extractmodein"; // Mode de sortie (linkId 3354867075704) pmsiItem.item as modeOutItem where (linkId = '3354867075704') then { modeOutItem.answer as ans then { ans.valueString as valueString -> encounter.hospitalization as hosp, hosp.dischargeDisposition as dischargeDisposition, dischargeDisposition.coding as dischargeDispositionCoding, dischargeDispositionCoding.code = valueString "setdischargedisposition"; } "navValue"; } "extractmodeout"; src -> encounter.id as encId, encounterEntry.fullUrl = append('urn:uuid:', encId) "setfullUrl"; // Create nested Conditions and Procedures pmsiItem then CreateConditions(pmsiItem, patient, encounter, bundle) "createconditions"; pmsiItem then CreateProcedures(pmsiItem, patient, encounter, bundle) "createprocedures"; } "createencounter"; } "encounterentry"; } // Group: Create Conditions from nested diagnostics group CreateConditions(source pmsiItem, target patient : Patient, target encounter : Encounter, target bundle : Bundle) { // Diagnostics group (linkId 9391816419630) - can repeat pmsiItem.item as diagGroup where (linkId = '9391816419630') -> bundle.entry as conditionEntry then { diagGroup -> conditionEntry.resource = create('Condition') as condition then { diagGroup -> condition.id = uuid() "conditionid"; diagGroup -> condition.meta = create('Meta') as meta then { diagGroup -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-condition' "conditionprofile"; } "conditionmeta"; // Link to patient diagGroup -> condition.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject"; // Link to encounter diagGroup -> encounter.id as encId, condition.encounter = create('Reference') as ref, ref.reference = append('Encounter/', encId) "setencounter"; // Diagnostic code (linkId 5505101189372) - CIM-10 diagGroup.item as diagCodeItem where (linkId = '5505101189372') then { diagCodeItem.answer as ans -> condition.code = create('CodeableConcept') as code then { ans -> code.coding as coding, coding.code = (%ans.valueString) "setcoding"; } "setcode"; } "extractdiagcode"; // Type de diagnostic (linkId 6427586743735) - DP/DAS/DR diagGroup.item as diagTypeItem where (linkId = '6427586743735') then { diagTypeItem.answer as ans -> condition.category = create('CodeableConcept') as category then { ans -> category.coding = create('Coding') as coding then { ans -> coding.system = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/CodeSystem/pmsi-mco-diag-type' "diagtypesystem"; ans -> coding.code = (%ans.valueString) "diagtypecode"; } "setcategorycoding"; } "setcategory"; } "extractdiagtype"; // Recorded date (linkId 7114466839467) diagGroup.item as dateItem where (linkId = '7114466839467') then { dateItem.answer as ans -> condition.recordedDate = (%ans.valueDate) "setrecordeddate"; } "extractrecordeddate"; // fullurl pmsiItem -> condition.id as condId, conditionEntry.fullUrl = append('urn:uuid:', condId) "setfullUrl"; } "createcondition"; } "conditionentry"; } // Group: Create Procedures from nested actes group CreateProcedures(source pmsiItem, target patient : Patient, target encounter : Encounter, target bundle : Bundle) { // Actes group (linkId 591926901726) - can repeat pmsiItem.item as acteGroup where (linkId = '591926901726') -> bundle.entry as procedureEntry then { acteGroup -> procedureEntry.resource = create('Procedure') as procedure then { acteGroup -> procedure.id = uuid() "procedureid"; acteGroup -> procedure.meta = create('Meta') as meta then { acteGroup -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-procedure' "procedureprofile"; } "proceduremeta"; // status acteGroup -> procedure.status = 'completed' "setStatus"; // Link to patient acteGroup -> procedure.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject"; // Link to encounter acteGroup -> encounter.id as encId, procedure.encounter = create('Reference') as ref, ref.reference = append('Encounter/', encId) "setencounter"; // Acte code (linkId 7758110033600) - CCAM acteGroup.item as acteCodeItem where (linkId = '7758110033600') then { acteCodeItem.answer as ans -> procedure.code = create('CodeableConcept') as code then { ans -> code.coding as coding, coding.code = (%ans.valueString) "setcoding"; } "setcode"; } "extractactecode"; // Date de l'acte (linkId 5066866286682) acteGroup.item as dateItem where (linkId = '5066866286682') then { dateItem.answer as ans -> procedure.performed = (%ans.valueDateTime) "setperformed"; } "extractperformeddate"; // fullurl pmsiItem -> procedure.id as procId, procedureEntry.fullUrl = append('urn:uuid:', procId) "setfullUrl"; } "createprocedure"; } "procedureentry"; } // Group: Create Medication Requests group CreateMedicationRequests(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) { // Exposition médicamenteuse (linkId 817801935685) src.item as medExpoGroup where (linkId = '817801935685') then { // Médicament prescrit (linkId 156631794800) - repeating medExpoGroup.item as prescribedGroup where (linkId = '156631794800') -> bundle.entry as medReqEntry then { prescribedGroup -> medReqEntry.resource = create('MedicationRequest') as medReq then { prescribedGroup -> medReq.id = uuid() "medreqid"; // fullurl src -> medReq.id as medReqId, medReqEntry.fullUrl = append('urn:uuid:', medReqId) "setfullUrl"; prescribedGroup -> medReq.meta = create('Meta') as meta then { prescribedGroup -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-medication-request' "medreqprofile"; } "medreqmeta"; // Link to patient prescribedGroup -> medReq.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject"; // Status and intent prescribedGroup -> medReq.status = 'active' "setstatus"; prescribedGroup -> medReq.intent = 'order' "setintent"; // MedicationCodeableConcept prescribedGroup.answer as prescribedMedication then { prescribedMedication.item as atcItem where (linkId = '1923143398283') then { atcItem.answer as ans -> medReq.medication = create('CodeableConcept') as medReqCC, medReqCC.coding as medReqC, medReqC.code = (%ans.valueString), medReqC.display = (%prescribedMedication.valueString) "setAtcCoding"; } "navAtcItem"; } "navPrescribedMedication"; // Create Medication resource and reference // prescribedGroup -> bundle.entry as medEntry then { prescribedGroup -> medEntry.resource = create('Medication') as medication then { prescribedGroup -> medication.id = uuid() "med-id"; // ATC code from nested items prescribedGroup.item as atcItem where (linkId.contains('ATC')) then { atcItem.answer as ans -> medication.code = create('CodeableConcept') as code then { ans -> code.coding = (%ans.valueCoding) "set-atc-coding"; } "set-med-code"; } "extract-atc"; prescribedGroup -> medication.id as medId, medEntry.fullUrl = append('urn:uuid:', medId) "set-fullUrl"; // Link MedicationRequest to Medication prescribedGroup -> medication.id as medId, medReq.medication = create('Reference') as ref, ref.reference = append('Medication/', medId) "set-medication-reference"; } "create-medication"; } "medication-entry"; // Dosage instructions prescribedGroup -> medReq.dosageInstruction = create('Dosage') as dosage then { // Route prescribedGroup.answer as prescribedMedication then { prescribedMedication.item as routeItem where (linkId = '387026794874') then { routeItem.answer as ans -> dosage.route as route then { ans -> route.coding as routeCoding, routeCoding.code = (%ans.valueString) "setroutecoding"; } "setroute"; } "navRouteItem"; } "navPrescribedMedication"; // Timing medExpoGroup.item as posoGroup where (linkId = '6348237104421') -> dosage.timing as timing, timing.repeat as timingRepeat, timingRepeat.boundsPeriod as timingPeriod then { posoGroup.item as DateDebItem where (linkId = '316347573327') then { DateDebItem.answer as ans -> timingPeriod.start = (%ans.valueDate) "setDateDeb"; } "navDateDeb"; posoGroup.item as DateFinItem where (linkId = '429570775935') then { DateFinItem.answer as ans -> timingPeriod.end = (%ans.valueDate) "setDateFin"; } "navDateFin"; } "navPoso"; } "setdosage"; } "createmedreq"; } "medreqentry"; } "processmedexpo"; } // Group: Create Medication Administrations group CreateMedicationAdministrations(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) { // Exposition médicamenteuse (linkId 817801935685) src.item as medExpoGroup where (linkId = '817801935685') then { // Médicament administré (linkId 266852453304) - repeating medExpoGroup.item as adminGroup where (linkId = '266852453304') -> bundle.entry as medAdminEntry then { adminGroup -> medAdminEntry.resource = create('MedicationAdministration') as medAdmin then { adminGroup -> medAdmin.id = uuid() "medadminid"; // fullurl src -> medAdmin.id as medAdminId, medAdminEntry.fullUrl = append('urn:uuid:', medAdminId) "setfullUrl"; adminGroup -> medAdmin.meta = create('Meta') as meta then { adminGroup -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-medication-administration' "medadminprofile"; } "medadminmeta"; // Link to patient adminGroup -> medAdmin.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject"; // Status adminGroup -> medAdmin.status = 'completed' "setstatus"; // MedicationCodeableConcept adminGroup.answer as administeredMedication then { administeredMedication.item as atcItem where (linkId = '631972144976') then { atcItem.answer as ans -> medAdmin.medication = create('CodeableConcept') as medAdminCC, medAdminCC.coding as medAdminC, medAdminC.code = (%ans.valueString), medAdminC.display = (%administeredMedication.valueString) "setAtcCoding"; } "navAtcItem"; } "navadministeredMedication"; // Create Medication resource and reference // adminGroup -> bundle.entry as medEntry then { adminGroup -> medEntry.resource = create('Medication') as medication then { adminGroup -> medication.id = uuid() "med-id"; // ATC code from nested items adminGroup.item as atcItem where (linkId.contains('ATC')) then { atcItem.answer as ans -> medication.code = create('CodeableConcept') as code then { ans -> code.coding = (%ans.valueCoding) "set-atc-coding"; } "set-med-code"; } "extract-atc"; adminGroup -> medication.id as medId, medEntry.fullUrl = append('Medication/', medId) "set-fullUrl"; // Link MedicationAdministration to Medication adminGroup -> medication.id as medId, medAdmin.medication = create('Reference') as ref, ref.reference = append('urn:uuid:', medId) "set-medication-reference"; } "create-medication"; } "medication-entry"; // Dosage (FHIR) adminGroup -> medAdmin.dosage as dosage then { // Route adminGroup.answer as administeredMedication then { administeredMedication.item as routeItem where (linkId = '811931484859') then { routeItem.answer as ans -> dosage.route = create('CodeableConcept') as route then { ans -> route.coding as routeCoding, routeCoding.code = (%ans.valueString) "setroutecoding"; } "setroute"; } "navRoute"; } "navadministeredMedication"; // Dosage (QR) medExpoGroup.item as doseGroup where (linkId = '5720103839343') then { // Dose doseGroup.item as quantityItem where (linkId = '4765772671997') then { quantityItem.answer as ans -> dosage.dose = (%ans.valueQuantity) "setDose"; } "navquantity"; // Effective period doseGroup.item as startItem where (linkId = '1443558617577') then { startItem.answer as startAns then { doseGroup.item as endItem where (linkId = '780829110731') then { endItem.answer as endAns -> medAdmin.effectivePeriod as adminPeriod, adminPeriod.start = (%startAns.value), adminPeriod.end = (%endAns.value) "setAdminPeriod"; } "navEnd"; } "navStartAns"; } "navStart"; } "navDosage"; } "setdosage"; } "createmedadmin"; } "medadminentry"; } "processmedexpoadmin"; } // Group: Create Vital Sign Observations group CreateVitalSignObservations(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) { // Examen clinique (linkId 214880328197) src.item as examGroup where (linkId = '214880328197') then { // Dossier de soins (linkId 305831246173) - repeating examGroup.item as dossierGroup where (linkId = '305831246173') then { // Height (linkId 4846902346416) dossierGroup.item as heightItem where (linkId = '4846902346416') then { heightItem.answer as ans -> bundle.entry as obsEntry then { ans -> obsEntry.resource = create('Observation') as obs then { ans -> obs.id = uuid() "obsid"; ans -> obs.id as obsId, obsEntry.fullUrl = append('urn:uuid:', obsId) "setfullUrl"; ans -> obs.meta = create('Meta') as meta then { ans -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-observation-body-height' "obsprofile"; } "obsmeta"; ans -> obs.status = 'final' "obsstatus"; ans -> obs.category = cc('http://terminology.hl7.org/CodeSystem/observation-category', 'vital-signs') "obscategory"; ans -> obs.code = cc('http://loinc.org', '8302-2', 'Body height') "obscode"; // Link to patient ans -> obs.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject"; // Value ans -> obs.value = (%ans.valueQuantity) as tgtObsVal, tgtObsVal.code = (%ans.valueQuantity.unit), tgtObsVal.system = 'http://unitsofmeasure.org' "setvalue"; // Effective date from nested item ans.item as dateItem where (linkId = '941821315470') then { dateItem.answer as dateAns then { dateAns.value as val -> obs.effective = cast(val, 'dateTime') "seteffective"; } "navDateAns"; } "extracteffective"; } "createheightobs"; } "heightobsentry"; } "extractheight"; // Weight (linkId 451513217936) dossierGroup.item as weightItem where (linkId = '451513217936') then { weightItem.answer as ans -> bundle.entry as obsEntry then { ans -> obsEntry.resource = create('Observation') as obs then { ans -> obs.id = uuid() "obsid"; ans -> obs.id as obsId, obsEntry.fullUrl = append('urn:uuid:', obsId) "setfullUrl"; ans -> obs.meta = create('Meta') as meta then { ans -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-observation-body-weight' "obsprofile"; } "obsmeta"; ans -> obs.status = 'final' "obsstatus"; ans -> obs.category = cc('http://terminology.hl7.org/CodeSystem/observation-category', 'vital-signs') "obscategory"; ans -> obs.code = cc('http://loinc.org', '29463-7', 'Body weight') "obscode"; // Link to patient ans -> obs.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject"; // Value ans -> obs.value = (%ans.valueQuantity) as tgtObsVal, tgtObsVal.code = (%ans.valueQuantity.unit), tgtObsVal.system = 'http://unitsofmeasure.org' "setvalue"; // Effective date from nested item ans.item as dateItem where (linkId = '151269044052') then { dateItem.answer as dateAns then { dateAns.value as val -> obs.effective = cast(val, 'dateTime') "seteffective"; } "navDateAns"; } "extracteffective"; } "createweightobs"; } "weightobsentry"; } "extractweight"; // Blood Pressure - need both systolic and diastolic dossierGroup.item as sysItem where (linkId = '4160905247955') then { sysItem.answer as sysAns then { dossierGroup.item as diaItem where (linkId = '848797127998') then { diaItem.answer as diaAns -> bundle.entry as obsEntry then { sysAns -> obsEntry.resource = create('Observation') as obs then { sysAns -> obs.id = uuid() "obsid"; sysAns -> obs.id as obsId, obsEntry.fullUrl = append('urn:uuid:', obsId) "setfullUrl"; sysAns -> obs.meta = create('Meta') as meta then { sysAns -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/edsh-observation-blood-pressure' "obsprofile"; } "obsmeta"; sysAns -> obs.status = 'final' "obsstatus"; sysAns -> obs.category = cc('http://terminology.hl7.org/CodeSystem/observation-category', 'vital-signs') "obscategory"; sysAns -> obs.code = cc('http://loinc.org', '85354-9', 'Blood pressure panel') "obscode"; // Link to patient sysAns -> obs.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject"; // Systolic component sysAns -> obs.component as sysComp then { sysAns -> sysComp.code = cc('http://loinc.org', '8480-6', 'Systolic blood pressure') "syscode"; sysAns -> sysComp.value = (%sysAns.valueQuantity) as sysVal, sysVal.code = (%sysAns.valueQuantity.unit), sysVal.system = 'http://unitsofmeasure.org' "sysvalue"; } "setsystolic"; // Diastolic component diaAns -> obs.component as diaComp then { diaAns -> diaComp.code = cc('http://loinc.org', '8462-4', 'Diastolic blood pressure') "diacode"; diaAns -> diaComp.value = (%diaAns.valueQuantity) as diaVal, diaVal.code = (%diaAns.valueQuantity.unit), diaVal.system = 'http://unitsofmeasure.org' "diavalue"; } "setdiastolic"; // Effective date from nested item sysAns.item as sysDateItem where (linkId = '987654638442') then { sysDateItem.answer as dateAns then { dateAns.value as val -> obs.effective = cast(val, 'dateTime') "seteffective"; } "navDateAns"; } "navDate"; } "createbpobs"; } "bpobsentr"; } "extractdiastolic"; } "processsystolic"; } "extractbloodpressure"; } "processdossier"; } "processexam"; } // Group: Create Laboratory Observations group CreateLaboratoryObservations(source src : QuestionnaireResponse, target patient : Patient, target bundle : Bundle) { // Biologie group (linkId 7702944131447) src.item as bioGroup where (linkId = '7702944131447') then { // Fonction rénale (linkId 5241323453538) bioGroup.item as renalGroup where (linkId = '5241323453538') then { // Urée (linkId 7169026818760) renalGroup.item as ureaItem where (linkId = '7169026818760') then { ureaItem.answer as ans -> bundle then CreateLabObservation(ans, ureaItem, patient, bundle) "createureaobs"; } "extracturea"; // Créatininémie (linkId 500408205043) renalGroup.item as creatItem where (linkId = '500408205043') then { creatItem.answer as ans -> bundle then CreateLabObservation(ans, creatItem, patient, bundle) "createcreatobs"; } "extractcreat"; // DFG (linkId 786621340679) renalGroup.item as dfgItem where (linkId = '786621340679') then { dfgItem.answer as ans -> bundle then CreateLabObservation(ans, dfgItem, patient, bundle) "createdfgobs"; } "extractdfg"; } "processrenal"; // Hémogramme (linkId 419282985970) bioGroup.item as hemoGroup where (linkId = '419282985970') then { // Leucocytes (linkId 210077225604) hemoGroup.item as leukoItem where (linkId = '210077225604') then { leukoItem.answer as ans -> bundle then CreateLabObservation(ans, leukoItem, patient, bundle) "createleukoobs"; } "extractleuko"; // Hémoglobine (linkId 304159088493) hemoGroup.item as hemoItem where (linkId = '304159088493') then { hemoItem.answer as ans -> bundle then CreateLabObservation(ans, hemoItem, patient, bundle) "createhemoobs"; } "extracthemo"; // Hématocrite (linkId 813863316705) hemoGroup.item as hematItem where (linkId = '813863316705') then { hematItem.answer as ans -> bundle then CreateLabObservation(ans, hematItem, patient, bundle) "createhematobs"; } "extracthemat"; // Erythrocytes (linkId 459731866614) hemoGroup.item as eryItem where (linkId = '459731866614') then { eryItem.answer as ans -> bundle then CreateLabObservation(ans, eryItem, patient, bundle) "createeryobs"; } "extractery"; // VGM (linkId 163624088831) hemoGroup.item as vgmItem where (linkId = '163624088831') then { vgmItem.answer as ans -> bundle then CreateLabObservation(ans, vgmItem, patient, bundle) "createvgmobs"; } "extractvgm"; // Plaquettes (linkId 794156787471) hemoGroup.item as platItem where (linkId = '794156787471') then { platItem.answer as ans -> bundle then CreateLabObservation(ans, platItem, patient, bundle) "createplatobs"; } "extractplat"; // Neutrophiles (linkId 961905168477) hemoGroup.item as neutItem where (linkId = '961905168477') then { neutItem.answer as ans -> bundle then CreateLabObservation(ans, neutItem, patient, bundle) "createneutobs"; } "extractneut"; // Lymphocytes (linkId 695150914696) hemoGroup.item as lymphItem where (linkId = '695150914696') then { lymphItem.answer as ans -> bundle then CreateLabObservation(ans, lymphItem, patient, bundle) "createlymphobs"; } "extractlymph"; // Eosinophiles (linkId 700490326748) hemoGroup.item as eosiItem where (linkId = '700490326748') then { eosiItem.answer as ans -> bundle then CreateLabObservation(ans, eosiItem, patient, bundle) "createeosiobs"; } "extracteosi"; // Monocytes (linkId 168661900522) hemoGroup.item as monoItem where (linkId = '168661900522') then { monoItem.answer as ans -> bundle then CreateLabObservation(ans, monoItem, patient, bundle) "createmonoobs"; } "extractmono"; // TP (linkId 658898841893) hemoGroup.item as tpItem where (linkId = '658898841893') then { tpItem.answer as ans -> bundle then CreateLabObservation(ans, tpItem, patient, bundle) "createtpobs"; } "extracttp"; // TCA (linkId 795145096241) hemoGroup.item as tcaItem where (linkId = '795145096241') then { tcaItem.answer as ans -> bundle then CreateLabObservation(ans, tcaItem, patient, bundle) "createtcaobs"; } "extracttca"; } "processhemo"; // Bilan hépatique (linkId 796308115381) bioGroup.item as liverGroup where (linkId = '796308115381') then { // ASAT (linkId 715226319725) liverGroup.item as asatItem where (linkId = '715226319725') then { asatItem.answer as ans -> bundle then CreateLabObservation(ans, asatItem, patient, bundle) "createasatobs"; } "extractasat"; // ALAT (linkId 876439410327) liverGroup.item as alatItem where (linkId = '876439410327') then { alatItem.answer as ans -> bundle then CreateLabObservation(ans, alatItem, patient, bundle) "createalatobs"; } "extractalat"; // GGT (linkId 287545455976) liverGroup.item as ggtItem where (linkId = '287545455976') then { ggtItem.answer as ans -> bundle then CreateLabObservation(ans, ggtItem, patient, bundle) "createggtobs"; } "extractggt"; // PAL (linkId 508269571594) liverGroup.item as palItem where (linkId = '508269571594') then { palItem.answer as ans -> bundle then CreateLabObservation(ans, palItem, patient, bundle) "createpalobs"; } "extractpal"; // Bilirubine totale (linkId 927344090061) liverGroup.item as bilTotItem where (linkId = '927344090061') then { bilTotItem.answer as ans -> bundle then CreateLabObservation(ans, bilTotItem, patient, bundle) "createbiltotobs"; } "extractbiltot"; // Bilirubine conjuguée (linkId 208196328453) liverGroup.item as bilConjItem where (linkId = '208196328453') then { bilConjItem.answer as ans -> bundle then CreateLabObservation(ans, bilConjItem, patient, bundle) "createbilconjobs"; } "extractbilconj"; } "processliver"; // Métabolisme glucidique (linkId 334039497382) bioGroup.item as glucoseGroup where (linkId = '334039497382') then { // Glycémie à jeun (linkId 273778921448) glucoseGroup.item as glycItem where (linkId = '273778921448') then { glycItem.answer as ans -> bundle then CreateLabObservation(ans, glycItem, patient, bundle) "createglycobs"; } "extractglyc"; // HbA1c (linkId 632894677152) glucoseGroup.item as hba1cItem where (linkId = '632894677152') then { hba1cItem.answer as ans -> bundle then CreateLabObservation(ans, hba1cItem, patient, bundle) "createhba1cobs"; } "extracthba1c"; } "processglucose"; } "processbiology"; } // Helper: Create a single Laboratory Observation group CreateLabObservation(source ans, source parentItem, target patient : Patient, target bundle : Bundle) { ans -> bundle.entry as obsEntry then { ans -> obsEntry.resource = create('Observation') as obs then { ans -> obs.id = uuid() "obsid"; ans -> obs.id as obsId, obsEntry.fullUrl = append('urn:uuid:', obsId) "setfullUrl"; ans -> obs.meta = create('Meta') as meta then { ans -> meta.profile = 'https://aphp.github.io/IG-FHIR-EDSH-SOCLE-COMMUN/StructureDefinition/dm-observation-laboratory-generic' "obsprofile"; } "obsmeta"; // Status ans -> obs.status = 'final' "obsstatus"; // Category ans -> obs.category = create('CodeableConcept') as cat then { ans -> cat.coding = create('Coding') as coding then { ans -> coding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catsystem"; ans -> coding.code = 'laboratory' "catcode"; } "setcategorycoding"; } "setcategory"; // Link to patient ans -> obs.subject = create('Reference') as ref, patient.id as patId, ref.reference = append('Patient/', patId) "setsubject"; // Value as Quantity ans -> obs.value = (%ans.valueQuantity) as tgtObsVal, tgtObsVal.code = (%ans.valueQuantity.unit), tgtObsVal.system = 'http://unitsofmeasure.org' "setvalue"; // Extract nested items - LOINC code, effective date, status, reference ranges // LOINC code ans.item as loincItem where (text.contains('code loinc')) then { loincItem.answer as loincAns -> obs.code as code, code.coding as coding, coding.code = (%loincAns.valueString) "setloinccoding"; } "extractloinc"; // effectiveDateTime ans.item as dateItem where (text.contains('Date et heure du prélèvement')) then { dateItem.answer as dateAns -> obs.effective = (%dateAns.valueDateTime) "seteffective"; } "extracteffective"; // parentItem.item as statusItem where (linkId.contains('Statut de validation')) then { statusItem.answer as statusAns -> obs.extension = create('Extension') as ext then { statusAns -> ext.url = 'http://hl7.org/fhir/StructureDefinition/observation-status' "status-url"; statusAns -> ext.value = (%statusAns.valueString) "status-value"; } "set-status-ext"; } "extract-validation-status"; // Reference ranges (low and high) ans -> obs.referenceRange as refRange then { ans.item as lowItem where (text.contains('Borne inférieure')) then { lowItem.answer as lowAns -> refRange.low = (%lowAns.valueQuantity) as tgtLow, tgtLow.code = (%ans.valueQuantity.unit), tgtLow.system = 'http://unitsofmeasure.org' "setlow"; } "extractlow"; ans.item as highItem where (text.contains('Borne supérieure')) then { highItem.answer as highAns -> refRange.high = (%highAns.valueQuantity) as tgtHigh, tgtHigh.code = (%ans.valueQuantity.unit), tgtHigh.system = 'http://unitsofmeasure.org' "sethigh"; } "extracthigh"; } "setrefrange"; } "createobs"; } "obsentry"; }