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: SenologieToOncoBoxBrustPrimaerfall

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

title: Senologie Condition + Patient + Encounter to OncoBox Brust Primaerfall status: draft

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

// title: Senologie Condition + Patient + Encounter to OncoBox Brust Primaerfall
// status: draft

uses "http://hl7.org/fhir/StructureDefinition/Bundle" alias Bundle as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" alias Patient as source
uses "http://hl7.org/fhir/StructureDefinition/Encounter" alias Encounter 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/Procedure" alias Procedure as source
uses "http://hl7.org/fhir/StructureDefinition/CarePlan" alias CarePlan as source
uses "http://hl7.org/fhir/StructureDefinition/ResearchSubject" alias ResearchSubject as source

imports "https://www.senologie.org/fhir/StructureMap/SenologieToOncoBoxBrustOperation"
imports "https://www.senologie.org/fhir/StructureMap/SenologieToOncoBoxBrustTherapie"
imports "https://www.senologie.org/fhir/StructureMap/SenologieToOncoBoxBrustVerlauf"

// Import-only map: no target `uses` declaration — the calling map
// (SenologieToOncoBoxBrust) provides the correct BackboneElement context
// (primaerfall). Omitting the root-level target type avoids SM_TARGET_PATH
// false positives where the validator would resolve property names against
// oncobox-brust-meldung root.
// ============================================================================
// Primaerfall: Condition (Brust-Diagnose) + Patient + Encounter -> Primaerfall
// Pro Primaerfall (Condition mit ICD-10 aus dem Mamma-Spektrum) werden
// Patientendaten, Fall-Daten, Diagnose-Block und Therapie-Subblocks befuellt.
// ============================================================================
group MapPrimaerfall(source bundle : Bundle, target tgt : BackboneElement) {
  // --- Condition (Brust-Diagnose) aus dem Bundle extrahieren ---
  bundle.entry as condEntry where resource.is(Condition) and resource.code.coding.exists((system = 'http://fhir.de/CodeSystem/bfarm/icd-10-gm') and (code.startsWith('C50') or code.startsWith('D05') or code.startsWith('D24') or code.startsWith('Z40') or code.startsWith('Z42'))) then {
    condEntry.resource as src then {
      // --- Fall-ID aus Condition.id ---
      src.id as cid -> tgt.fallId = cid "SetFallId";
      // --- Primaerfallart aus ICD-10 ableiten ---
      src.code as code then {
        code.coding as c where system = 'http://fhir.de/CodeSystem/bfarm/icd-10-gm' then {
          c.code as cd where $this.startsWith('C50') -> tgt.primaerfallart = '1' "SetPfArtInvasiv";
          c.code as cd where $this.startsWith('D05') -> tgt.primaerfallart = '2' "SetPfArtDCIS";
          c.code as cd where $this.startsWith('Z40') -> tgt.primaerfallart = '7' "SetPfArtRisiko";
          c.code as cd where $this.startsWith('Z42') -> tgt.primaerfallart = '8' "SetPfArtRekon";
          c.code as cd where $this.startsWith('D24') -> tgt.primaerfallart = '9' "SetPfArtBenigne";
        } "MapPrimaerfallartICD";
      } "MapPrimaerfallart";
      // --- Diagnose-Block ---
      src -> tgt.diagnose as diag then MapDiagnose(src, diag) "CallMapDiagnose";
    } "ConditionCtx";
  } "EntryCondition";
  // --- Patientendaten ---
  bundle.entry as entry where resource.is(Patient) then {
    entry.resource as patient -> tgt.patient as pat then MapPatient(patient, pat) "CallMapPatient";
    entry.resource as patient then {
      patient.id as pid -> tgt.patientPseudonym = pid "SetPatientPseudonym";
    } "PseudCtx";
    // Menopausenstatus aus Observation (moved from MapPatient)
    bundle.entry as menoEntry where resource.is(Observation) and resource.code.coding.exists(code = '86805-9') then {
      menoEntry.resource as obs then {
        obs.value as val then {
          val.coding as c then {
            c.code as cd where $this = '289903006' -> pat.menopausenstatus = '1' "SetMenoPrae";
            c.code as cd where $this = '289904000' -> pat.menopausenstatus = '2' "SetMenoPeri";
            c.code as cd where $this = '76977008' -> pat.menopausenstatus = '3' "SetMenoPost";
          } "MapMenoCoding";
        } "MapMenoVal";
      } "MapMenoObs";
    } "EntryMeno";
  } "EntryPatient";
  // --- Fall aus Encounter ---
  bundle.entry as entry where resource.is(Encounter) then {
    entry.resource as encounter -> tgt.fall as fall then MapFall(encounter, fall) "CallMapFall";
  } "EntryEncounter";
  // --- Diagnose bundle lookups (moved from MapDiagnose) ---
  // Histologische Sicherung praeoperativ
  bundle.entry as specEntry where resource.is(Specimen) and resource.meta.profile.exists($this.contains('senologie-pathologie-praeparat')) then {
    specEntry.resource as specimen then {
      specimen.type as t then {
        t.coding as c where code = '122737001' -> tgt.diagnose as diag then {
          c -> diag.histologischeSicherungPraeop = '1' "SetHistPraeopStanz";
        } "WrapHistPraeopStanz";
        t.coding as c where code = '399014008' -> tgt.diagnose as diag then {
          c -> diag.histologischeSicherungPraeop = '2' "SetHistPraeopVakuum";
        } "WrapHistPraeopVakuum";
        t.coding as c where code = '119342007' -> tgt.diagnose as diag then {
          c -> diag.histologischeSicherungPraeop = '3' "SetHistPraeopFNA";
        } "WrapHistPraeopFNA";
        t.coding as c where code = '119380005' -> tgt.diagnose as diag then {
          c -> diag.histologischeSicherungPraeop = '4' "SetHistPraeopOffen";
        } "WrapHistPraeopOffen";
      } "MapHistPraeopType";
    } "MapHistPraeopSpec";
  } "EntryHistPraeop";
  // Bildgebung
  bundle.entry as bgEntry where resource.is(Observation) and resource.meta.profile.exists($this.contains('senologie-bildgebung')) then {
    bgEntry.resource as obs -> tgt.diagnose as diag then {
      obs -> diag.bildgebung as bg then MapBildgebung(obs, bg) "CallMapBgInner";
    } "WrapBgDiag";
  } "EntryBg";
  // cTNM, pTNM, Histologie, Grading, Lymphknoten, Rezeptorstatus
  // (bundle lookups target diagnose sub-elements via tgt.diagnose)
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '21905-5') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.cTNM as ctnm then {
      obs.value as val then {
        val.coding as c then {
          c.code as cd -> ctnm.cT = cd "SetCT";
        } "MapCTCoding";
      } "MapCTVal";
    } "MapCT";
  } "EntryCT";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '21906-3') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.cTNM as ctnm then {
      obs.value as val then {
        val.coding as c then {
          c.code as cd -> ctnm.cN = cd "SetCN";
        } "MapCNCoding";
      } "MapCNVal";
    } "MapCN";
  } "EntryCN";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '21907-1') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.cTNM as ctnm then {
      obs.value as val then {
        val.coding as c then {
          c.code as cd -> ctnm.cM = cd "SetCM";
        } "MapCMCoding";
      } "MapCMVal";
    } "MapCM";
  } "EntryCM";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '44648-0') and resource.meta.profile.exists($this.contains('senologie-bildgebung') or $this.contains('senologie-tumorgroesse')).not() then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.cTNM as ctnm then {
      obs.value as val then {
        val.value as v -> ctnm.tumorgroesseKlinisch = truncate(v) "SetTGKlin";
      } "MapTGKlinVal";
    } "MapTGKlin";
  } "EntryTGKlin";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '21899-0') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.pTNM as ptnm then {
      obs.value as val then {
        val.coding as c then {
          c.code as cd -> ptnm.pT = cd "SetPT";
        } "MapPTCoding";
      } "MapPTVal";
    } "MapPT";
  } "EntryPT";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '21900-6') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.pTNM as ptnm then {
      obs.value as val then {
        val.coding as c then {
          c.code as cd -> ptnm.pN = cd "SetPN";
        } "MapPNCoding";
      } "MapPNVal";
    } "MapPN";
  } "EntryPN";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '21901-4') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.pTNM as ptnm then {
      obs.value as val then {
        val.coding as c then {
          c.code as cd -> ptnm.pM = cd "SetPM";
        } "MapPMCoding";
      } "MapPMVal";
    } "MapPM";
  } "EntryPM";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '33728-7') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.pTNM as ptnm then {
      obs.value as val then {
        val.value as v -> ptnm.tumorgroesseInvasiv = truncate(v) "SetTGInv";
      } "MapTGInvVal";
    } "MapTGInv";
  } "EntryTGInv";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '21908-9') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.cTNM as ctnm then {
      obs.method as method then {
        method.coding as c then {
          c.code as cd -> ctnm.tnmVersion = cd "SetCTNMVersion";
        } "ExtractCTNMVersionCode";
      } "MapCTNMVersion";
      obs.value as val then {
        val.coding as c then {
          c.code as cd -> ctnm.uiccStadium = cd "SetCUICC";
        } "ExtractCUICC";
      } "MapCUICC";
    } "MapCTNMDetail";
  } "EntryCTNMDetail";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '21902-2') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.pTNM as ptnm then {
      obs.method as method then {
        method.coding as c then {
          c.code as cd -> ptnm.tnmVersion = cd "SetPTNMVersion";
        } "ExtractPTNMVersionCode";
      } "MapPTNMVersion";
      obs.value as val then {
        val.coding as c then {
          c.code as cd -> ptnm.uiccStadium = cd "SetPUICC";
        } "ExtractPUICC";
      } "MapPUICC";
      obs.component as comp where code.coding.exists(code = '59479-6') then {
        comp.value as val then {
          val.coding as c then {
            c.code as cd -> ptnm.ySymbol = cd "SetYSymbol";
          } "ExtractYCode";
        } "MapYValue";
      } "MapYSymbol";
      obs.component as comp where code.coding.exists(code = '33739-4') then {
        comp.value as val then {
          val.coding as c then {
            c.code as cd -> ptnm.l = cd "SetLKat";
          } "ExtractLCode";
        } "MapLValue";
      } "MapLKat";
      obs.component as comp where code.coding.exists(code = '33740-2') then {
        comp.value as val then {
          val.coding as c then {
            c.code as cd -> ptnm.v = cd "SetVKat";
          } "ExtractVCode";
        } "MapVValue";
      } "MapVKat";
      obs.component as comp where code.coding.exists(code = '92837-4') then {
        comp.value as val then {
          val.coding as c then {
            c.code as cd -> ptnm.pn = cd "SetPnKat";
          } "ExtractPnCode";
        } "MapPnValue";
      } "MapPnKat";
    } "MapPTNMDetail";
  } "EntryPTNMDetail";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '59847-4') then {
    entry.resource as obs -> tgt.diagnose as diag then {
      obs.value as val then {
        val.coding as c where system = 'urn:oid:2.16.840.1.113883.6.43.1' -> diag.diagnoseICDO as icdo then {
          c.code as cd -> icdo.code = cd "SetHistCode";
          c.version as v -> icdo.version = v "SetHistVersion";
        } "MapHistICDO";
      } "MapHistValue";
    } "MapHistObs";
  } "EntryHistologie";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '33732-9') then {
    entry.resource as obs -> tgt.diagnose as diag then {
      obs.value as val then {
        val.coding as c then {
          c.code as cd -> diag.grading = cd "SetGrading";
        } "MapGrading";
      } "MapGradingVal";
    } "MapGradingObs";
  } "EntryGrading";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '21894-1') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.lymphknoten as lk then {
      obs.value as val then {
        val.value as v -> lk.untersucht = truncate(v) "SetLKUnt";
      } "MapLKUntVal";
    } "MapLKUnt";
  } "EntryLKUnt";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '21893-3') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.lymphknoten as lk then {
      obs.value as val then {
        val.value as v -> lk.befallen = truncate(v) "SetLKBef";
      } "MapLKBefVal";
    } "MapLKBef";
  } "EntryLKBef";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '92832-5') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.lymphknoten as lk then {
      obs.value as val then {
        val.value as v -> lk.sentinelUntersucht = truncate(v) "SetSLKUnt";
      } "MapSLKUntVal";
    } "MapSLKUnt";
  } "EntrySLKUnt";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '92833-3') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.lymphknoten as lk then {
      obs.value as val then {
        val.value as v -> lk.sentinelBefallen = truncate(v) "SetSLKBef";
      } "MapSLKBefVal";
    } "MapSLKBef";
  } "EntrySLKBef";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '85337-4') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.rezeptorstatus as rez then {
      obs.value as val then {
        val.coding as c where code = '10828004' -> rez.erStatus = 'P' "SetERPositiv";
        val.coding as c where code = '260385009' -> rez.erStatus = 'N' "SetERNegativ";
        val.coding as c where code = '261665006' -> rez.erStatus = 'U' "SetERUnbekannt";
      } "MapER";
    } "MapERObs";
  } "EntryER";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '85339-0') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.rezeptorstatus as rez then {
      obs.value as val then {
        val.coding as c where code = '10828004' -> rez.prStatus = 'P' "SetPRPositiv";
        val.coding as c where code = '260385009' -> rez.prStatus = 'N' "SetPRNegativ";
        val.coding as c where code = '261665006' -> rez.prStatus = 'U' "SetPRUnbekannt";
      } "MapPR";
    } "MapPRObs";
  } "EntryPR";
  bundle.entry as entry where resource.is(Observation) and resource.code.coding.exists(code = '85319-2') then {
    entry.resource as obs ->  tgt.diagnose as diag,  diag.rezeptorstatus as rez then {
      obs.value as val then {
        val.coding as c where code = '10828004' -> rez.her2Status = 'P' "SetHER2Positiv";
        val.coding as c where code = '260385009' -> rez.her2Status = 'N' "SetHER2Negativ";
        val.coding as c where code = '261665006' -> rez.her2Status = 'U' "SetHER2Unbekannt";
      } "MapHER2";
    } "MapHER2Obs";
  } "EntryHER2";
  // --- Operationen ---
  bundle.entry as entry where resource.is(Procedure) and resource.meta.profile.exists($this.contains('senologie-brustop') or $this.contains('senologie-operation')) then {
    entry.resource as procedure -> tgt.operation as op then MapOperation(procedure, op) "CallMapOperation";
    // Op: Drahtmarkierung aus ServiceRequest
    bundle.entry as srEntry where resource.is(ServiceRequest) then {
      srEntry.resource as sr then {
        sr.extension as ext where url = 'https://www.senologie.org/fhir/StructureDefinition/ex-senologie-pre-op-markierung' then {
          ext.value as val then {
            val.coding as c where code = 'N' -> op.drahtmarkierung = '0' "SetDrahtKeine";
            val.coding as c where code = 'S' -> op.drahtmarkierung = '1' "SetDrahtSono";
            val.coding as c where code = 'M' -> op.drahtmarkierung = '2' "SetDrahtMammo";
            val.coding as c where code = 'T' -> op.drahtmarkierung = '3' "SetDrahtMRT";
          } "MapDrahtVal";
        } "MapDrahtExt";
      } "MapDrahtSR";
    } "EntryDrahtSR";
    // Op: Schnellschnitt / Praeparatkontrolle aus Specimen
    bundle.entry as specEntry where resource.is(Specimen) and resource.meta.profile.exists($this.contains('senologie-pathologie-praeparat')) then {
      specEntry.resource as specimen then {
        specimen.processing as proc where procedure.coding.exists(code = '123038009') -> op.intraopSchnellschnitt = '1' "SetSSJa";
        specimen.processing as proc then {
          proc.procedure as p then {
            p.coding as c where system = 'http://snomed.info/sct' then {
              c.code as cd where $this = '71651007' -> op.intraopPraeparatkontrolle = '1' "SetPKMammo";
              c.code as cd where $this = '16310003' -> op.intraopPraeparatkontrolle = '2' "SetPKSono";
            } "MapPKCoding";
          } "MapPKProcedure";
        } "MapPKProcessing";
      } "SpecCtx";
    } "EntrySpecimen";
    // Op: Komplikationen aus Observations
    bundle.entry as kompEntry where resource.is(Observation) and resource.meta.profile.exists($this.contains('senologie-operative-komplikation')) then {
      kompEntry.resource as obs -> op.komplikationen as komp then {
        obs.component as comp where code.coding.exists(code = '116224001') then {
          comp.value as val then {
            val.coding as c then {
              c.code as cd -> komp.kuerzel = cd "SetKompKuerzel";
            } "MapKompKuerzelCoding";
          } "MapKompKuerzelVal";
        } "MapKompKuerzelComp";
        obs.value as val then {
          val.coding as c where system = 'http://snomed.info/sct' then {
            c.code as cd -> komp.clavienDindo = cd "SetKompClavien";
          } "MapKompClavienCoding";
        } "MapKompClavien";
      } "MapKompObs";
    } "EntryKomp";
  } "EntryOperation";
  // --- Systemtherapie ---
  bundle.entry as entry where resource.is(Procedure) and resource.meta.profile.exists($this.contains('senologie-systemtherapie-procedure')) then {
    entry.resource as procedure -> tgt.systemtherapie as syst then MapSystemtherapie(procedure, syst) "CallMapSystemtherapie";
  } "EntrySystemtherapie";
  // --- Endokrine Therapie (Systemtherapie mit therapieart=HO) ---
  bundle.entry as entry where resource.is(Procedure) and resource.meta.profile.exists($this.contains('senologie-systemtherapie-procedure')) then {
    entry.resource as procedure where code.coding.exists((system = 'https://www.medizininformatik-initiative.de/fhir/ext/modul-onko/CodeSystem/mii-cs-onko-therapie-typ') and (code = 'HO')) then {
      procedure -> tgt.endokrineTherapie as endo then MapEndokrineTherapie(procedure, endo) "CallMapEndoTherapie";
    } "CheckHO";
  } "EntryEndoTherapie";
  // --- Strahlentherapie ---
  bundle.entry as entry where resource.is(Procedure) and resource.meta.profile.exists($this.contains('senologie-strahlentherapie')) then {
    entry.resource as procedure -> tgt.strahlentherapie as rt then MapStrahlentherapie(procedure, rt) "CallMapStrahlentherapie";
  } "EntryRT";
  // --- Tumorkonferenz aus CarePlan ---
  bundle.entry as entry where resource.is(CarePlan) and resource.meta.profile.exists($this.contains('senologie-tumorboard')) then {
    entry.resource as cp -> tgt.tumorkonferenz as tk then MapTumorkonferenz(cp, tk) "CallMapTK";
  } "EntryTK";
  // --- Psychoonkologie aus Procedure (senologie-psychoonkologie) ---
  bundle.entry as entry where resource.is(Procedure) and resource.meta.profile.exists($this.contains('senologie-psychoonkologie')) then {
    entry.resource as proc -> tgt.psychoonkologie as psych then MapPsychoonkologie(proc, psych) "CallMapPsych";
  } "EntryPsychoonko";
  // --- Studienteilnahme aus ResearchSubject ---
  bundle.entry as entry where resource.is(ResearchSubject) then {
    entry.resource as rs -> tgt.studienteilnahme as stud then MapStudienteilnahme(rs, stud) "CallMapStud";
  } "EntryResearchSubject";
  // --- Verlauf (inkl. OncoBox 2.0 FM-Felder J03-J05) ---
  bundle -> tgt then MapVerlaufFromBundle(bundle, tgt) "CallMapVerlauf";
}

