Both systems send a coded lab result and the receiver still cannot use it. Why?
A code means nothing without its code system, its version and a mapping the receiver trusts. Local catalogues dominate, LOINC, SNOMED CT and ICD answer different questions, value set expansions drift with versions, and every local-to-standard map is lossy, owned and perpetually going stale.
What the interviewer is scoring
- Does the candidate insist on code plus code system plus version rather than treating the code as self-identifying
- Whether classifications and clinical terminologies are given different jobs instead of being lumped together
- That a local-to-standard map is treated as an owned, versioned, lossy asset rather than a migration script
- Whether units, reference ranges and interpretation are recognised as part of making a result comparable
- Does the answer state that a display string must never be trusted over the code it accompanies
Answer
A code is a pointer, and pointers need a namespace
4548-4 means nothing on its own. It means something as a concept in a named code system, at a stated version, with a stated meaning. Drop any of those three and the receiver is guessing. This is the whole reason FHIR identifies code systems by URI and gives you Coding with system, version, code and display as separate elements rather than a bare string: the namespace travels with the value.
The commonest concrete failure in a live interface is exactly this. The sender populates a code that happens to look like a standard one but asserts the wrong system, or asserts no system, or asserts a local system URI that the receiver has never seen. The message validates, the field is populated, and the receiver has a string it cannot resolve. The second commonest is the display string: a sender puts a helpful human label next to the code, the label is stale or hand-edited, and a receiver that renders the display rather than resolving the code shows a clinician the wrong name for the right concept. The rule is that the code is authoritative and the display is a convenience, and no logic anywhere may branch on the display.
Local catalogues are the default state of the world
Every laboratory has its own test catalogue, built up over decades, reflecting which analyser it bought and which panels its clinicians order. Every hospital has local codes for procedures, locations, order items and specimen types. These are not a failure of standardisation, they are how operational systems work, and they are not going away.
So interoperability is a mapping problem before it is a standards problem. The standard code systems exist to give the local codes somewhere to point, and each answers a different question, which is why you need several at once rather than picking one.
LOINC identifies what was measured. Its concepts are defined along several axes at once — the component measured, the property, the timing, the specimen or system, the scale, and where relevant the method — which is why two tests both called "glucose" are different LOINC concepts if one is on serum and the other on cerebrospinal fluid. That granularity is the point: it is what makes results from two laboratories comparable, and it is also why mapping is careful work rather than a string match on the test name.
SNOMED CT covers clinical findings, disorders, procedures, body structures, organisms and situations, with a formal hierarchy of subtype relationships and defining attributes. Because it is a description-logic terminology, you get subsumption for free: a query for a parent concept can retrieve its descendants, which is what makes it usable for decision support and cohorting. It also supports post-coordination, expressing a concept by combining others when no single concept exists, which is powerful and also the part most implementations deliberately restrict because arbitrary expressions are hard to consume.
ICD is a classification, not a clinical terminology, and this distinction is worth stating explicitly because it is the one candidates most often miss. A classification exists to place every case into exactly one bucket for counting, reporting and reimbursement. It is therefore exhaustive and mutually exclusive by construction, with residual "other" and "unspecified" categories, and it deliberately loses clinical detail. Coding a diagnosis into ICD is a lossy projection of the clinical record, which is fine for its purpose and wrong as a source of clinical truth.
Medications and units are their own problem, and this is where practice varies most by market: the drug terminology in use differs by country, so a design that assumes one is not portable, and quantities need a unit code system such as UCUM rather than a free-text unit that nobody can compute with.
Value sets, bindings and the drift nobody expects
A value set is a defined selection of concepts, possibly drawn from several code systems, identified by a URL and versioned. A profile binds an element to a value set with a strength — required, extensible, preferred or example — and that binding is what turns "there is a code here" into "the code will be one the receiver understands".
The subtlety is that a value set is usually defined by intension rather than by enumeration: all descendants of a concept, everything with a given property. Resolving it into a concrete list of codes is an expansion, and an expansion is a function of the value set definition and the version of every code system it draws on. Two servers holding the same value set and different code system releases will expand it differently, and both are behaving correctly. So validation results can differ between environments for reasons that have nothing to do with the data, and reproducing a past validation decision requires knowing which expansion was in force.
Code systems also change substantively between releases. Concepts are added, and concepts are inactivated or deprecated with a stated successor. Historic data must keep its original code, because the record has to say what was recorded at the time; new messages should move to the successor. That means your terminology layer needs to answer questions about concepts that are no longer active, which rules out simply loading the current release and discarding the last one.
FHIR gives this its own service surface: $lookup to resolve a code, $validate-code to test membership in a value set, $expand to materialise a value set, $subsumes to ask about the hierarchy, and $translate to apply a ConceptMap. Delegating to a terminology server rather than embedding tables in each application is the right default, because the alternative is every service holding its own stale copy of the same subset.
The map is a living asset with an owner
The mapping from a local catalogue to standard concepts is the deliverable that actually makes an interface useful, and it has properties that teams under-plan for.
It is lossy and it must record how lossy. A ConceptMap carries an equivalence for each mapping — equivalent, source narrower than target, source broader than target, and so on — and a consumer needs that to know whether an aggregate is safe. Mapping ten local specimen variants to one broad parent concept is legitimate; presenting the result as if it were an exact match is not, because a downstream analysis will treat a widened concept as a precise one.
It goes stale continuously. A laboratory adds three assays when it replaces an analyser and nobody tells the integration team, so three local codes arrive with no mapping. The failure needs to be loud: an unmapped code should raise an operational alert and route the item for human handling, not pass through as text-only where it is technically present and practically invisible. A weekly report of unmapped codes by volume is one of the highest-value, lowest-effort controls in a healthcare integration estate.
And it needs an owner with clinical authority. Deciding that a local test maps to a particular LOINC concept is a clinical judgement with safety consequences, not a data-engineering task, and the sign-off should be recorded against the mapping version so a change is attributable.
What comparability actually requires
Even with a perfect code, a numeric result is not usable without its units, its reference range, and the interpretation the reporting laboratory applied. Two laboratories measuring the same analyte can report in different units and against different ranges, so a value stripped of them cannot be trended, compared or safely flagged. Carrying the unit as a coded quantity and the range as reported, rather than normalising to something you invented, is the safe default: normalisation is a decision the consumer should make explicitly, with the original values retained.
The framing worth offering is that standardising the transport was the easy half. Two systems can exchange perfectly conformant resources and still be mutually useless because the concepts inside them are not aligned, and the work of alignment is a curated, versioned, owned mapping estate that never finishes.
Likely follow-ups
- Two servers expand the same value set differently. What would you check first?
- A concept you have been sending for years is inactivated in the next release of the code system. What happens to historic data and to new messages?
- When is it right to map a local code to a broader parent concept, and what must the receiver be told?
- How would you detect that a lab has silently added tests to its catalogue that your map does not cover?
Related questions
- How does your order placement change on a venue that allocates pro rata within a price level instead of first in, first out?hardSame kind of round: concept6 min
- How would you design a thread-safe component, and why is adding synchronized to every method not a design?hardSame kind of round: concept7 min
- How do you test a Node service, and what do you refuse to mock?mediumSame kind of round: concept5 min
- How does Node load your modules, and how would you make a Node service use more than one core?mediumSame kind of round: concept6 min
- Angular, Vue and React are answers to the same problems. Compare how each handles change detection, reactivity and dependency injection.hardSame kind of round: concept5 min
- How do you turn what the business tells you into a domain model that holds up once the exceptions arrive?hardSame kind of round: design7 min
- Walk me through what happens between a customer tapping a card and the merchant getting paid.hardSame kind of round: concept6 min
- How do you choose between a document store, a key-value store, a wide-column store and a graph database for a new service?hardSame kind of round: design5 min