Kulcare Docs
Test plansClinic app

queue booking

# Test Plan: Queue & Appointment Booking

Module: Clinic App — Queue Management & Appointment Booking Code Audit Date: 2026-06-17 Status: Pending


Code Audit Summary

Pages & Components

PageURLComponentPurpose
Queue Page/cms/queueQueuePage.tsxToday's patient queue with filters, status changes, actions
Appointments Page/cms/appointmentsAppointmentsPage.tsxCalendar (Month/Week/Day) + listing sidebar
Add Booking Modal—AddAppointmentModal/index.tsx2-step modal (Doctor+Time → Patient Info)

APIs

APIMethodPurpose
/clinical/facilities/:id/queueGETFetch queue (server-side: date, search, pagination)
/clinical/appointmentsPOSTCreate appointment (via AddAppointmentModal)
/clinical/appointments/:idPATCHUpdate status (via QueueRow status dropdown)
/clinical/appointmentsGETList appointments (for Calendar view)

Key Hooks

HookPurpose
useQueueFiltersDate, practitioner, search, status filter state
useQueueDataFetch queue + client-side filter (practitioner, status)
useQueueActionsStatus change with terminal confirmation dialog
useQueuePaginationPage/size state management

Queue Row Actions (per patient)

ActionConditionComponent/Modal
Start EncounterNot past date, not encounter-driven status, not terminalNavigate to encounter
BillingcanManageBilling permissionBillingPanel slide-in
Next VisitAlways availableNextVisitModal
Notes (Add/Edit)Always availableNotesModal
Admit to IPDAlways availableAdmissionForm modal
Preview/PrintAlways availablePatientPreviewModal
Cancel/RemoveAlways availableStatus change to 'cancelled'

FLOW A: Queue Page

Component: QueuePage.tsx, QueueHeader.tsx, QueueTable.tsx, QueueRow.tsx URL: /cms/queue API: GET /clinical/facilities/{id}/queue?date=&page=&per_page=&search=

A.1 Page Load

#Test CasePriorityExpectedStatus
Q-01Load queue pageP0Page loads with today's date, queue table visible✅ PASS
Q-02Queue with patientsP0Active queue rows displayed with position #, name, phone, doctor, time, status✅ PASS
Q-03Queue empty — todayP0"No patients in queue today" message + "Add Patient" button✅ PASS
Q-04Queue empty — past dateP1"No patients for this date" message, no Add Patient button✅ PASS
Q-05Loading stateP0LoadingSpinner overlay with "Loading queue for [date]..." text✅ PASS
Q-06Error stateP1EmptyState with AlertTriangle: "Failed to load queue"✅ PASS
Q-07Overnight stale date fixP2Tab left open overnight → date auto-corrects to today on visibility change⏭️ Not Tested

A.2 Queue Header — Date Navigation

#Test CasePriorityExpectedStatus
Q-10Today buttonP0Click Today → resets date to today, refetches queue✅ PASS
Q-11Previous dayP0Click ← → moves date back 1 day, refetches✅ PASS
Q-12Next dayP0Click → → moves date forward 1 day, refetches⚠️ Disabled when no future queue data
Q-13Date pickerP0Click calendar icon → date picker opens, select date → refetches✅ PASS
Q-14Past date — status disabledP1On past date, status dropdowns are read-only badges✅ PASS
Q-15Past date — Start Encounter hiddenP1On past date, Start Encounter button not shown✅ PASS
#Test CasePriorityExpectedStatus
Q-20Search by nameP0Type patient name → debounced 500ms → API call with search= param → filtered results✅ PASS
Q-21Search by phoneP0Type phone digits → matches patients by phone✅ PASS
Q-22Search partial matchP0Type partial name → returns matching patients✅ PASS
Q-23Clear searchP0Clear search field → resets to full queue✅ PASS
Q-24Search — no resultsP0Type non-matching term → "No patients found" + "Clear filters" link✅ PASS
Q-25Debounce behaviorP1Rapid typing → only 1 API call after 500ms pause✅ PASS

