Document DSL

  • Document is schema for Questionnaire with questions and answers and types of values.

  • Document is used as source of meta-information by FormLayout

  • Document is used as source of meta-information by FormFinalize

  • Document resources stored in SDCDocument table.

  • Document can define computed fields via rules.

Marking schema as SDC Document entity

Document definition should be marked with aidbox.sdc/doc tag, and also tagged as zen/schema - because it's already schema.

MyDocument
{:zen/tags #{zen/schema aidbox.sdc/doc}}

And after that you can define your custom properties of the document and it's meta information (like source of the document)

Document source defined as fhir Coding like structure, with :system, :code and :url properties

MyDocument
{:zen/tags #{zen/schema aidbox.sdc/doc}
 :source {:code "85353-1" :system "http://loinc.org"}}

To define document fields - you should add :type zen/map property and put your fields under :keys property.

MyDocument
{:zen/tags #{zen/schema aidbox.sdc/doc},
 :type zen/map
 :keys {:loinc-8310-5 {:text "Body temperature"
                       :type zen/map,
                       :confirms #{aidbox.sdc.fhir/quantity},
                       :sdc/boundaries {:imperial {:min 86, :max 105},
                                        :metric {:min 30, :max 42}},
                       :units [{:name "°F"} {:name "°C"}]}}}

Every document field should confirms aidbox.sdc/super-field schema.

For details see Document fields definition section.

DB Storage & Common properties

To support document db-saving ability and support common fields for all documents such as:

  • :author - Reference to user which create document,

  • :encounter - Reference to encounter,

  • :unit-system - What unit system was used in this document at launch,

  • :patient - Reference to patient

  • :status - Status of the document,

  • :type - Full name of document profile.

  • :form - Name/version of form, with which document was captured

You need to add :confirms #{aidbox.sdc/Document} property

MyDocument
{:zen/tags #{zen/schema aidbox.sdc/doc}
 :type zen/map
 :confirms #{aidbox.sdc/Document}}

Rules

Rules used for computed properties. Properties schema and compute formula - defined separately.

To support rules definition you need to add tag aidbox.sdc/rules

MyDocument
{:zen/tags #{aidbox.sdc/doc zen/schema aidbox.sdc/rules}}

and after that you can define caclulated properties and their formulas under :sdc/rules property

MyDocument
{:zen/tags #{aidbox.sdc/dok zen/schema aidbox.sdc/rules},
 :type zen/map
 :sdc/rules {:loinc-39156-5 (when (and (get-in [:loinc-29463-7])
                                       (get-in [:loinc-8302-2]))
                             (* (divide (* (get-in [:loinc-29463-7]) 703)
                                        (* (get-in [:loinc-8302-2])
                                           (get-in [:loinc-8302-2])))
                                1))},
 :keys {:loinc-39156-5 {:type zen/number,
                        :text "BMI"}}}
  • name of the rule (:loinc-39156-5) should be matched with name of the field.

  • If sdc-type inference can't recognize field as calculated - you can mark it manually - add :sdc-type aidbox.sdc/calculated to it

When form launched - Rules from Document will be merged with rules from Layout and placed under :rules key in response.

Don't use same keys in Document rules and Layout rules

Rules logic defined via Embeddel lisp. See details in Lisp reference.

Aidbox Form UI has embedded lisp engine. If you use your custom ui - you should implement your lisp-engine, based on lisp reference.

Document Field definition

SDCDocument has several embedded field-types:

  • aidbox.sdc/text - fields with multiline text

  • aidbox.sdc/string - fields with oneline text

  • aidbox.sdc/number - fields with number

  • aidbox.sdc/quantity - fields with measurement units

  • aidbox.sdc/choice - fields with answers, located in valuesets

  • aidbox.sdc/calculated - fields, which need to be calculated via rules engine

This field types inferred from Document field schemas. But you can overwrite that by specifying it directly via :sdc-type key

super-field schema

Field-type definition.

Schema contains several aspects of Document (Field) lifecycle

  • how it stored in DB

  • how it validates

  • how it appeares in UI layout

  • what the possible options

  • what the source of the field

Can contain sub-fields or behaves like an array. Also has links to original sources of questions.

super-field schema has next keys:

propertydescriptiontyperequired?

text

Question text

string

yes

help

Question explanation or some hint - how to interpret it

string

no

type

zen/type of the value, which will be stored in DB

symbol

no

sdc-type

field meta-type - used for determine UI input type

symbol

no

confirms

additional schemas for stored value confirmation

set of symbols

no

sdc/default-value

Default field value (also for repeated fields)

zen/any

no

enum

List of available values (used in choice)

zen/keyword

no

sdc/options

Alternative options source (used in choice)

zen/keyword

no

units

List of units (used for quantity fields)

vector of {:name string}

no

keys

When field is complex object(map) - used for defining nested fields

map of super-fields

no

every

When field is coll (zen/vector) - used for defining coll-item schema

super-field

no

sdc/boundaries

Min/max values for quantity fields (for different measurement units)

{:imperial MinMaxMap, :metric MinMaxMap}

no

last-change-datetime

Meta field - contains datetime of last changes

any

no

code

CodeSystem of the question (used in extractions)

Coding

no

linkId

Link to original questing (in questionnaire, used in converter to QR)

string

no

quantity field-type

Quantity contains units of measurement

quantity schema has next additional keys:

propertydescriptiontyperequired?

units

List of units

vector of {:name string}

no

Example:

MyDocument
{:zen/tags #{aidbox.sdc/doc zen/schema}
 :keys {:temp {:text "Body temperature"
               :type zen/map,
               :confirms #{aidbox.sdc.fhir/quantity},
               :units [{:name "°F"} {:name "°C"}]}}}

choice field-type

Choise field - references valueset with answers

Choice fields should have these properties:

propertydescriptiontyperequired?

:enum

List of available values

zen/keyword

no

:sdc/options

Alternative options source

zen/keyword

no

By default choice field uses :enum keyword for options definition.

Example:

MyDocument
{:zen/tags #{zen/schema aidbox.sdc/doc},
 :keys {:bp-measurement {:text "BP measurement site"
                         :confirms #{aidbox.sdc.fhir/coding}    ;; <-- if you use :enum to enumerate possible values - this confirms is optional 
                         :enum [{:value {:text "Biceps left",
                                         :code "LA11158-5",
                                         :system "http://loinc.org"}}
                                {:value {:text "Biceps right",
                                         :code "LA11159-3",
                                         :system "http://loinc.org"}}]}}}

If by some reason you can't use zen-defined :enum keyword with options - you also have 2 alternative sources for retreiving them:

  • :aidbox.sdc.options/valueset use valuset stored in aidbox db

  • :aidbox.sdc.options/rpc - use custom rpc

If you specify :sdc/options :aidbox.sdc.options/valueset, then you also must specify :valueset property.

propertydescriptiontyperequired?

valueset

ValueSet ID with list of choices

zen/string

yes

If you specify :sdc/options :aidbox.sdc.options/rpc, then you also must specify :rpc property.

propertydescriptiontyperequired?

valueset

ValueSet ID with list of choices

zen/string

yes

rpc

rpc method invocation description

zen/map

yes

RPC method invocations have next structure

propertydescriptiontyperequired?

valueset

ValueSet ID with list of choices

zen/string

yes

method

rpc method name

zen/symbol

yes

params

parameters map

zen/map

yes

Each value of parameters-map should be valid lisp expression.

Example:

:sdc/options :aidbox.sdc.options/rpc
:rpc {:method my-ns/my-rpc
      :params {:p1 (+ 1 2)
               :p2 20}}

\

calculated field-type

Calculated field. Rule with same name should be used to calculate the result.

Calculated fields don't provide additional keys. Instead it depends on :sdc/rules

NOTE: we have one restriction - calculated fields can't be in nested fields.

MyDocument
{:zen/tags #{zen/schema aidbox.sdc/doc aidbox.sdc/rules},
 :keys {:height  {...}
        :weigth  {...}
        :bmi     {:text "BMI",
                  :type zen/number}}
 :sdc/rules {:bmi (divide (get :weigth)
                          (* (get :height)
                             (get :height)))}}

QuestionnaireResponse convertions

If you need to convert SDCDocument to QuestionnaireResponse you need to specify additional field property

  • :linkId - linkId of original Questionnaire (if not given key of the question will be taken)

MyDocument
{:zen/tags #{zen/schema aidbox.sdc/doc},
 :keys {:bmi {:text "BMI",
              :type zen/number,
              :linkId "/39156-5"}},
 }

SDCDocument extraction

If you need to extract some values to Observation you need specify additional field property

  • :code - code/system of original Questionnaire question

MyDocument
{:zen/tags #{zen/schema aidbox.sdc/doc},
 :keys {:bmi {:text "BMI",
              :type zen/number,
              :code [{:system "http://loinc.org"}]}},
 }

Last updated

Change request #2416: