import type { Observation } from 'fhir/r4'; const INTERPRETATION_SYSTEM = 'http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation'; export const INTERPRETATIONS: { code: string; display: string }[] = [ { code: 'N', display: 'Normal' }, { code: 'L', display: 'Low' }, { code: 'H', display: 'High' }, { code: 'LL', display: 'Critically low' }, { code: 'HH', display: 'Critically high' }, { code: 'A', display: 'Abnormal' }, ]; export const interpretationLabel = (observation: Observation): string => { const first = observation.interpretation?.[0]; return first?.text ?? first?.coding?.[0]?.display ?? first?.coding?.[0]?.code ?? ''; }; export const valueChanges = (observation: Observation, typed: string): boolean => { const value = String(typed ?? '').trim(); if (!value) return false; if (observation.valueQuantity) { const number = Number(value); return Number.isFinite(number) && number !== observation.valueQuantity.value; } return value !== (observation.valueString ?? ''); }; // A correction that changes a report's number has to change the Observation that holds it, and the old // reading of that number ("in your usual range") must be restated, never carried onto the new value. // `interpretation` is a code, '' for none, or undefined when it has not been restated yet. export const correctedMeasurement = (observation: Observation, typed: string, interpretation: string | undefined): Observation | undefined => { if (!valueChanges(observation, typed) || interpretation === undefined) return undefined; const value = String(typed).trim(); const { interpretation: _stale, ...rest } = observation; const reading = INTERPRETATIONS.find((i) => i.code === interpretation); return { ...rest, status: 'corrected', ...(observation.valueQuantity ? { valueQuantity: { ...observation.valueQuantity, value: Number(value) } } : { valueString: value }), ...(reading && { interpretation: [{ coding: [{ system: INTERPRETATION_SYSTEM, code: reading.code, display: reading.display }] }] }), }; };