Encounter Type System

A smart interview + resource-matching + treatment-plan-generation engine that connects the patient portal's complaint intake to the doctor's minimal-click visit workflow. Encounter types are first-class, versioned entities: they define what questions to ask, what resources to book, what defaults to pre-select, and what treatment plans to generate — and they learn from every visit.

System Overview

The Encounter Type System is the bridge between what the patient says ("I have a cough") and what the practice does (book a 20-min acute slot with an MA + exam room + spirometer, ask about fever and smoking, pre-fill the doctor's respiratory review, and auto-suggest a CXR order). It has five interlocking parts:

graph TB
  subgraph "Patient Side"
    P1[Complaint Intake] --> P2[Smart Suggestion Engine]
    P2 --> P3[Pre-Visit Questionnaire]
  end

  subgraph "Scheduling Side"
    S1[Encounter Type Definition] --> S2[Resource Matching]
    S2 --> S3[Slot Booking]
  end

  subgraph "Doctor Side"
    D1[Minimal-Click Interview] --> D2[Treatment Plan Generation]
    D2 --> D3[Coding Auto-Suggest]
  end

  subgraph "Learning Side"
    L1[Post-Encounter Review] --> L2[Question Bank Update]
    L2 --> L3[Encounter Type Editor]
  end

  P1 --> S1
  P2 --> S2
  P3 --> D1
  S3 --> D1
  D2 --> L1
  L3 --> S1
  D3 --> L1

  style P1 fill:#4A90D9,color:#fff
  style P2 fill:#4A90D9,color:#fff
  style P3 fill:#4A90D9,color:#fff
  style S1 fill:#7B68EE,color:#fff
  style S2 fill:#7B68EE,color:#fff
  style S3 fill:#7B68EE,color:#fff
  style D1 fill:#2ECC71,color:#fff
  style D2 fill:#2ECC71,color:#fff
  style D3 fill:#2ECC71,color:#fff
  style L1 fill:#E67E22,color:#fff
  style L2 fill:#E67E22,color:#fff
  style L3 fill:#E67E22,color:#fff
    

Each part is specified in detail below, with schemas, flows, and wireframes.

1. Encounter Type Definition Schema

Each encounter type is a first-class entity — versioned, org-scoped, and composable. It replaces the flat "visit type" concept in Scheduling with a rich template that drives every downstream workflow.

EncounterType Entity

FieldTypeScopeNotes
EncounterTypeIDShortGUID (PK)GlobalUnique across the platform
OrganizationIDShortGUIDOrg-scopedFK → Organization. System-wide types have null (platform-managed).
NameString (120)Org-scopedDisplay name, e.g. "Annual Physical — Established Adult"
DescriptionString (500)Org-scopedOne-line purpose for admin UI and patient-facing copy
CategoryEnumGlobalPreventive|Acute|ChronicFollowUp|NewPatient|Procedure|Telehealth
IsActiveBoolOrg-scopedSoft-deactivate without deleting
VersionIntegerOrg-scopedMonotonically increasing; every edit creates a new version row
IsCompositeBoolOrg-scopedtrue if this type is a combination of other types (e.g. Annual + Acute)
CompositeOfTypeIDsShortGUID[]Org-scopedOrdered list of constituent EncounterTypeIDs when IsComposite = true
TotalDurationMinutesIntegerOrg-scopedSum of stage durations; for composites, sum of constituents minus dedup-overlap minutes
StagesEncounterStage[]Org-scopedOrdered list of stages (inherits scheduling stage model; see below)
RequiredResourcesResourceRequirement[]Org-scopedPeople, equipment, and rooms needed
PreVisitQuestionnaireQuestionRef[]Org-scopedOrdered list of question references (deduplication via shared Question bank)
TreatmentPlanTemplateTreatmentPlanTemplateOrg-scopedRules for auto-generating orders, refs, Rx, follow-up
CodingHintsCodingHintSetOrg-scopedSuggested E/M level, CPT, ICD-10 ranges based on answer patterns
ComplaintKeywordsString[]Org-scopedKeywords/phrases that trigger this encounter type from patient complaint text
PatientFacingCopyString (200)Org-scopedWhat the patient sees, e.g. "Annual checkup with your doctor"
CreatedDateTimeUTCDateTimeAudit
ModifiedDateTimeUTCDateTimeAudit
ModifiedByUserIDShortGUIDAudit — FK → User
EncounterStage (extends scheduling VisitStage)
FieldTypeNotes
StageIDShortGUIDUnique within this encounter type
NameString (80)e.g. "Rooming + vitals", "Provider eval"
OrderIndexIntegerZero-based position in stage sequence
DurationMinutesIntegerFixed duration for this stage
StageTypeEnumCheckIn|Waiting|Rooming|Provider|Nurse|Procedure|Checkout|Telehealth
RequiredResourcesResourceRequirement[]Resources needed for this specific stage
QuestionRefsQuestionRef[]Questions to ask during this stage (e.g. vitals questions during Rooming)

This extends the VisitStage model from Scheduling by adding QuestionRefs so that stage-specific questions (e.g. intake questions during Rooming) are driven by the encounter type template.

ResourceRequirement
FieldTypeNotes
ResourceTypeEnumPerson|Equipment|Room
RoleOrCapabilityStringFor Person: MD, MA, RN, FrontDesk. For Equipment: PhlebotomyChair, EKG, Spirometer, Otoscope. For Room: ExamRoom, LabDrawStation, ProcedureRoom.
QuantityMinIntegerMinimum count needed (usually 1)
QuantityMaxIntegerMaximum useful count (e.g. 2 MAs for complex rooming)
RequiredForStagesString[]Which stage(s) this resource is needed for (by StageID)
IsOptionalBoolIf true, the solver can book without this resource but should try to include it

Question Bank & Deduplication

Questions are defined once in a global Question Bank and referenced by encounter types. When a visit combines multiple encounter types (e.g. Annual Physical + Acute), shared questions are asked once.

FieldTypeScopeNotes
QuestionIDShortGUID (PK)GlobalUnique across the platform
TextString (500)GlobalThe question as asked to the patient, e.g. "Are you allergic to latex?"
ShortLabelString (60)GlobalAbbreviated label for doctor view, e.g. "Latex allergy?"
QuestionTypeEnumGlobalYesNo|MultipleChoice|FreeText|Numeric|Scale|Date|SingleSelect
ChoicesChoiceOption[]GlobalFor MultipleChoice / SingleSelect: value + label pairs
UnitsString (30)GlobalFor Numeric: e.g. "lbs", "mg/dL", "pack-years"
ScaleMin / ScaleMaxIntegerGlobalFor Scale: e.g. 0–10 pain scale
IsRequiredBoolPer-refRequired vs. optional — set on the QuestionRef, not the Question itself (same question can be required in one type, optional in another)
ComplaintTriggerString[]Per-refKeywords that activate this question within the encounter type. Empty = always show.
ShowIfConditionExpressionPer-refConditional logic: show this question only if another answer meets criteria (e.g. "Show if Q5 = yes")
ClinicalMappingCodeableConceptGlobalFHIR-aligned mapping: SNOMED-CT observation code, LOINC panel, etc.
SourceEnumGlobalSystemWide|PracticeSpecific
SourceOrganizationIDShortGUIDOrg-scopedNull for system-wide; org ID for practice-specific
DeprecatedDateTimeUTCDateTime?GlobalSet when admin deprecates; excluded from active questionnaires
CreatedDateTimeUTCDateTimeAudit
ModifiedDateTimeUTCDateTimeAudit
QuestionRef (the link between EncounterType and Question)
FieldTypeNotes
QuestionIDShortGUIDFK → Question
OrderIndexIntegerPosition within this encounter type's questionnaire
IsRequiredBoolRequired in this encounter type (overrides Question default)
ComplaintTriggerString[]Keywords from the patient's complaint that activate this question. Empty = always show for this encounter type.
ShowIfConditionExpressionConditional logic expression referencing other QuestionIDs, e.g. { "questionId": "q-smoking", "operator": "equals", "value": "yes" }
StageIDShortGUID?If set, this question is asked during a specific stage (e.g. vitals questions during Rooming). Null = pre-visit questionnaire.
ChoiceOption
FieldTypeNotes
ValueStringStored value, e.g. "current", "former", "never"
LabelStringDisplay label, e.g. "Current smoker", "Former smoker", "Never smoked"
OrderIndexIntegerDisplay order
IsDefaultBoolPre-selected for the doctor view

Overlapping Question Deduplication Engine

When a visit combines multiple encounter types (e.g. Annual Physical + Acute Complaint), the dedup engine:

  1. Collects all QuestionRefs from each constituent encounter type
  2. Groups by QuestionID — questions referenced by multiple types appear once
  3. Merges ComplaintTrigger arrays (union of keywords)
  4. Takes the stricter IsRequired (if required in any type, it's required overall)
  5. Resolves ShowIfCondition conflicts: if any type would show it unconditionally, it's shown unconditionally
  6. Orders: shared questions first, then type-specific questions in constituent order
graph LR
  ET1[Annual Physical
Questions: Q1–Q12] --> DEDUP{Dedup Engine} ET2[Acute Visit
Questions: Q8–Q15] --> DEDUP DEDUP --> MERGED[Merged Questionnaire
Q1–Q7 shared + Q8–Q12 Annual + Q13–Q15 Acute
Q8–Q12 asked ONCE]

Treatment Plan Template

FieldTypeNotes
TemplateIDShortGUID (PK)Unique ID for this template
EncounterTypeIDShortGUIDFK → EncounterType
NameString (120)e.g. "Annual Physical — Standard Orders"
RulesPlanRule[]Ordered list of conditional rules
DefaultFollowUpWeeksIntegerDefault follow-up interval (e.g. 52 for annual, 4 for acute)
PatientEducationTopicsString[]Topics to surface in patient portal after visit
VersionIntegerTemplate version
PlanRule (conditional treatment rule)
FieldTypeNotes
RuleIDShortGUIDUnique within this template
ConditionExpressionExpressionWhen to fire: references question answers and patient data, e.g. { "questionId": "q-diabetic", "operator": "equals", "value": "yes" }
ActionTypeEnumLabOrder|ImagingOrder|Referral|Prescription|FollowUpVisit|ProblemListAdd|PatientEducation|Screening
ActionPayloadJSONAction-specific data. Lab: { "loincCodes": [...], "fastingRequired": true }. Referral: { "specialty": "Cardiology", "urgency": "routine" }. Rx: { "rxNormCode": "...", "sig": "..." }
IsDefaultBoolIf true, this action is auto-checked in the doctor's review; doctor just signs off
PriorityEnumRequired|Recommended|Optional
CategoryStringGrouping label for the doctor view, e.g. "Labs", "Referrals", "Prescriptions"

Coding Hint Set

FieldTypeNotes
DefaultEMLevelStringSuggested E/M code, e.g. 99213 for acute, 99214 for annual, 99215 for complex chronic
EMLevelRulesEMLevelRule[]Conditional E/M upgrades based on answer patterns (e.g. if 3+ chronic conditions reviewed → 99214)
SuggestedCPTCodesString[]CPT codes commonly used with this encounter type, e.g. 99396 (periodic preventive, established 40–64)
ICD10RangesICD10Range[]Common ICD-10 ranges for this encounter type, e.g. Z00.00 (general adult exam), J00–J06 (acute URI)
ModifierHintsString[]Suggested modifiers, e.g. -25 for significant separately identifiable E/M on same day as procedure
EMLevelRule (conditional E/M upgrade)
FieldTypeNotes
ConditionExpressionExpressionWhen to suggest upgrade, e.g. "3+ chronic conditions reviewed"
SuggestedLevelStringe.g. 99214, 99215
MDMRationaleStringPre-written MDM justification text for audit defense

2. Smart Encounter Type Suggestion Engine

When a patient enters complaints on the portal (steps 5–6 of the self-scheduling wizard), the suggestion engine maps complaint text → encounter type(s) and presents a recommendation.

Suggestion Flow

sequenceDiagram
  participant P as Patient Portal
  participant E as Suggestion Engine
  participant D as Dedup Engine
  participant S as Scheduling Solver

  P->>E: Complaint text ("cough for 2 weeks, chest tightness")
  E->>E: Tokenize + keyword match against EncounterType.ComplaintKeywords
  E->>E: Score each encounter type by match count + specificity
  E->>P: Top match: Acute Visit (score: 0.87)
Alt: Annual Physical + Acute (score: 0.72) alt Single type match P->>P: Show: "We recommend a 20-min Acute Visit" end alt Multiple types match P->>D: Merge Annual Physical + Acute Visit D->>D: Deduplicate shared questions D->>P: "Based on your concerns, we recommend a
45-min Annual Physical + 20-min Acute Visit.
Total time: 65 min." end P->>P: Patient accepts or overrides P->>S: Book encounter type(s) → resource graph solver finds slot

Matching Algorithm (Phase 1 — Rule-Based)

StepDescriptionExample
1. TokenizeLowercase, remove stop words, stem"cough for 2 weeks" → ["cough", "2", "week"]
2. Keyword matchMatch tokens against EncounterType.ComplaintKeywords"cough" ∈ Acute.ComplaintKeywords
3. ScoreSum of match weights; keyword specificity bonusAcute: 0.87, Annual+Acute: 0.72
4. ThresholdOnly suggest if score ≥ 0.50.87 passes → suggest Acute
5. Composite detectionIf patient also says "annual" or "checkup", detect Annual Physical keyword and suggest composite"annual checkup + cough" → Annual+Acute composite
6. Problem list augmentationCheck patient's active problem list; if chronic condition present, suggest chronic follow-up typeT2D on problem list → suggest Diabetes Follow-Up in addition
Phase 2 — ML Enhancement. After sufficient booking data is collected, a lightweight classification model (fine-tuned BERT or similar) will replace keyword matching. The model will be trained on complaint text → actual encounter type booked, with human-labeled validation data from the override rate metric. Target: reduce override rate from ~25% (keyword) to <10% (ML).

Patient-Facing Suggestion UI

┌─────────────────────────────────────────────────────────────┐ │ Based on your concerns, we recommend: │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ ★ Annual Physical + Acute Visit │ │ │ │ 65 minutes total │ │ │ │ Includes: health review + cough/chest evaluation │ │ │ │ Pre-visit questions: 15 (3 min estimated) │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Acute Visit only │ │ │ │ 20 minutes total │ │ │ │ Includes: cough/chest evaluation │ │ │ │ Pre-visit questions: 8 (2 min estimated) │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ [Accept Recommendation] [Choose Different Visit Type] │ └─────────────────────────────────────────────────────────────┘

Override Tracking

When a patient overrides the suggestion, the override is logged for model improvement:

FieldTypeNotes
SuggestionIDShortGUIDUnique ID for this suggestion event
PatientIDShortGUIDFK → Patient
ComplaintTextStringOriginal complaint text entered by patient
SuggestedTypeIDsShortGUID[]Encounter type IDs suggested, in rank order
SuggestedScoresFloat[]Match scores for each suggestion
AcceptedTypeIDShortGUIDEncounter type the patient actually selected
WasOverrideBooltrue if patient chose a non-top-ranked suggestion
CreatedDateTimeUTCDateTimeAudit

3. Doctor-Side Minimal-Click Interview

When the doctor opens the encounter in Clinical Documentation, the encounter-type template drives a one-screen summary with all pre-visit answers populated and defaults pre-selected. The doctor's job is to review and approve, not to fill out from scratch.

Interview Flow

sequenceDiagram
  participant DOC as Doctor
  participant UI as Encounter Surface
  participant Q as Questionnaire Engine
  participant TPT as Treatment Plan Engine
  participant COD as Coding Engine

  DOC->>UI: Open encounter
  UI->>Q: Load EncounterType + pre-visit answers
  Q->>UI: Pre-filled summary (all answered questions + defaults)

  UI->>DOC: One-screen summary:
✅ 12/15 pre-populated
⚠️ 3 need attention (unanswered)
📋 Treatment plan ready for review DOC->>UI: Review unanswered questions (3 clicks) DOC->>UI: [Approve All] — sign off on pre-populated items DOC->>UI: Add free-text note (optional) UI->>TPT: Generate treatment plan from answers + template TPT->>UI: Proposed: 2 labs, 1 Rx, 1 follow-up
(all auto-checked, doctor modifies if needed) DOC->>UI: [Sign & Send] — one click UI->>COD: Auto-suggest coding from encounter type + answers + time COD->>UI: E/M 99214, CPT 99396, ICD-10 Z00.00 + J06.9 DOC->>UI: [Accept Codes]

Doctor Encounter Surface — Wireframe

┌───────────────────────────────────────────────────────────────────────────┐ │ ENCOUNTER: Annual Physical + Acute Visit Pt: Maria Garcia, 52F │ │───────────────────────────────────────────────────────────────────────────│ │ │ │ PRE-VISIT ANSWERS (12/15 populated) [Approve All ▼] │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ ✅ Current medications: Lisinopril 10mg, Metformin 500mg BID │ │ │ │ ✅ Allergies: Penicillin (rash), Latex (contact dermatitis) │ │ │ │ ✅ Smoking status: Former smoker (quit 2018) │ │ │ │ ✅ Exercise: Walking 30 min × 3/week │ │ │ │ ✅ Last mammogram: 2024-03 — Normal │ │ │ │ ⚠️ CHEST TIGHTNESS DURATION: ____ [2 weeks ▼] │ │ │ │ ⚠️ FEVER PRESENT: [Yes / No ▼] │ │ │ │ ⚠️ EXPOSURE TO SICK CONTACTS: [Yes / No ▼] │ │ │ │ ✅ Cough productive: Yes — clear sputum │ │ │ │ ✅ Night sweats: No │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ VITALS (MA-entered) │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ BP: 138/88 HR: 76 Temp: 98.4 SpO2: 97% WT: 165 lbs │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ TREATMENT PLAN (auto-generated — review & approve) │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ LABS: ☑ CBC ☑ CMP ☑ Lipid Panel ☑ HbA1c ☐ CXR │ │ │ │ RX: ☑ Albuterol inhaler PRN │ │ │ │ REF: ☐ Pulmonology (if CXR abnormal or spirometry indicated) │ │ │ │ F/U: ☑ Follow-up in 4 weeks (Acute) + 12 months (Annual) │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ CODING (auto-suggested) │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ E/M: 99214 (moderate MDM) CPT: 99396 + 99213-25 │ │ │ │ ICD-10: Z00.00 + J06.9 + E11.65 │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ FREE-TEXT NOTE: _______________________________________________ │ │ │ │ [Sign & Close Encounter] [Add Question to Encounter Type] │ └───────────────────────────────────────────────────────────────────────────┘

One-Click Actions

ActionButtonWhat It DoesDownstream
Approve All[Approve All]Sign off on all pre-populated questionnaire answers in one clickAnswers stored as QuestionResponse entities on the encounter
Order Labs[Order Labs]Send checked lab orders to Labs moduleLab requisition created; sample tracking initiated
Prescribe[Rx]Send checked prescriptions to eRxRx transmitted to pharmacy; EPCS if controlled
Refer[Refer]Send checked referrals to ReferralsReferral created; prior-auth check initiated
Add to Problem List[+ Problem]Add a new condition to the patient's global problem listSNOMED-CT + ICD-10-CM coded; visible across all orgs
Sign & Close[Sign & Close]Finalize encounter note, sign all orders, close encounterNote versioned; orders transmitted; encounter status → Completed

4. Treatment Plan Generation

The treatment plan engine evaluates the TreatmentPlanTemplate rules against the patient's questionnaire answers + existing clinical data (problem list, medication list, recent labs) and produces a concrete plan for the doctor to review, modify, and approve.

Plan Generation Flow

graph TD
  A[Questionnaire Answers] --> RULES{TreatmentPlanTemplate
Rule Evaluation} B[Patient Problem List] --> RULES C[Patient Medication List] --> RULES D[Recent Lab Results] --> RULES RULES -->|Condition met| E1[Auto-checked action
Doctor just signs off] RULES -->|Condition met + optional| E2[Unchecked recommendation
Doctor opts in] RULES -->|No condition met| E3[Action not shown] E1 --> REVIEW[Doctor Review Surface] E2 --> REVIEW REVIEW -->|Approve| FINAL[Finalized Treatment Plan] REVIEW -->|Modify| FINAL REVIEW -->|Remove| FINAL FINAL --> CHART[Saved to Patient Chart] FINAL --> PORTAL[Appears in Patient Portal
my-plan.html] FINAL --> TASKS[Follow-up tasks created
in Task Management]

Generated Treatment Plan Entity

FieldTypeNotes
TreatmentPlanIDShortGUID (PK)Unique ID
EncounterIDShortGUIDFK → Encounter
PatientIDShortGUIDFK → Patient
EncounterTypeIDShortGUIDFK → EncounterType (source template)
ItemsTreatmentPlanItem[]Ordered list of plan items
StatusEnumDraft|PendingReview|Approved|PartiallyCompleted|Completed
ApprovedByUserIDShortGUIDFK → User (the approving clinician)
ApprovedDateTimeUTCDateTimeWhen the doctor signed off
PatientEducationLinksString[]URLs surfaced in patient portal
CreatedDateTimeUTCDateTimeAudit
TreatmentPlanItem
FieldTypeNotes
ItemIDShortGUIDUnique within this plan
ItemTypeEnumLabOrder|ImagingOrder|Referral|Prescription|FollowUpVisit|ProblemListAdd|PatientEducation|Screening
PriorityEnumRequired|Recommended|Optional
IsAutoGeneratedBooltrue if template-driven, false if manually added by doctor
StatusEnumPending|Approved|Removed|Completed
PayloadJSONAction-specific data (same shape as PlanRule.ActionPayload)
TriggerRuleIDShortGUID?FK → PlanRule that generated this item; null if manually added
TriggerAnswerIDsShortGUID[]QuestionResponse IDs that triggered this item (for audit trail)
CategoryStringGrouping label: "Labs", "Referrals", "Prescriptions", etc.
SortOrderIntegerDisplay order within category

Doctor Modification Patterns

5. Learning Loop

After encounter close, the doctor can add new questions to the encounter type. This is the same Question Learning Loop described in the Coding / CDS module, but now applied specifically to the encounter-type template rather than the coding surface.

graph TD
  ENC[Encounter Completes] --> EXTRACT{Question Extraction}
  EXTRACT -->|Scribe captures questions asked| NEWQ[New Questions Identified]
  EXTRACT -->|Doctor manually adds| MANUAL[Doctor adds question]

  NEWQ --> TASK[Auto-create Task:
"Review 3 new questions from
Acute Visit encounters this week"] MANUAL --> TASK TASK --> PM[Practice Manager
reviews in Task Queue] PM -->|Accept| ADD[Add to EncounterType
as PracticeSpecific] PM -->|Edit| ADD PM -->|Reject| REJ[Deprecate Question
or leave unadopted] PM -->|Promote| PROMOTE[Admin promotes to
SystemWide scope] ADD --> NEXT[Next visit of this type
includes new question] PROMOTE --> NEXT2[All orgs see question
after next sync] style ENC fill:#2ECC71,color:#fff style TASK fill:#E67E22,color:#fff style PM fill:#9B59B6,color:#fff style ADD fill:#4A90D9,color:#fff style PROMOTE fill:#4A90D9,color:#fff

Learning Loop Entities

CandidateQuestion (extracted from scribe or manually added)
FieldTypeNotes
CandidateIDShortGUID (PK)Unique ID
EncounterIDShortGUIDFK → Encounter that generated this candidate
EncounterTypeIDShortGUIDFK → EncounterType this candidate targets
TextString (500)The question text
QuestionTypeEnumSuggested type: YesNo, MultipleChoice, FreeText, etc.
SourceMethodEnumScribeExtracted|DoctorAdded
FrequencyIntegerHow many encounters this question appeared in
ReviewStatusEnumPending|Accepted|Edited|Rejected|Promoted
ReviewedByUserIDShortGUID?FK → User who reviewed
ResultingQuestionIDShortGUID?FK → Question created after acceptance
CreatedDateTimeUTCDateTimeAudit
Key design decision: Questions start as PracticeSpecific (tied to the org). A practice manager or admin can promote a practice-specific question to SystemWide scope, making it available to all organizations. Promotion requires:
  1. The question has been used in ≥ 10 encounters across ≥ 3 providers
  2. The accept rate is ≥ 80% (doctors are keeping it in their workflow)
  3. An admin explicitly clicks "Promote to System-Wide"
No question enters the system-wide bank without human review and a data-backed quality gate.

6. Encounter Type Editor

An admin/practice-manager interface for CRUD on encounter types, question bank management, and template editing. This is the control surface for the entire system.

Editor Capabilities

CapabilityDescriptionNotes
CRUD Encounter TypesCreate, read, update, deactivate encounter typesUpdates create a new version row; old versions preserved for audit
Drag-and-Drop Stage ReorderingReorder stages within an encounter typeReorder updates OrderIndex on all stages; solver uses new order
Question Bank ManagementAdd, edit, deprecate, merge duplicate questionsMerge: reassign all QuestionRefs from deprecated ID to target ID
Resource Requirement EditingAdd/remove resources per stageChanges take effect on next booking; existing appointments unchanged
Treatment Plan Template EditingAdd/remove/modify PlanRulesVersioned; old template preserved
Coding Hint EditingAdjust E/M levels, CPT codes, ICD-10 rangesOnly org-scoped types are editable; system-wide types are read-only for non-platform-admins
Preview Mode"What would the patient see? What would the doctor see?"Interactive preview renders the patient questionnaire and doctor summary surface side-by-side
Composite BuilderCombine existing encounter types into a compositeShows dedup preview: "7 shared questions will be asked once"

Editor Wireframe

┌───────────────────────────────────────────────────────────────────────┐ │ ENCOUNTER TYPE EDITOR [Save Draft] [Publish] │ │───────────────────────────────────────────────────────────────────────│ │ │ │ Name: [Annual Physical — Established Adult ] │ │ Category: [Preventive ▼] Duration: [45] min Active: [☑] │ │ Description: [Comprehensive annual exam for established adult patients]│ │ │ │ ── STAGES ─────────────────────────────────────────────────────────── │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ ≡ 1. Check-in 3 min [front-desk] [✕] │ │ │ │ ≡ 2. Waiting 5 min [waiting-room] [✕] │ │ │ │ ≡ 3. Rooming + vitals 7 min [ma, exam-room] [✕] │ │ │ │ ≡ 4. Provider eval 22 min [provider, exam-room] [✕] │ │ │ │ ≡ 5. Nurse follow-up 5 min [rn] [✕] │ │ │ │ ≡ 6. Checkout 3 min [front-desk] [✕] │ │ │ │ [+ Add Stage] │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ ── PRE-VISIT QUESTIONS ───────────────────────────────────────────── │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ ≡ Q1 Medication changes? YesNo Required [Edit] │ │ │ │ ≡ Q2 Allergy updates? YesNo Required [Edit] │ │ │ │ ≡ Q3 Smoking status? Select Required [Edit] │ │ │ │ ≡ Q4 Exercise frequency? Numeric Optional [Edit] │ │ │ │ ≡ Q5 Chest pain? (if acute) YesNo Req* [Edit] │ │ │ │ * Shown only if complaint includes respiratory keywords │ │ │ │ [+ Add Question] │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ ── TREATMENT PLAN TEMPLATE ───────────────────────────────────────── │ │ Rule 1: IF diabetic → order HbA1c + lipid panel ☑ Auto-check │ │ Rule 2: IF age > 50 AND no mammogram in 12mo → refer mammo ☐ Rec │ │ Rule 3: IF smoking = current → order CXR + refer cessation ☐ Rec │ │ [+ Add Rule] │ │ │ │ ── CODING HINTS ──────────────────────────────────────────────────── │ │ Default E/M: [99214 ▼] CPT: [99396] ICD-10: [Z00.00] │ │ │ │ ── PREVIEW ───────────────────────────────────────────────────────── │ │ [Preview Patient View] [Preview Doctor View] │ └───────────────────────────────────────────────────────────────────────┘

JSON Data Shapes

Complete JSON shapes for the four core entities, ready for implementation.

EncounterType (complete JSON shape)
{
  "EncounterTypeID": "A1b2C3d4E5f6G7h8I9j0K1",
  "OrganizationID": null,
  "Name": "Annual Physical — Established Adult",
  "Description": "Comprehensive annual exam with labs, screenings, and preventive counseling",
  "Category": "Preventive",
  "IsActive": true,
  "Version": 3,
  "IsComposite": false,
  "CompositeOfTypeIDs": [],
  "TotalDurationMinutes": 45,
  "Stages": [
    {
      "StageID": "s1",
      "Name": "Check-in",
      "OrderIndex": 0,
      "DurationMinutes": 3,
      "StageType": "CheckIn",
      "RequiredResources": [
        { "ResourceType": "Person", "RoleOrCapability": "FrontDesk", "QuantityMin": 1, "QuantityMax": 1, "RequiredForStages": ["s1"], "IsOptional": false }
      ],
      "QuestionRefs": []
    },
    {
      "StageID": "s3",
      "Name": "Rooming + vitals",
      "OrderIndex": 2,
      "DurationMinutes": 7,
      "StageType": "Rooming",
      "RequiredResources": [
        { "ResourceType": "Person", "RoleOrCapability": "MA", "QuantityMin": 1, "QuantityMax": 1, "RequiredForStages": ["s3"], "IsOptional": false },
        { "ResourceType": "Room", "RoleOrCapability": "ExamRoom", "QuantityMin": 1, "QuantityMax": 1, "RequiredForStages": ["s3", "s4"], "IsOptional": false }
      ],
      "QuestionRefs": [
        { "QuestionID": "q-reason-for-visit", "OrderIndex": 0, "IsRequired": true, "ComplaintTrigger": [], "ShowIfCondition": null, "StageID": "s3" }
      ]
    },
    {
      "StageID": "s4",
      "Name": "Provider eval",
      "OrderIndex": 3,
      "DurationMinutes": 22,
      "StageType": "Provider",
      "RequiredResources": [
        { "ResourceType": "Person", "RoleOrCapability": "MD", "QuantityMin": 1, "QuantityMax": 1, "RequiredForStages": ["s4"], "IsOptional": false }
      ],
      "QuestionRefs": []
    }
  ],
  "RequiredResources": [
    { "ResourceType": "Person", "RoleOrCapability": "FrontDesk", "QuantityMin": 1, "QuantityMax": 2, "RequiredForStages": ["s1", "s6"], "IsOptional": false },
    { "ResourceType": "Person", "RoleOrCapability": "MA", "QuantityMin": 1, "QuantityMax": 1, "RequiredForStages": ["s3"], "IsOptional": false },
    { "ResourceType": "Person", "RoleOrCapability": "MD", "QuantityMin": 1, "QuantityMax": 1, "RequiredForStages": ["s4"], "IsOptional": false },
    { "ResourceType": "Person", "RoleOrCapability": "RN", "QuantityMin": 1, "QuantityMax": 1, "RequiredForStages": ["s5"], "IsOptional": false },
    { "ResourceType": "Room", "RoleOrCapability": "ExamRoom", "QuantityMin": 1, "QuantityMax": 1, "RequiredForStages": ["s3", "s4"], "IsOptional": false }
  ],
  "PreVisitQuestionnaire": [
    { "QuestionID": "q-med-changes", "OrderIndex": 0, "IsRequired": true, "ComplaintTrigger": [], "ShowIfCondition": null, "StageID": null },
    { "QuestionID": "q-allergy-updates", "OrderIndex": 1, "IsRequired": true, "ComplaintTrigger": [], "ShowIfCondition": null, "StageID": null },
    { "QuestionID": "q-smoking", "OrderIndex": 2, "IsRequired": true, "ComplaintTrigger": [], "ShowIfCondition": null, "StageID": null },
    { "QuestionID": "q-exercise", "OrderIndex": 3, "IsRequired": false, "ComplaintTrigger": [], "ShowIfCondition": null, "StageID": null },
    { "QuestionID": "q-alcohol", "OrderIndex": 4, "IsRequired": true, "ComplaintTrigger": [], "ShowIfCondition": null, "StageID": null },
    { "QuestionID": "q-chest-pain", "OrderIndex": 5, "IsRequired": true, "ComplaintTrigger": ["chest pain", "chest tightness", "shortness of breath"], "ShowIfCondition": null, "StageID": null },
    { "QuestionID": "q-latex-allergy", "OrderIndex": 6, "IsRequired": false, "ComplaintTrigger": [], "ShowIfCondition": null, "StageID": null }
  ],
  "TreatmentPlanTemplate": {
    "TemplateID": "tpt-annual-std",
    "EncounterTypeID": "A1b2C3d4E5f6G7h8I9j0K1",
    "Name": "Annual Physical — Standard Orders",
    "Rules": [
      {
        "RuleID": "r1",
        "ConditionExpression": { "questionId": "q-diabetic", "operator": "equals", "value": "yes" },
        "ActionType": "LabOrder",
        "ActionPayload": { "loincCodes": ["4548-4", "17861-6", "2093-3"], "fastingRequired": true, "description": "HbA1c + Lipid Panel + CMP" },
        "IsDefault": true,
        "Priority": "Required",
        "Category": "Labs"
      },
      {
        "RuleID": "r2",
        "ConditionExpression": { "questionId": "q-smoking", "operator": "equals", "value": "current" },
        "ActionType": "Referral",
        "ActionPayload": { "specialty": "Smoking Cessation", "urgency": "routine" },
        "IsDefault": false,
        "Priority": "Recommended",
        "Category": "Referrals"
      }
    ],
    "DefaultFollowUpWeeks": 52,
    "PatientEducationTopics": ["Preventive health", "Exercise", "Nutrition"],
    "Version": 2
  },
  "CodingHints": {
    "DefaultEMLevel": "99214",
    "EMLevelRules": [
      {
        "ConditionExpression": { "field": "ChronicConditionCount", "operator": "gte", "value": 3 },
        "SuggestedLevel": "99215",
        "MDMRationale": "3+ chronic conditions reviewed; moderate-complexity data analysis; moderate risk"
      }
    ],
    "SuggestedCPTCodes": ["99396"],
    "ICD10Ranges": [
      { "Range": "Z00.00–Z00.13", "Description": "General adult examination" }
    ],
    "ModifierHints": ["-25"]
  },
  "ComplaintKeywords": ["annual", "checkup", "physical", "yearly", "wellness exam", "preventive"],
  "PatientFacingCopy": "Annual checkup with your doctor",
  "CreatedDateTimeUTC": "2026-01-15T10:00:00Z",
  "ModifiedDateTimeUTC": "2026-05-20T14:30:00Z",
  "ModifiedByUserID": "U1b2C3d4E5f6G7h8"
}
Question (complete JSON shape)
{
  "QuestionID": "q-smoking",
  "Text": "What is your smoking status?",
  "ShortLabel": "Smoking status?",
  "QuestionType": "SingleSelect",
  "Choices": [
    { "Value": "current", "Label": "Current smoker", "OrderIndex": 0, "IsDefault": false },
    { "Value": "former", "Label": "Former smoker (quit > 12 months ago)", "OrderIndex": 1, "IsDefault": false },
    { "Value": "never", "Label": "Never smoked", "OrderIndex": 2, "IsDefault": true }
  ],
  "Units": null,
  "ScaleMin": null,
  "ScaleMax": null,
  "ClinicalMapping": {
    "system": "http://loinc.org",
    "code": "72166-2",
    "display": "Tobacco smoking status"
  },
  "Source": "SystemWide",
  "SourceOrganizationID": null,
  "DeprecatedDateTimeUTC": null,
  "CreatedDateTimeUTC": "2026-01-15T10:00:00Z",
  "ModifiedDateTimeUTC": "2026-01-15T10:00:00Z"
}
TreatmentPlanTemplate (complete JSON shape)
{
  "TemplateID": "tpt-acute-resp",
  "EncounterTypeID": "B2c3D4e5F6g7H8i9J0k1",
  "Name": "Acute Visit — Respiratory Protocol",
  "Rules": [
    {
      "RuleID": "ar1",
      "ConditionExpression": { "questionId": "q-cough-duration", "operator": "gte", "value": "14" },
      "ActionType": "ImagingOrder",
      "ActionPayload": { "modality": "CXR", "views": ["PA", "Lateral"], "urgency": "routine", "reason": "Cough ≥ 2 weeks" },
      "IsDefault": true,
      "Priority": "Recommended",
      "Category": "Imaging"
    },
    {
      "RuleID": "ar2",
      "ConditionExpression": { "questionId": "q-smoking", "operator": "in", "value": ["current", "former"] },
      "ActionType": "LabOrder",
      "ActionPayload": { "loincCodes": ["19841-2"], "fastingRequired": false, "description": "Spirometry" },
      "IsDefault": false,
      "Priority": "Recommended",
      "Category": "Labs"
    },
    {
      "RuleID": "ar3",
      "ConditionExpression": { "questionId": "q-wheezing", "operator": "equals", "value": "yes" },
      "ActionType": "Prescription",
      "ActionPayload": { "rxNormCode": "236185", "description": "Albuterol inhaler", "sig": "2 puffs Q4-6H PRN shortness of breath" },
      "IsDefault": true,
      "Priority": "Recommended",
      "Category": "Prescriptions"
    },
    {
      "RuleID": "ar4",
      "ConditionExpression": { "operator": "always" },
      "ActionType": "FollowUpVisit",
      "ActionPayload": { "encounterTypeID": "B2c3D4e5F6g7H8i9J0k1", "intervalWeeks": 4, "reason": "Follow-up for respiratory symptoms" },
      "IsDefault": true,
      "Priority": "Required",
      "Category": "Follow-up"
    }
  ],
  "DefaultFollowUpWeeks": 4,
  "PatientEducationTopics": ["Cough and cold", "When to seek emergency care"],
  "Version": 1
}
EncounterSession (complete JSON shape — runtime state)
{
  "EncounterSessionID": "ES1b2C3d4E5f6G7h8",
  "EncounterID": "E1b2C3d4E5f6G7h8I9j0K1",
  "PatientID": "P1b2C3d4E5f6G7h8",
  "EncounterTypeIDs": [
    "A1b2C3d4E5f6G7h8I9j0K1",
    "B2c3D4e5F6g7H8i9J0k1"
  ],
  "IsComposite": true,
  "MergedQuestionnaire": {
    "Source": "dedup-merge",
    "SharedQuestionIDs": ["q-med-changes", "q-allergy-updates", "q-smoking", "q-latex-allergy"],
    "TypeSpecificQuestions": {
      "A1b2C3d4E5f6G7h8I9j0K1": ["q-exercise", "q-alcohol", "q-mammogram-date"],
      "B2c3D4e5F6g7H8i9J0k1": ["q-cough-duration", "q-fever", "q-wheezing", "q-sick-exposure"]
    },
    "OrderedQuestionIDs": [
      "q-med-changes", "q-allergy-updates", "q-smoking", "q-latex-allergy",
      "q-exercise", "q-alcohol", "q-mammogram-date",
      "q-cough-duration", "q-fever", "q-wheezing", "q-sick-exposure"
    ]
  },
  "QuestionResponses": [
    { "QuestionID": "q-med-changes", "ResponseValue": "no", "RespondedDateTimeUTC": "2026-05-28T09:15:00Z", "Source": "PreVisit" },
    { "QuestionID": "q-allergy-updates", "ResponseValue": "no", "RespondedDateTimeUTC": "2026-05-28T09:15:05Z", "Source": "PreVisit" },
    { "QuestionID": "q-smoking", "ResponseValue": "former", "RespondedDateTimeUTC": "2026-05-28T09:15:10Z", "Source": "PreVisit" },
    { "QuestionID": "q-cough-duration", "ResponseValue": "14", "RespondedDateTimeUTC": "2026-05-28T09:15:20Z", "Source": "PreVisit" },
    { "QuestionID": "q-fever", "ResponseValue": null, "RespondedDateTimeUTC": null, "Source": null },
    { "QuestionID": "q-wheezing", "ResponseValue": "yes", "RespondedDateTimeUTC": "2026-05-28T09:15:30Z", "Source": "PreVisit" }
  ],
  "PreVisitAnswersPopulated": 9,
  "PreVisitAnswersPending": 2,
  "TreatmentPlanDraft": {
    "TreatmentPlanID": "TP1b2C3d4E5f6G7h8",
    "Status": "Draft",
    "Items": [
      { "ItemID": "i1", "ItemType": "LabOrder", "Priority": "Required", "IsAutoGenerated": true, "Status": "Pending", "Payload": { "loincCodes": ["4548-4", "17861-6"], "fastingRequired": true, "description": "HbA1c + Lipid Panel" }, "Category": "Labs", "SortOrder": 0 },
      { "ItemID": "i2", "ItemType": "ImagingOrder", "Priority": "Recommended", "IsAutoGenerated": true, "Status": "Pending", "Payload": { "modality": "CXR", "views": ["PA", "Lateral"], "reason": "Cough ≥ 2 weeks" }, "Category": "Imaging", "SortOrder": 1 },
      { "ItemID": "i3", "ItemType": "Prescription", "Priority": "Recommended", "IsAutoGenerated": true, "Status": "Pending", "Payload": { "rxNormCode": "236185", "description": "Albuterol inhaler", "sig": "2 puffs Q4-6H PRN" }, "Category": "Prescriptions", "SortOrder": 2 },
      { "ItemID": "i4", "ItemType": "FollowUpVisit", "Priority": "Required", "IsAutoGenerated": true, "Status": "Pending", "Payload": { "intervalWeeks": 4, "reason": "Follow-up for respiratory symptoms" }, "Category": "Follow-up", "SortOrder": 3 }
    ]
  },
  "CodingSuggestions": {
    "EMLevel": "99214",
    "CPTCodes": ["99396", "99213-25"],
    "ICD10Codes": ["Z00.00", "J06.9", "E11.65"],
    "Modifiers": ["-25"],
    "MDMRationale": "2 chronic conditions managed (T2D, HTN) + acute respiratory complaint; moderate data review; moderate risk"
  },
  "CreatedDateTimeUTC": "2026-05-28T09:00:00Z",
  "Status": "InProgress"
}

Use Cases

Six concrete walkthroughs showing the end-to-end flow from patient complaint through treatment plan, with key design decisions noted for each.

UC-1Annual Physical — Established Adult

Patient books "annual checkup"
Patient enters "annual checkup" in complaint field. Suggestion engine matches against ComplaintKeywords: "annual", "checkup" → Annual Physical encounter type (score 0.95). Single match; patient sees: "We recommend a 45-min Annual Physical with your doctor." Patient accepts.
Pre-visit questionnaire fires
7 questions: medication changes (YesNo), allergy updates (YesNo), smoking status (SingleSelect), exercise frequency (Numeric, times/week), alcohol use (SingleSelect), chest pain (YesNo — shown if respiratory keywords in complaint), latex allergy (YesNo). Patient answers all 7 in ~2 min. Answers stored as QuestionResponse entities with Source = PreVisit.
Doctor opens encounter
Pre-visit answers pre-populated. Vitals (MA-entered): BP 138/88, HR 76, SpO2 97%. All 7 questions show ✅. Doctor reviews summary, clicks [Approve All]. Notices BP is borderline — adds free-text note: "BP trending up, consider lisinopril dose adjustment."
Treatment plan auto-generated
Template rules evaluated against answers + problem list (T2D, HTN):
  • Required: CBC, CMP, Lipid Panel (always for annual)
  • Required (diabetic rule): HbA1c — auto-checked ✅
  • Recommended (smoking = former): CXR — unchecked ☐
  • Recommended (age > 50, no mammogram in 12 mo): Mammogram referral — unchecked ☐
Doctor checks mammogram referral, unchecks CXR, clicks [Sign & Send].
Coding auto-suggested
E/M 99214 (2 chronic conditions, moderate data, moderate risk). CPT 99396 (periodic preventive, 40–64). ICD-10 Z00.00 + E11.65 + I10. Doctor clicks [Accept Codes].
Key design decision: Annual physical defaults to 99214, not 99213, because the problem-list cross-reference (T2D + HTN) already pushes MDM to moderate complexity. The doctor can still downcode via the coding surface, but the default captures the work actually done — fewer undercodes, fewer audits.

UC-2Acute Sick Visit

Patient enters "cough for 2 weeks, chest tightness"
Suggestion engine: "cough" + "chest tightness" → Acute Visit (score 0.87). Patient sees: "We recommend a 20-min Acute Visit for your cough and chest symptoms." Patient accepts.
Pre-visit questionnaire fires
Acute Respiratory template: cough duration (Numeric, days), fever present (YesNo), productive cough (YesNo), smoking status (SingleSelect), sick exposures (YesNo), wheezing (YesNo), night sweats (YesNo), shortness of breath at rest (YesNo), latex allergy (YesNo — shared question). 9 questions, ~2 min.
Doctor gets focused respiratory review
Pre-populated answers: duration = 14 days, productive = yes, wheezing = yes, smoking = former, fever = no, sick exposure = no. Vitals: SpO2 96%. Doctor adds: "Lung sounds: scattered wheezes bilaterally, no consolidation." Clicks [Approve All] on pre-visit answers.
Auto-suggests: CXR, spirometry, inhaler Rx
Template rules:
  • Recommended: CXR (cough ≥ 14 days) — auto-checked ✅
  • Recommended: Spirometry (former smoker + wheezing) — unchecked ☐
  • Recommended: Albuterol inhaler (wheezing = yes) — auto-checked ✅
  • Required: Follow-up in 4 weeks
Doctor checks spirometry, keeps CXR and inhaler, signs plan.
Coding
E/M 99213 (acute, low MDM). CPT 99213. ICD-10 J06.9 (acute URI) + R05.9 (cough). Modifier -25 not needed (single E/M, no procedure). Doctor accepts.
Key design decision: Acute visit defaults to 99213. The system will suggest 99214 if the cough duration triggers a moderate-complexity workup (e.g. CXR + spirometry = data review that pushes MDM up). The rule is: "If ≥ 2 recommended orders are auto-checked → upgrade to 99214."

UC-3New Patient Comprehensive

No prior data — extended intake
Patient has no chart in the system. During self-scheduling, the patient is identified as new (no PatientID match). The system auto-suggests "New Patient Comprehensive" (60 min) — no keyword matching needed; the scheduling logic already detects new-patient status.
Extended pre-visit questionnaire
25 questions covering: past medical history, surgical history, family history, social history (smoking, alcohol, drugs, occupation), medication list, allergy list, immunization history, review of systems (14-system ROS). Patient fills out in ~8 min on the portal, or completes in the waiting room on a tablet during the Check-in + Paperwork stage.
Records import
If the patient authorizes, the system requests records from the prior practice via FHIR Bulk Data or fax. Imported data is staged for doctor review in a "Pending Import" section of the encounter surface. Doctor reviews, accepts or rejects each imported fact (medication, problem, allergy).
Doctor reviews imported + patient-entered data
One-screen summary with two sections: (1) Patient-entered answers (25 items, all ✅), (2) Imported records (12 items — 8 auto-matched, 4 needing review). Doctor resolves the 4 pending imports, then [Approve All].
Care plan from scratch
Since no problem list exists yet, the template has fewer conditional rules. Baseline labs are auto-suggested (CBC, CMP, Lipid Panel, TSH). Doctor adds condition-specific orders as needed. Follow-up set to 4 weeks (shorter than established, to establish care).
Key design decision: New-patient questionnaire is the longest in the system (25 questions). To prevent abandonment, the portal saves progress every 5 questions and allows resuming later. Unanswered questions at appointment time are handled during the MA intake stage (12-min rooming for new patients).

UC-4Combined Visit — Annual Physical + Acute

Patient wants annual but also has a new concern
Patient enters: "annual checkup" + "cough for 2 weeks, chest tightness." Suggestion engine detects two keyword clusters: "annual checkup" → Annual Physical (score 0.92), "cough, chest tightness" → Acute Visit (score 0.87). Composite detection fires: both score above 0.5.
Deduplication engine: health-history questions asked once
Annual Physical has Q1–Q7. Acute Visit has Q5–Q12 (plus shared Q8: latex allergy, Q5: smoking status from Annual). Dedup engine:
  • Shared: q-smoking, q-latex-allergy → asked once, in the Annual section
  • Annual-specific: q-med-changes, q-allergy-updates, q-exercise, q-alcohol
  • Acute-specific: q-cough-duration, q-fever, q-wheezing, q-sick-exposure, q-productive-cough, q-night-sweats, q-sob-at-rest
Total: 11 unique questions (not 16). Estimated time: 3 min.
Extended 65-min slot
Annual Physical (45 min) + Acute Visit (20 min) = 65 min total. The scheduling solver finds a 65-min contiguous block with the required resources. The stage sequence merges: Annual stages run first, with the Acute provider eval time added to the Annual provider eval stage (22 + 8 = 30 min provider time).
Doctor gets merged view
Encounter surface shows two sections in the pre-visit summary: (1) "Annual Physical" answers (4 shared + 3 annual-specific), (2) "Acute Visit — Respiratory" answers (2 shared [already shown] + 7 acute-specific). Shared questions show once with a badge: "Shared between Annual + Acute." Doctor reviews both, clicks [Approve All] once.
Treatment plan merges both templates
Annual template → baseline labs, A1c if diabetic. Acute template → CXR if cough ≥ 14 days, inhaler if wheezing. Both sets of items appear in the plan, grouped by category. Doctor signs off in one pass.
Coding
E/M 99214 with modifier -25 (significant separately identifiable E/M on same day as preventive). CPT 99396 + 99213-25. ICD-10 Z00.00 + J06.9. The -25 modifier is auto-suggested by the coding hints because the encounter is a composite with an acute component.
Key design decision: Composite visits extend the provider stage rather than running two full stage sequences. The MA rooming, check-in, and checkout stages are shared — only the provider eval time is additive. This minimizes total slot time (65 min vs. 85 min if two separate visits) and maximizes room utilization.

UC-5Chronic Care Follow-Up — Diabetes

System detects T2D on problem list
Patient books "diabetes follow-up" or "check my sugar." Suggestion engine matches keyword AND cross-references the problem list: ICD-10 E11.x is active. Auto-adds "Diabetes Follow-Up" encounter type (20 min). If the patient booked a generic "follow-up," the system upgrades the suggestion: "Based on your medical history (Type 2 Diabetes), we recommend a 20-min Diabetes Management Visit."
Auto-adds diabetes-specific questions
Beyond standard follow-up questions, the diabetes template adds:
  • When was your last A1c test? (Date)
  • Have you been checking glucose at home? (YesNo → if yes: how often? Numeric, times/week; last fasting value? Numeric, mg/dL)
  • Any numbness or tingling in feet? (YesNo)
  • Last eye exam? (Date)
  • Any symptoms of low blood sugar? (YesNo)
8 questions total. Conditional: glucose-log questions only appear if "checking at home" = yes.
Doctor gets focused diabetes review + general vitals
Pre-visit answers: last A1c = 3 months ago, checking glucose = yes (3×/week, fasting ~140), foot numbness = yes (bilateral toes), last eye exam = 14 months ago. Vitals: BP 132/82, A1c result (if recent lab): 7.8%. Doctor sees focused summary with diabetes-relevant data highlighted.
Auto-suggests: A1c lab, eye referral, podiatry
Template rules:
  • Required: A1c lab (always for diabetes follow-up) ✅
  • Required: Urine microalbumin (annual screening) ✅
  • Recommended: Eye referral (if > 12 months since last exam) ✅
  • Recommended: Podiatry referral (if foot numbness = yes) ✅
  • Optional: Nutrition referral ☐
  • Required: Follow-up in 3 months (diabetes protocol)
Doctor checks nutrition referral (patient mentioned difficulty with diet), signs plan.
Key design decision: Chronic care follow-ups use the problem list as a first-class input to the suggestion engine — not just keyword matching. A patient who types "follow-up" and has T2D + HTN on their problem list gets a different suggestion than a patient who types "follow-up" and has only hypothyroidism. The problem list acts as an implicit "second complaint" that the patient didn't have to type.

UC-6Pediatric Well-Child + Immunizations

Parent books well-child
Parent enters "well-child visit" or selects from age-appropriate options. Suggestion engine matches "well-child" → Well-Child encounter type (30 min). System detects patient age (18 months) and selects age-appropriate template variant automatically.
Age-appropriate developmental screening questions
The Well-Child template has conditional question branches by age:
  • 0–12 months: feeding method, sleep position, developmental milestones (rolling, sitting, babbling)
  • 12–24 months: walking status, words spoken, feeding transition, MCHAT-R/F screen
  • 2–5 years: toilet training, speech clarity, social interaction, preschool readiness
  • 5–12 years: school performance, behavior concerns, screen time, physical activity
For this 18-month-old: walking = yes, words = 8, feeding = table foods + milk. MCHAT-R/F = 0 (low risk). 6 questions, ~2 min.
Immunization schedule check
System queries the patient's immunization record against CDC ACIP schedule. At 18 months: DTaP (dose 4) due, Hib (dose 4 if not given at 12m), Hep A (dose 2). System auto-generates immunization orders for all due vaccines.
Doctor gets checklist with defaults
Doctor sees: developmental milestones ✅ (parent-entered), growth chart (MA-entered: weight, length, head circumference plotted on WHO curves), immunization checklist with all due vaccines pre-checked. Doctor reviews, unchecks Hib (already given at 12m per record), clicks [Approve All].
Auto-generates: immunization orders, developmental screening results
Immunization orders sent to MA/Nurse stage for administration. Developmental screening results (MCHAT-R/F score) auto-recorded in the encounter note. Follow-up: next well-child at 24 months.
Key design decision: Pediatric well-child templates are age-branching — a single EncounterType entity with conditional question branches keyed on Patient.DateOfBirth. The ShowIfCondition expression supports age-range predicates: { "field": "PatientAgeMonths", "operator": "between", "value": [12, 24] }. This avoids creating 12 separate encounter types for each well-child interval.

End-to-End Flow — Unified View

graph TB
  subgraph "Patient Portal"
    A1[Patient enters complaints] --> A2[Suggestion Engine]
    A2 --> A3[Accept / Override]
    A3 --> A4[Pre-Visit Questionnaire]
    A4 --> A5[Slot Booked]
  end

  subgraph "Scheduling"
    A5 --> B1[Resource Graph Solver]
    B1 --> B2[Appointment Created]
  end

  subgraph "Day of Visit"
    B2 --> C1[MA Rooming + Vitals]
    C1 --> C2[Doctor Opens Encounter]
  end

  subgraph "Doctor Workflow"
    C2 --> D1[Pre-populated Summary]
    D1 --> D2[Approve All / Answer Remaining]
    D2 --> D3[Treatment Plan Review]
    D3 --> D4[Sign & Close]
    D4 --> D5[Coding Auto-Suggest]
    D5 --> D6[Codes Accepted]
  end

  subgraph "Post-Encounter"
    D6 --> E1[AVS → Patient Portal]
    D6 --> E2[Orders Transmitted]
    D6 --> E3[Follow-up Tasks Created]
    E3 --> E4[Learning Loop: Extract Questions]
    E4 --> E5[Practice Manager Review]
    E5 --> E6[Question Bank Updated]
    E6 -.->|Next visit| A4
  end

  style A1 fill:#4A90D9,color:#fff
  style A2 fill:#4A90D9,color:#fff
  style D1 fill:#2ECC71,color:#fff
  style D3 fill:#2ECC71,color:#fff
  style E4 fill:#E67E22,color:#fff
  style E5 fill:#E67E22,color:#fff
  style E6 fill:#E67E22,color:#fff
    

Design Decisions & Trade-offs

DD-1: Encounter types vs. flat visit types

Decision: Promote encounter types to first-class entities

The current scheduling module uses flat VisitType + VisitStage with no questionnaire, no treatment plan template, and no learning loop. Encounter types subsume visit types: every EncounterType has stages (inheriting the scheduling model), but adds questionnaire, treatment plan, coding hints, and complaint keywords. The existing VisitType data migrates to EncounterType with empty questionnaire/template fields. Migration is additive — existing scheduling continues to work; encounter-type features light up as templates are configured.

DD-2: Shared question bank vs. per-type questions

Decision: Global question bank with per-type references

Questions are defined once and referenced by multiple encounter types. This enables deduplication in composite visits (same question asked once, not twice) and cross-type analytics ("Which encounter types include the smoking status question?"). The trade-off: question edits affect all referencing types. Mitigated by versioning: editing a question creates a new version; referencing types can be updated incrementally.

DD-3: Keyword matching vs. ML for suggestion engine

Decision: Start with keyword matching, upgrade to ML in Phase 2

Keyword matching is deterministic, auditable, and requires zero training data. It's sufficient for the initial launch where encounter types are few and keywords are well-defined. ML becomes valuable as encounter types multiply and complaint language varies. The override tracking mechanism collects the labeled data needed for ML training. Target: keyword matching for Phase 1, ML model for Phase 2.

DD-4: Composite visits vs. sequential visits

Decision: First-class composite encounter types

When a patient has both an annual and an acute concern, the system creates a composite encounter type instance (not two separate appointments). The composite has a single 65-min slot, a merged questionnaire (deduplicated), and a merged treatment plan. This is better than two sequential visits because: (1) the patient makes one trip, (2) the room is held for one contiguous block, (3) the doctor signs one note, (4) coding applies modifier -25 automatically. The trade-off: composites are harder to cancel/reschedule (can't cancel just the acute part). Mitigated by allowing the doctor to "split" the composite into two visits during the encounter if needed.

DD-5: Practice-specific vs. system-wide questions

Decision: Two-tier question scope with promotion gate

New questions from the learning loop start as PracticeSpecific. Promotion to SystemWide requires: ≥ 10 encounters, ≥ 3 providers, ≥ 80% accept rate, and explicit admin action. This prevents low-quality questions from polluting the global bank while allowing practices to customize freely. The trade-off: practices may duplicate each other's questions before promotion. Mitigated by a "merge suggestion" feature that surfaces similar practice-specific questions for admin review.

DD-6: Treatment plan auto-generation — how aggressive?

Decision: Auto-check "Required" items, leave "Recommended" unchecked

Treatment plan rules have two tiers: Required (auto-checked — doctor must explicitly uncheck to remove) and Recommended (unchecked — doctor must explicitly check to add). A third tier, Optional, is hidden behind a "More options" toggle. This balances speed (required items are one-click sign-off) with safety (recommended items require deliberate opt-in). The doctor never has to uncheck something they didn't expect.

Open Questions

#QuestionImpactOptions
OQ-1 Should composite encounters produce one note or two? Affects clinical-doc.html, coding, and AVS generation (A) Single merged SOAP note with sections for each type. (B) Two linked notes in one encounter. (C) Doctor's choice at encounter open.
OQ-2 How to handle encounter-type versioning during an in-progress visit? If admin edits the template mid-visit, does the doctor see the old or new version? (A) Snapshot at booking time (doctor sees what was booked). (B) Live (doctor always sees latest). (C) Snapshot at encounter-open time.
OQ-3 Should the question bank support branching logic beyond ShowIf? Affects questionnaire complexity and patient abandonment rate (A) ShowIf only (simple conditional). (B) Full branching with skip patterns (like BRFSS). (C) ShowIf + page breaks for long questionnaires.
OQ-4 Minimum encounter-type data for a practice to go live? Onboarding time and effort (A) Must configure full template before enabling. (B) Staged: stages first, then questionnaire, then treatment plan. (C) Copy system-wide defaults and let them customize over time.
OQ-5 Should the suggestion engine consider insurance/payer rules? Some payers require separate visits for preventive + acute; some allow modifier -25 (A) Ignore payer rules (patient's choice). (B) Show a warning if payer likely denies composite. (C) Auto-split into two visits if payer rule requires it.

Demo Pages to Build / Update

The following pages would need to be created or updated to implement the encounter type system. These are not built yet — they are listed here for sprint planning.

New Pages to Create

PageDescriptionPriority
encounter-type-editor.htmlAdmin interface for CRUD on encounter types, question bank, treatment plan templates. Drag-and-drop stage reordering, composite builder, preview mode.P1 — Core admin surface
encounter-type-preview.htmlSplit-pane preview: patient questionnaire view on left, doctor summary view on right. Driven by encounter-type ID in query params.P1 — Embedded in editor
question-bank.htmlStandalone question bank management: add, edit, deprecate, merge duplicates. Filters by source (system-wide vs. practice-specific), question type, clinical mapping.P1 — Referenced by editor
learning-loop-review.htmlPractice manager's queue of candidate questions extracted from scribe + manually added. Accept/edit/reject/promote workflow.P2 — Learning loop surface
my-plan.htmlPatient portal treatment plan view: active plan items, status, education links. Referenced from patient-portal.html but not yet built.P2 — Patient-facing plan

Existing Pages to Update

PageUpdatePriority
scheduling.htmlReplace VisitType selector with EncounterType selector. Add encounter-type-driven stage timeline. Update domain entities to reference EncounterTypeID.P1 — Schema migration
clinical-doc.htmlAdd encounter-type-driven interview surface: pre-populated summary, [Approve All] button, one-click actions, treatment plan review. Link to treatment plan template.P1 — Doctor workflow
patient-portal.htmlUpdate self-scheduling steps 5–6: complaint entry → suggestion engine → encounter type recommendation. Add pre-visit questionnaire step. Add my-plan link.P1 — Patient workflow
coding-cds.htmlUpdate coding hint section: reference EncounterType.CodingHints. Add composite visit modifier -25 auto-suggestion. Cross-reference learning loop.P2 — Coding integration
task-mgmt.htmlAdd task type: CandidateQuestionReview. Add task template for "Review N new questions from [type] encounters this week."P2 — Learning loop tasks

Cross-Module Reference Map

graph LR
  ETS[Encounter Type System] --> SCHED[Scheduling]
  ETS --> CD[Clinical Doc]
  ETS --> PP[Patient Portal]
  ETS --> CDS[Coding / CDS]
  ETS --> TM[Task Mgmt]
  ETS --> LABS[Labs]
  ETS --> RX[eRx / EPCS]
  ETS --> REF[Referrals]

  ETS -.->|EncounterTypeID| SCHED
  ETS -.->|Pre-visit answers| CD
  ETS -.->|Suggestion engine| PP
  ETS -.->|CodingHints| CDS
  ETS -.->|CandidateQuestion| TM
  ETS -.->|Lab orders| LABS
  ETS -.->|Prescriptions| RX
  ETS -.->|Referral orders| REF

  style ETS fill:#7B68EE,color:#fff,stroke:#333,stroke-width:3px
  style SCHED fill:#4A90D9,color:#fff
  style CD fill:#2ECC71,color:#fff
  style PP fill:#4A90D9,color:#fff
  style CDS fill:#2ECC71,color:#fff
  style TM fill:#E67E22,color:#fff
  style LABS fill:#9B59B6,color:#fff
  style RX fill:#9B59B6,color:#fff
  style REF fill:#9B59B6,color:#fff