// ============================================================================
// Patient -> Patient-Block (Geburtsdatum, Geschlecht, PLZ, Menopausenstatus)
// ============================================================================
group MapPatient(source src : Patient, target tgt : BackboneElement) {
  src.birthDate as bd -> tgt.geburtsdatum = bd "SetPatGebdat";
  src.gender as g where $this = 'female' -> tgt.geschlecht = 'W' "SetPatGeschlW";
  src.gender as g where $this = 'male' -> tgt.geschlecht = 'M' "SetPatGeschlM";
  src.gender as g where $this = 'other' -> tgt.geschlecht = 'D' "SetPatGeschlD";
  src.gender as g where $this = 'unknown' -> tgt.geschlecht = 'U' "SetPatGeschlU";
  src.address as addr then {
    addr.postalCode as plz -> tgt.postleitzahl = plz "SetPatPLZ";
  } "MapPatPLZ";
}

// ============================================================================
// Fall -> Fall-Block (Typ, Aufnahme/Entlassung)
// ============================================================================
group MapFall(source src : Encounter, target tgt : BackboneElement) {
  src.class as cls then {
    cls.code as cd where $this = 'IMP' -> tgt.fallTyp = '1' "SetFallTypStat";
    cls.code as cd where $this = 'AMB' -> tgt.fallTyp = '2' "SetFallTypAmb";
    cls.code as cd where $this = 'SS' -> tgt.fallTyp = '3' "SetFallTypTeilstat";
  } "MapFallTyp";
  src.period as period then {
    period.start as s -> tgt.aufnahmedatum = s "SetFallAufn";
    period.end as e -> tgt.entlassungsdatum = e "SetFallEntl";
  } "MapFallPeriod";
}

