Aidbox
Search…
⌃K

Write a custom zen profile

This article is work-in-progress. Please contact us if you want to get details on how to create a custom zen profile.
Note: you can not use Attributes and zen profiles on the same resource at the same time

Validation modes supported with zen schemas

Zen schemas are used by Aidbox for validating resources e.g. in FHIR CRUD API. Such zen schemas must be tagged with either zen.fhir/base-schema or zen.fhir/profile-schema. Additionally they must have :zen.fhir/type and :zen.fhir/profileUri keys specified.

zen.fhir/base-schema

Schemas tagged with zen.fhir/base-schema are used to validate every resource of a specified type. When loaded into Aidbox they will be used in place of the default JSON schemas.
zen.fhir/base-schema
{:zen/tags #{zen/schema zen/tag}
:zen/desc "This schema should be used to validate all resources of its type"
:confirms #{structure-schema}
:type zen/map
:require #{:zen.fhir/type}}

zen.fhir/profile-schema

Schemas tagged with zen.fhir/profile-schema are used to validate resources that mention their :zen.fhir/profileUri in the meta.profile attribute.
Those schemas must be tagged with zen.fhir/profile-schema, describe data structure in the Aidbox format and conform to the following schema:
zen.fhir/profile-schema
{:zen/tags #{zen/tag zen/schema}
:type zen/map
:confirms #{zen.fhir/structure-schema}
:keys {:zen.fhir/type {:type zen/string}
:zen.fhir/profileUri {:type zen/string}}}
zen.fhir/profile-schema, by virtue of being a zen.fhir/nested-schema, must also conform to the following schema:
zen.fhir/nested-schema
{:zen/tags #{zen/schema}
:type zen/map
:keys {:fhir/flags {:type zen/set}
:fhir/extensionUri {:type zen/string}
:fhir/polymorphic {:type zen/boolean}
:zen.fhir/reference {:type zen/map
:keys {:refers {:type zen/set
:every {:type zen/symbol}}}}
:zen.fhir/value-set {:type zen/map
:keys {:symbol {:type zen/symbol}
:strength {:type zen/keyword
:enum [{:value :required}
{:value :extensible}
{:value :preferred}
{:value :example}]}}}
:keys {:type zen/map
:values {:confirms #{nested-schema}}}
:every {:confirms #{nested-schema}}}}

Description of various schema keys

key
Text
description
zen.fhir/type
required
Used to find schema by matching against resourceType of incoming data
zen.fhir/profileUri
required
Used to find schema by matching against meta.profile of incoming data
fhir/flags
optional
A set of keywords derived from FHIR ElementDefinition boolean attributes: isModifier (:?!), isSummary (:SU), mustSupport (:MS)
fhir/extensionUri
optional
Used in Aidbox->FHIR format transformations to create extension element with url described in this key
fhir/polymorphic
optional
Used in Aidbox->FHIR format transformations to detect whether the element is a choice type
zen.fhir/reference
optional
Used to specify resource types that can be referenced
zen.fhir/reference.refers
optional
set of symbols referring to other zen.fhir/profile-schemas or zen.fhir/base-schemas, used on reference validation
zen.fhir/value-set.symbol
optional
symbol referring to zen.fhir/value-set schema, used on validation to check data against a valueSet
zen.fhir/value-set.strength
optional
keyword specifying strength of binding

Examples

:zen.fhir/reference

Patient.managingOrganization is a reference to an Organiazation resource:
hl7-fhir-r4-core.Patient
schema
{#_...
:keys
{#_...
:managingOrganization
{:confirms #{hl7-fhir-r4-core.Reference/schema zen.fhir/Reference}
:zen.fhir/reference {:refers #{hl7-fhir-r4-core.Organization/schema}}}}}

zen.fhir/value-set

To enable value-set validation in zen concept resources with valueset attribute populated must be loaded into Aidbox.
:zen.fhir/value-set key must be a symbol tagged with zen.fhir/value-set
hl7-fhir-r4-core.Patient
schema
{#_...
:keys
{#_...
:gender
{#_...
:zen.fhir/value-set
{:symbol hl7-fhir-r4-core.value-set.administrative-gender/value-set
:strength :required}}}}
zen.fhir/value-set symbol definition must contain :uri and :fhir/code-systems attributes
:uri is a ValueSet.url, which must be mentioned in a Concept.valueset.*
:fhir/code-systems :fhir/url is a CodeSystem.url, which must be a value of Concept.system :zen.fhir/content can have a value :bundled , this means that a CodeSystem content is accessible as Aidbox Concept resources. Other option is :not-present, Aidbox will skip validation of such concept assuming that the CodeSystem content is not loaded into Aidbox
hl7-fhir-r4-core.value-set.administrative-gender
value-set
{:zen/tags #{zen.fhir/value-set},
#_...
:uri "http://hl7.org/fhir/ValueSet/administrative-gender",
:fhir/code-systems #{{:fhir/url "http://hl7.org/fhir/administrative-gender",
:zen.fhir/content :bundled}}}

:slicing

:slicing allows to validate a part of some array with a zen-schema. Such part is called a slice. :slicing allows to reproduce FHIR profiling Slicing operation
Before applying :schema to a slice zen needs to determine elements of the array this slice consists of, this logic is described using :filter key. :filter must specify an :engine. Currently there're two engines available :zen and :match
:zen engine matches elements against specified zen schema
:match engine is a pattern matching DSL:
  • primitive (e.g. string or a number): constant, i.e. literal match of a value
  • {} : objects validated with this match must contain and conform to every key from this pattern
  • #{} : at least one element of an array must conform each element of this pattern
From example below: :match {:code "29463-7", :system "http://loinc.org"} means that elements with specified code and systems will be considered as a part of the slice.
:schema is a zen schema which will be applied to a slice.
Following example describes that in the code.coding array there is a slice called BodyWeightCode consisting of exactly one element with code="29463-7" and system="http://loinc.org":
hl7-fhir-r4-core.bodyweight
schema
{#_...
:keys
{#_...
:code
{:confirms #{hl7-fhir-r4-core.CodeableConcept/schema}
:type zen/map
:keys
{:coding
{:type zen/vector
:every {:confirms #{hl7-fhir-r4-core.Coding/schema}}
:slicing
{:slices
{"BodyWeightCode"
{:filter
{:engine :match
:match {:code "29463-7", :system "http://loinc.org"}}
:schema
{:type zen/vector
:minItems 1
:maxItems 1
:every
{:type zen/map
:require #{:system :code}}}}}}}}}}}
Slicing on Organization.identifier constraining max one element in both NPI and CLIA slices:
hl7-fhir-us-core.us-core-organization
schema
{#_...
:keys
{#_...
:identifier
{:type zen/vector
:every {:confirms #{hl7-fhir-r4-core.Identifier/schema}}
:slicing
{:slices
{"NPI"
{:schema {:type zen/vector, :maxItems 1}
:filter
{:engine :match
:match {:system "http://hl7.org/fhir/sid/us-npi"}}}
"CLIA"
{:schema {:type zen/vector, :maxItems 1}
:filter {:engine :match
:match {:system "urn:oid:2.16.840.1.113883.4.7"}}}}}}}}