A.4 Queue Header — Practitioner Filter

#Test CasePriorityExpectedStatus
Q-30Filter by practitionerP0Select doctor from dropdown → only that doctor's patients shown✅ PASS
Q-31Clear practitioner filterP0Select "All" → shows all practitioners✅ PASS
Q-32Practitioner filter + search combinedP1Filter doctor + type search → both filters applied✅ PASS
Q-33No patients for practitionerP1Select doctor with no queue → empty state with filters message✅ PASS

A.5 Queue Header — Status Filter

#Test CasePriorityExpectedStatus
Q-40Filter — AllP0Default: shows all statuses✅ PASS
Q-41Filter — WaitingP0Select Waiting → only patients with waiting status✅ PASS
Q-42Filter — In ProgressP0Select In Progress → only in-progress patients✅ PASS
Q-43Filter — CompletedP0Select Completed → only completed patients✅ PASS
Q-44Combined filtersP1Practitioner + Status + Search → all three filters applied✅ PASS

A.6 Queue Header — Statistics

#Test CasePriorityExpectedStatus
Q-50Stats — with patientsP0Shows 4 stats: Total, Waiting, In Progress, Completed✅ PASS
Q-51Stats — empty queueP0All stats show 0✅ PASS
Q-52Stats — update on status changeP1Change a patient status → stats counters update✅ PASS
Q-53Stats — update on new bookingP1Add a patient → total count increments✅ PASS

A.7 Queue Table — Active Queue

#Test CasePriorityExpectedStatus
Q-60Queue position numbersP0Patients numbered sequentially starting at 1✅ PASS
Q-61Patient name + note indicatorP0Name displayed, FileText icon shown if notes exist✅ PASS
Q-62Patient age + genderP0"M, 45y" format below name✅ PASS
Q-63Note previewP1If patient has note, first 2 lines shown below name in muted text✅ PASS
Q-64Phone displayP0Phone icon + number displayed✅ PASS
Q-65Practitioner displayP0Doctor name shown, "-" if no practitioner✅ PASS
Q-66Time displayP0Appointment time formatted (e.g., "10:30 AM") with type icon✅ PASS
Q-67Wait time displayP0"Wait: 15 min" shown for active patients (not terminal statuses)✅ PASS
Q-68Wait time — hidden for completed/cancelledP1No wait time shown for completed/cancelled/no-show patients✅ PASS

A.8 Queue Table — Out of Queue Section

How OoQ works: Patients manually marked "Completed" (fulfilled) via status dropdown move to out_of_queue[]. BUT encounter-driven "finished" stays in the main queue (read-only badge), and "cancelled" disappears from both lists entirely. The split is inconsistent — see Bug #48.

#Test CasePriorityExpectedStatus
Q-70Manual completed → moves to OoQP0Select "Completed" from dropdown → patient moves to out_of_queue section with separator + "Completed" badge✅ PASS
Q-71Finished (encounter) → stays in queueP0Finish encounter → status "finished" shown as read-only badge in main queue, NOT moved to OoQ✅ PASS
Q-72Cancelled → disappears from bothP0Cancel appointment → patient removed from queue list entirely, not shown in OoQ✅ PASS

A.9 Queue Table — Empty States

#Test CasePriorityExpectedStatus
Q-80Empty — today, no filtersP0"No patients in queue today" + "Add a patient to get started" + Add Patient button✅ PASS
Q-81Empty — past/future date, no filtersP0"No patients for this date" message, no Add Patient button✅ PASS
Q-82Empty — active filtersP0"No patients found" + "Try adjusting your filters" + "Clear filters" link✅ PASS
Q-83Clear filters linkP1Click "Clear filters" → resets all filters, refetches queue✅ PASS

A.10 Queue Table — Pagination

