From 1d2707bfcda83a12d187a892c81fff18a8cd33c1 Mon Sep 17 00:00:00 2001 From: James Gilmore <109554461+GilmoreA6@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:26:12 -0700 Subject: [PATCH] create documentation for hl7-fhir transforms (#15670) * create documentation for hl7-fhir transforms * update documentation for hl7-fhir transforms * update documentation formatting for hl7-fhir transforms * update documentation for null vs empty --- .../fhir-to-hl7-transforms.md | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 prime-router/docs/onboarding-users/fhir-to-hl7-transforms.md diff --git a/prime-router/docs/onboarding-users/fhir-to-hl7-transforms.md b/prime-router/docs/onboarding-users/fhir-to-hl7-transforms.md new file mode 100644 index 00000000000..9d22507f9ef --- /dev/null +++ b/prime-router/docs/onboarding-users/fhir-to-hl7-transforms.md @@ -0,0 +1,180 @@ +This file documents the types of transforms currently being used by Engagement. This document does not recommend any particular method of acheiving the needed transformations or purport to show best practices. This is simply to document how things have been accomplished so far. + +## Types of FHIR->HL7 transforms currently used + +Default value in field - Default a static value into a single field or subfield +```yaml + - name: ak-receiving-application + value: [ '"AKDOH"' ] + hl7Spec: [ 'MSH-5-1' ] +``` + +Replace value in single field/subfield with empty string +```yaml + - name: ak-ordering-provider-id-number + value: [ '""' ] + hl7Spec: [ '/PATIENT_RESULT/ORDER_OBSERVATION/OBR-16-1' ] +``` + +Replace value in multiple fields/subfields with empty string +```yaml + - name: remove-hl7-fields + value: [ '""' ] + hl7Spec: [ 'MSH-19-1' , 'MSH-19-2' , 'MSH-19-3' , '%{ORC}-2-1' , '%{ORC}-2-2' , '%{ORC}-2-3' , '%{ORC}-2-4' , '%{ORC}-4-1' , '%{ORC}-4-2' , '%{ORC}-4-3' , '%{ORC}-4-4' , '%{OBR}-2-1' , '%{OBR}-2-2' , '%{OBR}-2-3' , '%{OBR}-2-4' ] +``` + +Modify value - Change the format of a value in a single field or subfield +```yaml +- name: obx-value-dtm-dt + condition: '%context.extension(%`rsext-obx-observation`).extension.where(url = "OBX.2").value = "DT"' + value: [ '%resource.value.extension(%`rsext-hl7v2-date-time`).value.toString().replace("-","")' ] + hl7Spec: [ '%{hl7OBXField}-5' ] +``` + +Modify value based on valueset - Correlate a set of values to another set of values +```yaml + - name: ak-patient-ethnicity-identifier-code + value: + - 'Bundle.entry.resource.ofType(Patient).extension(%`rsext-ethnic-group`).value.coding[0].code' + hl7Spec: [ '/PATIENT_RESULT/PATIENT/PID-22-1' ] + valueSet: + values: + H: 2135-2 + N: 2186-5 +``` + +Use customFhirFunction to correlate FHir valuesets with HL7 valuesets +```yaml + - name: ak-patient-race-coding-system + resource: 'Bundle.entry.resource.ofType(Patient).extension("http://ibm.com/fhir/cdm/StructureDefinition/local-race-cd").value.coding' + condition: '%resource.code.exists()' + value: [ '%resource.system.getCodingSystemMapping()' ] + hl7Spec: [ '/PATIENT_RESULT/PATIENT/PID-10-3' ] +``` + +Override base mappings to prevent certain segments/fields from being mapped to outbound HL7 +```yaml + - name: obx-equipment-instance-identifier + condition: 'false' +``` + +Override base mappings to prevent a field in specific datatype from being mapped to outbound hl7 +```yaml + - name: xtn-extension-value + resource: '%resource.extension(%`rsext-xtn-contact-point`)' + schema: classpath:/metadata/hl7_mapping/receivers/Common/remove-xtn-1/XTNExtension.yml +``` +```yaml +elements: + + - name: xtn-2-telecom-use-code + value: [ '%resource.extension("XTN.2").value' ] + hl7Spec: [ '%{hl7TelecomPath}-2' ] + + - name: xtn-3-telecom-equipment-type + value: [ '%resource.extension("XTN.3").value' ] + hl7Spec: [ '%{hl7TelecomPath}-3' ] + + - name: xtn-4-communication-address + value: [ '%resource.extension("XTN.4").value' ] + hl7Spec: [ '%{hl7TelecomPath}-4' ] + + - name: xtn-7-local-number + value: [ '%resource.extension("XTN.7").value' ] + hl7Spec: [ '%{hl7TelecomPath}-7' ] + + - name: xtn-9-any-text + value: [ '%resource.extension("XTN.9").value' ] + hl7Spec: [ '%{hl7TelecomPath}-9' ] + + - name: xtn-12-unformatted-telephone-number + value: [ '%resource.extension("XTN.12").value' ] + hl7Spec: [ '%{hl7TelecomPath}-12' ] +``` + +Override base mappings to create segments/fields in a specific format/ordering +```yaml + - name: ca-order-observations + resource: 'Bundle.entry.resource.ofType(DiagnosticReport)' + condition: '%resource.count() > 0' + schema: classpath:/metadata/hl7_mapping/receivers/STLTs/CA/ca-order-observation.yml + resourceIndex: orderIndex +``` +```yaml +constants: + hl7Order: '/PATIENT_RESULT/ORDER_OBSERVATION(%{orderIndex})' + diagnostic: 'Bundle.entry.resource.ofType(DiagnosticReport)[%orderIndex]' + service: 'Bundle.entry.resource.ofType(DiagnosticReport)[%orderIndex].basedOn.resolve()' + specimen: 'Bundle.entry.resource.ofType(DiagnosticReport)[%orderIndex].specimen.resolve()' +elements: + - name: ca-observation-result + resource: '%resource.result.resolve()' + schema: classpath:/metadata/hl7_mapping/receivers/STLTs/CA/ca-observation-result.yml + resourceIndex: resultIndex +``` +```yaml +constants: + hl7ObservationPath: '/PATIENT_RESULT/ORDER_OBSERVATION(%{orderIndex})/OBSERVATION(%{resultIndex})' + rsext: '"https://reportstream.cdc.gov/fhir/StructureDefinition/"' + observation: '%diagnostic.result[%resultIndex].resolve()' +elements: + + # California requirement: Move all regular notes and AOE questions between last OBX segment and SPM + # as NTE segments + # To do that we have to compare the Observation index against the Observation count + # to make sure is the last OBX segment and only add notes and AOE questions to that segment + - name: ca-order-observation-note + resource: '%diagnostic.result.resolve().note.text.split(''\n'') | %service.note.text.split(''\n'') | %service.supportingInfo.resolve()' + condition: >- + (Bundle.entry.resource.ofType(Observation).note.exists() or %service.note.exists() or %service.supportingInfo.exists()) + and (%diagnostic.result.count() - 1) = %resultIndex + schema: classpath:/metadata/hl7_mapping/receivers/STLTs/CA/ca-order-note.yml + resourceIndex: noteIndex + constants: + hl7NotePath: '%{hl7ObservationPath}' +``` +```yaml +elements: + - name: aoe-note + condition: '%resource is Observation' + schema: classpath:/metadata/hl7_mapping/receivers/STLTs/CA/ca-aoe-note.yml + + - name: note + condition: '%resource is string' + schema: classpath:/metadata/hl7_mapping/datatypes/annotation/NTE.yml + constants: + noteDetails: '%resource.note' +``` +```yaml +constants: + caAoeNteFieldPath: '%{hl7NotePath}/NTE(%{noteIndex})' + commentCondition: '%resource.code.coding.code.exists() and %resource.code.text.exists()' +elements: + - name: aoe-note-id + value: [ '%noteIndex + 1' ] + hl7Spec: [ '%{caAoeNteFieldPath}-1' ] + + - name: aoe-note-source + value: + - '"L"' + hl7Spec: [ '%{caAoeNteFieldPath}-2' ] + + - name: aoe-note-comment-datetime + condition: '%resource.value.exists() and %resource.value is dateTime and %commentCondition' + value: [ '%resource.code.coding.code + " " + %resource.code.text + ": " + %resource.value.toString()' ] + hl7Spec: [ '%{caAoeNteFieldPath}-3' ] + + - name: aoe-note-comment-string + condition: '%resource.value.exists() and %resource.value is string and %commentCondition' + value: [ '%resource.code.coding.code + " " + %resource.code.text + ": " + %resource.value' ] + hl7Spec: [ '%{caAoeNteFieldPath}-3' ] + + - name: aoe-note-comment-cwe + condition: '%resource.value.exists() and %resource.value is CodeableConcept and %commentCondition' + value: [ '%resource.code.coding.code + + " " + %resource.code.text + + ": " + %resource.value.coding.display + + " " + %resource.value.coding.code + + " " + %resource.value.coding.system.getCodingSystemMapping()' ] + hl7Spec: [ '%{caAoeNteFieldPath}-3' ] +```