feat: practice-managed custom forms — builder, scored renderer, send to patients (OTR-2309 pt 1/2)#8130
Open
dmabram wants to merge 1 commit into
Open
feat: practice-managed custom forms — builder, scored renderer, send to patients (OTR-2309 pt 1/2)#8130dmabram wants to merge 1 commit into
dmabram wants to merge 1 commit into
Conversation
…to patients
Practices can author their own form questionnaires and send them to patients,
independent of the canonical intake paperwork.
Authoring (EHR admin):
- Questionnaires admin tab: list/create/edit/delete practice-managed FHIR
Questionnaires (tagged practice-managed), with import-JSON and soft delete
(retired status; existing responses still render). The canonical url/name are
preserved on edit so renaming a live form never orphans prior responses.
- Form builder: paged items, answer options, conditional display (enableWhen),
calculated expressions on hidden items for scoring, live preview + test dialog.
- admin-{list,get,create,update,delete}-questionnaire zambdas (structured
APIErrors for user-actionable failures; paginated catalog listing).
Patient-facing:
- send-patient-form zambda texts the patient a link (visit-scoped
/forms/:appointmentId/:questionnaireId or patient-scoped
/forms/patient/:patientId/:questionnaireId).
- StandaloneFormPage (intake app) renders and submits the form outside any
booking flow: required-field validation, per-page answers scoped correctly,
in-progress responses resume, save/submit failures surface to the patient,
answers to enableWhen-disabled items are pruned, and numeric scoring artifacts
(option prefixes, live totals) never display to patients. Computed expression
values save to the QuestionnaireResponse; finalize files a PDF into the
patient's Paperwork folder and can spawn follow-up tasks (failures there are
reported to Sentry, not swallowed).
- get/save/finalize practice-managed-response zambdas enforce caller→patient
authorization (EHR users pass implicitly); writes authorize against the QR's
own subject.
EHR visit details:
- "Send Form" action in the top action row opens a filterable form picker (with
distinct error vs empty states).
- Completed forms render on the visit page and in the response viewer.
Attaching forms to the intake paperwork itself is intentionally out of scope
here — that lands separately as paperwork flows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 1 of 2 for OTR-2309 (part 2, paperwork flows, is a stacked PR on this branch). Practices can author their own form questionnaires and send them to patients, independent of the canonical intake paperwork.
What this adds
Form authoring (EHR admin → Questionnaires tab)
enableWhen, all/any), and scoring via calculated expressions on hidden items.Send to patients (EHR visit details)
/forms/:appointmentId/:questionnaireIdor patient-scoped/forms/patient/:patientId/:questionnaireId); link also copyable.Patient completion (intake app)
Provider review
Security & correctness
get-/save-practice-managed-responseenforce caller→patient authorization (EHR users pass implicitly); writes authorize against the stored QR's own subject; unauthorized → explicitACCESS_DENIEDthe patient app renders.valueCoding(+ display); answers to enableWhen-disabled items are pruned.captureException'd, never swallowed; catalog listings paginate (no silent truncation past one page).Verification
config/.env/local.jsonmachine secrets, identical on base); utils fhir 185/185.yes/ free text /no); EHR shows display text; completed forms on visits render via the existing-QR path.Functional requirements:
practice-forms-functional-requirements.mdPart 1 (local docs).Attaching forms to the booking intake itself is intentionally out of scope here — that lands in part 2 (paperwork flows).
🤖 Generated with Claude Code