/** * A READING THAT IS A PAIR, AND THE ONE OBSERVATION THIS PRODUCT DECLARES AS ONE. * * `master-system-overview.md` ยง11 says a proposal opens **the real form** condensed. The real * observation form already handles a paired reading - it edits `Observation.component` behind its own * tab - so a condensed form that cannot hold a pair is the condensing losing a shape the real form has, * not a design question anybody still owes an answer to. * * WHY THIS IS STATED RATHER THAN DERIVED. The field catalogue is generated from the forms precisely so * a description of them cannot drift, and it reads flat controls; `component` is a field array behind a * tab and the generator's own rule is that an unrecognised shape STOPS it rather than being guessed at. * So the pair is declared here, in the same spirit as the two other stated facts on this path - the * field whose one line of text is a backbone element's `text`, and the one that is a number. * * AND THE CODES ARE NOT INVENTED HERE. `vitalsCatalog.ts` already builds a blood pressure as a panel of * two components, and this says the same thing in the shape the condensed form needs. * `aPairedReadingIsDeclaredTheSameWayTwice` compares the two and fails if they drift, because a fact * kept in two places drifts unless something checks it. */ const LOINC = 'http://loinc.org'; const UCUM = 'http://unitsofmeasure.org'; export interface PairedObservation { /** The panel's own code - what the observation as a whole IS. */ panel: { system: string; code: string; display: string }; /** The two halves, in the order a clinician says them. */ halves: { label: string; system: string; code: string; display: string }[]; /** Both halves share one unit; a pair measured in two different units is not one of these. */ unit: { system: string; code: string; display: string }; } export const BLOOD_PRESSURE: PairedObservation = { panel: { system: LOINC, code: '85354-9', display: 'Blood pressure panel' }, halves: [ { label: 'Systolic', system: LOINC, code: '8480-6', display: 'Systolic blood pressure' }, { label: 'Diastolic', system: LOINC, code: '8462-4', display: 'Diastolic blood pressure' }, ], unit: { system: UCUM, code: 'mm[Hg]', display: 'mmHg' }, }; /** * Is this reading two numbers with a slash between them? * * DELIBERATELY NOT "is this a blood pressure". The note says `128/78 mmHg` and the shape is what the * form has to cope with; which observation it belongs to is decided by the coded field the clinician * confirms, never by guessing from the number. */ export const readPair = (text: unknown): { systolic: number; diastolic: number } | undefined => { if (typeof text !== 'string') return undefined; const matched = /^\s*(\d+(?:\.\d+)?)\s*\/\s*(\d+(?:\.\d+)?)\b/.exec(text); if (!matched) return undefined; const systolic = Number(matched[1]); const diastolic = Number(matched[2]); return Number.isFinite(systolic) && Number.isFinite(diastolic) ? { systolic, diastolic } : undefined; }; /** * The two halves as the observation transform takes them. * * `valueType` is set per component for the same reason it is set on the observation itself: every value * arm in that transform is gated on it, and a component without one carries a code and no reading. */ export const pairedComponents = ( pair: { systolic: number; diastolic: number }, paired: PairedObservation = BLOOD_PRESSURE, ): unknown[] => { /* ONLY THE THREE FIELDS A CODING HAS. `label` is this module's own - it names the input a clinician types into - and handing the whole half to the transform put it inside the coding. WALKED AND FOUND, 2026-09-14: the components were right in every other respect and the write was refused outright - `Unrecognised property '@label'` at `Observation.component[0].code.coding[0]`, twice, one per half. A shape that is correct except for one extra key is not partially correct; it is a 400, and everything that looked right about it made the cause harder to see rather than easier. */ const coding = (half: PairedObservation['halves'][number]) => ({ system: half.system, code: half.code, display: half.display }); return [ { code: coding(paired.halves[0]), valueType: 'quantity', valueQuantity: { value: pair.systolic, unit: paired.unit } }, { code: coding(paired.halves[1]), valueType: 'quantity', valueQuantity: { value: pair.diastolic, unit: paired.unit } }, ]; };