Terminology: the part of a FHIR project that gets budgeted least
The facade and the repository solve the shape of the data, not what it means. We look at why terminology is underestimated at budgeting time and how it is maintained after go-live.

In the two previous installments we compared the facade and the repository as paths to FHIR. Both solve the shape of the data: which table feeds which resource and which column lands in which element. Neither one solves, on its own, what that data means.
A well-formed resource with a code nobody understands
A hospital HIS records a diagnosis with the internal code 0045 and the description HTA, the local abbreviation for hypertension. Structural mapping turns it into a correct Condition: patient referenced, recorded date, clinical status. If the national profile requires ICD-10 or SNOMED CT in the diagnosis code, that resource fails validation. If the profile only recommends it, the resource passes, and the target server stores a diagnosis no other system knows how to interpret.
ORIGIN TARGET
HIS 0045 HTA ICD-10 I10 Essential hypertension
SNOMED 38341003 Hypertensive disorder
LIS GLU LOINC 2345-7 Glucose in serum or plasma
Pharmacy AMOXI 500 CAP ATC J01CA04 Amoxicillin
The last row has a nuance. ATC classifies the active ingredient, so the 500 mg capsule presentation travels in other elements of the resource: dose form and strength. A formulary mapping is almost never a one-to-one table.
The profile decides how much it matters
Every coded element in a FHIR profile is bound to a ValueSet with a binding strength. With required, only codes from that set are accepted and anything else is an error. With extensible, the set must be used when the concept exists in it, and another code is allowed only when it does not. Preferred and example guide without obliging.
A local code can produce a valid resource that no other system interprets. The binding strength decides whether that gets caught or slips through.
That strength determines whether a local code stops the load or slips into the target. That is why it has to be read element by element in the Implementation Guide before estimating the work: two profiles of the same resource can demand very different things.
Why writing more code does not solve it
In a facade, the equivalence table lives inside the translator and is applied on every query. A correction takes effect from the next query on, but there is no point at which to verify that the whole data set conforms. In a repository fed by scripts, the table lives in the load script, and a correction does not touch what was already loaded: it has to be reprocessed by hand.
In both cases, the part no integrator solves is still pending. Someone has to decide whether HTA corresponds to I10 or to I15, which is secondary hypertension. That decision is clinical, and it belongs to the coding team or a physician at the institution. And it keeps coming back: the formulary adds new products, the lab adds tests, and terminologies publish releases with new codes and retired concepts.
Structural mapping is estimated by counting tables and columns. Terminology is measured in distinct codes and in hours of the clinical staff who review them, and its cost continues after go-live. Estimates that only count tables fall short.
High-volume codes get mapped quickly. The time goes into the long tail of infrequent codes, and into free text: a diagnosis written as "HTA + DM2 desc." is not solved by any equivalence table. That calls for curation or natural language processing, and it should be budgeted separately.
Every new product in the formulary is a new code to map. Terminology is maintained for as long as the system is in use.
How we solve it in Harmony
In Harmony, terminology translation is configuration. Each equivalence lives in a versioned ConceptMap within the control plane catalog, and the mapping rule references it. Each run records which version it applied, so any load can be explained afterwards.
Before a mapping is saved, the Mapper tests it against real data and returns the findings of the official FHIR validator, without writing to the target. That is where the codes the ConceptMap does not yet cover show up.
A CodeableConcept accepts several codings, and the practice we recommend is to send the standard code together with the original local code. The target receives what the profile requires, and an auditor can trace every value back to its source.
For codes with no equivalence, each flow defines its policy. In strict mode, the record stops and an alert is raised. In permissive mode, it passes flagged with its local code. When the clinical team adds the missing equivalence, a new version of the ConceptMap is published and the flow is run again: idempotent upserts correct the target without duplicating records.
The clinical decision remains with the institution. Harmony makes sure that, once made, it is versioned and applied the same way on every run.
What comes next
The next installment returns to the scenario we left open in the facade article: a clinician who needs to see, in real time, the history of a patient treated at several institutions that are not going to hand their data to a central database. There the question changes scale, because it becomes about how a network of institutions is queried without copying what each one holds. Terminology shows up again in that scenario, because each institution codes in its own way and the clinician needs to read a single history.
If your institution has a formulary or a lab catalog that needs to reach a standard, write to us at [email protected] and we will review a sample of your codes together.
HL7® and FHIR® are registered trademarks of HL7 International. SNOMED CT® is a registered trademark of SNOMED International. LOINC® is a registered trademark of Regenstrief Institute, Inc.