#Test CasePriorityExpectedStatus
Q-90Pagination — shown when neededP0Pagination controls visible when queue > per_page✅ PASS
Q-91Next/Previous pageP0Navigate between pages✅ PASS
Q-92Page size changeP0Change per_page (10/25/50) → refetch with new size✅ PASS
Q-93Page reset on filter changeP0Change date/filter/search → page resets to 1✅ PASS
Q-94Page reset on practitioner changeP0Change practitioner → page resets to 1✅ PASS

A.11 Queue Row — Status Change

Status Types:

  • status (API field) = FHIR AppointmentStatus: proposed, pending, booked, arrived, fulfilled, cancelled, noshow
  • queue_status (API field) = combined status from backend including encounter state

Valid Transitions (from VALID_STATUS_TRANSITIONS):

proposed  → pending, booked, cancelled
pending   → booked, cancelled, noshow
booked    → arrived, cancelled, noshow
arrived   → fulfilled, noshow, cancelled
fulfilled → terminal (read-only badge)
cancelled → terminal (read-only badge)
noshow    → terminal (read-only badge)

Encounter-driven (ENCOUNTER_DRIVEN_STATUSES): When an active encounter exists, queue_status reflects the encounter (in_progress, finished, etc.) and the status dropdown becomes a read-only badge.

Terminal confirmation: fulfilled, cancelled, noshow require confirmation dialog with optional reason.

Past dates: Status shown as read-only badge, no dropdown.

#Test CasePriorityExpectedStatus
Q-100Status dropdown for booked appointmentP0Shows valid transitions: arrived, cancelled, noshow✅ PASS
Q-101Change to arrived (non-terminal)P0Select "Arrived" → immediate update, toast: "Status updated to Arrived"✅ PASS
Q-102Change to fulfilled (terminal)P0Select "Completed" → confirmation dialog opens with patient name✅ PASS
Q-103Confirm terminal statusP0Click Confirm → status updated, dialog closes✅ PASS
Q-104Cancel terminal status dialogP0Click Cancel → status unchanged✅ PASS
Q-105Cancel with reasonP1Change to "Cancelled", enter reason → reason saved✅ PASS
Q-106Encounter-driven — read-only badgeP0When encounter is active (in_progress) → status shown as read-only badge, no dropdown✅ PASS
Q-107Encounter-driven — finished badgeP0When encounter finished → shows "Finished" badge, read-only✅ PASS
Q-108Terminal status — read-only badgeP0fulfilled/cancelled/noshow → read-only badge, no dropdown✅ PASS
Q-109Past date — read-only badgeP1Past date → read-only badge✅ PASS
Q-110Status change — loading stateP1During mutation → LoadingSpinner in dropdown, "Updating" text✅ PASS
Q-111Status change — error handlingP1API fails → status reverts, error toast✅ PASS
Q-112Only valid transitions shownP0Dropdown only shows transitions valid for current status✅ PASS

A.12 Queue Row — Start Encounter

#Test CasePriorityExpectedStatus
Q-110Start encounter button visibleP0"Stethoscope" button shown for active (non-terminal) patients on today✅ PASS
Q-111Click Start EncounterP0Click → API call → navigate to /cms/encounters/{id}✅ PASS
Q-112Start Encounter hidden — terminal statusP1No button shown for completed/cancelled patients✅ PASS
Q-113Start Encounter hidden — past dateP1No button shown on past dates✅ PASS
Q-114Start Encounter — click rowP0Click patient row → same as Start Encounter (shortcut)✅ PASS
Q-115Start Encounter — errorP1API fails → error toast shown✅ PASS

A.13 Queue Row — Billing

#Test CasePriorityExpectedStatus
Q-120Billing button — with permissionP0"Plus" button shown when canManageBilling is true✅ PASS
Q-121Billing button — without permissionP1Button disabled/greyed out when no billing permission✅ PASS
Q-122Click BillingP0Click → BillingPanel slides in with patient details✅ PASS
Q-123Close Billing panelP0Close panel → returns to queue✅ PASS

A.14 Queue Row — Actions Dropdown