// ============================================================================
// Diagnose -> Diagnose-Block
// ============================================================================
group MapDiagnose(source src : Condition, target tgt : BackboneElement) {
  // Diagnose_Datum aus Condition.onsetDateTime
  src.onset as on where $this.is(dateTime) -> tgt.diagnosedatum = on "SetDiagDatum";
  // ICD-10-GM
  src.code as code then {
    code.coding as c where system = 'http://fhir.de/CodeSystem/bfarm/icd-10-gm' -> tgt.diagnoseICD as icd then {
      c.code as cd -> icd.code = cd "SetDiagICDCode";
      c.version as v -> icd.version = v "SetDiagICDVersion";
    } "MapDiagICDCoding";
  } "MapDiagICD";
  // Dignitaet aus ICD-10-GM-Prefix
  src.code as code then {
    code.coding as c where system = 'http://fhir.de/CodeSystem/bfarm/icd-10-gm' then {
      c.code as cd where $this.startsWith('C50') -> tgt.dignitaet = '1' "SetDignMaligne";
      c.code as cd where $this.startsWith('D05') -> tgt.dignitaet = '2' "SetDignInSitu";
      c.code as cd where $this.startsWith('D24') -> tgt.dignitaet = '4' "SetDignBenigne";
    } "MapDignICD";
  } "MapDignitaet";
  // Seitenlokalisation
  src.bodySite as bs then {
    bs.coding as c where system = 'http://snomed.info/sct' then {
      c.code as cd where $this = '24028007' -> tgt.seitenlokalisation = 'R' "SetDiagSeiteR";
      c.code as cd where $this = '7771000' -> tgt.seitenlokalisation = 'L' "SetDiagSeiteL";
      c.code as cd where $this = '51440002' -> tgt.seitenlokalisation = 'B' "SetDiagSeiteB";
    } "MapDiagSeiteSCT";
  } "MapDiagSeite";
  // Histologische Sicherung praeoperativ -- default only
  src -> tgt.histologischeSicherungPraeop = '0' "SetHistPraeopDefault";
}

