Healthy Route Implementation Guide
0.1.0 - ci-build
Healthy Route Implementation Guide, published by Savannah Informatics. This guide is not an authorized publication; it is the continuous build for version 0.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/savannahghi/healthy-route-ig/ and changes regularly. See the Directory of published versions
The screening visit, and everything measured during it.
The protocols describe a single cross-sectional contact. A participant attending a routine clinic is approached, consented, interviewed, has three blood pressure readings taken, gives a urine sample for dipstick, gives blood and urine for the laboratory, and has both eyes photographed. There is no follow-up visit and no admission.
HREncounter is the spine everything else
hangs from. Observation, ServiceRequest, DiagnosticReport and
ImagingStudy all require one, because a result that cannot be placed at a visit
cannot be placed against the consent that was in force, or against the clinic the
participant was recruited from.
The clinic matters. Both protocols recruit from general out-patient, hypertension,
diabetes and renal clinics, and a cohort drawn mostly from a renal clinic has a
different disease prevalence from one drawn mostly from general out-patients.
Predictive values move with prevalence, so Encounter.location is where an
analysis finds out which population it is actually looking at.
HRObservation carries creatinine, eGFR, HbA1c, the urine albumin-to-creatinine ratio, the urine dipstick, height, weight, body mass index, and the additional investigations one country collects.
They differ in code, unit and value type. They do not differ in shape, and a
profile for each analyte would mean a new StructureDefinition and a new release
of this guide every time a laboratory adds a test. What distinguishes one
measurement from another is Observation.code, which is what a consumer filters
on.
The rule this follows: profile where the datatype alone does not constrain the
value; do not where it does. A creatinine is a Quantity with a UCUM unit and
the datatype has already done the work.
Blood pressure puts its two readings in component rather than in value[x].
FHIR core already profiles that as
http://hl7.org/fhir/StructureDefinition/bp,
with the components sliced, their LOINC codes fixed and their units fixed to
mmHg. HRBloodPressure derives from
it and adds only tenancy and the encounter requirement.
FHIR is single-inheritance, so the tenant extension is restated there rather than
inherited from HRObservation. Three lines of duplication is a better trade than
reimplementing a profile HL7 maintains.
This is where the two protocols visibly differ, and where the guide's architecture was tested.
One times three readings around the retinal photography — sixty minutes before, fifteen minutes either side, sixty minutes after — and averages them. The other takes a triplicate after five minutes of rest and uses the mean of the last two, discarding the first.
Those are different procedures, not different thresholds. They are nevertheless instance data, because of how the readings are modelled:
HRBloodPressure, with its own effectiveDateTimederivedFrom
names the readings it actually usedThree readings and their mean are four resources, not one resource with four
values. What differs between countries is which readings derivedFrom points at,
and that is data. The averaging rule itself belongs to the study, not to the
resource — so the profile deliberately does not encode it, and a consumer can
check the arithmetic instead of trusting it.
HRDipstickProteinVS lists Negative, Trace, +1, +2 and +3.
It is not bound to HRObservation.value[x], and that is deliberate. The scale is
printed on the protocols' own data collection tool as fixed options, so values
reach the record by transcription from a form. The constraint that matters is on
the entry screen, not on a StructureDefinition. LOINC publishes an answer list for
5804-0, but it is not expandable on the public terminology server, so a binding
would have meant inventing a local scale and requiring it of every site.
The value set exists so that whoever builds the form has a canonical list, and so a consumer knows what the values mean.
It matters more than its size suggests: in one protocol the dipstick gates eligibility, and in the other it is the comparator the algorithm's sensitivity and specificity are computed against.
An eGFR is a number produced by an equation, and the equation is not recoverable from the number.
The example records derivedFrom naming the creatinine it was computed from, and
method naming the equation. The LOINC code is 98979-8, the CKD-EPI 2021
revision with the race coefficient removed. 62238-1 is the generic CKD-EPI code
and would understate what was done.
Where a laboratory reports eGFR directly rather than the platform deriving it,
the same profile applies and derivedFrom is simply absent.
HRServiceRequest records that an
investigation was asked for, by whom and when. authoredOn is required: samples
are drawn during a routine clinical visit where the participant's ordinary care is
also happening, and a result with no request behind it cannot be told apart from
one belonging to that other episode. intent is fixed to order — nothing here
is a proposal awaiting authorisation.
HRDiagnosticReport gathers the
results a laboratory issued together. The individual values are HRObservation
resources and stand on their own; the report ties them to one issuing laboratory
and one point in time. issued is kept distinct from effective[x], because the
interval between a sample being drawn and a result being released is what a site
is asked about once the participant has gone home.
HRImagingStudy is metadata. It records which eye, when, and where the pixel data is held — it is not the images.
series.laterality is required, where the base resource leaves it optional.
It is the only thing distinguishing two otherwise identical series, and a
prediction attributed to the wrong eye is not detectable after the fact.
series is 1..* rather than 2..*. The protocols photograph both eyes, so a
conforming study ordinarily carries two — but a capture can fail on the day, and a
study recording a single usable eye is a truthful record where one asserting two
would not be.
started is required because one protocol times its blood pressure readings
relative to this moment. The interval is meaningless unless both carry a time.
Specimen is referenced by Observation.specimen,
ServiceRequest.specimen and DiagnosticReport.specimen, and is not yet
profiled — those references point at the base resource. Device is likewise
unprofiled, so the instrument on a blood pressure reading or a retinal camera can
be referenced but not constrained.
Eligibility is absent deliberately. Encoding it needs a contradiction in one protocol resolved first: its screen-failure rule excludes a negative dipstick, while its recruitment target requires a control group most of whom will have one.