#Test CasePriorityExpectedStatus
Q-130Open dropdownP0Click ⋮ → dropdown with: Next Visit, Notes, Admit to IPD, Preview, Cancel✅ PASS
Q-131Next VisitP0Click → NextVisitModal opens with patient pre-filled✅ PASS
Q-132Add Notes (no existing note)P0Click "Add Notes" → NotesModal opens empty✅ PASS
Q-133Edit Notes (existing note)P1Click "Edit Notes" (label changes) → NotesModal with existing note✅ PASS
Q-134Admit to IPDP1Click → AdmissionForm modal with patient pre-filled✅ PASS
Q-135Preview / PrintP0Click → PatientPreviewModal opens✅ PASS
Q-136Cancel / Remove from QueueP0Click → confirmation dialog + status changes to cancelled✅ PASS

A.15 Add Patient (from Queue)

#Test CasePriorityExpectedStatus
Q-140Open Add Patient modalP0Click "Add Patient" → AddAppointmentModal opens with mode='queue' (WALKIN)✅ PASS
Q-141Complete bookingP0Fill steps → Submit → patient appears in queue, stats update✅ PASS
Q-142Close modal without bookingP0Close modal → no patient added, queue unchanged✅ PASS
Q-143Refetch after bookingP0After successful booking → queue refetches automatically✅ PASS

FLOW B: Add Booking Modal — Queue Mode (WALKIN)

Component: AddAppointmentModal/index.tsx (mode='queue') Steps: 2-step wizard (Doctor & Time → Patient Info) Form: react-hook-form + Zod (addAppointmentFormSchema) API: POST /clinical/appointments

BehaviorDetail
Size550px × 800px, max height calc(100vh-2rem)
Close preventionOutside click blocked, Escape key blocked
Reset on closeForm + steps reset to Step 1
Tenant nameShows current tenant name in header (Building2 icon)
Cancel buttonStep 1: "Cancel" ghost button, Step 2: "Cancel" ghost + "Back" outline

B.1 Modal Open & Reset

#Test CasePriorityExpectedStatus
B-01Open from Queue pageP0Click "Add Patient" → modal opens, appointment_type = WALKIN✅ PASS
B-02Modal titleP0Header shows "Add Appointment" + tenant name✅ PASS
B-03Stepper visibleP02-step stepper: "Doctor & Time" → "Patient Info", starts at Step 1✅ PASS
B-04Close prevention — outside clickP1Click outside modal → does NOT close✅ PASS
B-05Close prevention — Escape keyP1Press Escape → does NOT close✅ PASS
B-06Close via Cancel buttonP0Click "Cancel" on Step 1 → modal closes, form resets✅ PASS
B-07Reopen after close — form resetP0Close modal → reopen → form is blank, Step 1✅ PASS

B.2 Step 1 — Doctor Selection

#Test CasePriorityExpectedStatus
B-10Doctor dropdown — populatedP0Shows active practitioners for current facility (useFacilityPractitioners with active_only:true)✅ PASS
B-11Doctor dropdown — loadingP1LoadingSpinner + "Loading doctors..." while fetching✅ PASS
B-12Doctor dropdown — errorP1AlertCircle + "Failed to load doctors" if API fails✅ PASS
B-13Doctor dropdown — emptyP1"No doctors available" if no active practitioners✅ PASS
B-14Select doctor from dropdownP0Click doctor → selected, displayed in trigger✅ PASS
B-15Doctor details shownP0After selection: doctor name, specialization if available✅ PASS
B-16Change doctorP0Select different doctor → time slot cleared, new doctor selected✅ PASS

B.3 Step 1 — Appointment Type

#Test CasePriorityExpectedStatus
B-20Appointment type — radio buttonsP0Three options: Walk-in, On Call, Telemedicine (RadioGroup)✅ PASS
B-21Queue mode — default WALKINP0mode='queue' → WALKIN pre-selected✅ PASS
B-22Switch to ONCALLP0Select ONCALL → Date picker + Time slot + Duration fields appear✅ PASS
B-23Switch to TELEMEDICINEP0Select TELEMEDICINE → Date + Time + Duration + Payment option appear✅ PASS
B-24Switch back to WALKINP0Select WALKIN → Date/Time/Duration/Payment fields hide✅ PASS

