Huli FHIR Core Implementation Guide (R4)
0.1.0 - Release

Huli FHIR Core Implementation Guide (R4) - Local Development build (v0.1.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions

Observation Mapping

Observation Mapping: Huli -> FHIR R4

HuliObservation carries vital signs, laboratory results, and clinical exam findings recorded against a Huli patient. The Public API supports read, search, create, and update for this resource.

Create and update route through the same practice observations service the Huli application uses, so a public write runs the platform's clinical rules rather than writing straight to the database:

  • The code must be a LOINC code present in the observation catalog; an unknown code is rejected with HTTP 400.
  • The numeric value is checked against the catalog's validation range for that code; an out-of-range value is rejected with HTTP 400.
  • Growth-parameter codes (weight/height/head-circumference-for-age) have their percentile and z-score recomputed server-side from the patient's age and sex.
  • Writes against a deceased patient are rejected.
  • The canonical display and unit are resolved from the catalog server-side; client-supplied code.display and valueQuantity.unit on write are advisory.

Resource Identity

FHIR path Cardinality Must Support Notes
Observation.id 1..1 UUID, allocated server-side; client-supplied IDs are rejected on POST
Observation.meta.lastUpdated 0..1 Set by the platform
Observation.meta.profile[0] 0..1 Always https://fhir.huli.ai/r4/StructureDefinition/HuliObservation

Status

Huli status FHIR Observation.status Notes
1 final Default emitted status for completed observations
2 preliminary Observation captured but not yet finalised
3 amended Updated after the initial final result
4 corrected Corrected after error in the final result
5 cancelled Captured but cancelled before completion
6 entered-in-error Void marker; FHIR R4 prohibits reverting from this state

The full value set above is what the Public API emits on read/search. On write the surface honours only a subset, and rejects the rest with HTTP 422 at Observation.status (rather than silently storing a status it cannot represent):

  • A create (POST) accepts only final. registered, preliminary, amended, corrected, and cancelled are rejected with HTTP 422.
  • An update (PUT) accepts final (a value edit, which keeps the stored status final) or entered-in-error (the terminal void). Any other status is rejected with HTTP 422.

PUTs that try to mutate an observation already in entered-in-error are rejected with HTTP 422 (FHIR R4 prohibits reverting from the terminal void state).

Code (LOINC)

FHIR path Notes
Observation.code.coding[0].system http://loinc.org (overridable per stored row)
Observation.code.coding[0].code LOINC code; required on write
Observation.code.coding[0].display Display string
Observation.code.text Mirror of the display string for human-readable rendering

Category

Derived from the LOINC code. The Public API emits exactly one category per observation:

LOINC code Emitted category FHIR system
Known vital-sign codes (29463-7, 8302-2, 8480-6, 8462-4, 8867-4, 8310-5, 59408-5, 9279-1, 9843-4, 39156-5) vital-signs http://terminology.hl7.org/CodeSystem/observation-category
All other LOINC codes laboratory (same)

For search, category accepts vital-signs, laboratory, or exam. laboratory and exam both match observations whose code is not in the vital-sign set (they share the same complement of LOINC codes).

References

FHIR path Cardinality Must Support Notes
Observation.subject 1..1 Yes Reference(HuliPatient); required on read and write
Observation.encounter 0..1 Yes Reference(HuliEncounter); emitted when the observation was captured during an encounter

References passed on create must resolve inside the authenticated organization; cross-organization references are rejected with HTTP 422.

Observation.encounter is read-only on the Public API: it is emitted on read and search when an observation was captured during an encounter, but a create or update that carries Observation.encounter is rejected with HTTP 400. Encounter-bound observations are recorded as part of the encounter itself (they are managed atomically with the encounter's clinical record), not as standalone Observation writes — the Public API mirrors the platform rule that keeps those two surfaces separate. Standalone Observation writes are always patient-scoped and out-of-encounter.

Effective time

FHIR path Cardinality Notes
Observation.effectiveDateTime 0..1 Always emitted on read. Observation.effectivePeriod is not used.

Value

FHIR path Notes
Observation.valueQuantity.value Decimal value; emitted when the stored value parses as a float
Observation.valueQuantity.unit Display unit
Observation.valueQuantity.system Always http://unitsofmeasure.org (UCUM)
Observation.valueQuantity.code UCUM code; mirror of unit

Other value[x] variants (valueString, valueCodeableConcept, valueBoolean, …) are not emitted; the Public API restricts observation values to UCUM-coded numeric quantities.

Interpretation

FHIR path Notes
Observation.interpretation[0].coding[0].system http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation
Observation.interpretation[0].coding[0].code Single code (e.g., N, H, L); emitted only when stored

Performer vs Device

The Public API selects one of two patterns based on how the observation was captured:

Capture source FHIR fields emitted
Automated device Observation.device.display = "Medical device"
Practitioner entry Observation.performer[0] = Reference(Practitioner) when a practitioner is on the record, otherwise Reference(Organization) for the organization

Search parameters

The Public API advertises the following search parameters on GET /fhir/R4/Observation:

Parameter Type Notes
_id token Direct lookup by Observation.id
patient reference Reference(HuliPatient); logical id or full reference
encounter reference Reference(HuliEncounter)
code token LOINC code; exact match
date date Filters Observation.effectiveDateTime; supports eq/gt/ge/lt/le prefixes
status token One of registered, preliminary, final, amended, corrected, cancelled, entered-in-error
category token vital-signs, laboratory, or exam (see Category above)
_count number Page size
_cursor string Opaque cursor returned in Bundle.link[rel=next]

Search responses are returned as a FHIR Bundle of type searchset with cursor-based pagination.

Fields not mapped to FHIR

Huli concept Reason it is not on Observation
SOAP narrative blocks (subjective / objective) Carried on Encounter clinical content rather than discrete Observations
Free-text comments captured during a checkup Operational notes; not part of the Observation contract
Imaging studies DiagnosticReport is not in this IG