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
POST / PUT /fhir/R4/Encounter route through the same practice encounter
service the in-app clinical chart uses, so the public API enforces the
application's clinical guards rather than writing straight to the database:
409 Conflict), matching the in-app behavior.finished) through the seal-the-snapshot path; the public API cannot produce
a partial finalize.appointment must belong to the
same patient and practitioner.in-progress is scheduled for the
24-hour auto-close by the durable reconciler.Encounter.subject is immutable on update — a PUT whose subject differs from
the stored patient is rejected.
No version history surface. The Encounter resource exposes only its current
state — there is no _history / vread / Provenance amendment surface (it had
no application equivalent). meta.versionId tracks the row's modified_on
(mirrored in the ETag) and advances on every update, but prior versions are not
addressable.
| FHIR path | Cardinality | Must Support | Justification |
|---|---|---|---|
Encounter.id |
1..1 | – | PK, always present |
Encounter.meta.lastUpdated |
0..1 | – | Auto-updated trigger |
Encounter.serviceProvider |
0..1 | Yes | Resolves to an Organization reference |
| FHIR path | Cardinality | Must Support | Justification |
|---|---|---|---|
Encounter.status |
1..1 | Yes | Required; defaults to in-progress |
Value mapping:
| Huli value | FHIR value | Notes |
|---|---|---|
planned |
planned |
Direct match |
in-progress |
in-progress |
Direct match |
completed |
finished |
KEY DIVERGENCE: Huli uses "completed", FHIR R4 uses "finished" |
cancelled |
cancelled |
Direct match |
Source: Huli Public FHIR API (Encounter status values)
The set of Encounter.status values accepted depends on the operation:
POST) — restricted to planned, in-progress, finished,
cancelled (the four states the codec round-trips). The
transitional/terminal markers (arrived,
triaged, onleave, entered-in-error, unknown) are rejected at the
adapter boundary with Encounter.status must be one of: planned,
in-progress, finished, cancelled on create — they have no meaning as an
initial state.PUT) — accepts the broader FHIR R4 status set. Which target
status is actually reachable is governed by the status-transition table: an
illegal transition (e.g. finished → planned) is rejected by the use-case
with 422 Unprocessable Entity.| FHIR path | Cardinality | Must Support | Justification |
|---|---|---|---|
Encounter.class |
1..1 | Yes | Required; defaults to ambulatory |
Value mapping:
| Huli value | FHIR system | FHIR code | FHIR display |
|---|---|---|---|
ambulatory |
http://terminology.hl7.org/CodeSystem/v3-ActCode |
AMB |
ambulatory |
emergency |
(same) | EMER |
emergency |
inpatient |
(same) | IMP |
inpatient encounter |
virtual |
(same) | VR |
virtual |
Source: Huli Public FHIR API (Encounter class values)
| FHIR path | Cardinality | Must Support | Justification |
|---|---|---|---|
Encounter.subject |
1..1 | Yes | Required; references the patient |
Encounter.participant[0].individual |
1..* | Yes | Required; references the user |
Encounter.appointment[0] |
0..1 | – | Nullable; no enforced referential constraint |
Participant write behavior. On write, only participant[0].individual
is read, and it is honored as a Practitioner reference (a Huli user id).
Additional participant[] entries and PractitionerRole references are not
consumed on write, even though the profile cardinality allows 1..*
participants and a Practitioner or PractitionerRole individual.
| FHIR path | Cardinality | Must Support | Justification |
|---|---|---|---|
Encounter.period.start |
1..1 | Yes | Required; timestamp with offset |
Encounter.period.end |
0..1 | – | NULL while in-progress |
| FHIR path | Cardinality | Must Support | Justification |
|---|---|---|---|
Encounter.reasonCode[0].text |
0..* | – | Free text chief complaint (LOINC 10154-3) |
| FHIR path | Cardinality | Must Support | Justification |
|---|---|---|---|
Encounter.diagnosis[].condition (contained HuliCondition) .code.coding[0].code |
0..* | – | ICD-10 code |
Contained Condition .code.coding[0].system |
– | – | Always "http://hl7.org/fhir/sid/icd-10" |
Contained Condition .code.coding[0].display |
– | – | Diagnosis display name |
Encounter.diagnosis[].rank |
– | – | "primary"->rank=1, "secondary"->rank=2+ |
Mapping rule: Each diagnosis entry becomes:
HuliCondition resource with ICD-10 codingEncounter.diagnosis backbone entry referencing the contained Conditionrank = 1 for type="primary", rank = 2 (incrementing) for type="secondary"rank is writable and round-trips. On write, the Encounter.diagnosis[].rank
of the entry referencing each contained Condition selects the app's binary
primary/secondary classification:
rank: 1 → primary diagnosis.rank ≥ 2, or no rank → secondary diagnosis.Because the app model is binary (primary vs. secondary), the ordinal rank
collapses: a rank: 3 (or higher) is stored as secondary and reads back as
secondary (rank: 2), not rank: 3. Only the rank-1 / not-rank-1 distinction
survives the round-trip.
The following SOAP-structured fields are carried by the Public API as
discrete Observation resources, as contained resources on the
Encounter, or are not modelled through FHIR in this IG. They are listed
here so partner systems know where to look for the corresponding clinical
content.
The SOAP narrative blocks ride on the Encounter as contained resources
identified by a stable, well-known id. The Public API both emits these
ids on read and uses them to route the corresponding contained entries on
write — so a client must set the exact id below for a write to land in the
right place:
| Contained resource | contained[].id |
Maps to |
|---|---|---|
ClinicalImpression (subjective/objective) |
subjective-objective-summary |
SOAP S + O narratives |
ClinicalImpression (diagnostic impression) |
diagnostic-impression |
Diagnostic impression narrative |
CarePlan (follow-up plan) |
care-plan |
Follow-up plan narrative |
HuliCondition (each diagnosis) |
server-allocated per diagnosis | The encounter's structured diagnoses |
Subjective / Objective summary. The SOAP Subjective (S) and
Objective (O) narratives both map to the single contained
ClinicalImpression with id: "subjective-objective-summary": on read, S and
O are concatenated into its summary with a blank line between them
(S\n\nO); on write, the public API splits summary back into S and O on the
first blank-line separator. Supplying a summary with no blank-line separator
stores the whole value as the Subjective narrative.
Diagnostic impression ("Impresión diagnóstica"). A contained
ClinicalImpression with id: "diagnostic-impression" carries the
diagnostic-impression narrative in its summary.
The entry may optionally carry the LOINC code 51848-0 (Evaluation note)
on code.coding[0]; the code is advisory — routing is driven by the contained
id, not by the code.
Follow-up plan ("Plan de seguimiento"). A contained CarePlan with
id: "care-plan" carries the follow-up-plan narrative in its description.
contained blockA write that sets the diagnostic impression and follow-up plan (alongside the subjective/objective summary) supplies:
{
"resourceType": "Encounter",
"status": "in-progress",
"subject": { "reference": "Patient/01936b7c-8d4e-7000-8000-000000004001" },
"contained": [
{
"resourceType": "ClinicalImpression",
"id": "subjective-objective-summary",
"status": "completed",
"subject": { "reference": "Patient/01936b7c-8d4e-7000-8000-000000004001" },
"summary": "Refiere cefalea de 3 días.\n\nTA 120/80, afebril, consciente y orientado."
},
{
"resourceType": "ClinicalImpression",
"id": "diagnostic-impression",
"status": "completed",
"code": { "coding": [{ "system": "http://loinc.org", "code": "51848-0" }] },
"subject": { "reference": "Patient/01936b7c-8d4e-7000-8000-000000004001" },
"summary": "Cefalea tensional, probable origen postural."
},
{
"resourceType": "CarePlan",
"id": "care-plan",
"status": "active",
"intent": "plan",
"subject": { "reference": "Patient/01936b7c-8d4e-7000-8000-000000004001" },
"description": "Control en 1 semana. Higiene postural y analgésico de rescate."
}
]
}
| Huli concept | FHIR equivalent on the Public API |
|---|---|
| Vital signs | Observation with category = vital-signs (see Observation Mapping) |
| Clinical observations / lab results | Observation with category = laboratory |
| Subjective narrative (S in SOAP) | Contained ClinicalImpression#subjective-objective-summary.summary (writable; S then O, separated by a blank line) |
| Objective narrative (O in SOAP) | Contained ClinicalImpression#subjective-objective-summary.summary (writable; S then O, separated by a blank line) |
| Diagnostic impression (A in SOAP) | Contained ClinicalImpression#diagnostic-impression.summary (writable; optional LOINC 51848-0) |
| Care plan narrative (P in SOAP) | Contained CarePlan#care-plan.description (writable) |
| Orders — medications | MedicationRequest resource (see MedicationRequest Mapping) |
| Orders — studies / labs | ServiceRequest resource (see ServiceRequest Mapping) |
| Custom intake forms | Not modelled through FHIR in this IG |
| Drawings / body-site annotations | Not modelled through FHIR in this IG |
| Huli concept | Reason |
|---|---|
| Soft-delete status | Not exposed; internal lifecycle |
| Record creation timestamp | Not exposed; no standard FHIR path |
| Search index | Not exposed; internal search index |