B.4 Step 1 — Date & Time (ONCALL/TELEMEDICINE only)

#Test CasePriorityExpectedStatus
B-30Date picker — opensP0Click date button → calendar popover opens✅ PASS
B-31Date picker — past dates disabledP0Dates before today are greyed out✅ PASS
B-32Select dateP0Click a date → date button shows "Jun 17" format, calendar closes✅ PASS
B-33Date picker — today defaultP1First open: date defaults to today (if no date set)✅ PASS
B-34Change date — clears time slotP0Select new date → time slot selection resets✅ PASS

B.5 Step 1 — Time Slots (ONCALL/TELEMEDICINE only)

#Test CasePriorityExpectedStatus
B-40Time slot dropdown — loadingP1LoadingSpinner in dropdown while fetching (usePractitionerTimeSlots)✅ PASS
B-41Time slot dropdown — disabled until doctor+dateP0Greyed out before doctor and date selected✅ PASS
B-42Time slot dropdown — available slotsP0Shows available time slots in 12h format (e.g., "10:00 AM")✅ PASS
B-43Time slot — booked slots disabledP1Booked slots shown as disabled with "Booked" label + destructive styling✅ PASS
B-44Time slot — no slots availableP0"No slots available" message when API returns empty✅ PASS
B-45Time slot — select doctor+date first messageP1Before selecting: "Select date and doctor first" message✅ PASS
B-46Select time slotP0Click available slot → selected✅ PASS
B-47Time slot validation messageP1Before selecting: red text "Time selection is required for appointments"✅ PASS

B.6 Step 1 — Duration

#Test CasePriorityExpectedStatus
B-50Duration — default from doctor scheduleP0Shows doctor's slot_duration (e.g., 15 min) from schedule✅ PASS
B-51Duration — accepts any valueP1Type any number → form accepts ≥5 min (Zod max(120) not enforced, backend also no cap)Bug #44 ⚠️
B-52Duration — invalid inputP1Enter letters or <5 → validation error✅ PASS

B.7 Step 1 — Payment Option (TELEMEDICINE only)

#Test CasePriorityExpectedStatus
B-55Payment options — visible for TELEMEDICINEP0Select TELEMEDICINE → payment dropdown appears (BEFORE/AFTER/NO)✅ PASS
B-56Payment options — hidden for WALKIN/ONCALLP0WALKIN or ONCALL → no payment option field✅ PASS

B.8 Step 1 — Reason for Visit

#Test CasePriorityExpectedStatus
B-60Reason for visit — textareaP1Optional textarea (2 rows, no resize) visible for all types✅ PASS
B-61Reason for visit — accepts textP1Type multi-line reason → stored✅ PASS

B.9 Step 1 — Continue Button

#Test CasePriorityExpectedStatus
B-65Continue — disabled without doctorP0No doctor selected → Continue button disabled (greyed out)✅ PASS
B-66Continue — disabled without time (ONCALL/TELEMEDICINE)P0ONCALL/TELEMEDICINE without time slot → disabled✅ PASS
B-67Continue — enabled for WALKIN with doctorP0WALKIN + doctor selected → enabled immediately (no time needed)✅ PASS
B-68Continue — toast validation on clickP1Click disabled Continue → toast: "Doctor selection is required" or "Time slot is required"✅ PASS
B-69Continue → advances to Step 2P0Click enabled Continue → Step 2 (Patient Info) shown✅ PASS

B.10 Step 2 — Federated Patient Search (FederatedPatientPicker)

