Therapy order

DSP therapy orders cover PT, OT, ST, cardiac/pulmonary rehab, and respiratory therapy. These are procedural referrals, not continuous interventions — ServiceRequest (category=therapy) is the right fit. Realization as delivered care (encounters, procedures) happens downstream.

DSP content_type

order.therapy

FHIR target

ServiceRequest (category=therapy)

Field-by-field

DSPFHIR R4Notes
type: THERAPY_ORDERServiceRequest.category = therapyUse IG CodeSystem order-category code therapy, or SNOMED 277132007 (therapeutic procedure).
order_data.therapy_typecodeSNOMED: 91251008 physical therapy, 5880005 physical exam? no — OT: 310483005, ST: 708176008.
order_data.frequency / sessions_per_weekoccurrenceTiming.repeat.frequency / period / periodUnit"3×/wk for 6 weeks" → frequency=3, period=1, periodUnit=wk, boundsDuration=6wk.
order_data.durationoccurrenceTiming.repeat.boundsDuration
order_data.focus / goalsorderDetail + link to Goal via Goal.addressesTherapy goals (strength, ROM, gait) belong on Goal resources for progress tracking. DSP can emit them as child resources.
order_data.body_sitebodySiteSNOMED.
order_data.performer_specialtyperformerTypee.g. "physical therapist" (SNOMED 36682004).
reasonreasonCode / reasonReference

Side-by-side example

DSP

{
  "id": "therapy-001",
  "type": "THERAPY_ORDER",
  "context": { "content_type": "order.therapy" },
  "description": "Physical therapy, right knee, 3x/week for 6 weeks, focus on strength and ROM post-ACL repair",
  "intent": "order",
  "reason": "Status post right ACL reconstruction; deconditioning",
  "reason_references": ["cond-006"],
  "provenance": [58, 60, 62],
  "order_data": {
    "therapy_type": "91251008",
    "therapy_type_system": "SNOMED",
    "body_site": "6757004",
    "frequency_per_week": 3,
    "duration": { "value": 6, "unit": "week" },
    "focus": ["strength","range_of_motion"],
    "performer_specialty": "physical_therapist"
  }
}

FHIR R4 (DSP-FHIR profile)

{
  "resourceType":"ServiceRequest",
  "status":"active","intent":"order",
  "category":[{"coding":[{"system":"https://dsp-fhir.org/CodeSystem/order-category","code":"therapy"}]}],
  "code":{"coding":[{"system":"http://snomed.info/sct","code":"91251008","display":"Physical therapy procedure"}]},
  "bodySite":[{"coding":[{"system":"http://snomed.info/sct","code":"6757004","display":"Right knee"}]}],
  "subject":{"reference":"Patient/pat-67890"},
  "encounter":{"reference":"Encounter/enc-12345"},
  "occurrenceTiming":{
    "repeat":{
      "frequency":3,"period":1,"periodUnit":"wk",
      "boundsDuration":{"value":6,"unit":"wk","system":"http://unitsofmeasure.org","code":"wk"}
    }
  },
  "performerType":{"coding":[{"system":"http://snomed.info/sct","code":"36682004","display":"Physical therapist"}]},
  "orderDetail":[
    {"coding":[{"system":"https://dsp-fhir.org/CodeSystem/therapy-focus","code":"strength"}]},
    {"coding":[{"system":"https://dsp-fhir.org/CodeSystem/therapy-focus","code":"range-of-motion"}]}
  ],
  "reasonCode":[{"text":"Status post right ACL reconstruction; deconditioning"}],
  "reasonReference":[{"reference":"Condition/cond-006"}]
}

DSP → FHIR mapping

Skeleton for DspTherapyOrder → ServiceRequest(category=therapy). Orthogonal Goal resources are produced by a sibling map.

map "https://dsp-fhir.org/StructureMap/DspTherapyOrderToServiceRequest" = "DspTherapyOrderToServiceRequest"

