Skip to content
This repository is currently being migrated. It's locked while the migration is in progress.
Merged
76 changes: 73 additions & 3 deletions lib/unified_health_data/adapters/lab_or_test_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,64 @@ def initialize(mr_log: nil)
'LP29684-5' => 'Radiology'
}.freeze

#
# Interpretation code map based on https://terminology.hl7.org/3.1.0/CodeSystem-v3-ObservationInterpretation.html
#

INTERPRETATION_MAP = {
'CAR' => 'Carrier',
'CARRIER' => 'Carrier',
'<' => 'Off scale low',
'>' => 'Off scale high',
'A' => 'Abnormal',
'AA' => 'Critical abnormal',
'AC' => 'Anti-complementary substances present',
'B' => 'Better',
'D' => 'Significant change down',
'DET' => 'Detected',
'E' => 'Equivocal',
'EX' => 'Outside threshold',
'EXP' => 'Expected',
'H' => 'High',
'H*' => 'Critical high',
'HH' => 'Critical high',
'HU' => 'Significantly high',
'H>' => 'Significantly high',
'HM' => 'Hold for Medical Review',
'HX' => 'Above high threshold',
'I' => 'Intermediate',
'IE' => 'Insufficient evidence',
'IND' => 'Indeterminate',
'L' => 'Low',
'L*' => 'Critical low',
'LL' => 'Critical low',
'LU' => 'Significantly low',
'L<' => 'Significantly low',
'LX' => 'Below low threshold',
'MS' => 'Moderately susceptible',
'N' => 'Normal',
'NCL' => 'No CLSI defined breakpoint',
'ND' => 'Not detected',
'NEG' => 'Negative',
'NR' => 'Non-reactive',
'NS' => 'Non-susceptible',
'OBX' => 'Interpretation qualifiers in separate OBX segments',
'POS' => 'Positive',
'QCF' => 'Quality control failure',
'R' => 'Resistant',
'RR' => 'Reactive',
'S' => 'Susceptible',
'SDD' => 'Susceptible-dose dependent',
'SYN-R' => 'Synergy - resistant',
'SYN-S' => 'Synergy - susceptible',
'TOX' => 'Cytotoxic substance present',
'U' => 'Significant change up',
'UNE' => 'Unexpected',
'VS' => 'Very susceptible',
'W' => 'Worse',
'WR' => 'Weakly reactive'
}.freeze

def parse_labs(records)
return [] if records.blank?

Expand Down Expand Up @@ -466,17 +524,29 @@ def extract_interpretation(obs)
return nil if interpretations.blank?

fallback_text = nil
fallback_code = nil

interpretations.each do |interp|
if interp['coding'].present?
hl7_coding = interp['coding'].find do |coding|
coding['system']&.include?('v3-ObservationInterpretation') && coding['code'].present?
end
return hl7_coding['code'] if hl7_coding
if hl7_coding
# Priority 1: Mapped human-friendly display from INTERPRETATION_MAP
mapped = INTERPRETATION_MAP[hl7_coding['code']]
return mapped if mapped.present?

# Capture raw code as absolute last resort fallback
fallback_code ||= hl7_coding['code']
end
Comment thread
liztownd marked this conversation as resolved.
end
fallback_text ||= interp['text'] if interp['text'].present?

# Priority 2: text or coding.display from the CodeableConcept
fallback_text ||= extract_codeable_concept_display(interp)
end
Comment thread
liztownd marked this conversation as resolved.

fallback_text
# Prefer human-readable text/display over raw code
fallback_text || fallback_code
end

