PreNUDGE FHIR® IG for Data Provider / Data from Apps (R4)
0.1.0 - ci-build

PreNUDGE FHIR® IG for Data Provider / Data from Apps (R4) - Local Development build (v0.1.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions

StructureMap: ATHIS-based Smoking Status Q to O

Official URL: https://fhir.hl7.at/prenudge/appdata/r4/StructureMap/SmokingStatusQuestionnaireResponseToObservation Version: 0.1.0
Active as of 2026-06-03 Responsible: The PreNUDGE Consortium Computable Name: SmokingStatusQuestionnaireResponseToObservation

ATHIS-based Smoking Status Q to O

map "https://fhir.hl7.at/prenudge/appdata/r4/StructureMap/SmokingStatusQuestionnaireResponseToObservation" = "SmokingStatusQuestionnaireResponseToObservation"

// ATHIS-based Smoking Status Q to O

uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QR as source
uses "http://hl7.org/fhir/StructureDefinition/Observation" alias Obs as target

group SmokingStatusQuestionnaireResponseToObservation(source src : QR, target tgt : Obs) {
  // Administrative metadata. Implementations may replace or enrich the identifier
  // if the Observation needs a separate stable business identifier.
  src -> tgt.status = 'final' "setFinalStatus";
  src.identifier as identifier -> tgt.identifier = identifier "copyIdentifier";
  src.subject as subject -> tgt.subject = subject "copySubject";
  src.authored as authored ->  tgt.effective = authored,  tgt.issued = authored "copyAuthoredToObservationTimes";
  // IPS/APS-style tobacco smoking status coding.
  src -> tgt.code = cc('http://loinc.org', '72166-2', 'Tobacco smoking status') "setTobaccoSmokingStatusCode";
  // User-entered QuestionnaireResponse data is considered manual input.
  src -> tgt.method = cc('http://snomed.info/sct', '87982008', 'Manual') "setManualMethod";
  // Keep the derivation from QuestionnaireResponse to Observation traceable.
  src.id as id -> tgt.derivedFrom = create('Reference') as reference then {
    id -> reference.reference = append('QuestionnaireResponse/', id) "setDerivedFromReference";
  } "setDerivedFrom";
  // ATHIS answer mapping to the clinical SNOMED CT valueCodeableConcept.
  src.item as groupItem where groupItem.linkId = 'smoking-status-athis' then SmokingStatusGroupToObservation(groupItem, tgt) "mapSmokingStatusGroup";
}

group SmokingStatusGroupToObservation(source groupItem : QR, target tgt : Obs) {
  // SK1 = Ja, täglich -> current every day smoker.
  groupItem.item as sk1 where sk1.linkId = 'sk1' then {
    sk1.answer as answer then {
      answer.valueCoding as coding where (coding.system = 'https://fhir.hl7.at/prenudge/appdata/r4/CodeSystem/athis-answers') and (coding.code = 'yn-yes-daily') -> tgt.valueCodeableConcept = cc('http://snomed.info/sct', '449868002', 'Smokes tobacco daily') "mapCurrentDailySmoker";
    } "evaluateSk1Daily";
  } "sk1Daily";
  // SK1 = Ja, gelegentlich -> current occasional smoker.
  groupItem.item as sk1 where sk1.linkId = 'sk1' then {
    sk1.answer as answer then {
      answer.valueCoding as coding where (coding.system = 'https://fhir.hl7.at/prenudge/appdata/r4/CodeSystem/athis-answers') and (coding.code = 'yn-yes-occasionally') -> tgt.valueCodeableConcept = cc('http://snomed.info/sct', '428041000124106', 'Occasional tobacco smoker') "mapCurrentOccasionalSmoker";
    } "evaluateSk1Occasional";
  } "sk1Occasional";
  // SK1 = Nein and past tobacco smoking = Ja, täglich or Ja, gelegentlich -> former smoker.
  // The past-tobacco-smoking item is enabled only when SK1 is negative.
  groupItem.item as past where past.linkId = 'past-tobacco-smoking' then {
    past.answer as answer then {
      answer.valueCoding as coding where (coding.system = 'https://fhir.hl7.at/prenudge/appdata/r4/CodeSystem/athis-answers') and (coding.code = 'yn-yes-daily') -> tgt.valueCodeableConcept = cc('http://snomed.info/sct', '8517006', 'Ex-smoker') "mapPastDailyToFormerSmoker";
      answer.valueCoding as coding where (coding.system = 'https://fhir.hl7.at/prenudge/appdata/r4/CodeSystem/athis-answers') and (coding.code = 'yn-yes-occasionally') -> tgt.valueCodeableConcept = cc('http://snomed.info/sct', '8517006', 'Ex-smoker') "mapPastOccasionalToFormerSmoker";
    } "evaluatePastSmoking";
  } "pastSmokingFormer";
  // SK1 = Nein and past tobacco smoking = Nein -> never smoker.
  groupItem.item as past where past.linkId = 'past-tobacco-smoking' then {
    past.answer as answer then {
      answer.valueCoding as coding where (coding.system = 'https://fhir.hl7.at/prenudge/appdata/r4/CodeSystem/athis-answers') and (coding.code = 'yn-no') -> tgt.valueCodeableConcept = cc('http://snomed.info/sct', '266919005', 'Never smoked tobacco') "mapPastNoToNeverSmoker";
    } "evaluatePastNo";
  } "pastSmokingNever";
}