SDCDocument - contains questions with answers and other meta data
Other layers you could add as you need some special behavior:
Form Layout - define fields layout and display rules
Form Launch - define form init parameters and prepopulate logic.
Form Finalize - define additional validations and extractions for form sign
SDCDocument
Lets define some subset of the Vitals questionaire.
VitalsDocument
{:zen/tags #{zen/schema aidbox.sdc/doc aidbox.sdc/rules},
:type zen/map,
;; define source of original questionaire (optional)
:source {:code "85353-1", :system "http://loinc.org"},
;; title of your document
:zen/desc "Basic Vitals Document",
;; to validate against common document fields you need to confirms sdc/Document
;; document also has common fields: author, patient, encounter
:confirms #{aidbox.sdc/Document},
;; you also can define some rules for your document and also computed fields.
;; (lisp reference see bellow)
:sdc/rules {:bmi (when (and (get :weight) (get :height))
(* (divide (get :weight)
(get :height))
10000))},
;; all fields should be defined under :keys
;; fields are defined with zen types and confirms.
:keys {:weight {:text "Weight",
:confirms #{aidbox.sdc.fhir/quantity},
:units [{:name "kg"}]},
:height {:text "Body height",
:confirms #{aidbox.sdc.fhir/quantity}
:units [{:name "cm"}]},
:bmi {:text "BMI",
:type zen/number}}}
SDC Rules is just are lisp expressions that can be used for two things:
store temporary value
calculate document field
To store rule value in SDCDocument give it the same name as the field:
DepressionDocument
{...
:sdc/rules {:phq2-score (+ (get-in [...] ...)
:type zen/map
:keys {:phq2-score {:type zen/integer}} ;; phq2-score will be calculated on-fly and stored in the document
...
}
Form layout defines fields layout for specific SDCDocument and layout-engine
Default Layout engine is aidbox.sdc/Hiccup uses DSL in shape of nested objects {:type component-type :children []}
VitalsLayout
{:zen/tags #{aidbox.sdc/Layout}
;; bind form to document
:document VitalsDocument
;; set layout engine (pluggable, default: aidbox.sdc/Hiccup)
:engine aidbox.sdc/Hiccup
;; layout specified according to layout engine
:layout
{:type aidbox.sdc/col,
:children
;; {:bind [:field-name]} used to bind widget to specific field of the document
[{:bind [:loinc-29463-7]}
{:bind [:loinc-8302-2]}
{:bind [:loinc-39156-5]}]}}
Form Finalize defines extractions that should be done after document sign and optionally binds to custom constraint schema for validations.
Default export-engine - aidbox.sdc/LispExport (see available commands: LISP Reference)
VitalsFinalize{:zen/tags #{aidbox.sdc/Finalize zen/schema};; bind to document:document VitalsDocument;; possible to define custom export engine:export-engine aidbox.sdc/LispExport;; describe which resources should be created based on form data:create [;; use lisp template to generate observation if field is exists {:template aidbox.sdc/gen-observation-template:params {:path [:bmi]} };; create observation resource if the field exists (when (get:height) {:resourceType"Observation":status"final":code {:coding [{:code"29463-7"}]}:subject (get:patient):encounter (get:encounter):value {:Quantity (get:height)}});; decribe other resources to create ,,,]}
Finalize Constraints
The Form gets validated on sign operation using the document schema. An additional validation profile can be defined within the Finalize layer.
This profile can e.g. declare mandatory fields or set some limitations like min/max for numeric fields etc. The profile is defined via zen schema.
VitalsFinalizeConstraints{:zen/tags #{zen/schema}:type zen/map;; list of mandatory fields:require #{:bmi:weight:height}:keys {;; limit field value to the specified range:bmi {:type zen/number :min20, :max220};; denote this field value is required:weight {:type zen/map :require #{:value}};; more validation constraints ,,, }}}
Form
Form used just to bind all DSLs to one item.
VitalsForm
{:zen/tags #{aidbox.sdc/Form}
;; form title
:title "Vitals Signs"
;; bind to Document
:document VitalsDocument
;; bind to Layout
:layout VitalsLayout
;; bind to Launch
:launch VitalsLaunch
;; bind to Finalize
:finalize VitalsFinalize}
For now you can already try to use created document via aidbox.sdcAPI