Palamond Docs
Resource Modeling

Questionnaires

Rendering forms, writing responses, and answers the care team reconciles.

Palamond collects structured patient input with the standard FHIR pair: a Questionnaire defines the form, and a QuestionnaireResponse records the answers. Questionnaires are versioned canonical resources, reused across protocols and assessments. This page covers the authoring shape you will render, how to write the response, and the item kinds that need special rendering.

Questionnaire shape

A Questionnaire is a tree of items. Groups organize the form; leaf items are the questions. The fields you render from are:

FieldPurpose
item.linkIdStable id for the item, used to key answers.
item.typegroup, boolean, string, choice, integer, and so on.
item.textThe question or group label.
item.enableWhenConditional display based on another answer.
item.answerOptionChoices for a choice item.

Questionnaires carry a couple of Palamond conventions as item extensions, which you read when rendering:

  • A helper subtitle extension holds short guidance shown beneath a question. FHIR has no native field for it.
  • A group marked with the standard SDC item-control page renders all its child questions together on one screen, instead of one question per screen.
Read a questionnaire by canonical url
const [questionnaire] = await palamond.searchResources('Questionnaire', {
  url: 'https://palamond.dev/fhir/Questionnaire/intake',
});

Recording a response

A QuestionnaireResponse mirrors the questionnaire's structure and is patient-authored, so it is one of the two things your app writes on the record plane directly. Reference the questionnaire, and answer each item by linkId.

Write a response
import type { QuestionnaireResponse } from '@palamond/sdk/fhir';

const response = await palamond.createResource<QuestionnaireResponse>({
  resourceType: 'QuestionnaireResponse',
  status: 'completed',
  questionnaire: `${questionnaire.url}|${questionnaire.version}`,
  item: [
    { linkId: 'chief-complaint', answer: [{ valueString: 'Recurring headaches' }] },
    { linkId: 'severity', answer: [{ valueInteger: 6 }] },
  ],
});

Pin the version you rendered. The questionnaire element should carry the url|version the patient actually saw, so a response is always interpretable against the exact form, even after the questionnaire is revised. Save drafts with status: 'in-progress' and update as the patient goes.

File-upload answers

For an item answered with a file (a photo, a document), upload the bytes first: documents.upload takes the filename and the raw file and returns an attachment ready to embed as a valueAttachment answer.

const { attachment } = await palamond.documents.upload(file.name, file, file.type);
// { url, contentType, title } -> use as answer: [{ valueAttachment: attachment }]

Reconciliation items: reviewing the chart

Some questions do more than record an answer. Palamond supports reconciliation items: instead of a plain control, the renderer shows the patient their current chart entries and lets them confirm, add, or remove. Two kinds exist today: allergy review and medication review.

These items are serialized as type: boolean (the answer is the patient's "these are correct" acknowledgement) plus a Palamond capture extension whose code marks the kind. Import the coordinates.

Detect a reconciliation item
import {
  QUESTIONNAIRE_ITEM_CAPTURE_EXTENSION_URL,
  QUESTIONNAIRE_ITEM_CAPTURE_CODES,
} from '@palamond/sdk/codes';

function captureKind(item): string | undefined {
  return item.extension?.find(
    (e) => e.url === QUESTIONNAIRE_ITEM_CAPTURE_EXTENSION_URL,
  )?.valueCode;
  // returns QUESTIONNAIRE_ITEM_CAPTURE_CODES.allergyReview
  //      or QUESTIONNAIRE_ITEM_CAPTURE_CODES.medicationReview
}

Intercept these items before your normal type switch and render the review widget. The patient's acknowledgement and reported entries travel on the QuestionnaireResponse; the care team reconciles the chart from them when they review the intake. Your app does not write allergy or medication resources itself.

Patient-reported entries are provisional. A clinician confirms them during review, so never present a patient-reported allergy or medication as verified chart data in your UI.

Completing the task

An intake questionnaire is usually attached to a patient-facing Task (its focus is the Questionnaire). Write the QuestionnaireResponse, then complete the task referencing it; completion is what advances the workflow.

await palamond.tasks.complete(task.id, {
  questionnaireResponse: `QuestionnaireResponse/${response.id}`,
});

A task that is already closed or not yet due answers 409; see Errors and Limits. The full loop is walked through in Complete an Assessment, and the task model lives in Encounters and Tasks.

On this page