uses "https://dsp-fhir.org/StructureDefinition/DspResource" alias DspResource as source
uses "http://hl7.org/fhir/StructureDefinition/ServiceRequest" alias ServiceRequest as target

group DspTherapyOrderToServiceRequest(source src : DspResource, target tgt : ServiceRequest) {
  src.id as id -> tgt.id = id;
  src -> tgt.status = 'active';
  src -> tgt.intent = 'order';
  src -> tgt.category as cat, cat.coding as co,
    co.system = 'https://dsp-fhir.org/CodeSystem/dsp-order-category',
    co.code = 'therapy' "category";

  src.payload as p then {
    p.therapy_type as tt -> tgt.code as code, code.text = tt "code-text";
    p.frequency as f -> tgt.occurrenceTiming as t, t.repeat as rep, rep.frequency = f "freq";
    p.duration_weeks as dw -> tgt.occurrenceTiming as t, t.repeat as rep,
      rep.boundsDuration as bd, bd.value = dw, bd.unit = 'wk',
      bd.system = 'http://unitsofmeasure.org', bd.code = 'wk' "duration";
  };

  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";
}

// Therapy goals (if DSP emits them) are mapped separately to Goal resources,
// with Goal.addresses -> Condition and ServiceRequest.basedOn -> Goal.

FHIR → DSP (canonical $graphql read)

ServiceRequest's occurrenceTiming.repeat carries the frequency / period / boundsDuration triple — sufficient to recover DSP's "3×/wk for 6 weeks" exactly.

Canonical query

query DspTherapyOrder($id: ID!) {
  ServiceRequest(id: $id) {
    id status intent
    code { text coding { system code display } }
    bodySite { coding { system code display } text }
    performerType { coding { system code display } text }
    occurrenceTiming {
      repeat {
        frequency period periodUnit
        boundsDuration { value unit system code }
      }
    }
    orderDetail { coding { system code display } }
    reasonCode { text }
    reasonReference { reference }

    confidence: extension(url: "https://dsp-fhir.org/StructureDefinition/dsp-confidence-score") {
      valueDecimal
    }
    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

function toDspTherapyOrder(s) {
  const r   = s.occurrenceTiming?.repeat;
  const bd  = r?.boundsDuration;
  const turnRefs = s.turnRefs ?? [];
  return {
    id: s.id,
    type: 'THERAPY_ORDER',
    intent: s.intent,
    description: s.code?.text,
    reason: s.reasonCode?.[0]?.text,
    reason_references: s.reasonReference?.map(r => r.reference),
    order_data: {
      therapy_type:        s.code?.coding?.[0]?.code,
      therapy_type_system: s.code?.coding?.[0]?.system,
      body_site:           s.bodySite?.[0]?.coding?.[0]?.code,
      frequency_per_week:  r?.periodUnit === 'wk' ? r?.frequency : undefined,
      duration:            bd && { value: bd.value, unit: bd.code ?? bd.unit },
      focus:               s.orderDetail?.map(d => d.coding?.[0]?.code),
      performer_specialty: s.performerType?.coding?.[0]?.code,
    },
    confidence_score: s.confidence?.[0]?.valueDecimal,
    provenance:       turnRefs.map(t => t.turn?.valueInteger),
    transcript_ref:   turnRefs[0]?.transcript?.valueReference?.reference,
  };
}
No data loss. Therapy frequency/duration round-trip exactly. Per-encounter Goal resources (if emitted) are queried separately.

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_service_request_therapy — DSP Therapy order (ServiceRequest)

Flattens DSP dsp therapy order (servicerequest) orders. Filtered by category=therapy.

{
  "resourceType": "ViewDefinition",
  "url": "https://dsp-fhir.org/ViewDefinition/dsp-service-request-therapy",
  "name": "dsp_service_request_therapy",
  "title": "DSP Therapy order (ServiceRequest)",
  "status": "draft",
  "description": "Flattens DSP dsp therapy order (servicerequest) orders. Filtered by category=therapy.",
  "resource": "ServiceRequest",
  "fhirVersion": [
    "4.0.1"
  ],
  "where": [
    {
      "path": "category.coding.where(code='therapy').exists()"
    }
  ],
  "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": "status",
          "path": "status",
          "type": "code"
        },
        {
          "name": "intent",
          "path": "intent",
          "type": "code"
        },
        {
          "name": "priority",
          "path": "priority",
          "type": "code"
        },
        {
          "name": "subject_patient_id",
          "path": "subject.reference.substring(8)",
          "type": "string"
        },
        {
          "name": "encounter_id",
          "path": "encounter.reference.substring(10)",
          "type": "string"
        },
        {
          "name": "authored_on",
          "path": "authoredOn",
          "type": "dateTime"
        },
        {
          "name": "requester_practitioner_id",
          "path": "requester.reference.where($this.startsWith('Practitioner/')).substring(13).first()",
          "type": "string"
        },
        {
          "name": "code_system",
          "path": "code.coding.system.first()",
          "type": "uri"
        },
        {
          "name": "code",
          "path": "code.coding.code.first()",
          "type": "code"
        },
        {
          "name": "code_display",
          "path": "code.coding.display.first()",
          "type": "string"
        },
        {
          "name": "code_text",
          "path": "code.text",
          "type": "string"
        },
        {
          "name": "reason_code_text",
          "path": "reasonCode.text.first()",
          "type": "string"
        },
        {
          "name": "reason_reference",
          "path": "reasonReference.reference.first()",
          "type": "string"
        },
        {
          "name": "body_site_code",
          "path": "bodySite.coding.code.first()",
          "type": "code"
        },
        {
          "name": "therapy_kind",
          "path": "category.coding.where(system='https://dsp-fhir.org/CodeSystem/therapy-kind').code.first()",
          "type": "code",
          "description": "PT/OT/SLP/respiratory/behavioral etc."
        },
        {
          "name": "frequency",
          "path": "occurrence.ofType(Timing).repeat.frequency.first()",
          "type": "integer"
        },
        {
          "name": "period",
          "path": "occurrence.ofType(Timing).repeat.period.first()",
          "type": "decimal"
        },
        {
          "name": "period_unit",
          "path": "occurrence.ofType(Timing).repeat.periodUnit.first()",
          "type": "code"
        }
      ]
    }
  ]
}