#Test CasePriorityExpectedStatus
B-70Search input visibleP0"Search existing patients" input at top of Step 2✅ PASS
B-71Search — In Clinic bucketP0Type existing patient name → shows in "In this clinic" bucket✅ PASS
B-72Search — In Kulcare bucketP1Type patient from other clinic → shows in "Elsewhere on Kulcare" bucket✅ PASS
B-73Search — No match → New PatientP0Type unknown name → both buckets empty → "Create new patient" option✅ PASS
B-74Select In Clinic patientP0Click in-clinic patient → form auto-fills: name, phone, gender, DOB, email✅ PASS
B-75Select In Kulcare patientP1Click in-kulcare patient → form auto-fills: name, phone (no DOB — known Bug #32)✅ PASS
B-76Create new patientP0Click "Create new" → form fields cleared for manual entry✅ PASS

B.11 Step 2 — Patient Form Fields

#Test CasePriorityExpectedStatus
B-80first_name + last_name — 2-col gridP0Two input fields side by side✅ PASS
B-81Country code + Phone — 2-col gridP0RegionSelect dropdown + phone input (10 digits)✅ PASS
B-82Email — full widthP1Email input below phone row✅ PASS
B-83Gender — radio groupP1M / F / O radio buttons✅ PASS
B-84DOB — date inputP1Date input, max=today✅ PASS
B-85Fields disabled — existing patientP0When patient selected from search → all fields disabled (greyed out, not editable)✅ PASS
B-86Fields enabled — new patientP0New patient mode → all fields editable✅ PASS

B.12 Step 2 — Couple Session

#Test CasePriorityExpectedStatus
B-90Couple session — checkboxP2Collapsible section at bottom: "Couple Session" with checkbox✅ PASS
B-91Enable couple sessionP2Check → spouse details section expands (first_name, last_name, phone, email, gender, DOB)✅ PASS
B-92Disable couple sessionP2Uncheck → spouse section collapses, spouse data cleared✅ PASS

B.13 Step 2 — Validation

#Test CasePriorityExpectedStatus
B-95First name — emptyP0Submit without first_name → Zod error: "First name is required" (toast on Continue click)Pending
B-96Phone — emptyP0Submit without phone → Zod error: "Phone number is required"Pending
B-97Phone — invalid formatP0Enter "abc" or "12345" → Zod regex: "Phone number must be 10 digits"Pending
B-98Phone — 10 digits validP0Enter "9889988998" → passes validationPending
B-99Email — invalid formatP1Enter "notanemail" → superRefine: "Invalid email format"Pending
B-100DOB — future dateP1Enter tomorrow's date → Zod refine: "Date of birth cannot be in the future"Pending
B-101Couple session — spouse requiredP2Enable couple session, leave spouse empty → Zod: "Spouse details are required"Pending
B-102Spouse phone — 10 digits (frontend Zod)P2Enter invalid phone → Zod regex: "Spouse phone must be 10 digits"Pending
B-103Spouse — backend validationP2Backend: phone_number + country_code required for new spousePending

B.14 Step 2 — Navigation

#Test CasePriorityExpectedStatus
B-105Back to Step 1P0Click "Back" → returns to Step 1, all data preserved✅ PASS
B-106Change doctor in Step 1 → affects Step 2P1Go back, change doctor, advance → Step 2 data preserved, doctor updated✅ PASS

B.15 Submit Booking

#Test CasePriorityExpectedStatus
B-110Submit — existing patient (WALKIN)P0Fill all fields → click "Add Appointment" → API call with patient_id✅ PASS
B-111Submit — new patient (WALKIN)P0Fill all fields → click "Add Appointment" → API call with patient_params✅ PASS
B-112Submit — ONCALL with time slotP0ONCALL mode, date+time+doctor → API call with start_time (UTC, clinic timezone)✅ PASS
B-113Submit — TELEMEDICINE with paymentP1TELEMEDICINE + payment option → API call includes payment_option✅ PASS
B-114Submit — success toast (existing patient)P0Toast: "Appointment created successfully" + "The appointment has been booked."✅ PASS
B-115Submit — success toast (new patient)P0Toast: "Appointment created successfully" + "New patient profile created and appointment booked."✅ PASS
B-116Submit — success toast (cross-tenant)P1In-Kulcare patient: "Patient imported from another clinic and appointment booked."✅ PASS
B-117Submit — button loading stateP0Click Submit → spinner + "Adding..." text, button disabled✅ PASS
B-118Submit — modal closes after successP0500ms after success toast → modal auto-closes, queue refetches✅ PASS
B-119Submit — API errorP1API returns error → error toast, form stays open for retry✅ PASS
B-120Submit — facility not availableP1No facility_id → toast: "Facility information not available"✅ PASS
B-121Submit — couple sessionP2Enable couple session, fill spouse → API includes couple_session + spouse_details✅ PASS

FLOW C: Appointments Calendar Page

Component: AppointmentsPage.tsx URL: /cms/appointments

C.1 Calendar Views

#Test CasePriorityExpectedStatus
C-01Month view — defaultP0Page loads with month calendar view✅ PASS
C-02Week viewP0Switch to Week view → shows 7-day grid✅ PASS
C-03Day viewP0Switch to Day view → shows hourly slots✅ PASS
C-04Today buttonP0Click Today → resets to current date✅ PASS
C-05Navigate monthsP0← → arrows navigate between months/weeks✅ PASS
C-06Date with appointmentsP0Dates with appointments show indicators/dots✅ PASS

C.2 Doctor Filter (Calendar)

#Test CasePriorityExpectedStatus
C-10Filter by doctorP0Select doctor → calendar shows only that doctor's appointments✅ PASS
C-11Clear doctor filterP0Select "All" → shows all practitioners✅ PASS

C.3 Appointments Listing Sidebar

#Test CasePriorityExpectedStatus
C-20Click date → listingP0Click a date → right sidebar shows appointments for that date✅ PASS
C-21Listing — appointment detailsP0Shows patient name, time, type, status for each appointment✅ PASS
C-22Listing — empty dateP0Click date with no appointments → "No appointments" message✅ PASS
C-23Listing — searchP1Search within appointment listing✅ PASS

C.4 Add Booking from Calendar (Scheduled Mode)

#Test CasePriorityExpectedStatus
C-30Click empty slotP0Click empty time slot → AddAppointmentModal opens with mode='scheduled'✅ PASS
C-31Modal pre-fills date/timeP0Selected date + time slot pre-filled in Step 1✅ PASS
C-32Scheduled mode — time slot requiredP0ONCALL mode: must select time slot to proceed✅ PASS
C-33Submit scheduled bookingP0Fill steps → Submit → appointment appears on calendar✅ PASS

C.5 Edit Appointment

#Test CasePriorityExpectedStatus
C-40Click appointment → editP0Click existing appointment → UpdateAppointmentModal opens✅ PASS
C-41Edit appointment fieldsP0Update time/doctor/status → Save✅ PASS
C-42Cancel editP0Close modal without saving → no changes✅ PASS

FLOW D: Multi-Clinic Scoping (Queue & Appointments)

Scope: All components use currentFacilityId from useProfile() for API calls. Switch: Admin switches facility via header dropdown → currentFacilityId changes → all data refetches.

D.1 Queue — Facility Scoping

#Test CasePriorityExpectedStatus
MC-01Queue shows only current facility patientsP0Patients in queue belong to current facility only✅ PASS
MC-02Switch facility → queue changesP0Switch Clinic A → Clinic B → different patients shown✅ PASS
MC-03Queue stats per facilityP0Stats (Total/Waiting/In Progress/Completed) are facility-scoped✅ PASS
MC-04Search scoped to facilityP0Search in Clinic A → only finds Clinic A patients✅ PASS
MC-05Practitioner filter — facility doctors onlyP0Doctor dropdown lists only practitioners in current facility✅ PASS
MC-06Past date queue per facilityP1Switch facility → past date shows only that facility's history✅ PASS
MC-07Pagination per facilityP1Clinic A page 2 ≠ Clinic B page 2✅ PASS

D.2 Add Booking — Facility Assignment

#Test CasePriorityExpectedStatus
MC-10Booking created in current facilityP0Book in Clinic A → appointment appears only in Clinic A queue✅ PASS
MC-11Booking from Clinic B → not in Clinic AP0Book in Clinic B → switch to Clinic A → patient NOT visible✅ PASS
MC-12Modal shows current facility tenant nameP1Modal header displays tenant name✅ PASS
MC-13Same patient — separate facility bookingsP1Book same patient in both clinics → separate appointments per clinic✅ PASS

D.3 Appointments Calendar — Facility Scoping

#Test CasePriorityExpectedStatus
MC-20Calendar shows only current facility appointmentsP0Switch facility → calendar appointments change✅ PASS
MC-21Doctor filter per facilityP0Calendar doctor dropdown is facility-scoped✅ PASS

D.4 Queue Actions — Facility Scoping

#Test CasePriorityExpectedStatus
MC-30Start Encounter — correct facilityP0Start encounter from Clinic A → encounter in Clinic A✅ PASS
MC-31Billing — correct facility contextP1Billing panel uses current facility✅ PASS
MC-32Status change — per facilityP0Change status in Clinic A → only affects Clinic A appointment✅ PASS

Test Summary

FlowTest CasesTestedPassedFailed
A — Queue Page63000
B — Add Booking Modal83000
C — Appointments Calendar17000
D — Multi-Clinic Scoping16000
Total179000

Test Execution Order

  1. Flow B: Add Booking Modal (B-01 to B-121) — 83 tests ✅ Done
  2. Flow A: Queue Page (Q-01 to Q-143) — 63 tests ← NOW
  3. Flow D: Multi-Clinic Scoping (MC-01 to MC-32) — 16 tests
  4. Flow C: Appointments Calendar (C-01 to C-42) — 17 tests

Status: Pending Last Updated: 2026-06-17

On this page

Code Audit SummaryPages & ComponentsAPIsKey HooksQueue Row Actions (per patient)FLOW A: Queue PageA.1 Page LoadA.2 Queue Header — Date NavigationA.3 Queue Header — SearchA.4 Queue Header — Practitioner FilterA.5 Queue Header — Status FilterA.6 Queue Header — StatisticsA.7 Queue Table — Active QueueA.8 Queue Table — Out of Queue SectionA.9 Queue Table — Empty StatesA.10 Queue Table — PaginationA.11 Queue Row — Status ChangeA.12 Queue Row — Start EncounterA.13 Queue Row — BillingA.14 Queue Row — Actions DropdownA.15 Add Patient (from Queue)FLOW B: Add Booking Modal — Queue Mode (WALKIN)Modal BehaviorB.1 Modal Open & ResetB.2 Step 1 — Doctor SelectionB.3 Step 1 — Appointment TypeB.4 Step 1 — Date & Time (ONCALL/TELEMEDICINE only)B.5 Step 1 — Time Slots (ONCALL/TELEMEDICINE only)B.6 Step 1 — DurationB.7 Step 1 — Payment Option (TELEMEDICINE only)B.8 Step 1 — Reason for VisitB.9 Step 1 — Continue ButtonB.10 Step 2 — Federated Patient Search (FederatedPatientPicker)B.11 Step 2 — Patient Form FieldsB.12 Step 2 — Couple SessionB.13 Step 2 — ValidationB.14 Step 2 — NavigationB.15 Submit BookingFLOW C: Appointments Calendar PageC.1 Calendar ViewsC.2 Doctor Filter (Calendar)C.3 Appointments Listing SidebarC.4 Add Booking from Calendar (Scheduled Mode)C.5 Edit AppointmentFLOW D: Multi-Clinic Scoping (Queue & Appointments)D.1 Queue — Facility ScopingD.2 Add Booking — Facility AssignmentD.3 Appointments Calendar — Facility ScopingD.4 Queue Actions — Facility ScopingTest SummaryTest Execution Order