Skip to content

QuestionnaireResponse Profile

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

Nexus EMR profile for QuestionnaireResponse -- completed intake, screening and consent forms, including those passed through from external eReferral partners. Appears in the patient chart's journey timeline. First pass: dating and form linkage; item structure is deliberately unconstrained.

TypedFhir API / Pydantic schema

The typed accessor surface QuestionnaireResponse exposes for QuestionnaireResponse — generated from this IG's compiled profile; each typed accessor has a validating raw-FHIR twin (xRaw) where marked. The three ports are parity-enforced.

The AI-facing shape: from typed_fhir.facade.generated.schemas import QuestionnaireResponseSchemamodel_json_schema() is a structured-output / tool definition; instantiating validates an extraction. Generated source.

class QuestionnaireResponseSchema(BaseModel):
    """AI-facing shape of the QuestionnaireResponse profile: the facade's typed accessor
    surface (curated + salient fields) as a pydantic model. `model_json_schema()` is a
    structured-output / tool schema; instantiating validates an extraction."""

    model_config = ConfigDict(extra="forbid")

    questionnaire: str | None = Field(
        None,
        description=(
            "Canonical URL of the form definition this answers. The Questionnaire that defines "
            "and organizes the questions for which answers are being provided. Note: For an "
            "EXTERNAL instrument this is a canonical reference to a definition the IG does not "
            "govern, which is correct and permanent. For a WELL-authored form it now resolves to "
            "a NexusEmrCoreQuestionnaire -- the gap this comment used to describe was closed in "
            "1.20.0. A response with no `questionnaire` still cannot be interpreted beyond its "
            "own display text, because nothing states what the items mean. "
            "QuestionnaireResponse.questionnaire — 0..1"
        ),
    )
    status: Literal[
        "amended",
        "completed",
        "entered-in-error",
        "in-progress",
        "stopped",
    ] | None = Field(
        None,
        description=(
            "Where the response is in its lifecycle. The position of the questionnaire response "
            "within its overall lifecycle. Note: Chart surfaces SHOULD scope to `completed` and "
            "`amended`. An `in-progress` response is a partially-filled form and rendering it as "
            "a chart fact overstates it. QuestionnaireResponse.status — 1..1"
        ),
    )
    subject: Reference | None = Field(
        None,
        description=(
            "The patient the form is about. The subject of the questionnaire response. This could "
            "be a patient, organization, practitioner, device, etc. This is who/what the answers "
            "apply to, but is not necessarily the source of information. Note: 0..1 per R4. "
            "Anything appearing in a patient chart MUST carry it -- an unsubjected response "
            "cannot be scoped to (or excluded from) a chart. QuestionnaireResponse.subject — 0..1"
        ),
    )
    encounter: Reference | None = Field(
        None,
        description=(
            "The encounter during which the form was completed. The Encounter during which this "
            "questionnaire response was created or to which the creation of this record is "
            "tightly associated. Note: Encounter is the association anchor for resources arising "
            "from a visit -- see the Encounter profile's appointment/encounter model. "
            "QuestionnaireResponse.encounter — 0..1"
        ),
    )
    authored: FuzzyDate | None = Field(
        None,
        description=(
            "When the form was completed. The date and/or time that this set of answers were last "
            "changed. Note: THE effective date for this profile. Optional in R4 and left optional "
            "here (pass-through responses may genuinely lack it), but see "
            "questionnaireresponse-has-authored: an undated response is invisible to the timeline "
            "rather than visibly incomplete. QuestionnaireResponse.authored — 0..1"
        ),
    )
    author: Reference | None = Field(
        None,
        description=(
            "Who recorded the answers. Person who received the answers to the questions in the "
            "QuestionnaireResponse and recorded them in the system. Note: Distinct from `source` "
            "(who the answers are about / who supplied them). A patient-completed intake form has "
            "Patient as source; the author may be the same Patient (self-serve portal) or a staff "
            "member transcribing. QuestionnaireResponse.author — 0..1"
        ),
    )
    source: Reference | None = Field(
        None,
        description=(
            "Who supplied the answers. The person who answered the questions about the subject. "
            "Note: If not specified, no inference can be made about who provided the data. "
            "QuestionnaireResponse.source — 0..1"
        ),
    )
    item: dict | None = Field(
        None,
        description=(
            "The answered questions (structure intentionally unconstrained). A group or question "
            "item from the original questionnaire for which answers are provided. Note: "
            "Deliberately unconstrained, not an oversight, and the asymmetry with "
            "NexusEmrCoreQuestionnaire is deliberate too: a RESPONSE may arrive from an external "
            "instrument whose tree we do not govern, so constraining it would make conformant "
            "partner data non-conformant, whereas a form DEFINITION in Nexus is one we authored "
            "or translated inward and IS constrained. Consumers MUST treat the item tree as open: "
            "recurse rather than index positionally, tolerate nested `item` at any depth (a real "
            "intake form reaches six levels), and expect `answer.value[x]` in any of its "
            "permitted types. QuestionnaireResponse.item — 0..*"
        ),
    )
    date: FuzzyDate | None = Field(
        None,
        description=(
            "When the form was completed. The date and/or time that this set of answers were last "
            "changed. Note: THE effective date for this profile. Optional in R4 and left optional "
            "here (pass-through responses may genuinely lack it), but see "
            "questionnaireresponse-has-authored: an undated response is invisible to the timeline "
            "rather than visibly incomplete. Salient field — authored"
        ),
    )