Nexaflow Editor
Implementation specification — 27 October 2026
Target project: /Volumes/Work/ai-studio/ai-agent-admin.
Provide an admin-operated configuration and testing area for customer accounts. Admins select a customer account, configure its WhatsApp/agent/module connections, and execute named test scenarios. The new screens and APIs must not expose the clinic's patients, bookings, clinical history, conversations, receipt contents or other operational records.
This specification is based on inspection of the existing admin React UI and Express server. It is not an implemented or deployed testing suite.
Add a sidebar group WhatsApp & Module Testing, with:
Expected implementation files:
server/src/routes/moduleTesting.ts: authenticated, admin-only endpoints.server/src/lib/ModuleTestingService.ts: ownership, metadata projection,
configuration validation and audits.server/src/lib/ModuleTestRunnerClient.ts: signed calls to the isolated runner.server/src/lib/ModuleTestCatalog.ts: versioned plans, cases and assertions.server/src/index.ts: register the new router without replacing existing routes.ui/src/pages/ModuleTesting.tsx: account/module settings and test workspace.ui/src/components/Sidebar.tsx and ui/src/App.tsx: navigation and route.Preserve the current uncommitted Account Replica and other admin changes. Do not build this feature by reusing the account export/replica or debug APIs: those have broader data access than the requested interface.
Display only the customer account identity and connection metadata required for administration: connected account ID, sender phone-number ID/display number, connection health and assigned agent. Never return access tokens, app secrets, refresh tokens or raw credential rows to the browser.
Admins can assign an already connected sender to the intended agent and enable its booking module link, after server-side validation that all assets belong to the selected account. Linking must be atomic and audited. Never silently move a sender already assigned to another agent.
Connecting a new Meta account still uses authorized Meta onboarding. Admin configuration cannot replace the account owner's required authorization or OTP. No interface for pasting arbitrary customer access tokens is required.
Expose only these configuration groups:
Use an explicit DTO/schema; never expose or write arbitrary module JSON. Update only the selected allowlisted paths, retaining unrelated customer configuration. Show a change preview and record admin identity, account/module IDs, changed field names and time in the configuration audit. Do not record secret values.
Top: selected customer account → module → test profile.
Tabs: Setup checks | Booking lifecycle | Finance | Incoming messages | Recovery | Run history.
Each case card shows:
The test profile contains tester-entered patient, guardian and doctor numbers, with explicit confirmation that they belong to consenting testers. It does not search or import customer contact records. Permit only configured test numbers for live dispatch; validate this on the server. Keep synthetic names and amounts fixed/versioned so comparisons are reproducible.
A single click starts the selected case. It may then wait for a genuine delivery receipt, handset reply or manual action. It must not manufacture a PASS while waiting. Run-all defaults to non-sending configuration checks; live cases remain explicitly selected operations with their recipient roles visible.
Run using account/agent/module metadata only. Check account ownership, sender linkage, required settings, template approval/language/parameter contracts, webhook subscription and server delivery gate. These are not proof of delivery.
Run the actual booking/payment/reschedule services against a dedicated test database and synthetic tenant. Never use production booking IDs, clone patient rows, or run the destructive integration-test setup against a customer's DB. Seed fixtures from versioned synthetic data and a sanitized settings snapshot. Serialize destructive database tests; namespace runs and retain cleanup status.
Business assertions include slot reservation/release, treatment linking, financial totals, idempotency and generated notification payloads. Returning a mocked WhatsApp success does not satisfy the live delivery assertion.
Use the selected account's authorized sender and approved templates, but only synthetic message parameters and approved test recipients. Token lookup and sending remain inside the application's trusted server boundary. Correlate each message/callback to a test run and step. Live test events must not create real patient, booking or payment records in the customer's module.
The runner combines isolated business assertions with live transport evidence when a case requires both. If the isolated runner, sender or template is missing, return BLOCKED with the missing prerequisite. Never substitute a simulation and mark the full E2E case passed.
The admin console requests tests; the booking application or a dedicated runner executes module behavior. Do not duplicate production booking algorithms in the admin app or spawn shell commands supplied by the browser.
The runner URL and credentials are server configuration, not editable request fields. Use authenticated requests, request IDs, bounded timeouts and idempotency. For signed requests, validate timestamp and nonce to reject replay. The runner must independently verify the requested account/module/sender association.
The request schema allows only account ID, module ID, catalog case ID, test profile ID and request key. It accepts no raw SQL, script, arbitrary URL, patient ID, booking ID, conversation ID or payment ID.
Runner responses have a strict allowlist: run ID, case ID, execution mode, status, assertion codes, timestamps and sanitized result evidence. The UI must not display raw SQL rows, provider payloads, stack traces or arbitrary runner response bodies.
All endpoints require existing authentication and requireAdmin middleware.
| Endpoint | Purpose |
| --- | --- |
| GET /api/admin/module-testing/accounts | Customer account selector metadata |
| GET /accounts/:accountId/configuration | Safe sender, agent and module settings metadata |
| PATCH /accounts/:accountId/modules/:moduleId/settings | Validate and update allowlisted settings |
| POST /accounts/:accountId/modules/:moduleId/linkage | Atomic account-owned sender/agent/module linkage |
| GET /catalog?module=booking | Versioned plans and cases |
| PUT /accounts/:accountId/modules/:moduleId/test-profile | Tester numbers and consent record |
| POST /accounts/:accountId/modules/:moduleId/runs | Start one allowlisted case |
| GET /accounts/:accountId/modules/:moduleId/runs | Sanitized run history |
| GET /accounts/:accountId/modules/:moduleId/runs/:runId | Sanitized step results |
Paths after the first row share the /api/admin/module-testing prefix.
Server-side ownership checks apply on every request, including reads and run
polling. Account/module identifiers from the browser are never trusted by
association alone.
| Group | Cases | | --- | --- | | Setup | Account ownership; agent/module link; sender; webhook subscription; delivery gate; approved templates and variable contracts | | Booking | Registration; walk-in confirmation; consented booking; availability conflict; reminder; reschedule proposal; confirmed reschedule to patient and doctor; cancellation; completion/no-show | | Finance | Estimate; bill on plan save; first instalment receipt; follow-up instalment; shared treatment counted once; unrelated treatment isolation; final settlement | | Incoming | Greeting and booking conversation; guardian recipient; STOP; START; recall YES/NO; reschedule secure-link confirmation | | Recovery | Missing template; rejected template; wrong language/count; disconnected sender; missing mobile; duplicate request; out-of-order callbacks; ambiguous timeout; worker restart; superseded reminder; receipt survives later appointment event | | Isolation | Another account's module/sender rejected; test recipients only; no operational data in API output; no production booking mutation | | Guided/manual | Real handset evidence; closed 24-hour window; third-party Meta authorization/OTP; blocked rollout gaps |
Reuse the detailed cases and template contracts in
docs/testing/booking-whatsapp-e2e-tutorial.md in the ai-agent project as the
initial catalog specification, then version the executable catalog alongside the
runner. Known unsupported cases stay visible and blocked with a reason.
Current gaps to represent honestly include legacy cancellation/recall direct text, dedicated YES-to-reschedule confirmation, complete inbound webhook batching, recall tenant attribution and automatic instalment-due schedules.
States: READY, RUNNING, WAITING_FOR_DELIVERY, WAITING_FOR_REPLY, MANUAL_REQUIRED, PASSED, FAILED, BLOCKED, CANCELLED. A guided/manual verification is explicitly labelled as manual evidence, not automated proof.
Store test profiles, runs, step assertions and configuration audits in dedicated admin testing tables. Do not repurpose customer bookings or clinical records as admin test results. Store only synthetic evidence and bounded diagnostic codes. Use unique request keys so double clicks start one run. Persist progress so a page refresh does not restart a message send. Unknown sends are not blindly retried.
PASS requires every mandatory assertion for the case. For delivery cases, an API acceptance alone is insufficient; require the defined delivery/handset evidence. If an external callback is required, keep the case waiting until it arrives or its explicit timeout expires.
This task can inspect the admin project, but its writable workspace currently covers ai-agent rather than ai-agent-admin. Applying and testing changes directly in the admin repository requires moving the task into the existing ai-agent-admin project in the sidebar. No admin project files have been modified by this specification.
Help us improve the world of AI agents.
Have a custom workflow need? Our engineers are ready to help.