SGHI FHIR Profile Implementation Guide
0.1.0 - ci-build

SGHI FHIR Profile Implementation Guide, published by Kathurima Kimathi. This guide is not an authorized publication; it is the continuous build for version 0.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/savannahghi/sil_fhir_profile_ig/ and changes regularly. See the Directory of published versions

StructureMap: ExtractVitalSigns

Official URL: https://fhir.slade360.co.ke/fhir/StructureMap/ExtractVitalSigns Version: 0.1.0
Draft as of 2026-03-30 Computable Name: ExtractVitalSigns

/// url = 'https://fhir.slade360.co.ke/fhir/StructureMap/ExtractVitalSigns'
/// name = 'ExtractVitalSigns'
/// status = 'draft'

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

group ExtractVitalSigns(source qr : QR, target bundle : Bundle) {
  qr -> bundle.type = 'transaction' "setBundleType";
  qr.item as itH where (linkId = '8302-2') then {
    itH.answer first as aH then {
      aH ->  bundle.entry as eH,  eH.resource = create('Observation') as oH then {
        qr ->  oH,  eH then BuildBaseObs(qr, oH, eH) "heightBase";
        qr -> oH.category as catH then {
          qr -> catH.coding as catHCoding then {
            qr -> catHCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catHSys";
            qr -> catHCoding.code = 'vital-signs' "catHCode";
            qr -> catHCoding.display = 'Vital Signs' "catHDisplay";
          } "catHCodingRule";
        } "categoryH";
        qr -> oH.code as codeH then {
          qr -> codeH.coding as codeHCoding then {
            qr -> codeHCoding.system = 'http://loinc.org' "codeHSys";
            qr -> codeHCoding.code = '8302-2' "codeHCode";
            qr -> codeHCoding.display = 'Body Height' "codeHDisplay";
          } "codeHCodingRule";
        } "codeH";
        aH.value as hv -> oH.valueQuantity as vH then {
          hv -> vH.value = hv "setVal";
          qr -> vH.system = 'http://unitsofmeasure.org' "setSys";
          qr -> vH.code = 'cm' "setCode";
          qr -> vH.unit = 'centimeter' "setUnit";
        } "valH";
      } "heightObs";
    } "heightAns";
  } "heightRule"; // Height
  qr.item as itW where (linkId = '29463-7') then {
    itW.answer first as aW then {
      aW ->  bundle.entry as eW,  eW.resource = create('Observation') as oW then {
        qr ->  oW,  eW then BuildBaseObs(qr, oW, eW) "weightBase";
        qr -> oW.category as catW then {
          qr -> catW.coding as catWCoding then {
            qr -> catWCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catWSys";
            qr -> catWCoding.code = 'vital-signs' "catWCode";
            qr -> catWCoding.display = 'Vital Signs' "catWDisplay";
          } "catWCodingRule";
        } "categoryW";
        qr -> oW.code as codeW then {
          qr -> codeW.coding as codeWCoding then {
            qr -> codeWCoding.system = 'http://loinc.org' "codeWSys";
            qr -> codeWCoding.code = '29463-7' "codeWCode";
            qr -> codeWCoding.display = 'Body Weight' "codeWDisplay";
          } "codeWCodingRule";
        } "codeW";
        aW.value as hv -> oW.valueQuantity as vW then {
          hv -> vW.value = hv "setVal";
          qr -> vW.system = 'http://unitsofmeasure.org' "setSys";
          qr -> vW.code = 'kg' "setCode";
          qr -> vW.unit = 'kilogram' "setUnit";
        } "valW";
      } "weightObs";
    } "weightAns";
  } "weightRule"; // Weight
  qr.item as itBmi where (linkId = '39156-5') then {
    itBmi.answer first as aBmi then {
      aBmi ->  bundle.entry as eBmi,  eBmi.resource = create('Observation') as oBmi then {
        qr ->  oBmi,  eBmi then BuildBaseObs(qr, oBmi, eBmi) "bmiBase";
        qr -> oBmi.category as catBmi then {
          qr -> catBmi.coding as catBmiCoding then {
            qr -> catBmiCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catBmiSys";
            qr -> catBmiCoding.code = 'vital-signs' "catBmiCode";
            qr -> catBmiCoding.display = 'Vital Signs' "catBmiDisplay";
          } "catBmiCodingRule";
        } "categoryBmi";
        qr -> oBmi.code as codeBmi then {
          qr -> codeBmi.coding as codeBmiCoding then {
            qr -> codeBmiCoding.system = 'http://loinc.org' "codeBmiSys";
            qr -> codeBmiCoding.code = '39156-5' "codeBmiCode";
            qr -> codeBmiCoding.display = 'Body mass index (BMI) [Ratio]' "codeBmiDisplay";
          } "codeBmiCodingRule";
        } "codeBmi";
        aBmi.value as hv -> oBmi.valueQuantity as vBmi then {
          hv -> vBmi.value = hv "setVal";
          qr -> vBmi.system = 'http://unitsofmeasure.org' "setSys";
          qr -> vBmi.code = 'kg/m2' "setCode";
          qr -> vBmi.unit = 'kilogram per square meter' "setUnit";
        } "valBmi";
        itBmi.item as bmiStatusItem where (linkId = '39156-5_status') then {
          bmiStatusItem.answer first as bmiStatusAns -> oBmi.interpretation as iBmi then {
            bmiStatusAns.value as statusText -> iBmi.text = statusText "interpBmi";
          } "setInterpBmi";
        } "findBmiStatus"; // Interpretation 39156-5_status
      } "bmiObs";
    } "bmiAns";
  } "bmiRule"; // BMI
  qr.item as itP where (linkId = '8889-8') then {
    itP.answer first as aP then {
      aP ->  bundle.entry as eP,  eP.resource = create('Observation') as oP then {
        qr ->  oP,  eP then BuildBaseObs(qr, oP, eP) "pulseBase";
        qr -> oP.category as catP then {
          qr -> catP.coding as catPCoding then {
            qr -> catPCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catPSys";
            qr -> catPCoding.code = 'vital-signs' "catPCode";
            qr -> catPCoding.display = 'Vital Signs' "catPDisplay";
          } "catPCodingRule";
        } "categoryP";
        qr -> oP.code as codeP then {
          qr -> codeP.coding as codePCoding then {
            qr -> codePCoding.system = 'http://loinc.org' "codePSys";
            qr -> codePCoding.code = '8889-8' "codePCode";
            qr -> codePCoding.display = 'Heart rate by Pulse oximetry' "codePDisplay";
          } "codePCodingRule";
        } "codeP";
        aP.value as hv -> oP.valueQuantity as vP then {
          hv -> vP.value = hv "setVal";
          qr -> vP.system = 'http://unitsofmeasure.org' "setSys";
          qr -> vP.code = '/min' "setCode";
          qr -> vP.unit = 'per minute' "setUnit";
        } "valP";
      } "pulseObs";
    } "pulseAns";
  } "pulseRule"; // Pulse
  qr.item as itBP where (linkId = '55284-4') then {
    qr ->  bundle.entry as eBP,  eBP.resource = create('Observation') as oBP then {
      qr ->  oBP,  eBP then BuildBaseObs(qr, oBP, eBP) "bpBase";
      qr -> oBP.category as catBP then {
        qr -> catBP.coding as catBPCoding then {
          qr -> catBPCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catBPSys";
          qr -> catBPCoding.code = 'vital-signs' "catBPCode";
          qr -> catBPCoding.display = 'Vital Signs' "catBPDisplay";
        } "catBPCodingRule";
      } "categoryBP";
      qr -> oBP.code as codeBP then {
        qr -> codeBP.coding as codeBPCoding then {
          qr -> codeBPCoding.system = 'http://loinc.org' "codeBPSys";
          qr -> codeBPCoding.code = '55284-4' "codeBPCode";
          qr -> codeBPCoding.display = 'Blood pressure systolic and diastolic' "codeBPDisplay";
        } "codeBPCodingRule";
      } "codeBP";
      itBP.item as itSys where (linkId = '8480-6') then {
        itSys.answer first as aSys -> oBP.component as cSys then {
          aSys -> cSys.code as bpSysCC then {
            aSys -> bpSysCC.coding as bpSysCoding then {
              aSys -> bpSysCoding.system = 'http://loinc.org' "bpSysCodingSystem";
              aSys -> bpSysCoding.code = '8480-6' "bpSysCodingCode";
              aSys -> bpSysCoding.display = 'Systolic blood pressure' "bpSysCodingDisplay";
            } "bpSysCodingRule";
          } "bpSysCode";
          aSys.value as hv -> cSys.valueQuantity as vSys then {
            hv -> vSys.value = hv "setVal";
            qr -> vSys.system = 'http://unitsofmeasure.org' "setSys";
            qr -> vSys.code = 'mm[Hg]' "setCode";
            qr -> vSys.unit = 'millimeter of mercury' "setUnit";
          } "bpSysVal";
        } "bpSysComponent";
      } "bpSysRule"; // Systolic 8480-6
      itBP.item as itDia where (linkId = '8462-4') then {
        itDia.answer first as aDia -> oBP.component as cDia then {
          aDia -> cDia.code as bpDiaCC then {
            aDia -> bpDiaCC.coding as bpDiaCoding then {
              aDia -> bpDiaCoding.system = 'http://loinc.org' "bpDiaCodingSystem";
              aDia -> bpDiaCoding.code = '8462-4' "bpDiaCodingCode";
              aDia -> bpDiaCoding.display = 'Diastolic blood pressure' "bpDiaCodingDisplay";
            } "bpDiaCodingRule";
          } "bpDiaCode";
          aDia.value as hv -> cDia.valueQuantity as vDia then {
            hv -> vDia.value = hv "setVal";
            qr -> vDia.system = 'http://unitsofmeasure.org' "setSys";
            qr -> vDia.code = 'mm[Hg]' "setCode";
            qr -> vDia.unit = 'millimeter of mercury' "setUnit";
          } "bpDiaVal";
        } "bpDiaComponent";
      } "bpDiaRule"; // Diastolic 8462-4
    } "bpObs";
  } "bpRule"; // Blood Pressure
  qr.item as itT where (linkId = '8310-5') then {
    itT.answer first as aT then {
      aT ->  bundle.entry as eT,  eT.resource = create('Observation') as oT then {
        qr ->  oT,  eT then BuildBaseObs(qr, oT, eT) "tempBase";
        qr -> oT.category as catT then {
          qr -> catT.coding as catTCoding then {
            qr -> catTCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catTSys";
            qr -> catTCoding.code = 'vital-signs' "catTCode";
            qr -> catTCoding.display = 'Vital Signs' "catTDisplay";
          } "catTCodingRule";
        } "categoryT";
        qr -> oT.code as codeT then {
          qr -> codeT.coding as codeTCoding then {
            qr -> codeTCoding.system = 'http://loinc.org' "codeTSys";
            qr -> codeTCoding.code = '8310-5' "codeTCode";
            qr -> codeTCoding.display = 'Body Temperature' "codeTDisplay";
          } "codeTCodingRule";
        } "codeT";
        aT.value as hv -> oT.valueQuantity as vT then {
          hv -> vT.value = hv "setVal";
          qr -> vT.system = 'http://unitsofmeasure.org' "setSys";
          qr -> vT.code = 'Cel' "setCode";
          qr -> vT.unit = 'degree Celsius' "setUnit";
        } "valT";
        itT.item as tStatusItem where (linkId = '8310-5_status') then {
          tStatusItem.answer first as tStatusAns -> oT.interpretation as iT then {
            tStatusAns.value as statusText -> iT.text = statusText "interpT";
          } "setInterpT";
        } "findTStatus"; // Interpretation 8310-5_status
      } "tempObs";
    } "tempAns";
  } "tempRule"; // Temperature
  qr.item as itO2 where (linkId = '20564-1') then {
    itO2.answer first as aO2 then {
      aO2 ->  bundle.entry as eO2,  eO2.resource = create('Observation') as oO2 then {
        qr ->  oO2,  eO2 then BuildBaseObs(qr, oO2, eO2) "spo2Base";
        qr -> oO2.category as catO2 then {
          qr -> catO2.coding as catO2Coding then {
            qr -> catO2Coding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catO2Sys";
            qr -> catO2Coding.code = 'vital-signs' "catO2Code";
            qr -> catO2Coding.display = 'Vital Signs' "catO2Display";
          } "catO2CodingRule";
        } "categoryO2";
        qr -> oO2.code as codeO2 then {
          qr -> codeO2.coding as codeO2Coding then {
            qr -> codeO2Coding.system = 'http://loinc.org' "codeO2Sys";
            qr -> codeO2Coding.code = '20564-1' "codeO2Code";
            qr -> codeO2Coding.display = 'Oxygen saturation in Blood' "codeO2Display";
          } "codeO2CodingRule";
        } "codeO2";
        aO2.value as hv -> oO2.valueQuantity as vO2 then {
          hv -> vO2.value = hv "setVal";
          qr -> vO2.system = 'http://unitsofmeasure.org' "setSys";
          qr -> vO2.code = '%' "setCode";
          qr -> vO2.unit = '%' "setUnit";
        } "valO2";
        itO2.item as o2StatusItem where (linkId = '20564-1_status') then {
          o2StatusItem.answer first as o2StatusAns -> oO2.interpretation as iO2 then {
            o2StatusAns.value as statusText -> iO2.text = statusText "interpO2";
          } "setInterpO2";
        } "findO2Status"; // Interpretation of SpO2 20564-1_status
      } "spo2Obs";
    } "spo2Ans";
  } "spo2Rule"; // SpO2
  qr.item as itRR where (linkId = '9279-1') then {
    itRR.answer first as aRR then {
      aRR ->  bundle.entry as eRR,  eRR.resource = create('Observation') as oRR then {
        qr ->  oRR,  eRR then BuildBaseObs(qr, oRR, eRR) "rrBase";
        qr -> oRR.category as catRR then {
          qr -> catRR.coding as catRRCoding then {
            qr -> catRRCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catRRSys";
            qr -> catRRCoding.code = 'vital-signs' "catRRCode";
            qr -> catRRCoding.display = 'Vital Signs' "catRRDisplay";
          } "catRRCodingRule";
        } "categoryRR";
        qr -> oRR.code as codeRR then {
          qr -> codeRR.coding as codeRRCoding then {
            qr -> codeRRCoding.system = 'http://loinc.org' "codeRRSys";
            qr -> codeRRCoding.code = '9279-1' "codeRRCode";
            qr -> codeRRCoding.display = 'Respiratory rate' "codeRRDisplay";
          } "codeRRCodingRule";
        } "codeRR";
        aRR.value as hv -> oRR.valueQuantity as vRR then {
          hv -> vRR.value = hv "setVal";
          qr -> vRR.system = 'http://unitsofmeasure.org' "setSys";
          qr -> vRR.code = '/min' "setCode";
          qr -> vRR.unit = 'per minute' "setUnit";
        } "valRR";
      } "rrObs";
    } "rrAns";
  } "rrRule"; // Respiratory rate
  qr.item as itMuac where (linkId = '9847-5') then {
    itMuac.answer first as aMuac then {
      aMuac ->  bundle.entry as eMuac,  eMuac.resource = create('Observation') as oMuac then {
        qr ->  oMuac,  eMuac then BuildBaseObs(qr, oMuac, eMuac) "muacBase";
        qr -> oMuac.category as catMuac then {
          qr -> catMuac.coding as catMuacCoding then {
            qr -> catMuacCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catMuacSys";
            qr -> catMuacCoding.code = 'vital-signs' "catMuacCode";
            qr -> catMuacCoding.display = 'Vital Signs' "catMuacDisplay";
          } "catMuacCodingRule";
        } "categoryMuac";
        qr -> oMuac.code as codeMuac then {
          qr -> codeMuac.coding as codeMuacCoding then {
            qr -> codeMuacCoding.system = 'http://loinc.org' "codeMuacSys";
            qr -> codeMuacCoding.code = '9847-5' "codeMuacCode";
            qr -> codeMuacCoding.display = 'Circumference' "codeMuacDisplay";
          } "codeMuacCodingRule";
        } "codeMuac";
        aMuac.value as hv -> oMuac.valueQuantity as vMuac then {
          hv -> vMuac.value = hv "setVal";
          qr -> vMuac.system = 'http://unitsofmeasure.org' "setSys";
          qr -> vMuac.code = 'mm' "setCode";
          qr -> vMuac.unit = 'millimeter' "setUnit";
        } "valMuac";
      } "muacObs";
    } "muacAns";
  } "muacRule"; // MUAC
  qr.item as itCC where (linkId = '10154-3') then {
    itCC.answer first as aCC then {
      aCC ->  bundle.entry as eCC,  eCC.resource = create('Observation') as oCC then {
        qr ->  oCC,  eCC then BuildBaseObs(qr, oCC, eCC) "chiefComplaintBase";
        qr -> oCC.category as catCC then {
          qr -> catCC.coding as catCCCoding then {
            qr -> catCCCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catCCSys";
            qr -> catCCCoding.code = 'social-history' "catCCCode";
            qr -> catCCCoding.display = 'Social History' "catCCDisplay";
          } "catCCCodingRule";
        } "chiefComplaintCategory";
        qr -> oCC.code as codeCC then {
          qr -> codeCC.coding as codeCCCoding then {
            qr -> codeCCCoding.system = 'http://loinc.org' "codeCCSys";
            qr -> codeCCCoding.code = '10154-3' "codeCCCode";
            qr -> codeCCCoding.display = 'Chief complaint Narrative - Reported' "codeCCDisplay";
          } "codeCCCodingRule";
        } "chiefComplaintCode";
        aCC.value as textVal -> oCC.valueString = textVal "chiefComplaintValue";
      } "chiefComplaintObs";
    } "chiefComplaintAns";
  } "chiefComplaintRule"; // Chief Complaint
  qr.item as hpiCC where (linkId = '8684-3') then {
    hpiCC.answer first as aCC then {
      aCC ->  bundle.entry as eCC,  eCC.resource = create('Observation') as oCC then {
        qr ->  oCC,  eCC then BuildBaseObs(qr, oCC, eCC) "historyOfPIBase";
        qr -> oCC.category as catHPI then {
          qr -> catHPI.coding as catHPICoding then {
            qr -> catHPICoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catHPISys";
            qr -> catHPICoding.code = 'social-history' "catHPICode";
            qr -> catHPICoding.display = 'Social History' "catHPIDisplay";
          } "catHPICodingRule";
        } "historyOfPICategory";
        qr -> oCC.code as codeHPI then {
          qr -> codeHPI.coding as codeHPICoding then {
            qr -> codeHPICoding.system = 'http://loinc.org' "codeHPISys";
            qr -> codeHPICoding.code = '8684-3' "codeHPICode";
            qr -> codeHPICoding.display = 'History of Present illness' "codeHPIDisplay";
          } "codeHPICodingRule";
        } "historyOfPICode";
        aCC.value as textVal -> oCC.valueString = textVal "historyOfPIValue";
      } "historyOfPIObs";
    } "historyOfPIAns";
  } "historyOfPIRule"; // History of Presenting Illness
  qr.item as hPastCC where (linkId = '11349-8') then {
    hPastCC.answer first as aCC then {
      aCC ->  bundle.entry as eCC,  eCC.resource = create('Observation') as oCC then {
        qr ->  oCC,  eCC then BuildBaseObs(qr, oCC, eCC) "historyOfPastIBase";
        qr -> oCC.category as catPastI then {
          qr -> catPastI.coding as catPastICoding then {
            qr -> catPastICoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catPastISys";
            qr -> catPastICoding.code = 'social-history' "catPastICode";
            qr -> catPastICoding.display = 'Social History' "catPastIDisplay";
          } "catPastICodingRule";
        } "historyOfPastICategory";
        qr -> oCC.code as codePastI then {
          qr -> codePastI.coding as codePastICoding then {
            qr -> codePastICoding.system = 'http://loinc.org' "codePastISys";
            qr -> codePastICoding.code = '11349-8' "codePastICode";
            qr -> codePastICoding.display = 'History of Past illness' "codePastIDisplay";
          } "codePastICodingRule";
        } "historyOfPastICode";
        aCC.value as textVal -> oCC.valueString = textVal "historyOfPastIValue";
      } "historyOfPastIObs";
    } "historyOfPastIAns";
  } "historyOfPastIRule"; // History of Past Illness / Past Medical History
  qr.item as hFH where (linkId = '8670-2') then {
    hFH.answer first as aCC then {
      aCC ->  bundle.entry as eCC,  eCC.resource = create('Observation') as oCC then {
        qr ->  oCC,  eCC then BuildBaseObs(qr, oCC, eCC) "familyFHIBase";
        qr -> oCC.category as catFH then {
          qr -> catFH.coding as catFHCoding then {
            qr -> catFHCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catFHSys";
            qr -> catFHCoding.code = 'social-history' "catFHCode";
            qr -> catFHCoding.display = 'Social History' "catFHDisplay";
          } "catFHCodingRule";
        } "familyHICategory";
        qr -> oCC.code as codeFH then {
          qr -> codeFH.coding as codeFHCoding then {
            qr -> codeFHCoding.system = 'http://loinc.org' "codeFHSys";
            qr -> codeFHCoding.code = '8670-2' "codeFHCode";
            qr -> codeFHCoding.display = 'History of family member diseases' "codeFHDisplay";
          } "codeFHCodingRule";
        } "familyHICode";
        aCC.value as textVal -> oCC.valueString = textVal "familyHIValue";
      } "familyHIObs";
    } "familyHIAns";
  } "familyHIRule"; // Family History
  qr.item as hSH where (linkId = '29762-2') then {
    hSH.answer first as aCC then {
      aCC ->  bundle.entry as eCC,  eCC.resource = create('Observation') as oCC then {
        qr ->  oCC,  eCC then BuildBaseObs(qr, oCC, eCC) "socialHistoryIBase";
        qr -> oCC.category as catSH then {
          qr -> catSH.coding as catSHCoding then {
            qr -> catSHCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catSHSys";
            qr -> catSHCoding.code = 'social-history' "catSHCode";
            qr -> catSHCoding.display = 'Social History' "catSHDisplay";
          } "catSHCodingRule";
        } "socialHistoryCategory";
        qr -> oCC.code as codeSH then {
          qr -> codeSH.coding as codeSHCoding then {
            qr -> codeSHCoding.system = 'http://loinc.org' "codeSHSys";
            qr -> codeSHCoding.code = '29762-2' "codeSHCode";
            qr -> codeSHCoding.display = 'Social history note' "codeSHDisplay";
          } "codeSHCodingRule";
        } "socialHistoryCode";
        aCC.value as textVal -> oCC.valueString = textVal "socialHistoryIValue";
      } "socialHistoryIObs";
    } "socialHistoryIAns";
  } "socialHistoryIRule"; // Social History
  qr.item as medicationH where (linkId = '10160-0') then {
    medicationH.answer first as aCC then {
      aCC ->  bundle.entry as eCC,  eCC.resource = create('Observation') as oCC then {
        qr ->  oCC,  eCC then BuildBaseObs(qr, oCC, eCC) "medicationHIBase";
        qr -> oCC.category as catMedH then {
          qr -> catMedH.coding as catMedHCoding then {
            qr -> catMedHCoding.system = 'http://terminology.hl7.org/CodeSystem/observation-category' "catMedHSys";
            qr -> catMedHCoding.code = 'therapy' "catMedHCode";
            qr -> catMedHCoding.display = 'Therapy' "catMedHDisplay";
          } "catMedHCodingRule";
        } "medicationHCategory";
        qr -> oCC.code as codeMedH then {
          qr -> codeMedH.coding as codeMedHCoding then {
            qr -> codeMedHCoding.system = 'http://loinc.org' "codeMedHSys";
            qr -> codeMedHCoding.code = '10160-0' "codeMedHCode";
            qr -> codeMedHCoding.display = 'History of Medication use Narrative' "codeMedHDisplay";
          } "codeMedHCodingRule";
        } "medicationHistoryCode";
        aCC.value as textVal -> oCC.valueString = textVal "medicationHistoryIValue";
      } "medicationHistoryIObs";
    } "medicationHistoryIAns";
  } "medicationHistoryIRule"; // Medication History
}

group BuildBaseObs(source qr : QR, target obs : Observation, target entry) {
  qr -> obs.status = 'final' "status";
  qr.subject as s -> obs.subject = s;
  qr.encounter as e -> obs.encounter = e;
  qr.authored as t -> obs.effectiveDateTime = t "effective";
  qr -> obs.id = uuid() then SetObservationFullUrl(obs, entry) "setObsIdAndFullUrl"; // Observation id and fullUrl
  qr -> entry.request as request then {
    qr -> request.method = 'POST' "reqMethod";
    qr -> request.url = 'Observation' "reqUrl";
  } "entryRequest"; // Bundle.entry.request (transaction POST Observation)
  qr -> obs.derivedFrom = create('Reference') as newRef then {
    qr.id as qid -> newRef.reference = append('QuestionnaireResponse/', qid) "setQRRef";
  } "linkQR"; // Link Observation -> QuestionnaireResponse
}

group SetObservationFullUrl(source obs : Observation, target entry) {
  obs.id as id -> entry.fullUrl = append('https://fhir.slade360.co.ke/fhir/Observation/', id) "assignFullUrl";
}