Skip to content

Questionnaire Profile

Canonical../StructureDefinition/nexus-emr-core-questionnaire
Statusdraft (experimental) · 1.26.0
BaseQuestionnaire (constraint)
SourceFSH · JSON

A Nexus EMR form definition: what it asks, what it produces, and where its answers land in the chart.

Overview

Forms carry contained prototypes of the resources they extract into, and are instantiated by cloning those prototypes and filling them from the QuestionnaireResponse -- the same idea NexusTemplate uses for letter templates and a Task uses for a suggested chart entry.

A form declares what it produces the way every other prototype-carrying resource in this specification does: templateExtractBundle names a contained transaction Bundle, and its entries are the prototypes. That is the same container NexusTemplate names with List.entry.item and a suggested-resource Task names with input[suggestion].

Output that depends on the answers is expressed inside the Bundle, not outside it. Each Bundle.entry carries a templateExtractContext expression naming the part of the response that fills it. An entry whose context selects a repeating item is instantiated once per repeat; an entry whose context matches nothing is removed. A repeating entry names its fullUrl by expression over an extractAllocateId variable, because a single authored urn:uuid cannot distinguish iterations.

SDC's per-item templateExtract is deliberately not used here, though SDC blesses it and ships the same demonstration form authored both ways. This is a narrowing, and it can be widened later without invalidating anything written against this profile. The reason is that mixing the two leaves a form with two prototype pools that cannot cite each other: a #id resolves against Questionnaire.contained, so an item cannot name a prototype that lives as a Bundle entry, and an entry cannot name one that lives loose in contained. One container removes the seam rather than documenting it.

A form definition: what it asks, what it produces, and where its answers land in the chart.

This is the other half of QuestionnaireResponse. The IG has profiled the answer set since 1.16.0 and never the form, so it could describe a completed questionnaire but not the thing that produced one. The response profile says so itself: its questionnaire element is "a canonical reference to a definition the IG does not govern -- for external instruments that is correct and permanent; for WELL-authored forms it is a gap."

This is the template mechanism

A form, a letter template and a suggested chart entry are the same idea, and this profile is short because that is true.

Each is content carrying contained prototypes of what it produces, instantiated by cloning those prototypes, filling in what the definition could not know, and resolving the references between them. NexusTemplate says that for letters; a Task says it for a suggested chart entry; this says it for forms.

The container is shared as well as the idea. What differs is the wrapper that supplies identity, and what drives the fill:

Wrapper Names the Bundle with Filled from
Letter template List entry.item the instantiation context
Suggested chart entry Task input[suggestion] already filled in
Form Questionnaire SDC's templateExtractBundle a QuestionnaireResponse

A form is the only one whose output can depend on what a user answers, and that is expressed inside the Bundle. Each Bundle.entry carries a templateExtractContext expression naming the part of the response that fills it: an entry whose context selects a repeating item is instantiated once per repeat, and an entry whose context matches nothing is removed. A repeating entry names its fullUrl by expression over an extractAllocateId variable, because one authored urn:uuid cannot distinguish iterations.

SDC's per-item templateExtract is deliberately not used here, though SDC blesses it -- and ships the same demonstration form authored both ways, which is as clear a statement as a specification makes that the two are one capability. Mixing them would leave a form with two prototype pools that cannot cite each other, since a #id resolves against Questionnaire.contained and a Bundle entry is not a contained resource. This is a narrowing rather than a judgement about SDC, and admitting the item spelling later would invalidate nothing written today.

The mechanism is documented once, on the handbook's Templates page.

Why the position differs from QuestionnaireResponse

QuestionnaireResponse.item is deliberately unconstrained. Questionnaire.item is not. That is not an inconsistency, it is the same rule applied to two different situations:

  • A response may arrive from an external instrument whose item tree we do not govern. Constraining it would make conformant partner data non-conformant.
  • A form definition in Nexus is one we authored, or one we translated inward at the boundary.

Nexus does not accept arbitrary foreign form definitions into the chart. External forms are translated into this shape on the way in — one generic format, ours. What is lossy in that translation is a declared question, not a silent drop; see What is not settled below.

Where the answers go

item.definition and item.code are the form-to-chart binding, and between them they replace what a form system would otherwise express as a flat enum of EMR field names.

  • item.definitionthe element an answer populates. R4 defines it as a reference to an ElementDefinition, so a binding may name an element of a Nexus profile and inherit that profile's constraints rather than restating them.
  • item.codewhat the question means. A question coded with the LOINC tobacco-smoking-status concept is recognisable as that question whichever form it appears on, which is what lets an answer become a clinical fact rather than form-specific text.

The requirements here come from a form model that names seventy EMR fields an answer can bind to — demographics, problem list, allergies, medications, and a granular tobacco and substance vocabulary. Every one is an element of a resource this IG already profiles, so the binding is a path rather than a code. Expressed that way, the flattening compromises dissolve: a parallel addr2* field enum is simply Patient.address[1].

Identity

url and version are both required here though 0..1 in R4.

A form is a definitional artifact: it is versioned, cached, and referenced by every response to it. A response to a form with no canonical cannot be interpreted beyond its own display text, and a response to an unversioned form cannot be interpreted at all once the form changes — the answers are against a shape nobody can reconstruct.

identifier is separate and optional: url is what this form is in Nexus, identifier is what it was called in the system it was translated from, so a translation can be traced back.

The authoring rule

A prototype is valid base R4. The extracted resource is valid Nexus.

The same rule, in the same words, that templates follow. A prototype has no patient, because a form is about no one until it is answered, and base R4 already permits that. Where base R4 does require a value, supply a truthful one — the form's own date, its author — and expect it to be overwritten.

Do not invent sentinel values

A placeholder like 1900-01-01 or Patient/placeholder is syntactically valid, which is exactly the problem: if the step that was supposed to replace it is missing, it survives into a real chart and nothing downstream can distinguish it from a value someone meant.

dom-3 and dom-4 do real work here rather than rules invented for this profile: a stray prototype nothing points at is already invalid, and a prototype cannot carry repository identity it has no right to.

What is not settled

Named rather than buried, because each is a real requirement with no current home:

  • Approximate date and duration. "About three years ago" is what patients answer, and R4 date cannot express it. A genuine clinical requirement with no FHIR datatype.
  • Body diagrams. Annotating an image has no item type; attachment carries the result but not the interaction.
  • Note generation. Producing clinical text is a first-class output of a medical form system — in the model this profile draws on, the note formatter is roughly the size of the scripting engine, and sections carry QUESTIONNAIRE | OBJECTIVE | ASSESSMENT | PLAN subcategories deciding what the patient sees versus what reaches the note. Nothing in FHIR Questionnaire addresses it. It is the same ruling as structured note sections and should be decided with it.
  • Expressions. Show/hide, formulas, prefill from prior answers, progress and validation are script in the source model. SDC expresses most of them in FHIRPath, which is specifiable and safe to accept where arbitrary script is not. Additive; not in this pass.
  • The inbound translation contract. What happens to the lossy parts — embedded script, diagrams — when an external form is translated in.
  • The item-type mapping. The source model's twenty item types are not mapped to R4 item.type anywhere in this IG, which is why item.type is left unconstrained here rather than bound. It is the largest thing a form implementer still has to reconstruct. It should be settled with the inbound translation contract above, because the same decision governs the item types that have no R4 equivalent.