// ============================================================================
// Bildgebung -> Bildgebung-Block
// ============================================================================
group MapBildgebung(source src : Observation, target tgt : BackboneElement) {
  src.effective as eff where $this.is(dateTime) -> tgt.datum = eff "SetBgDatum";
  // Methode aus Observation.method (SNOMED)
  src.method as m then {
    m.coding as c where system = 'http://snomed.info/sct' then {
      c.code as cd where $this = '71651007' -> tgt.methode = '1' "SetBgMammo";
      c.code as cd where $this = '16310003' -> tgt.methode = '2' "SetBgSono";
      c.code as cd where $this = '113091000' -> tgt.methode = '3' "SetBgMRT";
      c.code as cd where $this = '241489003' -> tgt.methode = '4' "SetBgTomo";
    } "MapBgMethodeCoding";
  } "MapBgMethode";
  // BI-RADS (falls value CodeableConcept)
  src.value as val then {
    val.coding as c then {
      c.code as cd -> tgt.birads = cd "SetBgBirads";
    } "MapBgBiradsCoding";
  } "MapBgBirads";
}

// ============================================================================
// Tumorkonferenz -> Tumorkonferenz-Block
// ============================================================================
group MapTumorkonferenz(source src : CarePlan, target tgt : BackboneElement) {
  src -> tgt.lnr = 1 "SetTKLnr";
  // Datum aus CarePlan.period.start
  src.period as period then {
    period.start as s -> tgt.datum = s "SetTKDatum";
  } "MapTKPeriod";
  // Typ aus CarePlan.category
  src.category as cat then {
    cat.coding as c then {
      c.code as cd where $this = 'praetherapeutisch' -> tgt.typ = '1' "SetTKTypPrae";
      c.code as cd where $this = 'postoperativ' -> tgt.typ = '2' "SetTKTypPost";
      c.code as cd where $this = 'rezidiv' -> tgt.typ = '3' "SetTKTypRez";
    } "MapTKTypCoding";
  } "MapTKTyp";
}

// ============================================================================
// Psychoonkologie -> Psychoonkologie-Block (KB-9)
// Procedure.status = completed -> erfolgt = '1', Procedure.performedDateTime -> datum
// Procedure.status = not-done  -> erfolgt = '0'
// ============================================================================
group MapPsychoonkologie(source src : Procedure, target tgt : BackboneElement) {
  // Psych_Erfolgt: completed=ja, not-done=nein
  src.status as s where $this = 'completed' -> tgt.erfolgt = '1' "SetPsychJa";
  src.status as s where $this = 'not-done' -> tgt.erfolgt = '0' "SetPsychNein";
  // Psych_Datum aus performedDateTime
  src.performed as perf where $this.is(dateTime) -> tgt.datum = perf "SetPsychDatum";
}

// ============================================================================
// Studienteilnahme -> Studien-Block
// ============================================================================
group MapStudienteilnahme(source src : ResearchSubject, target tgt : BackboneElement) {
  src -> tgt.teilgenommen = '1' "SetStudJa";
}