def format_observation_value(obs)
Expand Down
165 changes: 137 additions & 28 deletions modules/mobile/docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -28526,7 +28526,7 @@
"properties": {
"type": {
"type": "string",
"example": "labsAndTests"
"example": "DiagnosticReport"
},
"id": {
"type": "string",
Expand All @@ -28537,49 +28537,158 @@
"type": "object",
"additionalProperties": false,
"required": [
"category",
"subject",
"effectiveDateTime",
"issued",
"code",
"display",
"testCode",
"status"
Comment thread
liztownd marked this conversation as resolved.
],
"properties": {
"category": {
"display": {
"type": "string",
"example": "LAB"
"description": "User-friendly display name for the lab or test",
"example": "CHEM 7"
},
"subject": {
"testCode": {
"type": "string",
"example": "Patient/1234567"
"description": "HL7 v2-0074 diagnostic service section code or LOINC code",
"example": "CH"
},
"effectiveDateTime": {
"testCodeDisplay": {
"type": "string",
"format": "date-time",
"example": "2021-01-01T00:00:00Z"
"nullable": true,
"description": "Human-readable display name for the test code",
"example": "Chemistry and hematology"
},
"issued": {
"dateCompleted": {
"type": "string",
"format": "date-time",
"example": "2021-01-01T00:00:00Z"
"nullable": true,
"description": "Date/time the test was completed, in facility local time when available",
"example": "2025-01-23T15:01:52-07:00"
},
"code": {
"type": "object",
"properties": {
"coding": {
"type": "array",
"items": {
"type": "object"
}
},
"text": {
"type": "string"
}
"sampleTested": {
"type": "string",
"nullable": true,
"description": "Specimen type used for the test",
"example": "BLOOD"
},
"encodedData": {
"type": "string",
"nullable": true,
"description": "Base64-encoded presentedForm data (e.g., radiology report text)",
"example": ""
},
"location": {
"type": "string",
"nullable": true,
"description": "Name of the performing organization or location",
"example": "CHYSHR TEST LAB"
},
"orderedBy": {
"type": "string",
"nullable": true,
"description": "Name of the ordering practitioner",
"example": "John Doe"
},
"bodySite": {
"type": "string",
"nullable": true,
"description": "Body site related to the test, if applicable",
"example": "Left arm"
},
"comments": {
"type": "array",
"nullable": true,
"description": "Comments from the DiagnosticReport or ServiceRequest",
"items": {
"type": "string"
}
},
"status": {
"type": "string",
"description": "FHIR status of the DiagnosticReport",
"example": "final"
},
"source": {
"type": "string",
"nullable": true,
"description": "Data source identifier (e.g., vista or oracle-health)",
"example": "vista"
},
"facilityTimezone": {
"type": "string",
"nullable": true,
"description": "IANA timezone ID for the facility where the test was performed",
"example": "America/Denver"
},
"observations": {
"type": "array",
"nullable": true,
"description": "Individual test result observations within this report",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"testCode": {
"type": "string",
"description": "Name of the individual observation test",
"example": "GLUCOSE"
},
"value": {
"type": "object",
"nullable": true,
"description": "The observation result value",
"properties": {
"text": {
"type": "string",
"nullable": true,
"description": "Formatted value text",
"example": "99.0 mg/dL"
},
"type": {
"type": "string",
"nullable": true,
"description": "Value type (quantity, codeable-concept, string, date-time)",
"example": "quantity"
}
}
},
"referenceRange": {
"type": "string",
"nullable": true,
"description": "Reference range for the observation",
"example": "70 - 110 mg/dL"
},
"status": {
"type": "string",
"description": "FHIR status of the observation",
"example": "final"
},
"interpretation": {
"type": "string",
"nullable": true,
"description": "Human-readable interpretation display string mapped from HL7 v3 ObservationInterpretation codes (e.g., High, Low, Critical high). Falls back to CodeableConcept text or coding display if code is unmapped.",
"example": "High"
},
"comments": {
"type": "array",
"description": "Notes attached to the observation",
"items": {
"type": "string"
}
},
"bodySite": {
"type": "string",
"nullable": true,
"description": "Body site for the observation",
"example": ""
},
"sampleTested": {
"type": "string",
"nullable": true,
"description": "Specimen type for the observation",
"example": ""
}
}
}
}
}
}
Expand Down
Loading
Loading