---
name: fhir-resource-mapping
description: "Maps a piece of clinical data to the correct FHIR R4 resource and populates its required elements with the coding system that resource expects — a diagnosis to Condition (clinicalStatus, code, subject), a lab or vital to Observation (status, code, value[x], effective[x]), a prescription to MedicationRequest (status, intent, medication, subject) — using LOINC for measurements, SNOMED CT for problems, and RxNorm for drugs, and always naming the polymorphic element by its type suffix. Use when clinical facts (a diagnosis, lab result, vital sign, or medication order) must be turned into a FHIR R4 resource or its JSON. Do NOT use for FHIR REST/search API mechanics, Bundle transaction wiring, bulk-data export, profile/IG authoring, or non-FHIR interchange formats like HL7 v2 or CDA."
metadata:
  decimalai-skill-id: "87e81a40-a8ae-4e4d-81f4-2b1f2a7bfe5d"
  decimalai-version-id: "6b9c73d8-65cd-4ff6-a3dd-25bc0214e1be"
  decimalai-version: "1"
  decimalai-body-sha256: "4ecd0e75c004e024c3a7889fadd5179b896c29448b74233fc91fbaebe58f6913"
  decimalai-name: "fhir-resource-mapping"
  decimalai-format: "1"
  decimalai-invocation: "model"
  decimalai-category: "data"
  decimalai-source: "https://app.decimal.ai/s/fhir-resource-mapping@1/SKILL.md"
---
# Map clinical data to the right FHIR R4 resource and fields

Given a clinical fact, produce the FHIR R4 resource that represents it, with every required element
present and the coding system that resource actually expects. The failure mode this fixes: putting a
lab result in `Condition` or a diagnosis in `Observation`, dropping a required element (most often
`intent` on `MedicationRequest` or `status` on `Observation`), coding a lab with SNOMED instead of
LOINC, writing a bare `value` instead of the typed `value[x]`, or inventing a status code that isn't
in the required value set. Apply the rules in order; for the full per-element field list of a
resource, consult `references/resource-field-maps.md`.

## 1. Pick the resource from what the data *is*

Choose by the nature of the fact, not by the words in the sentence:

- **A diagnosis, problem, or clinical condition** the patient *has* → `Condition`.
- **A single measured or observed value** — lab result, vital sign, questionnaire score, or a
  qualitative clinical finding → `Observation`. A lab result is an Observation even though a lab
  "orders" it; the order is a `ServiceRequest`, the result is the Observation.
- **A medication ordered or prescribed** → `MedicationRequest`. A record that the patient is
  *taking* a drug (not a new order) is `MedicationStatement`; a dispense is `MedicationDispense`.
- Anything else — allergy, procedure performed, immunization given, a grouped report of several
  results — has its own resource; see the resource table in `references/resource-field-maps.md`.
  Do not force it into Condition/Observation/MedicationRequest because those are familiar.

## 2. Populate every required (1..1) element — no exceptions

A resource missing a required element is invalid. The elements the base model most often drops:

- **`Condition`** — always set `subject` (a `Reference` to the patient), `clinicalStatus` (active /
  recurrence / relapse / inactive / remission / resolved), and `code` (the diagnosis). Add
  `verificationStatus` when the note says whether it is confirmed vs. provisional/differential.
- **`Observation`** — always set `status` (usually `final` for a completed result, `preliminary`
  if not yet verified), `code` (what was measured), and `subject`. Give the result as the typed
  `value[x]` (below) or, if there is no value, `dataAbsentReason`. Set `effective[x]` to when the
  measurement applies.
- **`MedicationRequest`** — always set `status` (e.g. `active`), **`intent`** (`order`, `plan`,
  `proposal`…), the medication (`medicationCodeableConcept` or `medicationReference`), and
  `subject`. `intent` is required and is the element most often forgotten — an order without it is
  invalid.

Reference the patient as a `Reference`, e.g. `"subject": {"reference": "Patient/123"}`, not a bare
id or a name string.

## 3. Use the coding system the resource expects

Each coded element has a preferred/required terminology. Emit a full `Coding` — `system` (the
canonical URI), `code`, and `display` — inside a `CodeableConcept`, never a bare string:

- **`Observation.code`** → **LOINC** (`http://loinc.org`) for labs and vitals.
- **`Condition.code`** → **SNOMED CT** (`http://snomed.info/sct`); ICD-10-CM
  (`http://hl7.org/fhir/sid/icd-10-cm`) is also valid when the source is a billing code.
- **Medication** → **RxNorm** (`http://www.nlm.nih.gov/research/umls/rxnorm`).
- **`AllergyIntolerance.code`**, **`Procedure.code`** → SNOMED CT.

Pick the coding system from the *element*, not from habit: a serum potassium is `Observation.code`
so it takes a LOINC code, even though "hyperkalemia" (a Condition) would take SNOMED.

## 4. Name the polymorphic element by its type suffix

Choice elements (`value[x]`, `effective[x]`, `onset[x]`, `medication[x]`) are never written as the
bare stem. Pick exactly one concrete type and use its full name:

- A numeric result with a unit → **`valueQuantity`** with `value`, `unit`, `system`
  `http://unitsofmeasure.org` (UCUM), and the UCUM `code` (e.g. `mg/dL`).
- A coded/categorical result (positive/negative, blood type) → **`valueCodeableConcept`**.
- Free text → `valueString`; true/false → `valueBoolean`.
- A single timestamp → **`effectiveDateTime`**; a span → **`effectivePeriod`**.

Writing `"value": 5.1` is wrong — it must be `"valueQuantity": {"value": 5.1, ...}`.

## 5. Draw status and category codes from the required value set

`Condition.clinicalStatus`, `Observation.status`, `MedicationRequest.status`, and `intent` each bind
to a fixed FHIR value set. Use a code from that set; do not paraphrase ("done", "completed",
"prescribed" are not valid Observation statuses). When the source doesn't state the status, choose
the sensible default (`final` for a reported result, `active` for a current problem or order) rather
than omitting the required element.

## Output

Emit the resource as FHIR R4 JSON (or the field list requested), and for any element where the
source was ambiguous, say what you assumed rather than inventing a code. When a required element
cannot be determined from the input, name the gap instead of fabricating a value.

## Deeper lookup

`references/resource-field-maps.md` — a per-resource field map (which elements are required vs.
common-optional, the bound value sets, and the expected coding system) for Condition, Observation,
MedicationRequest, and the neighboring resources, plus the canonical system URIs. It is a lookup
catalog; the decision rules stay here in the body.
