Condition
DSP condition resources map almost directly onto FHIR Condition. The fit is near-perfect; the only extensions needed are DSP-specific metadata (spoken forms, transcript turn provenance, confidence).
condition
Condition (R4) + US Core Condition-Problems / Condition-Encounter-Diagnosis
Field-by-field
| DSP | FHIR R4 | Round-trip mechanism |
|---|---|---|
id | Condition.id | Native — exact |
description | Condition.code.text | Native — exact |
condition_concept.codes (SNOMED / ICD-10) | Condition.code.coding[] | Native — exact (multi-coded) |
condition_concept.concept_id | Condition.code.extension[dsp-concept-id] | DSP extension — exact |
clinical_status | Condition.clinicalStatus | Native — exact |
verification_status | Condition.verificationStatus + extension[dsp-assertion-category] | DSP nuances (asserted vs history) preserved on the extension |
category | Condition.category | Native — exact |
severity | Condition.severity | Native — bind to SNOMED 24484000/6736007/255604002 |
onset | Condition.onset[x] | Native — exact |
abatement | Condition.abatement[x] | Native — exact |
stage | Condition.stage | Native — exact |
evidence | Condition.evidence.code.text | Native — exact |
body_site | Condition.bodySite | Native; prefer SNOMED body structure codes |
notes | Condition.note.text | Native — exact |
confidence_score | extension[dsp-confidence-score] | DSP extension — exact |
spoken_forms | extension[dsp-spoken-forms] (repeating) | DSP extension — exact |
provenance (turn indices) | extension[dsp-transcript-turn-ref] (one per index) | One extension per index, each with a versioned DocumentReference reference — see indexing |
parent_resource | Condition.encounter | Native — exact |
children_resources | Inverse via Observation.focus, ServiceRequest.reasonReference, etc. | Recovered by traversal at read |
external_reference | identifier + meta.source + extension[dsp-linkage-confidence] | DSP extension — exact |
Every DSP-originated field lands in either a native FHIR field or a dsp-* extension. The canonical $graphql read reconstructs the DSP payload directly from those slots — no inverse mapping engine required.
Side-by-side example
DSP
{
"id": "condition-001",
"context": { "content_type": "condition" },
"description": "Moderate osteoarthritis of the right knee",
"condition_concept": {
"text": "Moderate osteoarthritis of the right knee",
"concept_id": "dragon-cid-00172",
"codes": [
{"system":"snomed","identifier":"239873007"},
{"system":"icd10","identifier":"M17.11"}
]
},
"clinical_status": "active",
"verification_status": "confirmed",
"category": "encounter-diagnosis",
"severity": "moderate",
"body_site": "right knee",
"provenance": [11, 15],
"confidence_score": 0.94,
"spoken_forms": ["arthritis in the right knee"]
} FHIR R4 (DSP-FHIR profile)
{
"resourceType": "Condition",
"id": "condition-001",
"meta": {
"profile": ["https://dsp-fhir.org/StructureDefinition/DspCondition"],
"source": "https://dsp-fhir.org/source/dsp-payload-abc"
},
"subject": {"reference":"Patient/pat-67890"},
"encounter": {"reference":"Encounter/enc-12345"},
"clinicalStatus": {"coding":[{"system":"http://terminology.hl7.org/CodeSystem/condition-clinical","code":"active"}]},
"verificationStatus": {"coding":[{"system":"http://terminology.hl7.org/CodeSystem/condition-ver-status","code":"confirmed"}]},
"category":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/condition-category","code":"encounter-diagnosis"}]}],
"severity": {"coding":[{"system":"http://snomed.info/sct","code":"6736007","display":"Moderate"}]},
"code": {
"text": "Moderate osteoarthritis of the right knee",
"coding": [
{"system":"http://snomed.info/sct","code":"239873007"},
{"system":"http://hl7.org/fhir/sid/icd-10-cm","code":"M17.11"}
],
"extension": [
{"url":"https://dsp-fhir.org/StructureDefinition/dsp-concept-id",
"valueString":"dragon-cid-00172"}
]
},
"bodySite":[{"text":"right knee"}],
"extension":[
{"url":"https://dsp-fhir.org/StructureDefinition/dsp-confidence-score",
"valueDecimal":0.94},
{"url":"https://dsp-fhir.org/StructureDefinition/dsp-spoken-forms",
"valueString":"arthritis in the right knee"},
{"url":"https://dsp-fhir.org/StructureDefinition/dsp-assertion-category",
"valueCode":"asserted"},
// One extension per turn index. The transcript reference is version-pinned (R1)
// so the integer index remains valid across re-transcription.
{"url":"https://dsp-fhir.org/StructureDefinition/dsp-transcript-turn-ref",
"extension":[
{"url":"transcript","valueReference":{"reference":"DocumentReference/dr-transcript-001/_history/3"}},
{"url":"turn","valueInteger":11}
]},
{"url":"https://dsp-fhir.org/StructureDefinition/dsp-transcript-turn-ref",
"extension":[
{"url":"transcript","valueReference":{"reference":"DocumentReference/dr-transcript-001/_history/3"}},
{"url":"turn","valueInteger":15}
]}
]
} provenance: [11, 15] is two integer offsets into a transcript.
The IG models each offset as one dsp-transcript-turn-ref extension
carrying a version-pinned DocumentReference reference and a
valueInteger. One extension per index keeps them ordered, queryable, and
re-transcription-safe (per R1 — Turn-index stability).
Resolving the underlying turn text is a follow-on read of the referenced
DocumentReference attachment; see
$ground.
assertion axis (asserted / history / denied / suspected) does not bijectively map to FHIR's
verificationStatus (asserted ∪ history → confirmed). The IG always preserves the original
DSP value on extension[dsp-assertion-category], and the canonical read prefers that extension before
falling back to verificationStatus.
DSP → FHIR (write projection)
On ingest the server projects the DSP condition onto a profiled Condition using the field landings shown above. The IG ships an executable FHIR Mapping Language skeleton as a reference implementation; partners are not required to use FML in production — a hand-written projection that satisfies the same field mapping is conformant.
map "https://dsp-fhir.org/StructureMap/DspConditionToCondition" = "DspConditionToCondition"
uses "https://dsp-fhir.org/StructureDefinition/DspConditionResource" alias DspCondition as source
uses "http://hl7.org/fhir/StructureDefinition/Condition" alias Condition as target
group DspConditionToCondition(source src : DspCondition, target tgt : Condition) {
src.id as id -> tgt.id = id;
src.payload as p then {
// Primary code path: structured code+system
p.code as c -> tgt.code as code, code.coding as coding then {
c -> coding.code = c;
p.code_system as sys -> coding.system = sys;
p.display as d -> coding.display = d;
} "code";
// Fallback: display text only
p.display as d -> tgt.code as code, code.text = d "display-fallback";
// Assertion category -> verificationStatus + preserve as extension
p.assertion as a -> tgt.extension as ext then {
a -> ext.url = 'https://dsp-fhir.org/StructureDefinition/dsp-assertion-category',
ext.value = create('code') as v, v.value = a;
} "assertion-ext";
p.assertion as a where (a = 'asserted' or a = 'history') -> tgt.verificationStatus as vs,
vs.coding as co, co.system = 'http://terminology.hl7.org/CodeSystem/condition-ver-status',
co.code = 'confirmed' "verif-confirmed";
p.assertion as a where a = 'denied' -> tgt.verificationStatus as vs,
vs.coding as co, co.system = 'http://terminology.hl7.org/CodeSystem/condition-ver-status',
co.code = 'refuted' "verif-refuted";
p.assertion as a where a = 'suspected' -> tgt.verificationStatus as vs,
vs.coding as co, co.system = 'http://terminology.hl7.org/CodeSystem/condition-ver-status',
co.code = 'provisional' "verif-provisional";
// Concept id hangs off the CodeableConcept
p.concept_id as cid -> tgt.code as code, code.extension as ext then {
cid -> ext.url = 'https://dsp-fhir.org/StructureDefinition/dsp-concept-id',
ext.value = create('string') as v, v.value = cid;
} "concept-id";
};
// Resource-level metadata
src.confidence as conf -> tgt.extension as ext then {
conf -> ext.url = 'https://dsp-fhir.org/StructureDefinition/dsp-confidence-score',
ext.value = create('decimal') as v, v.value = conf;
} "confidence";
// One extension per turn index. The version-pinned 'transcript' element is added by the
// controller before persisting (it is not in the DspResource source — see R1).
src.transcript_turn_refs as t -> tgt.extension as ext then {
t -> ext.url = 'https://dsp-fhir.org/StructureDefinition/dsp-transcript-turn-ref',
ext.extension as turnExt,
turnExt.url = 'turn',
turnExt.value = create('integer') as v, v.value = t;
} "turn-ref";
src.spoken_forms as sf -> tgt.extension as ext,
ext.url = 'https://dsp-fhir.org/StructureDefinition/dsp-spoken-forms',
ext.value = create('string') as v, v.value = sf "spoken-form";
// Default clinicalStatus - caller may override on ingest
src -> tgt.clinicalStatus as cs, cs.coding as co,
co.system = 'http://terminology.hl7.org/CodeSystem/condition-clinical',
co.code = 'active' "clinical-default";
} FHIR → DSP (canonical $graphql read)
The reverse direction is a read, not a transform. Standard FHIR $graphql selects every native field and DSP-namespaced extension that the write projection populated. A small adapter renames the result into the DSP shape. No FML inverse engine is required, and no DSP-originated field is lost — every input slot has a defined output slot.
Canonical query
POST [fhir-base]/$graphql with the condition id (or fan out from
ConditionList(encounter:) to retrieve every Condition on an encounter):
query DspCondition($id: ID!) {
Condition(id: $id) {
id
meta { profile source versionId lastUpdated }
code {
text
coding { system code display }
conceptId: extension(url: "https://dsp-fhir.org/StructureDefinition/dsp-concept-id") {
valueString
}
}
clinicalStatus { coding { system code } }
verificationStatus { coding { system code } }
category { coding { system code } }
severity { coding { system code display } text }
bodySite { coding { system code display } text }
note { text }
# Native onset/abatement choice fields
onsetDateTime
onsetString
abatementDateTime
# DSP-originated metadata as primitive extensions
confidence: extension(url: "https://dsp-fhir.org/StructureDefinition/dsp-confidence-score") {
valueDecimal
}
spokenForms: extension(url: "https://dsp-fhir.org/StructureDefinition/dsp-spoken-forms") {
valueString
}
assertion: extension(url: "https://dsp-fhir.org/StructureDefinition/dsp-assertion-category") {
valueCode
}
# One repeating extension per turn index, each with its own versioned transcript ref
turnRefs: extension(url: "https://dsp-fhir.org/StructureDefinition/dsp-transcript-turn-ref") {
transcript: extension(url: "transcript") { valueReference { reference } }
turn: extension(url: "turn") { valueInteger }
}
}
} DSP reconstruction adapter
The adapter is a deterministic shape-rename. It prefers dsp-* extensions over derived FHIR fields where the IG has guaranteed exact preservation (e.g. assertion):
function toDspCondition(c) {
const turnRefs = c.turnRefs ?? [];
return {
id: c.id,
context: { content_type: 'condition' },
description: c.code?.text,
condition_concept: {
text: c.code?.text,
concept_id: c.code?.conceptId?.[0]?.valueString,
codes: (c.code?.coding ?? []).map(toDspCode),
},
clinical_status: c.clinicalStatus?.coding?.[0]?.code,
verification_status: c.verificationStatus?.coding?.[0]?.code,
// Prefer the lossless DSP extension; fall back to verificationStatus
assertion: c.assertion?.[0]?.valueCode
?? deriveAssertion(c.verificationStatus),
category: c.category?.[0]?.coding?.[0]?.code,
severity: normalizeSeverity(c.severity),
body_site: c.bodySite?.[0]?.text ?? c.bodySite?.[0]?.coding?.[0]?.display,
onset: c.onsetDateTime ?? c.onsetString,
abatement: c.abatementDateTime,
notes: c.note?.map(n => n.text),
confidence_score: c.confidence?.[0]?.valueDecimal,
spoken_forms: c.spokenForms?.map(e => e.valueString) ?? [],
provenance: turnRefs.map(t => t.turn?.valueInteger),
transcript_ref: turnRefs[0]?.transcript?.valueReference?.reference,
};
} dsp-* extension — and the canonical read selects each one explicitly.
Profile-added defaults (status, intent, hardcoded
categories, terminology canonicalization) are profile shape, not DSP data, and are intentionally not
reconstructed.
Servers without $graphql can use the documented REST fallback —
see $graphql fallbacks. The same field landings apply.
SQL-on-FHIR v2 ViewDefinitions that flatten every field above — including DSP extensions — into a tabular projection. Runnable as-is on any spec-conformant engine (Pathling, sof-exec, Aidbox SQL-on-FHIR, Databricks). See the SQL-on-FHIR v2 spec. These ViewDefinitions also ship as JSON in the IG zip.
dsp_condition — DSP Condition
Flattens a DSP condition resource: status, severity, onset, abatement, primary code.
{
"resourceType": "ViewDefinition",
"url": "https://dsp-fhir.org/ViewDefinition/dsp-condition",
"name": "dsp_condition",
"title": "DSP Condition",
"status": "draft",
"description": "Flattens a DSP condition resource: status, severity, onset, abatement, primary code.",
"resource": "Condition",
"fhirVersion": [
"4.0.1"
],
"select": [
{
"column": [
{
"name": "id",
"path": "id",
"type": "id",
"description": "Server-assigned logical id."
},
{
"name": "version_id",
"path": "meta.versionId",
"type": "id",
"description": "FHIR version id (drives NEW/UPDATED classification)."
},
{
"name": "last_updated",
"path": "meta.lastUpdated",
"type": "instant",
"description": "Instant of last mutation."
},
{
"name": "meta_source",
"path": "meta.source",
"type": "uri"
},
{
"name": "payload_version",
"path": "meta.tag.where(system='https://dsp-fhir.org/CodeSystem/payload-version').code.first()",
"type": "code",
"description": "DSP payload version this resource was last emitted under."
},
{
"name": "confidence_score",
"path": "extension('https://dsp-fhir.org/StructureDefinition/confidence-score').value.ofType(decimal)",
"type": "decimal",
"description": "DSP confidence (0..1)."
},
{
"name": "transcript_ref",
"path": "extension('https://dsp-fhir.org/StructureDefinition/transcript-turn-refs').extension('transcript').value.ofType(Reference).reference",
"type": "string",
"description": "DocumentReference/<id>/_history/<v> that pins the transcript version for turn indices."
},
{
"name": "turn_indices",
"path": "extension('https://dsp-fhir.org/StructureDefinition/transcript-turn-refs').extension('turn').value.ofType(integer)",
"type": "integer",
"collection": true,
"description": "Turn indices joined by $ground into transcript content."
},
{
"name": "spoken_forms",
"path": "extension('https://dsp-fhir.org/StructureDefinition/spoken-forms').extension('form').value.ofType(string)",
"type": "string",
"collection": true
},
{
"name": "search_terms",
"path": "extension('https://dsp-fhir.org/StructureDefinition/search-terms').extension('term').value.ofType(string)",
"type": "string",
"collection": true
},
{
"name": "subject_patient_id",
"path": "subject.reference.substring(8)",
"type": "string"
},
{
"name": "encounter_id",
"path": "encounter.reference.substring(10)",
"type": "string"
},
{
"name": "clinical_status",
"path": "clinicalStatus.coding.code.first()",
"type": "code"
},
{
"name": "verification_status",
"path": "verificationStatus.coding.code.first()",
"type": "code"
},
{
"name": "category_code",
"path": "category.coding.where(system='http://terminology.hl7.org/CodeSystem/condition-category').code.first()",
"type": "code"
},
{
"name": "severity_code",
"path": "severity.coding.code.first()",
"type": "code"
},
{
"name": "code_text",
"path": "code.text",
"type": "string"
},
{
"name": "snomed_code",
"path": "code.coding.where(system='http://snomed.info/sct').code.first()",
"type": "code"
},
{
"name": "icd10_code",
"path": "code.coding.where(system='http://hl7.org/fhir/sid/icd-10-cm').code.first()",
"type": "code"
},
{
"name": "primary_display",
"path": "code.coding.display.first()",
"type": "string"
},
{
"name": "body_site_code",
"path": "bodySite.coding.code.first()",
"type": "code"
},
{
"name": "onset_datetime",
"path": "onset.ofType(dateTime)",
"type": "dateTime"
},
{
"name": "onset_string",
"path": "onset.ofType(string)",
"type": "string"
},
{
"name": "abatement_datetime",
"path": "abatement.ofType(dateTime)",
"type": "dateTime"
},
{
"name": "stage_summary",
"path": "stage.summary.text.first()",
"type": "string"
},
{
"name": "recorded_date",
"path": "recordedDate",
"type": "dateTime"
},
{
"name": "priority",
"path": "extension('https://dsp-fhir.org/StructureDefinition/dsp-resource-priority').value.ofType(code)",
"type": "code"
},
{
"name": "concept_id",
"path": "extension('https://dsp-fhir.org/StructureDefinition/dsp-concept-id').value.ofType(string)",
"type": "string"
}
]
}
]
}dsp_condition_coding — DSP Condition coding (unnested)
One row per Condition.code.coding so SNOMED+ICD-10 co-codings are queryable.
{
"resourceType": "ViewDefinition",
"url": "https://dsp-fhir.org/ViewDefinition/dsp-condition-coding",
"name": "dsp_condition_coding",
"title": "DSP Condition coding (unnested)",
"status": "draft",
"description": "One row per Condition.code.coding so SNOMED+ICD-10 co-codings are queryable.",
"resource": "Condition",
"fhirVersion": [
"4.0.1"
],
"select": [
{
"column": [
{
"name": "condition_id",
"path": "id",
"type": "id"
}
],
"select": [
{
"forEach": "code.coding",
"column": [
{
"name": "system",
"path": "system",
"type": "uri"
},
{
"name": "code",
"path": "code",
"type": "code"
},
{
"name": "display",
"path": "display",
"type": "string"
},
{
"name": "user_selected",
"path": "userSelected",
"type": "boolean"
}
]
}
]
}
]
}