Kerndatensatz Senologie
0.9.0 - ci-build

Kerndatensatz Senologie - Local Development build (v0.9.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions

StructureMap: SenologieToObdsDiagnose

Official URL: https://www.senologie.org/fhir/StructureMap/SenologieToObdsDiagnose Version: 0.9.0
Draft as of 2026-05-04 Computable Name: SenologieToObdsDiagnose

title: Senologie Diagnose Bundle to oBDS Diagnosemeldung status: draft

map "https://www.senologie.org/fhir/StructureMap/SenologieToObdsDiagnose" = "SenologieToObdsDiagnose"

// title: Senologie Diagnose Bundle to oBDS Diagnosemeldung
// status: draft

uses "http://hl7.org/fhir/StructureDefinition/Bundle" alias Bundle as source
uses "http://hl7.org/fhir/StructureDefinition/Condition" alias Condition as source
uses "http://hl7.org/fhir/StructureDefinition/Observation" alias Observation as source
uses "http://hl7.org/fhir/StructureDefinition/RiskAssessment" alias RiskAssessment as source
uses "https://www.senologie.org/fhir/StructureDefinition/obds-meldung" alias OBDSMeldung as target

imports "https://www.senologie.org/fhir/StructureMap/SenologieToObdsTumorzuordnung"
imports "https://www.senologie.org/fhir/StructureMap/SenologieToObdsTNM"
imports "https://www.senologie.org/fhir/StructureMap/SenologieToObdsHistologie"
imports "https://www.senologie.org/fhir/StructureMap/SenologieToObdsModulMamma"
imports "https://www.senologie.org/fhir/StructureMap/SenologieToObdsLeistungszustand"

// Known limitation: Sub-groups (MapDiagnose, MapWeitereKlassifikation) use
// `target tgt : BackboneElement`. See SenologieToObdsTNM.map for details.
// ============================================================================
// Hauptgruppe: Bundle -> oBDS Diagnosemeldung
// Das Bundle enthaelt eine Condition (Diagnose) sowie zugehoerige
// Observations (TNM, Histologie, Hormonrezeptoren).
// ============================================================================
group SenologieToObdsDiagnose(source src : Bundle, target tgt : OBDSMeldung) {
  // Tumorzuordnung: aus der Condition-Ressource
  src.entry as entry where resource.is(Condition) then {
    entry.resource as condition then {
      condition -> tgt.tumorzuordnung as tz then MapTumorzuordnung(condition, tz) "CallMapTumorzuordnung";
    } "ConditionContext";
  } "EntryConditionTZ";
  // Diagnose: aus der Condition-Ressource + Observations aus dem Bundle
  src.entry as entry where resource.is(Condition) then {
    entry.resource as condition -> tgt.diagnose as dx then MapDiagnose(condition, dx) "CallMapDiagnose";
    // Histologie from bundle (moved from MapDiagnose)
    src.entry as histEntry where resource.is(Observation) and resource.code.coding.exists(code = '59847-4') then {
      histEntry.resource as histObs -> dx.histologie as histo then MapHistologie(histObs, histo) "CallMapHistologie";
      src.entry as specEntry where resource.is(Specimen) then {
        specEntry.resource as specimen then {
          specimen.accessionIdentifier as accId then {
            accId.value as v -> histo.histologieEinsendeNr = v "SetEinsendeNrFromSpecimen";
          } "MapAccessionId";
          specimen.collection as coll then {
            coll.collected as collDt where $this.is(dateTime) -> histo.tumorHistologiedatum = collDt "SetHistologiedatumFromSpecimen";
          } "MapSpecimenCollection";
        } "SpecimenContext";
      } "EntrySpecimen";
      src.entry as gradEntry where resource.is(Observation) and resource.code.coding.exists(code = '59542-1') then {
        gradEntry.resource as gradObs then {
          gradObs.value as val then {
            val.coding as c -> histo.grading = translate(c, 'https://www.senologie.org/fhir/ConceptMap/cm-sct-to-obds-grading', 'code') "TranslateGradingSeparate";
          } "MapGradingSepValue";
        } "MapGradingSepObs";
      } "EntryGrading";
      src.entry as lkEntry where resource.is(Observation) and resource.code.coding.exists(code = '21894-1') then {
        lkEntry.resource as lkObs then {
          lkObs.value as val -> histo.lkUntersucht = val "SetLKUntersuchtSeparate";
        } "MapLKUntersuchtSep";
      } "EntryLKUntersucht";
      src.entry as lkbEntry where resource.is(Observation) and resource.code.coding.exists(code = '21893-3') then {
        lkbEntry.resource as lkbObs then {
          lkbObs.value as val -> histo.lkBefallen = val "SetLKBefallenSeparate";
        } "MapLKBefallenSep";
      } "EntryLKBefallen";
      src.entry as slkEntry where resource.is(Observation) and resource.code.coding.exists(code = '92832-5') then {
        slkEntry.resource as slkObs then {
          slkObs.value as val -> histo.sentinelLKUntersucht = val "SetSentinelLKUntersuchtSeparate";
        } "MapSentinelLKUntersuchtSep";
      } "EntrySentinelLKUntersucht";
      src.entry as slkbEntry where resource.is(Observation) and resource.code.coding.exists(code = '92831-7') then {
        slkbEntry.resource as slkbObs then {
          slkbObs.value as val -> histo.sentinelLKBefallen = val "SetSentinelLKBefallenSeparate";
        } "MapSentinelLKBefallenSep";
      } "EntrySentinelLKBefallen";
    } "EntryHistologie";
    // cTNM from bundle (moved from MapDiagnose)
    src.entry as tnmEntry where resource.is(Observation) and resource.code.coding.exists(code = '21908-9') then {
      tnmEntry.resource as tnmObs -> dx.cTNM as ctnm then MapTNM(tnmObs, ctnm) "CallMapCTNM";
    } "EntryCTNM";
    // Leistungszustand from bundle (moved from MapDiagnose)
    entry.resource as cond2 -> tgt.diagnose as dx2 then MapLeistungszustandFromBundle(src, dx2) "CallMapLeistungszustand";
    // Modul_Mamma from bundle (moved from MapDiagnose)
    entry.resource as cond3 ->  tgt.diagnose as dx3,  dx3.modulMamma as mamma then MapModulMamma(src, mamma) "CallMapModulMamma";
    // Weitere Klassifikationen from bundle (moved from MapDiagnose)
    src.entry as raEntry where resource.is(RiskAssessment) then {
      raEntry.resource as ra ->  tgt.diagnose as dx4,  dx4.weitereKlassifikationen as wk then MapWeitereKlassifikation(ra, wk) "CallMapWeitereKlassifikation";
    } "EntryWeitereKlassifikation";
  } "EntryConditionDX";
}

// ============================================================================
// Diagnose: Condition -> OBDSMeldung.diagnose
// Freitextdiagnose, ICD-O Topographie, Diagnosesicherung, fruehere Erkrankungen
// ============================================================================
group MapDiagnose(source src : Condition, target tgt : BackboneElement) {
  // Primaertumor_Diagnosetext: aus Condition.code.text
  src.code as code then {
    code.text as t -> tgt.primaertumorDiagnosetext = t "SetDiagnosetext";
  } "MapDiagnosetext";
  // Primaertumor_Topographie_ICD_O: ICD-O Topographie aus Condition.bodySite
  src.bodySite as bs then {
    bs.coding as c where system = 'urn:oid:2.16.840.1.113883.6.43.1' -> tgt.primaertumorTopographieICDO as topo then {
      c.code as cd -> topo.code = cd "SetTopoCode";
      c.version as v -> topo.version = v "SetTopoVersion";
    } "MapTopoCoding";
  } "MapTopographie";
  // Primaertumor_Topographie_Freitext: aus Condition.bodySite.text
  src.bodySite as bs then {
    bs.text as t -> tgt.primaertumorTopographieFreitext = t "SetTopoFreitext";
  } "MapTopoFreitext";
  // Diagnosesicherung: aus verificationStatus (MII Onko Diagnosesicherung Coding)
  src.verificationStatus as vs then {
    vs.coding as c where system = 'https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/CodeSystem/mii-cs-onko-primaertumor-diagnosesicherung' then {
      c.code as cd -> tgt.diagnosesicherung = cd "SetDiagnosesicherung";
    } "ExtractDiagnosesicherungCode";
  } "MapDiagnosesicherung";
  // Fruehere Tumorerkrankungen: aus Condition.extension (falls vorhanden)
  src.extension as ext where url = 'http://hl7.org/fhir/StructureDefinition/condition-related' then {
    ext.value as ref -> tgt.fruehereErkrankungen as fe then {
      ref.display as d -> fe.freitext = d "SetFrueherFreitext";
    } "MapFruehereErkrankung";
  } "MapFruehereErkrankungen";
// Histologie, cTNM, Leistungszustand, ModulMamma, WeitereKlassifikationen
// bundle lookups moved to calling group.
}

// ============================================================================
// Weitere Klassifikation: RiskAssessment (Genexpressionstest) -> Menge_Weitere_Klassifikation
// Mappt Genexpressionstests wie Oncotype DX, MammaPrint auf das oBDS-Element
// "Weitere_Klassifikation" (Datum, Name, Stadium/Ergebnis).
// ============================================================================
group MapWeitereKlassifikation(source src : RiskAssessment, target tgt : BackboneElement) {
  // Datum: aus RiskAssessment.occurrenceDateTime
  src.occurrence as occ where $this.is(dateTime) -> tgt.datum = occ "SetWKDatum";
  // Name: aus RiskAssessment.method.coding.display oder method.text
  src.method as m then {
    m.coding as c where system = 'https://www.senologie.org/fhir/CodeSystem/cs-senologie-genexpressionstest' then {
      c.display as d -> tgt.name = d "SetWKNameDisplay";
    } "MapWKMethodCoding";
    m.text as t -> tgt.name = t "SetWKNameText";
  } "MapWKMethod";
  // Stadium: aus RiskAssessment.prediction[0].qualitativeRisk.text + basis-Observation
  // Format: "<Score> (<RiskCategory>)"
  src.prediction as pred then {
    pred.qualitativeRisk as qr then {
      qr.text as t -> tgt.stadium = t "SetWKStadiumQualitativeText";
      qr.coding as c then {
        c.display as d -> tgt.stadium = d "SetWKStadiumQualitativeDisplay";
      } "MapWKQRCoding";
    } "MapWKQR";
  } "MapWKPrediction";
}