dsp_goal_therapy — DSP Therapy Goal

Flattens the optional Goal attached to a DSP therapy ServiceRequest.

{
  "resourceType": "ViewDefinition",
  "url": "https://dsp-fhir.org/ViewDefinition/dsp-goal-therapy",
  "name": "dsp_goal_therapy",
  "title": "DSP Therapy Goal",
  "status": "draft",
  "description": "Flattens the optional Goal attached to a DSP therapy ServiceRequest.",
  "resource": "Goal",
  "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": "lifecycle_status",
          "path": "lifecycleStatus",
          "type": "code"
        },
        {
          "name": "achievement_status",
          "path": "achievementStatus.coding.code.first()",
          "type": "code"
        },
        {
          "name": "description_text",
          "path": "description.text",
          "type": "string"
        },
        {
          "name": "target_measure_code",
          "path": "target.measure.coding.code.first()",
          "type": "code"
        },
        {
          "name": "target_quantity_value",
          "path": "target.detail.ofType(Quantity).value.first()",
          "type": "decimal"
        },
        {
          "name": "target_due_date",
          "path": "target.due.ofType(date).first()",
          "type": "date"
        },
        {
          "name": "addresses_condition_ref",
          "path": "addresses.reference.where($this.startsWith('Condition/')).substring(10).first()",
          "type": "string"
        }
      ]
    }
  ]
}
Orthogonal resources. If the payload carries therapy goals, emit them as Goal resources with Goal.addresses pointing at the underlying Condition and Goal.outcomeReference / outcomeCode for measurable targets. The therapy ServiceRequest then links back via supportingInfo.