Nexaflow Editor
Open the formatted testing reference · Download the case register
Revision: 4 November 2026. Scope: the Booking Management module in the current source tree, including the uncommitted treatment catalogue/pricing work. This is a test specification, not a claim that these tests have run or that the deployed build supports every flow. Record the deployed commit and compare it with this revision before execution.
Use this guide to turn each documented behavior into a manual or automated test case. It covers clinic setup through patient registration, scheduling, consultation, treatment, payment and follow-up, including invalid inputs, conflicts, authorization and recovery. Screenshots are helpful for navigation and expected appearance, but are not prerequisites for executing the cases.
Related guides:
Each case has a stable ID, priority, concrete action and an observable expected result. Preserve the ID when creating cases in the admin testing console or an external test tool. The CSV contains the same cases, prerequisites, steps and expected results; it starts with status Not run.
For every case:
CAN-002.patient-whatsapp and CAN-002.provider-whatsapp.| Priority | Meaning | Release handling |
|---|---|---|
| P0 | Access, patient identity, scheduling integrity, money, required business workflow or external delivery | All applicable cases must pass; an unresolved product decision/blocker cannot be counted as a pass |
| P1 | Important configuration, history, resilience or common usability behavior | Pass or obtain an explicit documented release decision for each failure |
| P2 | Noncritical polish or optional convenience | Track separately with the agreed acceptance decision |
Use Pass, Fail, Blocked, Not applicable and Not run. Blocked means an expected capability could not be tested, with a named missing prerequisite. Not applicable requires an explicit reason and product scope decision. Do not downgrade a missing required feature to Not applicable. Mocked API success, passing unit tests and a live handset result are different evidence types; label them.
| Fixture | Data and purpose |
|---|---|
| Clinic A | MyClinic QA; dedicated staging module; INR; patient prefix QAT; clinic timezone Asia/Kolkata |
| Clinic B | Separate account/organization and module, with identifiable different records for isolation tests |
| Location A / B | Main Clinic QA / Branch Clinic QA; same timezone; separate assignments; addresses suitable for test prints |
| Dr Alex QA | Consultation and follow-up services, verified test mobile/email, 09:00–13:00 and 14:00–17:00 on chosen future weekday D |
| Dr Jamie QA | Different identity and hours; also prepare an explicitly shared identity across modules for cross-module conflict tests |
| Consultation QA | 30 minutes, ₹500 fixed, initially zero buffers; explicit 30-minute start interval |
| Follow-up QA | Separate service; also test follow-up visits using the same service/provider as a linked course, because course compatibility requires those IDs to match |
| Patient Alex QA | Adult; valid past DOB; controlled mobile/email; record assigned patient number |
| Patient Jordan QA | Same household mobile as Alex, different person/DOB; proves family selection and independent history |
| Patient Sam QA | Child; separate patient identity; two registered adult guardian fixtures |
| Patient Taylor QA | Same surname as another patient but different DOB/mobile; proves disambiguation |
| Patient Morgan QA | Reception registration without mobile; proves permitted no-phone path |
| Treatment catalogue | Fixed ₹50,000; range ₹40,000–₹60,000; After assessment; INR; clear inclusions/exclusions |
| Financial account | Independent agreed cost ₹50,000 with three instalments; do not mix with pricing-adjustment fixtures |
| D | Future clinic-local weekday within horizon and outside required notice. Record actual date and equivalent UTC instants for every run |
| Controlled time | Automated fixed-clock fixtures for notice boundaries, reminders, started appointments and token expiry; record both UTC and clinic-local time |
| Integrations | Booking-enabled agent, allowed sender, compatible approved templates, delivery worker/webhook, test inbox, sandbox gateway/test calendar only where applicable |
Use unique run suffixes in names and payment references, such as QA-20261104-A. Replace all contact placeholders with numbers and addresses controlled by consenting testers. Do not send to arbitrary example numbers. Do not include real patient information or credentials in screenshots or bug reports.
| Area | Current navigation / save behavior |
|---|---|
| Scheduling | Calendar; Walk-ins; Appointments; Book appointment |
| Patient records | Patient Management → patient details → history, guardians, clinical history, Payments & Billing |
| Consultation | Open an appointment → Consultation & Clinical Records / Treatment Cost & Payments / Summary & Notes |
| Doctor schedule | Doctor Workspace → select doctor and day → open appointment/consultation |
| Recalls | Reviews & Recalls → creation, specialist, campaign history and treatment registry views |
| Configuration | Settings cog → Booking Profile; Services; Policies & Rules; Communications; Payments; Assistant Rules; Booking Portal; Locations |
| Service configuration | Settings → Services → Service types / Treatment types / Service providers / Working Hours |
| Profile/policies/channel settings | Use Save Configuration in settings header; reload to prove persistence |
| Patient, clinical, treatment and payment forms | Their own explicit save/record/link action; do not assume Save Configuration saves an unsent record form |
| Approved workflow link | Link using current sending contract saves immediately; wait for success |
| Mapping draft | Save mapping draft saves immediately but does not activate custom live parameter behavior |
| Template unassignment | Unassign followed by Save Configuration |
| Google Calendar controls | Some connection/calendar settings save through their own integration requests; prove effective persistence separately |
Some UI labels and older requirement documents have changed. Use the current page names above; if the deployed build differs, record its exact version and discrepancy. A hidden configuration control does not prove a missing API capability; an API endpoint does not prove that a promised user-facing workflow exists.
This journey proves the connections between screens before expanding into negative tests. Use a separate fixture for cancellation/no-show so that you do not corrupt the primary financial journey.
| Action | Total cost | Amount received this action | Cumulative paid | Balance | Expected payment state |
|---|---|---|---|---|---|
| Save agreed bill | ₹50,000 | ₹0 | ₹0 | ₹50,000 | unpaid |
| Deposit / QA-P1 | ₹50,000 | ₹10,000 | ₹10,000 | ₹40,000 | partially_paid |
| Stage payment / QA-P2 | ₹50,000 | ₹15,000 | ₹25,000 | ₹25,000 | partially_paid |
| Final payment / QA-P3 | ₹50,000 | ₹25,000 | ₹50,000 | ₹0 | fully_paid |
The agreed catalogue-price example uses ₹50,000 + ₹5,000 − ₹2,000 = ₹53,000. It is a different fixture. An estimate is neither an agreed payment nor evidence that money was received. Service booking price, catalogue guide price, patient agreed total and recorded receipts are distinct values.
Execute the following with enabled delivery, approved compatible templates, valid contacts and appropriate consent. Create separate test executions for staff/public sources, patient/guardian routing, each recipient and each active channel. For disabled or missing prerequisites expect truthful suppression/blocking, never a false delivered result.
| Trigger | Patient-facing recipient | Provider / clinic requirement | Extra assertions |
|---|---|---|---|
| Patient registration | Registered patient/designated permitted contact | Verify configured clinic channels; do not assume a doctor registration send | Patient number and DOB belong to selected patient |
| Appointment confirmed | Patient or designated guardian | Patient and doctor/provider WhatsApp updates are required acceptance checks | Same committed appointment/time; one send per intended recipient |
| Walk-in appointment | Selected patient/contact | Check configured provider/clinic channels explicitly | Registration alone is not the walk-in booking |
| Reminder at every configured lead | Patient/designated guardian | Additional provider reminders only if a defined supported requirement | Text, due time and template values inspectable; current confirmed time |
| Reschedule proposal | Patient/designated guardian | Verify clinic visibility of pending proposal | Original appointment unchanged until accepted |
| Applied reschedule | Patient/designated guardian | Doctor/provider update | Old/new times correct; no duplicate booking |
| Patient cancellation | Patient/designated guardian | Doctor/provider also receives update | Released slot and no stale pending reminder |
| Administrator/provider cancellation | Patient/designated guardian | Doctor/provider also receives update | Actor/reason retained; paid ledger retained |
| Visit completion / no-show | Configured patient/contact | Configured staff/email/in-app channels | Only committed valid transition triggers event |
| Send estimate | Patient/contact | Clinic traceability | No recorded payment created |
| Save bill/balance with send enabled | Patient/contact | Clinic traceability | Correct total, paid, balance and plan |
| Record payment with receipt enabled | Patient/contact | Clinic ledger/receipt | Correct historical receipt before/after values |
| Review invitation | Selected eligible patient/contact | Campaign history | Correct cohort; no appointment yet |
| Visiting specialist announcement | Selected patient/contact | Visit/campaign history | Advertised date/range, clinic-local time |
| Recall YES / NO / preferred time | Replying authorized contact | Recipient state/counts | Booking link / decline / request, respectively |
| STOP / START | Replying contact acknowledgement if supported | Sender-scoped preference | Preference saves even if acknowledgement cannot send |
This table states required acceptance outcomes; it does not claim all provider-recipient paths are currently implemented. Treat absent provider confirmation/cancellation delivery as a failure or blocker against the requirement. Keep staff email and provider WhatsApp as distinct recipients/channels.
The base register contains 180 cases across 20 areas, before expanding recipient/channel/source/boundary variants. This is a specification inventory, not an execution result.
| Prefix | Area | Base cases |
|---|---|---|
| ENV | Prepare the environment and prove access | 6 |
| CFG | Booking profile, numbering and linked settings | 7 |
| CAT | Services, categories, providers and assignments | 11 |
| HRS | Locations, working hours, exceptions and slot arithmetic | 10 |
| POL | Policies and effective cancellation rules | 7 |
| PAT | Patient registration, lookup and patient management | 12 |
| GUA | Guardians, primary contacts and delegated access | 5 |
| BKG | Staff and public appointment booking | 13 |
| APT | Calendar, appointment lists, doctor workspace and visit lifecycle | 10 |
| CAN | Cancellation by patient, administrator and provider | 6 |
| RSC | Rescheduling, proposals and patient response | 9 |
| CLN | Clinical records and allergy history | 6 |
| TRT | Treatment catalogue, patient agreement and shared courses | 14 |
| PAY | Estimates, agreed bills, instalments, payments and receipts | 12 |
| REV | Reviews, recalls, treatment registry and specialist visits | 11 |
| COM | Communications across the whole module | 11 |
| INT | Assistant, portal branding, payments configuration and integrations | 9 |
| SEC | Security, privacy, resilience and usable operation | 10 |
| WRK | Walk-in queue, branch QR and My Bookings | 5 |
| IMP | Guarded configuration edits and affected bookings | 6 |
Each section lists prerequisites, then independently addressable cases. Unless specified otherwise, after each successful mutation reload the current page and at least one dependent view. For every rejected mutation inspect that baseline records, financial totals and relevant outbox events remain unchanged. Save both actual and expected results.
Prerequisites and fixture: Use an isolated staging clinic, two separate browser profiles, a consenting patient test handset, and a separate provider test handset. Record the deployed commit, module ID, account/organization, browser, timezone and enabled integrations. Never run database-resetting integration suites against a working clinic.
Steps: Sign in as clinic staff. Open Calendar, Walk-ins, Appointments, Book appointment, Patient Management, Reviews & Recalls and Doctor Workspace. Open the settings cog and every settings page. Reload each destination.
Expected: Every page is reachable in the intended section; selected navigation and module identity remain correct; no blank screen or unrelated module data appears.
Steps: Sign out in profile B. Open a saved staff appointment URL and call its staff API without a token. Repeat with an expired token.
Expected: Staff records and mutation actions are unavailable. Authentication errors do not reveal patient, appointment or payment contents. Public booking remains a separate permitted flow.
Steps: Prepare clinic A and clinic B with different records. As B, substitute A module, appointment, patient, course, campaign and receipt references in staff requests. Repeat within one organization using another module.
Expected: Every object is scoped to the authorized module/account. No foreign record can be viewed or changed. Test public receipt boundaries separately in SEC-004.
Steps: Open a genuinely empty test module. Complete the first-appointment setup with one location, provider, service, working periods, timezone, price and confirmation. Save and inspect availability.
Expected: The configuration is created as one operation. All required records and assignments exist; available slots come from the server. A preview failure does not create another configuration set.
Steps: In a disposable test fixture, interrupt setup response after submission; retry the same request key. Separately inject a setup write failure and submit two different setups concurrently.
Expected: Retry returns the same setup. Failed setup leaves no partial records. Concurrent setup cannot create two initial catalogs. Record actual request keys and counts.
Steps: Remove one prerequisite at a time in a disposable configuration: provider hours, active service, active location or assignment. Open readiness and the booking page.
Expected: Staff receive a useful configuration destination; the public page shows appropriate unavailable/contact guidance. No slots are invented and no incomplete booking is accepted.
Prerequisites and fixture: Open Settings → Booking Profile. Use MyClinic QA as the clinic name, INR as currency and QAT as patient prefix. Save configuration, leave the module and reload before checking persistence.
Steps: Change practice name, support email, interface mode and currency. Save Configuration, reload and inspect staff screens and public portal.
Expected: Saved values persist in the correct places. Currency symbols and amounts are consistent; changing a default must not silently rewrite historical financial records.
Steps: Register patients in locations A and B, including simultaneous registrations. Compare numbers, then change the patient prefix and create another patient.
Expected: Numbers are unique clinic-wide and stable for existing patients. New numbers use the saved prefix; concurrent writes do not duplicate a sequence.
Steps: Set booking/invoice prefixes, next sequence values, invoice title, processing-token heading and GST identifier. Create two bookings and a payment receipt; inspect ticket and print output.
Expected: Supported outputs use saved settings and unique numbers. Existing identifiers remain stable. Record any setting whose receipt or booking implementation does not actually consume it as a gap.
Steps: Try a blank/one-character patient prefix, oversized text, invalid email and invalid sequence values. Save, then reload.
Expected: Invalid input is rejected or visibly normalized before persistence. No success message accompanies a failed save. The effective patient prefix contains 2–10 letters/numbers.
Steps: Link an authorized CRM module, register a patient, then change their contact details. Inspect the linked contact. Retry the update.
Expected: One mapped CRM contact is created/updated with correct patient metadata; retry does not create duplicates. An unrelated organization CRM cannot be selected or written.
Steps: Register a patient while the configured CRM target is unavailable or invalid in a controlled fixture. Reopen the patient and inspect synchronization evidence.
Expected: Core registration result remains truthful and usable; failed CRM sync is distinguishable from registration failure. Recovery must not duplicate the patient or contact.
Steps: Open settings in two tabs. In one, save a WhatsApp workflow link. In the other, change an unrelated profile field and Save Configuration. Reload both.
Expected: The profile change and newly saved workflow link survive. A stale settings snapshot must not silently erase template assignments or mapping drafts.
Prerequisites and fixture: Open Settings → Services. Current subpages are Service types, Treatment types, Service providers and Working Hours. Service assignments are managed with providers; treatment types are a separate clinical/pricing catalogue.
Steps: In Service types create Consultation QA with description, 30-minute duration and ₹500 fixed price. Save, reopen, edit the description and reload.
Expected: Exactly one service exists with the saved fields. It becomes bookable only after an active provider/location assignment and valid hours exist.
Steps: Create a category from the service form; select it for a second service; clear it from another. Try a duplicate with changed case and whitespace.
Expected: Category selection/clearing persists. Normalized duplicate categories are prevented. Services remain associated with the intended category.
Steps: Create variants with an explicit zero price, no specified price, fixed price and any estimate/range controls offered by this build. Open staff and public booking summaries.
Expected: Zero displays as Free; unspecified price displays as provider-decided, not zero. Fixed/range amounts and currencies match the selected service/assignment.
Steps: Submit missing name, zero/negative/non-integer duration, negative amount, excessive decimal precision and invalid buffer values through the supported form and API.
Expected: Invalid values are rejected server-side; no partially saved service or assignment appears. Document exact API schema limits rather than relying only on input min/max.
Steps: In Service providers add Dr Alex QA with mobile, email, specialty, selected active services and location. Choose copied clinic hours and confirm assignments.
Expected: Provider, chosen offerings and schedule save consistently. Doctor contact details are usable for notifications. Unselected services do not become offered.
Steps: Add another provider with custom hours; compare with copied clinic hours. Later edit the clinic hours and reopen both provider schedules.
Expected: Custom hours remain explicit. Copied hours are an independent saved schedule; later clinic-hour changes do not silently rewrite provider hours.
Steps: Change services/location after checking setup confirmation, then submit. Retry a failed/uncertain setup with the same key. Include an inactive/foreign service ID in a negative API request.
Expected: Changed choices require renewed confirmation. Retry cannot create a second provider. Inactive/foreign choices are rejected atomically.
Steps: Where assignment controls are available, set a service-specific duration, price and before/after buffers; save separately from provider details. Clear overrides and save again.
Expected: Availability and new appointment snapshots use effective overrides; clearing restores service defaults. Saving assignments does not discard unrelated unsaved provider fields.
Steps: Attempt the same provider/service/location assignment twice, then submit a service or location from clinic B.
Expected: Duplicate tuples and cross-module references are rejected. Existing assignments remain intact; no hidden offering appears in the portal.
Steps: Archive an unused service, provider or offering; reload public availability. Restore it. Repeat with a record referenced by future appointments using IMP cases.
Expected: Inactive records stop producing new slots. Restore makes eligible slots available again. Existing appointments keep their snapshots; affected bookings require explicit resolution.
Steps: In a second booking module explicitly reuse the same organization provider identity. Book a slot in A, then search/book the overlapping slot in B. Also create a same-named provider with a different identity.
Expected: The explicitly shared provider cannot be double-booked across modules. Matching names alone never establish shared identity or block an unrelated doctor.
Prerequisites and fixture: Create location A (Main Clinic QA) and B (Branch Clinic QA), both Asia/Kolkata. For deterministic tests choose a future weekday D within the booking horizon. Give A/provider morning hours 09:00–13:00 and afternoon hours 14:00–17:00. Use a zero-buffer 30-minute service and 30-minute start interval first.
Steps: Create both locations with names, addresses, timezone and hours. Assign the provider/services. Switch location in staff and public booking.
Expected: Names, addresses, timezone and assignments persist. Location selection changes the eligible providers and slots without carrying a stale selection forward.
Steps: Save 09:00–13:00 and 14:00–17:00 on D. Search the zero-buffer 30-minute service.
Expected: Expected starts are 09:00 through 12:30 and 14:00 through 16:30 at 30-minute intervals: 14 slots before bookings/blocks. No appointment occupies lunch or runs beyond closing.
Steps: Set location hours to 09:00–17:00 and provider hours to 10:00–12:00. Then make the provider unavailable all day.
Expected: Only the intersection produces slots; the zero-buffer 30-minute fixture yields 10:00, 10:30, 11:00, 11:30, then no slots after provider availability is removed.
Steps: Try end before start, equal start/end, overlapping periods, malformed clock strings and one interval crossing midnight. Save via UI and API.
Expected: Invalid/ambiguous schedules are rejected or explicitly handled. Overnight hours must be split into separate days; a visually accepted invalid rule must not create bad availability.
Steps: For D save an available exception 11:00–12:00; on another date set a full-day closure. Compare recurring weekly hours and other weeks.
Expected: The date exception replaces that date’s provider rules. Only 11:00 and 11:30 remain for the zero-buffer fixture. Closure yields no slots; other dates retain weekly hours.
Steps: Add provider leave and a location-wide block, including a multi-day block. Inspect each affected day and another provider/location.
Expected: Every overlapping slot is removed at the correct scope. Multi-day blocks render on each relevant date. Unaffected providers/locations remain available.
Steps: Set before/after buffers to 5/10 minutes and interval to 30. Book D 10:00–10:30. Search near it and near opening/closing.
Expected: Occupied interval is 09:55–10:40. A candidate 10:30 occupies 10:25–11:10 and is rejected; 11:00 occupies 10:55–11:40 and can pass. The entire occupied interval must fit hours; 09:00 fails the opening buffer.
Steps: With no service buffers, book the shared provider in A at 10:00–10:30. Set travel to 30 minutes and test B starts 10:30 and 11:00; compare same-location adjacency.
Expected: B 10:30 is unavailable; B 11:00 may be available if all other rules permit. Same-location appointments do not acquire the cross-location travel buffer.
Steps: Book D 10:00 Asia/Kolkata and inspect request, calendar, ticket, reminders and print. Repeat with browser timezone UTC and a different timezone.
Expected: The stored instant is D 04:30Z; clinic-facing date/time remains coherent. Local midnight does not shift records to the wrong clinic day. Public labels must make time interpretation clear.
Steps: Use a separate location with a DST timezone. Search a spring-forward gap and autumn repeated hour; submit ambiguous/missing local exception times.
Expected: Slots correspond to real UTC instants without duplicates representing the same instant. Ambiguous/nonexistent exception times are rejected; labels distinguish times where necessary.
Prerequisites and fixture: Open Settings → Policies & Rules. Save one policy at a time and restore baseline afterward. The screen also has customer self-cancellation controls based on time since creation; these are distinct from minimum notice before the appointment.
Steps: Change all six engine policies with sliders and numeric inputs. Save/reload. Try negative, fractional and above-limit values through API.
Expected: Valid values persist with their units. Integer limits: start interval 1–240 minutes or unset; lead/cancel/reschedule 0–525600 minutes; horizon 1–365 days; travel 0–1440 minutes. Slider zero for interval represents unset, not an API numeric zero.
Steps: Freeze time in an automated fixture; set lead=60 minutes. Test slots one minute before, exactly at and one minute after now+60. Repeat through staff, public and AI paths.
Expected: No slot before the minimum is accepted. A boundary slot can pass only if aligned and otherwise eligible. Server validation prevents bypass after stale availability.
Steps: Set horizon=7 days with fixed now. Query/book a fitting slot inside the window, one ending past the upper boundary and one outside it.
Expected: Both appointment interval and effective horizon are enforced server-side. Existing bookings are not moved by changing the policy.
Steps: Unset start interval for a 30-minute service with 5/10 buffers; compare with interval=15 and interval=30.
Expected: Unset uses duration plus buffers as the slot frequency, aligned to the working-period start. Explicit intervals change start frequency without shortening service duration or removing conflict checks.
Steps: Set both notices to 60 minutes. In a fixed-clock fixture cancel/reschedule at 61, 60 and 59 minutes before start. Use separate appointments and both staff/customer paths.
Expected: Changes satisfy engine notice checks at the documented boundary; too-late actions leave the appointment intact. Record server error codes and verify no false success or notification.
Steps: Disable customer cancellation, then attempt from ticket and direct public API. Re-enable and repeat within the permitted time window.
Expected: Disabled customer cancellation is enforced at the server. Enabling allows only authenticated/verified permitted actions; hiding a button alone is insufficient.
Steps: Test Pending Bookings Only and Pending + Time Window Limit. For the latter use a 30-minute creation window and test at 29, 30 and 31 minutes after creation with fixed time.
Expected: Record how booking status, time since creation and engine notice combine. The normal confirmed booking flow must have a coherent permitted path. If screen wording and engine behavior disagree, fail the case and obtain a product decision.
Prerequisites and fixture: Prepare Alex QA (adult), Sam QA (child), Jordan QA (same household mobile), Taylor QA (same surname but different DOB), and Morgan QA (reception registration without a mobile). Use controlled contact numbers; never use invented numbers for real sends.
Steps: In Walk-ins choose registration branch and register Alex QA with full name, past DOB, mobile, address and email. Open Patient Management.
Expected: A durable patient ID/number, source, branch and contact details exist. Registration does not itself book an appointment or record a payment. Registration notification is independently traceable.
Steps: Open the actual registration/portal entry used by this build in a signed-out browser. Register Sam QA with household mobile and DOB. Reload the resulting patient/booking flow.
Expected: Registration has the appropriate patient_qr/whatsapp_portal source and correct clinic. Mobile is required for public registration; staff-only fields cannot be forged by the public request.
Steps: Register Morgan QA at reception without a mobile. Add a mobile later. Attempt the equivalent public registration without mobile.
Expected: Reception can save without mobile; public registration rejects missing mobile. No WhatsApp send is claimed before a valid permitted contact exists. Adding a number preserves patient identity.
Steps: Try blank name/DOB, today’s DOB, future DOB, impossible date, invalid email and malformed mobile. Try 10 national digits, 91+10 digits and +91+10 digits in accepted form.
Expected: Registration requires a nonempty name and strictly past valid DOB. Accepted Indian mobile formats normalize to +91 plus 10 digits. Address/email remain optional subject to field validation.
Steps: Search Alex by patient number, mobile and name. In Patient Management combine surname search with DOB filter; repeat with Taylor and clear filters.
Expected: The intended patient can be uniquely selected using displayed identifiers. Name/mobile matches do not silently select a different family member. DOB filter and search combine correctly.
Steps: Register Jordan QA using Alex’s mobile but different identity/DOB. Look up the mobile in reception and portal. Book Jordan explicitly.
Expected: Both records remain distinct. Selection uses the chosen patient ID; booking, clinical history, payments and notifications identify Jordan without merging Alex’s data.
Steps: From the portal enter a household number, select an existing patient, then use the new-member action for a different person. Repeat same-name/number lookup and inspect the submitted patient ID.
Expected: Existing selection reuses the intended patient and new-member registration creates one distinct record. Any automatic matching is checked against DOB/identity expectations; phone possession alone must not grant sensitive access.
Steps: Edit contact details and DOB/address through Edit patient. Reopen the patient, prior appointments and a newly created appointment.
Expected: Patient details persist without changing patient number. Historical appointment/contact snapshots remain auditable; new bookings use the selected current details according to the displayed contact choice.
Steps: Open a patient with confirmed, completed, cancelled and no-show visits, across two services. Expand Treatment history and open each visit.
Expected: Active, completed and other groups contain the right visits once each; selected record opens the correct appointment. Missing records must not be confused with a failed history request.
Steps: Click Schedule appointment from Jordan’s patient page; select service/provider/time and confirm.
Expected: The selected patient is retained through booking. No duplicate registration or switch to another household member occurs. New visit appears in Jordan’s history.
Steps: In a disposable fixture attempt archive/delete with and without appointment, clinical, guardian and payment history. Cancel the confirmation first, then proceed only on disposable records.
Expected: Abandoning confirmation changes nothing. Referenced history must not become orphaned or silently disappear. Record the supported archive/delete contract and fail any irreversible accidental history loss.
Steps: Combine text, gender, DOB and age filters; clear all. Simulate a patient-load failure, then retry.
Expected: Results/counts reflect all active filters; clearing restores records. A load failure is visible and distinct from no matches; retry recovers without duplicates.
Prerequisites and fixture: Create two registered adult guardian records and the child Sam QA. Separate an appointment-only guardian contact declaration from a staff-verified relationship on the patient page.
Steps: Book Sam with a separate guardian name, relationship, phone, optional email and explicit authorization. Omit child phone only when this contract allows it.
Expected: Patient remains Sam. Guardian contact is stored separately and retained on reschedule. Patient-facing messages route to the designated contact; a guardian declaration grants no access to existing patient records.
Steps: On Sam’s patient page add a registered guardian; select parent/guardian, verify contact and check explicit confirmation. Change selection after confirming.
Expected: Only the explicitly verified selected relationship saves. Changing identity or relationship clears confirmation. The first verified guardian becomes primary.
Steps: Add the second verified guardian, switch primary, reload, then try adding a third or linking Sam as their own guardian.
Expected: At most two relationships exist; exactly one primary is retained. Self-links/duplicates/third guardians are blocked server-side. New contact selection uses the saved primary as designed.
Steps: Through a verified customer session test access to Sam by the linked guardian, an unlinked adult and a different phone. Revoke the relationship and retry the previous session.
Expected: Only supported patient-scoped access is granted while authorization is valid. Revocation removes delegated access. None of these identities gains staff-only clinical/payment management rights.
Steps: Select guardian routing without a guardian email; disable consent or use an invalid phone. Inspect all channel recipients and message bodies.
Expected: No silent fallback to the child/unintended adult occurs. Missing contacts are skipped/blocked truthfully. No diagnoses or medical notes leak into ordinary appointment notifications.
Prerequisites and fixture: Use the HRS zero-buffer fixture on future D. Keep two browser profiles open on the same free slot. For every successful booking record appointment ID, patient ID, offering ID, exact UTC start/end, clinic-local display time and notification event IDs.
Steps: Open Book appointment, choose Consultation QA, A, Dr Alex QA and D 10:00; choose Alex’s registered profile, review and confirm once.
Expected: One confirmed appointment is created for the exact selected offering and patient. End is 10:30; price is ₹500 if no override. It appears in calendar, appointments, patient history and doctor schedule.
Steps: Open the clinic public link signed out, choose a valid slot and enter permitted patient/guardian details. Review and explicitly confirm.
Expected: One booking is created with correct source, patient/contact, time and offering. Ticket shows reference and supported actions. Only safe public data is returned.
Steps: Select a service and slot but leave before confirmation. Separately submit a create request with confirmed=false/missing.
Expected: Selection is not a reservation or booking. Missing explicit confirmation is rejected; no patient side effect, appointment or notification remains from a failed transaction.
Steps: Test one active provider, one service and one location, with inactive alternatives present.
Expected: Sole eligible choices may be automatically selected and remain visible in summary. Time selection and final confirmation are still required; inactive alternatives do not affect eligibility.
Steps: Run fixtures with 1, 2, 6 and 20+ providers and with 5/6 services. Test auto scale and explicit solo/small/medium/large settings. Search doctor/department where shown.
Expected: Layout adapts without losing valid services/providers. The current date-based flow and its search thresholds remain usable; a hidden redundant selector must not hide required choices.
Steps: Switch month grid/strip, previous/next month, date, provider and location. Compare available/limited/unavailable colors with actual returned slots.
Expected: Selected date and slots agree with server availability. A late response for an old filter cannot overwrite the active selection. Month badges never promise slots absent from the selected day.
Steps: Choose a fully occupied week. Use Find next available where exposed; page the next window and clear filters. Inject one availability failure.
Expected: No phantom slots appear. Broader search uses bounded server windows and jumps to returned availability. Retry is actionable; doctor-first discovery retains the chosen doctor where that component is used.
Steps: Before and after save compare patient name/number, service, doctor, location, date/time, duration and effective charge. Inspect the appointments list and drawer.
Expected: Correct patient name and contact are visible to authorized staff, including for portal bookings. No stale summary from a previous slot or patient is submitted.
Steps: In two independent profiles select D 11:00 before either confirms. Submit simultaneously with different request keys.
Expected: Exactly one booking succeeds. The loser receives a conflict and can choose another slot. Failed creation leaves no extra patient/outbox record; no overlap is persisted.
Steps: Double-click Confirm. In a controlled network fixture lose the response after server commit and retry the same request key; then replay that key with different data.
Expected: Same-action replay yields one durable appointment/event. Reusing a key for changed intent is rejected. Refresh resolves uncertain outcome without creating another appointment.
Steps: Select a slot, then have another staff member block it, archive its offering or increase lead time before confirmation. Attempt to confirm the stale selection.
Expected: The server rechecks current catalog, schedule and policy inside the transaction. Invalidated selection fails without partial writes; the interface refreshes choices.
Steps: In an authorized test API client add end time, duration, price, source, staff role or an unauthorized existing patient ID to a create request.
Expected: Strict request boundaries reject unsupported fields; role comes from the verified session. Server derives end, pricing and access. No privilege escalation or price override succeeds.
Steps: Disable the booking portal/creation route in settings. Open long URL, short link and direct public create API; then restore.
Expected: The supported disable switch is enforced at all public entry points. Staff availability remains governed by staff permissions; direct API cannot bypass disabled public creation.
Prerequisites and fixture: Use separate visits for status transitions. For completed/no-show checks create a visit whose start has passed using a controlled clock fixture; do not change the workstation clock.
Steps: Switch supported calendar views, move dates, apply filters and open an appointment. Compare its patient/provider/time with the list.
Expected: Calendar and list refer to the same durable booking; supported view/date/filter state stays coherent. Empty days are distinct from loading or API errors.
Steps: Filter by appointment date, doctor and each status. Search patient name/number. Page results, clear filters and reopen a record.
Expected: Results and counts match the chosen filters without mixing doctors/dates. Appointment list does not use an amount-paid editing field as part of appointment scheduling.
Steps: Open from calendar, list, patient history and Doctor Workspace. Visit Consultation & Clinical Records, Treatment Cost & Payments and Summary & Notes; use Back and Edit.
Expected: All entry points open the same appointment and patient. Tabs retain the right context; edit does not overwrite unrelated records. Back returns to a useful originating view.
Steps: Select Dr Alex QA, move day and ±15-day range, use Today and refresh. Compare date counts and daily list with the calendar.
Expected: Only selected doctor/day records appear. Counts and list agree with the backend clinic-day query; switching doctor cannot leave the prior doctor’s records visible as current.
Steps: Search patient, phone and service. Use All, Follow-ups, Confirmed, Completed and Cancelled filters; open a consultation.
Expected: Each filter/search returns appropriate visits. Follow-up markers reflect explicit treatment linkage; opening a result keeps the selected patient/appointment identity.
Steps: For a started confirmed appointment click Complete, review confirmation if offered, and refresh all views.
Expected: Visit becomes Completed once; it stops consuming future/reminder behavior as appropriate. History and configured completion notification update. Treatment-course completion is a separate decision.
Steps: For a started confirmed appointment mark No-show; compare with trying it before the visit begins.
Expected: Started visit transitions once with appropriate event/history. Premature finish/no-show is rejected server-side; no false status or notification appears.
Steps: Try completing cancelled/no-show visits, rescheduling completed visits and repeating a terminal action with the original and a different key.
Expected: The state machine rejects invalid transitions and safely handles replay. No duplicate terminal events, resurrected bookings or silent edits to historical occupancy occur.
Steps: Print a visit containing long patient name, guardian contact and notes from desktop and phone. Inspect print preview.
Expected: Correct appointment, clinic time and permitted summary content print legibly without clipped actions or unrelated patient data. Printing does not change status or record a payment.
Steps: Fail doctor list, daily schedule and appointment-detail requests separately; change doctor while an earlier request is pending, then retry.
Expected: Error/empty/loading states are distinct; no old response replaces the current doctor/day. Retry recovers without mutations or duplicate records.
Prerequisites and fixture: Enable a permitted customer cancellation policy, satisfy engine notice, and enable the intended notification event/recipient settings. Prepare separate confirmed appointments for patient, administrator and provider cancellation. Both patient and provider receipt are release acceptance requirements.
Steps: From Alex’s ticket/My Bookings use Cancel, confirm identity as required, enter reason if offered and explicitly confirm. Refresh staff views and notifications.
Expected: Booking becomes Cancelled, slot is released, patient and provider each receive the correct configured update once, and unsent reminders are suppressed. Cancellation leaves clinical and financial history intact.
Steps: As administrator open a confirmed booking, choose Cancel, enter reason and confirm once. Inspect calendar, My Bookings and both handsets.
Expected: Cancelled state, actor/reason and freed slot agree across views. Both patient and provider notification paths are verified independently; a patient-only send is a failure of this acceptance requirement.
Steps: From the appointment workspace cancel with a reason. First dismiss the confirmation; then confirm.
Expected: Dismissal makes no change. Confirmation cancels once and produces correct notifications/metadata. A queued message is not described as already delivered.
Steps: Try cancelling using another person’s phone/email, a mismatching guardian or another clinic’s appointment reference via the public path.
Expected: Verification fails without exposing sensitive appointment data or changing status. Correct appointment ID alone is insufficient authorization.
Steps: Run cancel versus reschedule, cancel versus complete and repeated cancel concurrently on separate fixtures.
Expected: A consistent valid final state wins; no moved-but-active cancelled booking or stale reminder remains. Notifications match committed state, with replay/conflict handled truthfully.
Steps: Cancel a visit with a ₹10,000 recorded payment and printable receipt. Reopen patient billing.
Expected: Cancellation does not delete or duplicate payments and must not imply an automatic refund. Ledger and receipt remain traceable; unsupported refund flow is recorded as a separate scope decision.
Prerequisites and fixture: Use a confirmed D 10:00 appointment and a free D 14:00 target for the same offering. Record appointment ID before moving it. Where changing provider/service is offered, repeat compatibility checks for linked treatment.
Steps: Open Reschedule, select an exact returned target, review and confirm. Reload staff/public views and both recipients’ logs.
Expected: Existing appointment ID moves from 10:00 to 14:00; it is not a second booking. Original occupancy is freed, target becomes occupied, history and notifications record the change.
Steps: From My Bookings choose Reschedule for the selected visit, select a free time and confirm with required verification.
Expected: The reschedule endpoint acts on the selected appointment, never generic create. Patient, guardian and treatment links remain correct; notice and availability rules apply.
Steps: Select one or more offered slots in the proposal flow and send to the designated test contact. Open the proposal link without accepting.
Expected: A pending proposal and history exist; original appointment remains unchanged. The message/link lists proposed choices accurately and does not claim a confirmed change.
Steps: Choose one offered slot through the actual patient link and confirm once. Inspect history, original/target availability and patient/provider notifications.
Expected: Target is revalidated at acceptance. Exactly one reschedule commits; both sides receive the correct final time and obsolete reminders are suppressed.
Steps: Send a new proposal on a separate appointment; decline it and reopen the link/history.
Expected: Proposal shows declined; original appointment/time remain unchanged. A decline is not a cancellation and must not produce a confirmed-new-time message.
Steps: After proposing a target, book that target with another patient, then accept the proposal.
Expected: Acceptance fails safely without double booking or losing the original appointment. Interface offers recovery and does not report confirmation.
Steps: Open a random token, a deliberately expired fixture and a previously accepted/declined token. Try an unoffered slot and duplicate acceptance.
Expected: Invalid/outdated/terminal proposals cannot be applied. Replays cannot create another move or notification; unoffered or unauthorized targets are rejected.
Steps: Reschedule an explicitly linked treatment visit. Where allowed, change service/provider and reopen its treatment panel and payment routes.
Expected: Compatible reschedules preserve the link. Incompatible links are flagged and financial controls cannot act on another patient/provider/service’s account. No silent reassignment of a paid treatment occurs.
Steps: Move a visit while its notification transport fails. Inspect history, logs and retry controls.
Expected: The saved reschedule/history remain durable. Notification failure is separate from the business result; retry sends the appropriate event without moving the visit a second time.
Prerequisites and fixture: Open a registered patient’s appointment → Consultation & Clinical Records. Use fictional clinical text. Clinical-management endpoints are staff-only in this implementation; a doctor selector is not itself a user-permission boundary.
Steps: Enter diagnoses, prescriptions and medical notes on Alex’s appointment. Save once; reload appointment and patient page.
Expected: Entry is linked to the correct patient and appointment with author and timestamp. Saved content survives reload and is visible in the patient’s longitudinal history.
Steps: Save known allergies with a reaction; later add an entry marked Not reviewed; finally add an explicit No known allergies reported review on a separate test patient/fixture.
Expected: Known requires allergy text. Not reviewed must not erase the last explicit review. Latest explicit review and its provenance drive the displayed summary; no assumption of no allergies is made from blank data.
Steps: Try an entirely blank entry, known allergy without details and one character beyond each field limit via API.
Expected: Blank/invalid entry is rejected. Limits: diagnoses 10,000; prescriptions 10,000; allergies 5,000; medical notes 20,000 characters. No partially written entry remains.
Steps: Save one entry, add a second correcting it, then simulate response loss and retry the second using its same UUID entry key.
Expected: Correction is a new attributed entry; the original remains intact. A retry cannot duplicate the same clinical entry. Failed save retains the draft for review/retry.
Steps: Give Alex two appointments and Jordan one. Open clinical history from each and change patient rapidly during loading.
Expected: Alex’s history spans only Alex’s visits with correct appointment labels; Jordan’s entries never appear. Failed load shows an error and Retry, not No clinical records.
Steps: Request clinical history/add-entry endpoints as signed-out public user, verified patient/guardian and clinic B staff. Inspect public payloads, logs and ordinary reminders.
Expected: Staff authorization and module scope are enforced; sensitive clinical text is absent from public booking results and routine communications. Doctor-specific access restrictions require separate configured-role verification.
Prerequisites and fixture: Open Settings → Services → Treatment types. This catalogue and pricing UI are present in the current working tree and must be verified against the actual deployed build. Use Dental Implant QA (fixed ₹50,000), Orthodontic QA (range ₹40,000–₹60,000), and Assessment QA (After assessment). Keep recall registry entries separate from billing treatment courses.
Steps: Create the three fixture treatment types with currency INR and scope/inclusions/exclusions in Treatment details. Save each and reload.
Expected: Fixed estimate has one amount; range has ordered min/max; After assessment stores no guide amounts. All details persist in the catalogue without creating a patient course or payment.
Steps: Try blank name, case/space duplicate, name >200 characters, description >4,000, negative/overprecision amounts, maximum below minimum, invalid currency and After assessment with numeric API estimates.
Expected: Invalid/duplicate values are rejected. Amounts use nonnegative two-decimal values up to 9,999,999,999.99 and currency is three uppercase letters; unsupported monetary precision is a documented limitation.
Steps: Search by name; edit an unused type, archive it, toggle Show archived and restore.
Expected: Search and archive filters work; archived types are unavailable for new patient agreements. Restoring preserves identity and makes the active type selectable again.
Steps: On an unbilled appointment open Treatment Cost & Payments → Add treatment from catalogue. Select Dental Implant QA; inspect loaded details; save base ₹50,000, addition ₹5,000, discount ₹2,000 and reason QA agreed adjustment.
Expected: Name, description, guide estimate and currency load from the chosen type. Agreed price is ₹53,000; the appointment is explicitly linked to one new course with the correct patient, provider and service.
Steps: Try surcharge, discount, base outside guide range and a total below zero. Repeat without reason, then with reason. Test ₹0.10+₹0.20 exactly.
Expected: Increase/discount/out-of-guide changes require a reason; negative total is rejected. Two-decimal arithmetic is exact. Range/on-assessment agreements require an explicit chosen base, not an assumed range midpoint.
Steps: Choose Adjust price / discount, revise ₹53,000 to ₹51,000 with a reason, save and inspect Pricing history. Attempt to bypass it via the generic treatment-cost editor.
Expected: Each revision retains base, addition, discount, total, reason, actor and timestamp. Catalogue-derived price changes require the audited route; the generic cost route cannot silently bypass it.
Steps: Open the same course in two tabs. Save a revision in A; in B submit its stale expected revision.
Expected: A persists; B receives a conflict/reload requirement instead of overwriting A. Pricing history and financial totals remain consistent.
Steps: Record ₹10,000 against the course. Try setting total to ₹9,000 and changing payment currency via a bypass request.
Expected: Price below amount received and inconsistent currency are rejected. Existing receipt/ledger stay unchanged; error does not create a new pricing-history revision.
Steps: After creating the patient course, rename/edit/archive its catalogue type and change its guide price/details. Reopen the patient course.
Expected: Saved patient agreement retains its catalogue snapshot and pricing history. Changes affect future selection, not an already agreed amount or description.
Steps: On another visit enter New treatment name and Start treatment. Configure its cost/plan through the supported payment view.
Expected: One explicitly named course is created. It does not fabricate a catalogue snapshot or use catalogue revision controls that require one.
Steps: Book a second compatible visit for Alex without choosing a course. Inspect billing, then select the intended ongoing course and Link treatment.
Expected: No automatic enrolment occurs merely from matching patient/doctor/service. After explicit link the follow-up shows the same course billing account, cost, paid and balance once.
Steps: Try linking a course for another patient, provider, service or clinic. Try linking a visit that already has independent cost or receipts.
Expected: Mismatch is rejected; the UI hides unsafe financial controls for an incompatible existing link. Independent visit billing must be reconciled before linking; nothing is silently merged.
Steps: Change Ongoing to Paused/Completed, then attempt to link a new visit; return it to Ongoing and retry.
Expected: Inactive courses cannot receive new linked appointments. Status changes persist and retain prior visits/ledger. Completing a visit alone does not automatically complete the entire course.
Steps: Fail the treatment-context/catalogue request, retry, and switch appointments while loading. Cancel an unsaved pricing form.
Expected: Error/Retry is distinct from no linked treatment; stale content cannot be used for another appointment. Cancelling creates neither course nor price revision.
Prerequisites and fixture: Use an independent ₹50,000 treatment account for the exact ledger below; do not reuse the ₹53,000/₹51,000 catalogue arithmetic fixture without resetting expected values. Open Manage cost, payments & instalments from the appointment or patient page. Financial actions are distinct from sending notifications.
Steps: On a supported treatment with an estimate click Send estimate once. Inspect message event, patient handset and ledger.
Expected: Correct treatment estimate/range/currency is communicated if queued and delivered. No payment or receipt is recorded. If no message is queued the UI must not claim it was sent.
Steps: For a non-catalogue course set cost ₹50,000, currency INR, instalment plan of 3 and bill-send option. Save and reload.
Expected: Agreed cost=₹50,000, paid=₹0, balance=₹50,000, status unpaid, plan count=3. Bill-send outcome is separate from cost-save success.
Steps: Record ₹10,000 by UPI with unique test reference QA-P1, label Deposit and a note. Enable receipt. Save once and inspect all views.
Expected: One immutable ledger record/receipt has before=₹0, after=₹10,000, remaining=₹40,000 and instalment 1. Correct method/reference, patient, clinic and treatment appear.
Steps: Record ₹15,000 by card (QA-P2), then ₹25,000 by bank transfer (QA-P3). Open each receipt and patient totals.
Expected: After P2: paid ₹25,000/balance ₹25,000. After P3: paid ₹50,000/balance ₹0 and fully_paid. Receipt numbers are unique, history retains its own before/after values, and totals match exactly.
Steps: On separate fixtures exercise cash, card, UPI, bank transfer, online and cheque. Supply and omit optional reference/label/note.
Expected: Supported methods and entered details persist exactly. Recording method online is not proof that a real payment gateway captured funds; bank settlement evidence is separate.
Steps: Try zero, negative, nonnumeric, excessive decimal, above-balance and payment-before-cost on isolated accounts.
Expected: Zero/negative/nonnumeric amounts must fail. For overpayment, precision and payment-before-cost, compare actual behavior with the documented implementation notes below and obtain the business decision before sign-off; no silent unexplained money adjustment is accepted.
Steps: In a controlled fixture lose response after commit, double-click Record payment, and submit two payments concurrently from separate tabs. Compare ledger/counts with the original baseline.
Expected: Every real intended payment appears once; replay/duplicate uncertainty is resolved before any resend. Concurrent totals cannot lose an update. Missing idempotency or transaction protection is a release defect, not an assumed guarantee.
Steps: On a course with two explicitly linked visits record one ₹10,000 payment from the follow-up; inspect both visits and the patient summary.
Expected: Both visits reflect the same billing account; the ledger has one payment and the patient total counts the course once. Receipt attribution retains the requesting visit context where supported.
Steps: Record one payment with WhatsApp receipt unchecked. For another enable receipt and force transport failure. Reopen payment history.
Expected: Both real payments persist once. Unchecked suppresses send; failed send is visibly separate from saved money. Never re-enter the payment to resend its message.
Steps: Open View / Print Receipt from ledger; inspect patient, provider, clinic, currency, method, reference, instalment and historical balance. Reload and print on desktop/phone.
Expected: Correct stable receipt renders legibly and matches that payment’s snapshot. Public visibility is limited to the explicitly approved receipt-sharing design; execute SEC-004 before release.
Steps: Give Alex one shared course with two visits and one independent treatment. Open Patient Management → Payments & Billing, refresh and select each plan.
Expected: Total cost, cumulative paid, balance, count and ledger reflect distinct accounts once, not each linked visit. Each Manage plan action opens the intended account.
Steps: Fail patient-payment summary and appointment payment-summary requests separately, then retry.
Expected: Failure is visible; available appointment data is labelled as fallback rather than a complete ledger. Empty-history and fully-paid claims are not inferred from request failure.
Prerequisites and fixture: Open Reviews & Recalls. Prepare one prior completed patient, one active recall-registry treatment, one paused/completed registry treatment, a patient without a mobile and a second clinic’s patient. The recall registry and appointment billing courses are separate records; test each explicitly.
Steps: In the treatment registry select patient, service, optional provider, start/end or duration, recall interval, treatment name, notes and status. Save and reload.
Expected: Exactly one registry link exists with the chosen interval/date/status. It does not automatically create a billing course, charge, appointment or message.
Steps: Try invalid/foreign references, zero/negative interval and duration beyond 120 months. Remove a disposable registry link.
Expected: Invalid values/references are rejected. Removing a recall registry link does not delete the patient, clinical history, actual treatment ledger or prior appointments.
Steps: Filter by provider, service and branch; compare treatment_registry and previous_booking sources. Include different statuses and duplicate-eligible patients.
Expected: Eligibility and displayed selection match the intended cohort; patients are deduplicated by identity for the campaign. Cross-clinic records are excluded; paused/completed handling is explicitly verified.
Steps: Select a subset, set visit date/title and create campaign. Inspect list and detail before Dispatch.
Expected: Campaign, selected recipients and counts persist. Saving a campaign alone does not claim handset delivery or book visits.
Steps: Enable configured sender and approved follow-up template. Dispatch selected campaign once; inspect per-recipient events and test handsets.
Expected: Each eligible selected recipient has a traceable result. Consent/missing contacts and template failures are visible. Repeated dispatch does not silently send duplicate invitations.
Steps: Reply YES from an invited test phone. Open returned booking link, select an actual available slot on the visit date and confirm.
Expected: Acknowledgement supplies the correct patient-scoped link. YES alone is not a booking. Confirm creates one actual appointment through engine validation and updates campaign/booked counts.
Steps: On separate recipients reply NO and a natural-language preferred time. Inspect replies, campaign state and calendar.
Expected: NO records decline without booking. Preferred-time response is a request, not a confirmed appointment. Reply-template failures do not silently discard the recorded response.
Steps: Reuse a booked token, tamper with token/offering/start and have another patient take its displayed slot before confirmation.
Expected: No duplicate or unauthorized appointment is created. Server validates patient, module, offering and current availability; failed acceptance leaves truthful campaign state.
Steps: Inspect total, confirmed, declined and booked counts after each response and duplicate inbound webhook. Reload campaign list/detail.
Expected: Counts reconcile with individual recipients and bookings without incrementing twice on replay. Missing/failed recipients remain visible for investigation.
Steps: Create a visiting-specialist record with provider, optional service/branch, date/date range and hours. Test immediate send off, then on with a selected cohort.
Expected: Visit metadata and selected cohort persist; only requested notifications send. Announcing a visit does not itself create provider working hours, assignments or appointments unless explicitly implemented and verified.
Steps: Try impossible dates, end before start, past visit date, invalid start/end time and a clinic-day crossing UTC midnight.
Expected: Invalid inputs fail clearly rather than creating misleading campaign availability. Recall slots correspond to the advertised clinic-local visit day; UTC-day slicing must not exclude valid early/late local slots.
Prerequisites and fixture: Complete the linked WhatsApp setup/testing guide first. Enable intended events and channels; map approved compatible templates and prepare separate patient, guardian and provider handsets. Treat each recipient/channel/event combination as its own execution row.
Steps: Toggle patient email, staff email, in-app and each event preference independently. Save/reload; perform an enabled and disabled event.
Expected: Preferences persist independently and govern newly captured event recipients/channels. Disabled events do not falsely claim delivery. Staff email targets configured clinic email, not necessarily provider mobile.
Steps: Execute the event/recipient matrix in section 5 below and every W/T/N case in the WhatsApp tester guide. Inspect exact name/language, parameter order and filled values.
Expected: Every required active workflow uses its compatible approved contract. Draft mappings do not alter live sending. Unsupported extra/reordered placeholders are not represented as active.
Steps: Create one staff booking and one public booking with both recipients enabled. Inspect separate patient and provider notification records and handsets.
Expected: Both recipients receive correct confirmation once. Provider delivery must be proven independently; patient receipt alone is not a pass. Missing provider contact produces a truthful reason.
Steps: Open a confirmed appointment reminder preview and Settings → Communications → Logs; filter appointment_reminder and inspect scheduled time, body, parameters and recipient.
Expected: Reminder text, effective template values and scheduled time are inspectable. Preview is not proof of dispatch, and logs must remain readable even if the eventual send fails.
Steps: Enable 2 days/24 hours/2 hours/30 minutes or the configured custom set. With a controlled clock run before, at and after each due time, then run the scheduler again.
Expected: One eligible reminder per appointment-time/lead-time is created/dispatched. Repeat runs do not duplicate. Pending/in-flight/status timestamps distinguish scheduled from delivered.
Steps: Before reminders send, cancel, reschedule, complete or mark no-show on separate appointments; also disable delivery and make a reminder >15 minutes late.
Expected: Obsolete or disabled reminders are skipped; >15-minute-late reminders are skipped rather than sent late. New-time reminders use the rescheduled snapshot. In-flight transport outcomes are investigated separately.
Steps: Create with no consent; then test STOP/UNSUBSCRIBE and START/RESUME from a consenting phone. Repeat against the other clinic sender.
Expected: No-consent/opted-out ordinary sends are suppressed. Preference is scoped to sender/recipient and survives acknowledgement failure. START resumes only the intended sender’s permitted messages.
Steps: Observe queued, sending, accepted, delivered/read, failed, blocked, skipped and unknown outcomes using controlled fixtures. Try retry on definitive failure and unknown.
Expected: Accepted is not delivered. Known failures expose safe supported retry; unknown outcome cannot trigger blind resend. Status must not regress on out-of-order callbacks; no unrelated patient data appears in error logs.
Steps: Enable clinic/patient email and in-app. Test with transport disabled, simulated, accepted and failed; inspect real test inbox separately.
Expected: Queued/simulated is not delivered. In-app persistence and email-provider acceptance are recorded separately. Success does not assert inbox receipt without evidence; successful channels are not requeued on another channel’s retry.
Steps: In an integration fixture send invalid signature, duplicate receipt, out-of-order status and early callback for a known event/attempt.
Expected: Invalid callbacks cannot mutate delivery state. Valid callbacks correlate to the correct sender/event/attempt; duplicates do not create business actions or regress terminal status.
Steps: Create sender/template links and mapping drafts in staging. Run a non-WhatsApp test, a WhatsApp test and synthetic login; reopen configuration.
Expected: No runner silently replaces clinic communication settings or strands templates. Configuration isolation survives module tests and repeat runs; source/target accounts never mix.
Prerequisites and fixture: Open Settings → Assistant Rules, Booking Portal and Payments. A saved setting or connected badge proves configuration only; it is not evidence that the downstream integration works.
Steps: Set assistant name, exact help reply, location/landmark, offline-payment text and booking/service notes. Ask the actual connected agent the corresponding questions.
Expected: Saved rules are used coherently for this clinic. No unrelated module prompt/configuration is overwritten; unsupported or uncertain answers do not invent availability, charges or clinical advice.
Steps: Test redirect-to-portal enabled/disabled. Ask to book, change and cancel; omit explicit confirmation and try an unoffered time.
Expected: Assistant uses the supported route/shared engine and exact offered slots. No mutation occurs without explicit confirmed intent and required patient verification; no invented slot is booked.
Steps: From unverified/mismatching and valid customer identities ask for existing appointments, reschedule and cancellation. Repeat as verified guardian and after revocation.
Expected: Patient-specific verification is enforced independently of conversational claims. No prompt can claim staff privileges or disclose another patient’s appointments/history.
Steps: Set title, subtitle, contact phone, hero URL, logo and greeting; upload/replace/remove logo. Save/reload public link and short link.
Expected: Branding and greeting appear where supported without broken layout, script execution or cross-clinic images. Invalid upload/URL has a visible recoverable error.
Steps: In Payments configure merchant name, UPI IDs and message format; preview/print QR and save/reload. Test multiple IDs and invalid entries.
Expected: QR decodes to intended test merchant/UPI details and amount/reference if configured. Invalid entries are rejected. QR display/scan alone must not mark treatment money received.
Steps: If gateway checkout is connected for Booking, use sandbox keys; test success, decline, abandoned checkout and duplicate signed callback. Otherwise record configuration-only scope.
Expected: Only verified sandbox success records the intended payment once. Invalid callback cannot mark paid. If Booking checkout is not implemented, mark blocked/unsupported; a gateway settings panel is not a successful integration test.
Steps: Using a dedicated test calendar, link account, select calendar and enable push if supported. Create, move and cancel a visit; revoke token and retry.
Expected: Record actual event IDs and create/update/cancel behavior. Connected badge is insufficient. External busy-time conflict protection remains unproven until its sync policy and tests are implemented.
Steps: Copy/Open the long/short URLs, verify clinic target, simulate an invalid/deleted module, and revisit after sign-out.
Expected: Links resolve to the intended enabled clinic or a clean unavailable state. No admin-only context or credentials are embedded in copied links.
Steps: Test saved buzzer volume/tone and preview, including denied audio/autoplay and a new booking alert if supported.
Expected: Preview reflects settings without changing bookings. Browser audio restrictions are handled gracefully and do not suppress the visible booking record/notification.
Prerequisites and fixture: Use only authorized staging records and a controlled API/network fixture. These are acceptance requirements; source review alone does not prove that they pass.
Steps: Inspect anonymous catalog, availability, patient lookup, My Bookings, recall and proposal responses, including network payloads rather than only rendered text.
Expected: Public APIs return only the data required by their authorized workflow. No clinical history, internal schedule/occupied intervals, full contact lists or unrelated patients leak. Phone-only lookup needs explicit security review before being accepted.
Steps: Run a role matrix for owner/admin, receptionist, provider, unrelated member and signed-out user through direct URLs/APIs. Change provider dropdown as each role.
Expected: Actual configured permissions, not tab visibility, enforce access. Current Doctor Workspace uses staff management access; provider-only isolation must not be inferred from selecting a doctor.
Steps: Alter module/patient/offering/course/campaign IDs and proposal/recall tokens in read/write requests; supply body access claims and mixed-clinic references.
Expected: Authorization is server-derived and object-scoped. Missing/foreign objects fail without useful enumeration or partial writes. Valid token permits only its intended workflow and recipient.
Steps: Try valid receipt links, a mistyped number, a modified or enumerated receipt reference and the same reference under another module URL in controlled staging. Inspect returned fields.
Expected: Receipt sharing must match an explicitly approved privacy contract with adequate access protection. If guessable or improperly scoped receipt references expose unrelated patients/financial details, file a release-blocking defect; do not mark public access safe simply because the route exists.
Steps: Enter HTML/script-like text, quotes, emoji, Unicode and long strings in patient names, notes, category, treatment details and campaign title. Inspect page, print, messages and errors.
Expected: Content is treated as text where appropriate; no executable script, broken SQL, leaked stack trace or corrupted layout. Field limits still apply; data remains bound to its patient/module.
Steps: Interrupt availability, patient save, create booking, cancel, clinical save, price revision and payment recording at pre-submit and post-commit stages. Reload and reconcile IDs/counts before retry.
Expected: No false success or silent data loss. Actions with idempotency reuse their original key; payments with uncertain outcomes require ledger reconciliation. A failure cannot be retried by blindly creating duplicate business records.
Steps: Create/login to staging module A, then provision/login to B while A is active. Run test fixtures and inspect both modules and settings.
Expected: Each operation names its intended account/module. No active-browser session causes B to inherit A’s configuration or customer records. Runner metadata and results are correctly scoped.
Steps: At 360px phone width and desktop, use keyboard only for booking, patient selection, dialogs, date/slot choice, pricing and payment. Check focus, Escape, errors and scrolling.
Expected: Actions remain reachable; dialog focus is coherent, labels/errors readable and modal content scrollable. Primary save/confirm cannot be clipped or triggered accidentally by unrelated form submission.
Steps: Use 100+ patients, many appointments, 20+ providers and overlapping searches; measure list/search load against the agreed target. Rapidly change filters/date and resolve older responses last.
Expected: The correct current result wins. Lists/search remain operable and complete according to paging rules; define measured performance thresholds before declaring a performance pass.
Steps: Correlate actor/time/IDs for booking, cancel, clinical entry, pricing revision, payment and campaign. Remove only designated disposable fixtures after preserving results.
Expected: Evidence explains each committed change. Cleanup preserves configuration links and non-test history; incomplete cleanup is documented without resetting a shared staging module.
Prerequisites and fixture: Use two branches, two family members sharing a controlled number and one existing appointment. The Walk-ins view embeds the shared booking portal with arrivalType=walk_in; it is not a separate capacity or queue-override engine.
Steps: In Walk-ins select location A and scan its registration QR using a separate phone. Then select B and scan the new QR. Complete registration in each.
Expected: QR target contains the correct module/branch. Patient registration source and branch match the scanned context; a branch URL cannot assign a foreign module branch.
Steps: Use Find Patient with patient number and a 10-digit mobile, select Jordan QA explicitly, choose a valid provider/service/slot and confirm.
Expected: The existing patient ID is retained; one booking is created with walk_in arrival type. Correct walk-in workflow/contact is used, and calendar/doctor/patient views show the visit without duplicate registration.
Steps: Switch registration branch, inspect recent patients, select one, then Back to Walk-in Queue and search another. Fail the recent-list request once.
Expected: Recent list is scoped as designed; Back does not save an appointment. A failure must not misleadingly imply that no one registered; it has recoverable visible feedback rather than silently emptying the queue.
Steps: Try to book a walk-in into an occupied slot and outside provider hours. In another session take a walk-in selected slot before confirmation.
Expected: Walk-in does not bypass shared availability/conflict policies. Rejection preserves the selected patient and allows a valid new choice; no phantom queue position or overbooking is created.
Steps: In the public portal use correct and mismatching phone/email to find appointments; include same-number family records and a reference from clinic B. Open the selected visit for change/cancel.
Expected: Only explicitly permitted results are returned; chosen patient/appointment is unambiguous. Phone/email matching limitations are documented and reviewed under SEC-001; lookup must not expose clinical history or grant staff rights.
Prerequisites and fixture: Create future confirmed appointments with buffers, one completed appointment and one cancelled appointment. Keep original service/provider/location snapshots and schedule before attempting changes.
Steps: Reduce a provider working period so a future appointment including buffers no longer fits. Open the impact preview before save.
Expected: Preview lists exact affected future appointments and reasons and performs no writes. Existing booking times, outbox, service details and hours remain unchanged until an allowed save.
Steps: Attempt to archive a referenced provider/location/offering or remove its membership. Try both UI save and a direct authorized configuration request without preview.
Expected: Guarded save rechecks under the booking lock and rejects an unresolved impact with BOOKINGS_AFFECTED/409 as applicable. A hidden button or omitted preview does not bypass protection.
Steps: From the impact panel explicitly reschedule one affected booking and cancel another through shared actions. Then save the configuration edit again.
Expected: Only confirmed resolution actions change bookings and emit their events. Proposed hours are not active until the final configuration save. Failed resolution retains unresolved impact and requires retry/recheck.
Steps: Obtain a clean preview, then create a newly affected appointment from another session before saving the configuration change.
Expected: Save detects the new conflict rather than trusting stale preview. No confirmed booking silently becomes invalid, disappears or changes time.
Steps: Change service duration, price and buffers after a future booking is saved. Inspect that booking and new availability/booking.
Expected: Existing booking retains original duration, effective price, buffers and occupied interval. New bookings use new effective values. Historical completed/cancelled records remain intact.
Steps: For an explicitly shared organization provider, add leave or conflicting schedule changes in another module and test existing/new bookings across both.
Expected: Shared identity conflicts are checked across modules under the provider boundary. No equal-name heuristic is used; exact affected-booking and safe-resolution behavior is verified across linked modules.
These notes come from source inspection on 4 November 2026. They identify what the test must resolve; they are not a substitute for execution on the selected build.
| Area | Current evidence / boundary | Required disposition |
|---|---|---|
| Treatment catalogue and pricing | Present in the working tree, including new components/routes/schema changes; not assumed deployed | Record commit/migration status and run TRT cases on the deployed build before claiming support |
| Existing patient access | Public patient lookup currently accepts a mobile query; portal supports family selection | Review returned fields and proof of phone possession. Do not infer strong patient authorization from entering a number |
| Public receipts | Public receipt routes look up a receipt number; one route is not tied to the module path in the lookup call | Execute SEC-004. Decide receipt-sharing access protection; exposing unrelated receipts is a release blocker |
| Doctor Workspace | Current backend requires staff with booking-management access; selecting doctor filters the view | Verify actual role restrictions; do not describe it as provider-only security without implementation evidence |
| Payment above balance | Payment service currently clamps remaining balance to zero and can accumulate more than total cost | Define whether overpayment is blocked or explicitly tracked as credit; test the approved behavior rather than assuming rejection |
| Payment before cost | Current service raises an unset/nonpositive total to the incoming payment amount | Confirm that this is intended. UI/receipt must not silently misrepresent the agreed treatment cost |
| Payment duplicate/concurrency safety | Booking actions have explicit idempotency keys; payment recording does not visibly use the same contract | PAY-007 is a release gate. Do not claim duplicate-safe payment capture without real evidence |
| Money precision | Core offering contracts use minor units; treatment catalogue/pricing currently uses two-decimal values | Test conversions at each boundary. Catalogue multi-currency precision beyond two decimals is not established |
| Cancellation policies | Engine notice checks and customer creation-window/pending policy controls coexist | Execute POL-005/006/007 for each path; obtain a single explicit behavior contract if they disagree |
| Notifications to doctor | A provider profile number and a working patient message do not prove all provider workflows | Prove appointment confirmation and both cancellation sources on separate provider handset/log evidence |
| Reminder visibility | Preview/log functionality exists in source | Verify deployed UI exposes body, parameters, due time and correct recipient; rendering only status is insufficient |
| Template mapping | Custom mappings are saved as drafts; live delivery uses supported ordered contracts | Extra/reordered fields remain draft scope until sender support is implemented and tested |
| Recall registry vs billing course | Separate models and controls | Do not infer registry membership from a billing course or merge their statuses/financial totals |
| Gateway configuration | Settings exist; end-to-end Booking checkout requires independent proof | Sandbox execution or an explicit unsupported capability record; never use real money for QA |
| Google Calendar | A configuration/connection UI is present; external busy-time conflict guarantees need a sync policy | Prove each supported push action independently; do not claim external conflict protection from Connected |
| Deferred scheduling | Rooms/equipment, groups, waitlists, recurring series and multi-provider bookings have no established scope here | Record as out of scope unless separately specified; do not create fictional successful tests |
| History/delete/refunds | Delete controls are visible; audit-retention and refund workflows need explicit verified behavior | Prove referential/history integrity; cancellation does not imply refund support |
Automate the real assertion boundary:
| Layer | Suitable assertions | Evidence limits |
|---|---|---|
| Pure unit | Runtime validation, money arithmetic, policy boundaries, message values, mapping compatibility | Cannot prove database atomicity, UI or handset delivery |
| Frontend component | Field behavior, disabled states, errors/retry, correct selected IDs, stale-response handling | Mocked backend results are not actual bookings/payments |
| Dedicated DB/API integration | Module authorization, actual rows, rollback, conflict locks, snapshots, durable outbox, course totals | Mocked Meta/email/gateway is not external delivery evidence |
| Browser end-to-end | Navigation, complete journeys, cross-view persistence, real API responses, signed-out flows | Still needs separate handset/provider evidence for outbound communications |
| Controlled live integration | Test sender delivery, actual callback correlation, sandbox gateway and dedicated calendar | Keep account IDs, timestamps and exact integration configuration with results |
Use two independent browser sessions/API clients for races. Synchronize requests at the server boundary; two sequential clicks do not prove concurrency protection. Fix time in controlled test code for boundary/reminder tests, and assert UTC instants plus clinic-local labels. Reuse the same idempotency/entry key only when retrying the same action; changed intent requires a new key.
Suggested source anchors for case owners:
| Area | Current implementation / existing verification anchors |
|---|---|
| Navigation and settings | frontend/src/components/modules/booking/bookingNavigation.ts, BookingManager.tsx, BookingSettings.tsx |
| Booking engine and contracts | src/lib/booking/engine.ts, contracts.ts, availability.ts, policy.ts; tests/integration/modules/booking.engine.int.test.ts, booking.transaction.int.test.ts, booking.lifecycle.int.test.ts |
| Catalog and guarded edits | src/api/routes/bookingCatalog.ts, src/lib/booking/configuration.ts, providerSetup.ts; BookingCatalogRoutes.test.ts, booking.catalog.int.test.ts |
| Patients and guardians | src/lib/booking/patientRegistry.ts, providerIdentity.ts; BookingGuardianRelationships.test.tsx, booking.guardian-access.int.test.ts, booking.provider-identity.int.test.ts |
| Clinical history | src/lib/booking/clinicalHistory.ts, ClinicalHistoryPanel.tsx; booking.clinical-history.int.test.ts |
| Treatment catalogue/courses | src/lib/booking/treatmentTypes.ts, treatmentCourses.ts, BookingTreatmentTypes.tsx, TreatmentPricingEditor.tsx; tests/unit/TreatmentCourses.test.ts |
| Payments and receipts | src/lib/booking/bookingPaymentService.ts, BookingPaymentTracker.tsx, PatientDetailsPage.tsx, frontend/src/pages/public/BookingReceiptPage.tsx |
| Cancellation/reschedule | src/lib/booking/bookingCancellationService.ts, bookingRescheduleService.ts; corresponding unit/component suites |
| Recall | src/lib/booking/patientRecallService.ts, PatientRecallManager.tsx, RecallSelfBookingPage.tsx; booking.recall-whatsapp.int.test.ts |
| Delivery and reminders | src/lib/booking/notifications.ts, whatsappDelivery.ts, whatsappReminderService.ts, transactionalWhatsApp.ts; BookingNotifications.test.tsx, BookingWhatsAppRegression.test.ts |
| Public exposure | src/api/routes/public.ts, bookingEngine.ts, frontend/src/components/modules/booking/BookingPortalView.tsx |
Existing test names are discovery aids, not claims of full coverage or current passing results. Read each test and map its actual assertions to case IDs. Keep uncaptured manual/integration assertions open even if a similarly named suite is green.
For engineering execution, use repository test commands and an explicitly isolated DATABASE_URL_TEST. Backend integration files must run sequentially (fileParallelism: false); they can destructive-migrate test schemas. Use the pure-unit configuration when only pure tests are intended. Frontend tests run from frontend with Happy-DOM/MSW. Do not start the full DB suite as part of merely reading or publishing this guide.
For each test execution capture:
| Field | Required value |
|---|---|
| Identity | Case ID + child variant, run ID, tester, date/time, deployed commit and environment |
| Scope | Account/organization/module, role, browser/device, clinic timezone |
| Fixture | Patient/booking/offering/course/campaign IDs and exact inputs; no secrets |
| Preconditions | Effective policies/hours, relevant settings/consent, initial statuses and financial baseline |
| Execution | Action sequence, request/entry keys, response status/error code and correlation IDs |
| Result | Expected result, actual result, Pass/Fail/Blocked/Not applicable/Not run |
| Durable proof | Reloaded screenshots plus API/authorized read-only record evidence for the relevant changes |
| External proof | Event/message IDs, channel/recipient role, callback timeline and masked test-handset receipt where required |
| Recovery | Retry performed, final reconciliation, settings restored, fixtures cleaned or retained |
| Tracking | Defect URL, severity, owner, retest result and explicit scope/acceptance decision if applicable |
A useful defect includes the exact trigger, expected/actual behavior, reproducible fixture, build, minimal masked evidence and downstream effects. Example: “CAN-002.provider-whatsapp: administrator cancelled appointment 123; patient delivered, provider has no captured event despite valid profile and enabled settings.” Do not report only “WhatsApp not working.”
Run a short smoke set for every build: ENV-001/002, BKG-001/009, APT-003, CAN-002, RSC-001, CLN-001, TRT-004, PAY-003 and COM-003/004. This does not replace full regression. Run the full affected area plus the main clinic journey after changes to patient identity, availability, billing, clinical access or delivery.
Release sign-off requires all applicable P0 cases, all main-journey steps and every required recipient/channel variant to pass with evidence. Retest fixed failures on the exact candidate build and review P1/P2 dispositions. No Not run or Blocked critical case may be counted as covered. Attach unresolved product decisions, integration limits and migration/deployment status to the release record. This document itself provides no execution or release approval.
The guide can be used immediately without screenshots. For illustrated navigation, capture the numbered states in the screenshot checklist. Start with the core set; add optional/error states after the underlying behavior is verified. Send images using the suggested filenames so they can be placed beside the corresponding section without guessing.
Use fictional patient/clinic content. Mask full phone numbers, email addresses, tokens, sender IDs, API keys and browser URLs containing access tokens. Keep visible labels, selected date/time, status and expected test amounts. Existing WhatsApp tutorial images can be reused where they still match the deployed interface; new handset images should show the specific missing patient/provider workflow evidence.
Help us improve the world of AI agents.
Have a custom workflow need? Our engineers are ready to help.