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: Observation Transforms: R4 to SGHI R5

Official URL: https://fhir.slade360.co.ke/fhir/StructureMap/Observation4toSGHI5 Version: 0.1.0
Active as of 2025-09-17 Computable Name: Observation4toSGHI5

ObservationTransformsR4toSGHIR5

/// url = 'https://fhir.slade360.co.ke/fhir/StructureMap/Observation4toSGHI5'
/// name = 'Observation4toSGHI5'
/// title = 'Observation Transforms: R4 to SGHI R5'
/// status = 'active'

uses "http://hl7.org/fhir/4.0/StructureDefinition/Observation" alias ObservationR4 as source
uses "https://fhir.slade360.co.ke/fhir/StructureDefinition/sghi-observation" alias SGHIObservation as target

imports "http://hl7.org/fhir/StructureMap/*4to5"

group SGHIObservation(source src : ObservationR4, target tgt : SGHIObservation) <<type+>> {
  src.id as uuid -> tgt.id = uuid;
  src.active -> tgt.active;
  src.language -> tgt.language;
  src -> tgt.meta as t_meta then {
    src -> t_meta.profile = 'https://fhir.slade360.co.ke/fhir/StructureDefinition/sghi-observation' "addsghiprofile";
  } "addtometa";
  src where text.exists().not() -> tgt.text = create('Narrative') as t_text then {
    src -> t_text.status = 'generated' "settextstatus";
    src -> t_text.div = '<div xmlns=\"http://www.w3.org/1999/xhtml\"><h1>Generated text</h1></div>' "settextdiv";
  } "createhardcodedtext";
  src -> tgt.text = create('Narrative') as ttt then {
    src.text as st then {
      st.status as s -> ttt.status = s;
      st.div as d -> ttt.div = ('<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>' + d + '</p></div>') "wraptextinhtml";
    };
  } "setting text";
  src.id as s_id -> tgt.identifier = create('Identifier') as t_ident then {
    s_id as uuid -> t_ident.value = uuid "copyid";
    src -> t_ident.use = 'official' "setuse";
    src -> t_ident.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/sghi-identifier-codesystem' "setsystem";
    src -> t_ident.type = create('CodeableConcept') as t_type then {
      src -> t_type.coding = create('Coding') as t_code then {
        src -> t_code.system = 'https://fhir.slade360.co.ke/fhir/CodeSystem/sghi-identifier-codesystem' "typesystem";
        src -> t_code.code = 'fhir-id' "typecode";
        src -> t_code.display = 'FHIR Id' "typedisplay";
      } "initcoding";
    } "inittype";
    src.meta as sm then {
      sm.tag last as st -> t_ident.assigner = create('Reference') as ta then TransformAssigner(st, ta);
    } "setting owner";
  } "addfhirididentifier";
  src.effectiveInstant as se -> tgt.issued = se "mapissuedfromeffective";
  src.code as scode -> tgt.code as tcode then {
    scode.coding as d where system.exists().not() -> tcode.coding = translate(d, 'https://fhir.slade360.co.ke/fhir/ConceptMap/CIELtoLOINCObservationMap', 'Coding');
    scode.coding as d where system.exists() -> tcode.coding = create('Coding') as tcoding then {
      d.code as code -> tcoding.code = translate(code, 'https://fhir.slade360.co.ke/fhir/ConceptMap/CIELtoLOINCObservationMap', 'code');
      d.code as sd -> tcoding.system = translate(sd, 'https://fhir.slade360.co.ke/fhir/ConceptMap/CIELtoLOINCObservationMap', 'system');
      d.code as d -> tcoding.display = translate(d, 'https://fhir.slade360.co.ke/fhir/ConceptMap/CIELtoLOINCObservationMap', 'display');
      d.code as d -> tcode.text = translate(d, 'https://fhir.slade360.co.ke/fhir/ConceptMap/CIELtoLOINCObservationMap', 'display');
    };
  };
  src.code as s_code -> tgt.code as t_code then {
    s_code.text -> t_code.text;
    src.basedOn -> tgt.basedOn;
    src.partOf -> tgt.partOf;
    src.category -> tgt.category;
    src.status as v -> tgt.status = translate(v, 'http://hl7.org/fhir/uv/xver/ConceptMap/obs.status-4to5', 'code');
    src.subject as sb -> tgt.subject as tb then TransformReference(sb, tb);
    src.focus -> tgt.focus;
    src.encounter as se -> tgt.encounter as te then TransformReference(se, te);
    src.effective : dateTime -> tgt.effective;
    src.effective : Period -> tgt.effective;
    src.effective : Timing -> tgt.effective;
    src.effective : instant -> tgt.effective;
    src.value : Quantity -> tgt.value;
    src.value : CodeableConcept as sv -> tgt.value = sv;
    src.value : string -> tgt.value;
    src.value : boolean -> tgt.value;
    src.value : integer -> tgt.value;
    src.value : Range -> tgt.value;
    src.value : Ratio -> tgt.value;
    src.value : SampledData -> tgt.value;
    src.value : time -> tgt.value;
    src.value : dateTime -> tgt.value;
    src.value : Period -> tgt.value;
    src.dataAbsentReason -> tgt.dataAbsentReason;
    src.interpretation -> tgt.interpretation;
    src.note -> tgt.note;
    src.bodySite -> tgt.bodySite;
    src.method -> tgt.method;
    src.specimen -> tgt.specimen;
    src.device -> tgt.device;
    src.referenceRange as s -> tgt.referenceRange as t then ObservationReferenceRange(s, t);
    src.hasMember -> tgt.hasMember;
    src.derivedFrom -> tgt.derivedFrom;
    src.component as s -> tgt.component as t then ObservationComponent(s, t);
    src.performer as spf -> tgt.performer as tpf then TransformReference(spf, tpf);
    src where performer.exists().not() then {
      src.meta as sm then {
        sm.tag last as st -> tgt.performer = create('Reference') as tp then TransformAssigner(st, tp);
      };
    } "setting performer";
  };
}

group ObservationReferenceRange(source src, target tgt) extends BackboneElement {
  src.low as sl -> tgt.low = sl;
  src.high -> tgt.high;
  src.type -> tgt.type;
  src.appliesTo -> tgt.appliesTo;
  src.age -> tgt.age;
  src.text -> tgt.text;
}

group ObservationComponent(source src, target tgt) extends BackboneElement {
  src.value : Quantity -> tgt.value;
  src.value : CodeableConcept -> tgt.value;
  src.value : string -> tgt.value;
  src.value : boolean -> tgt.value;
  src.value : integer -> tgt.value;
  src.value : Range -> tgt.value;
  src.value : Ratio -> tgt.value;
  src.value : SampledData -> tgt.value;
  src.value : time -> tgt.value;
  src.value : dateTime -> tgt.value;
  src.value : Period -> tgt.value;
  src.dataAbsentReason -> tgt.dataAbsentReason;
  src.interpretation -> tgt.interpretation;
  src.referenceRange as s -> tgt.referenceRange as t then ObservationReferenceRange(s, t);
}

group TransformAssigner(source src, target tgt) <<types>> {
  src.code as code -> tgt.reference = append('Organization/', code);
  src where display.exists().not() -> tgt.display = 'Unknown display' "setting default display";
  src.display -> tgt.display;
  src.code -> tgt.id;
}

group TransformReference(source src, target tgt) <<types>> {
  src.id -> tgt.id;
  src.reference -> tgt.reference;
  src.display -> tgt.display;
  src where display.exists().not() -> tgt.display = 'Unknown display' "setting display";
}