Changelog¶
All notable changes to VitaraVox
This project adheres to Semantic Versioning.
[4.0.1] - 2026-02-16¶
Added¶
- OSCAR SOAP API Reference — Complete documentation for all 14 OSCAR SOAP web services at
/oscar/ws/, covering 80+ operations across DemographicService, ProviderService, ScheduleService, AllergyService, PrescriptionService, MeasurementService, DocumentService, PreventionService, BookingService, ProgramService, FacilityService, LabUploadService, LoginService, and SystemInfoService - Includes WS-Security authentication details, credential format, two-step auth flow, SOAP header examples
- Documents all transfer object field definitions (demographicTransfer, appointmentTransfer, drugTransfer with 55 fields, etc.)
- Non-bookable schedule codes reference table (14 codes: L, P, V, A, a, B, H, R, E, G, M, m, d, t)
- REST Bridge to SOAP operation mapping table (13 bridge methods)
- VitaraVox services-used subset (7 of 14 services actively consumed by OscarSoapAdapter)
- Cross-references to existing docs: Schedule Deep Dive, Adapter Implementations, SOAP Integration Evidence
[4.0.0] - 2026-02-15¶
Onboarding Redesign + Admin Provisioning Workflow¶
Complete restructure of the clinic onboarding flow and addition of admin-side clinic activation workflow.
Onboarding Flow Redesign (4 Steps — was 5)¶
- New step order: Clinic Details → EMR Connection → Business Hours → Validation
- EMR Connection (Step 2): EMR type selector cards (OSCAR, TELUS PS Suite, Accuro, Other) — OSCAR fully supported, others "coming soon" with contact support CTA
- Business Hours (Step 3): Enhanced with explanatory guidance text about typical Mon-Fri 8AM-5PM hours
- Validation (Step 4): Replaces old "Go Live" step with 6 parallel integration checks:
- EMR Connection — tests OSCAR connectivity
- Provider Roster — verifies at least 1 provider with OSCAR ID
- Schedule Codes — checks OSCAR config for template codes
- Appointment Types — verifies configured appointment types
- Sample Availability — retrieves actual schedule slots via adapter
- Sample Patient Search — tests patient search via adapter
- EMR Connection and Provider Roster are REQUIRED; others are informational warnings
- All 6 checks run in parallel via
Promise.allSettled()for speed - Expandable data panels show raw JSON results per check
- "Complete Onboarding" creates admin notification for provisioning
Admin Provisioning Workflow¶
- Pending Activation Card: Admin dashboard shows amber card listing clinics with
onboardingProgress.completedAtset butstatus=pending - Provisioning Checklist: Admin
ClinicDetailpage shows checklist: - Phone number assigned (check
clinic.vapiPhone) - Squad linked (check
config.vapiSquadId) - "Activate Clinic" button (enabled when phone + squad assigned)
- Activation Endpoint:
PUT /api/admin/clinics/:id/activatevalidates phone + squad, setsstatus=active, creates notification for clinic manager
10-Point Pre-Launch Validation (was 8)¶
- 7 blocking checks: clinic info, business hours, providers, EMR connection, Vapi squad, privacy officer, credentials encrypted
- 3 informational (non-blocking): test call passed, schedule data flow, OSCAR config synced (within 7 days)
OSCAR Config Management¶
- New
OscarConfigsettings page (/clinic/settings/oscar-config) - Schedule template codes management (bookable/non-bookable)
- Appointment type mappings configuration
- Config pull from OSCAR with sync status tracking
oscarConfigPulledAtfield tracks freshness (7-day staleness warning)
Booking Engine: SOAP Adapter Enhancements¶
- OscarSoapAdapter now production path (OscarBridgeAdapter retained for dev/fallback)
OscarUniversalAdapterrenamed toOscarBridgeAdapter(clarifies purpose)- Enhanced schedule slot parsing with
normalizeTime()for JAXB Calendar objects - Non-bookable codes expanded (L, P, V + full OSCAR set documented)
New API Endpoints¶
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/clinic/onboarding/complete |
Complete onboarding, notify admins |
| POST | /api/clinic/onboarding/test-slots |
Test schedule slot retrieval |
| POST | /api/clinic/onboarding/test-patient-search |
Test patient search |
| GET | /api/clinic/oscar-config |
OSCAR config (codes, types, sync status) |
| POST | /api/clinic/oscar-config/pull |
Pull config from OSCAR instance |
| GET | /api/admin/clinics/pending-activation |
Clinics awaiting activation |
| GET | /api/admin/clinics/:id/provisioning |
Provisioning status |
| PUT | /api/admin/clinics/:id/activate |
Activate clinic |
New Client API Methods¶
testScheduleSlots(),testPatientSearch(),completeOnboarding()getOscarConfig(),pullOscarConfig()getProvisioningStatus(clinicId),activateClinic(clinicId),getPendingActivationClinics()
New Shared Types¶
ValidationCheckResult,SlotTestResult,PatientSearchResult
Files Summary¶
- 1 new file:
StepValidation.tsx - 1 deprecated:
StepGoLive.tsx(replaced by StepValidation) - ~12 modified files across client, server, and shared packages
- 48 files changed total, +5239 / -1005 lines
[3.2.7] - 2026-02-14¶
Documentation¶
OSCAR Data Architecture — REST API & Known Bugs Update¶
- Updated OSCAR Data Architecture to v3.1
- REST API Endpoint Reference: Full OAuth 1.0a flow endpoints, Demographics CRUD (5 endpoints with mandatory/optional fields), Schedule/Appointment CRUD (9 endpoints)
- Known Bugs & Gotchas: 9 validated issues with workarounds — secUserRole NPE, provider reference trap, DemographicConverter link bug, AppointmentConverter null return, scheduledate.hour naming, template name VARCHAR(20) limit, missing admissionProgramId crash, OAuth provider validation, endTime off-by-one
- Entity Creation Order: 9-step sequence showing required creation dependencies
- Scheduling Layer updates: Slot duration formula (
1440 / len(timecode)), 96-char position reference table,'W'(Same Week) code added - Cross-reference to new OSCAR Demo Data page
OSCAR Demo Data & Test Environment — New Page¶
- New page: OSCAR Demo Data & Test Environment
- Design Principles: 6 rules for referential integrity in a no-FK database
- Provider Set: 4 doctors (100 Anderson, 101 Chen, 102 Patel, 10 Lee) with required secUserRole and program_provider records
- Schedule Templates: 16 templates (96-char) across 3 providers + 2 Public templates, fully decoded (FullDay, clinic, day-of-week variants)
- Demographic Set: 12 patients with diverse BC demographics, health card numbers, MRP assignments
- Appointment Set: 12 sample bookings across all providers and appointment types (Office Visit, Annual Physical, Consult, Prenatal, Mental Health, etc.)
- OAuth Clients: Production (VitaraPlatform, 1hr TTL) and test (vitaraPostman, 10hr TTL)
- Validation Checklist: 8 SQL checks for provider-role, patient-admission, demographic-provider, schedule-template, appointment reference integrity, secUserRole data quality, REST smoke tests
- Automation:
oscar-align-load.shscript documentation — 4-phase lifecycle (pre-flight, alignment, load, verification), fully idempotent
[3.2.6] - 2026-02-14¶
Documentation¶
OSCAR EMR Data Architecture — Complete Entity Reference¶
- New page: OSCAR Data Architecture in EMR Integrations section
- Identity Layer:
provider,secUserRole,ServiceClient(OAuth) — full column definitions, mandatory fields, REST prerequisites - Patient Layer:
demographic(with DOB-as-3-strings quirk),admission(program_id=10034 hardcoded),program,demographicExt(EAV),demographiccust - Scheduling Layer:
scheduletemplatecode(slot alphabet),scheduletemplate(timecode patterns),scheduledate(template assignment via name JOIN) - Appointment Layer:
appointment(independent of schedule slots),appointmentType(free text, no FK), status codes (t/H/C/T/b/A/sc) - OAuth Layer:
ServiceClient→ServiceRequestToken→ServiceAccessToken— full 5-step flow with token TTL and expiry rules - Cross-Entity Dependency Graph: Visual showing all provider_no references across 5 entities
- Documented critical traps: secUserRole NPE, provider reference NPE, no FK constraints, appointment/slot independence
- Added cross-references from OSCAR Schedule Deep Dive and OSCAR REST Bridge
[3.2.5] - 2026-02-13¶
Upgrade Plans¶
Booking Engine Upgrade — Master Implementation Plan¶
- New documentation section: Upgrade Plans
- Published Booking Engine Upgrade Plan for stakeholder review
- Full current-state vs future-state ASCII architecture diagrams
- 6-phase migration safety strategy with rollback checkpoints at every stage
- Impact analysis: 2 files created, 5 files modified, 0 database migrations
- 7 milestones (M0-M6) with 80+ acceptance criteria
- Agent team orchestration: parallel M1+M2, sequential M3-M6
- Comprehensive testing strategy: SOAP adapter, BookingEngine, and regression test cases
- Risk registry with 7 identified risks and mitigations
- Status: PLANNING — awaiting stakeholder approval before any code changes
[3.2.4] - 2026-02-13¶
Architecture Decision¶
ADR-004: Booking Product Architecture¶
- Decision: All booking intelligence lives in the VitaraVox platform layer. No custom code deployed on customer OSCAR instances.
- Created ADR-004: Booking Product Architecture documenting three-layer architecture
- Layer 1 (our servers): BookingEngine — availability calculation, conflict detection, slot locking, double-booking prevention, bookinglimit enforcement
- Layer 2 (pluggable adapters): SOAP Adapter (universal production), REST Adapter (OSCAR 15+), Bridge Adapter (dev/test only)
- Layer 3 (customer's OSCAR): Connect via standard SOAP/OAuth APIs. Install nothing.
- Corrected Schedule Deep Dive Section 7 — booking intelligence belongs in platform, NOT in bridge
- Bridge reclassified as dev/testing tool and reference implementation, not a portable production connector
- Migration path: Phase 1 Bridge Adapter → Phase 2 SOAP Adapter → Phase 3 first customer on SOAP
[3.2.3] - 2026-02-13¶
Documentation¶
OSCAR Schedule System Deep Dive¶
- New architecture decision page: OSCAR Schedule Deep Dive
- Documented core 4-table relationship chain (
scheduledate.hour→scheduletemplate.name→timecode→scheduletemplatecode) - Documented bookinglimit advisory-only enforcement (OSCAR never implemented strict limits)
- Critical finding: Appointments and schedule slots are completely independent (no FK between
appointmentandscheduledate) - Full API surface comparison: SOAP ScheduleWs vs OSCAR native REST vs our bridge — identified gap in native REST (no schedule endpoints)
- Duplicate booking vulnerability analysis: OSCAR SOAP
addAppointmenthas zero conflict checking;BookingWsrace condition in check-then-book flow - Commercial competitive analysis: Cortico, Ocean, Veribook, Porton, Phelix, OSCAR Self-Book — all subtract booked slots from availability; our bridge does not
- P0 required actions: subtract booked appointments from availability, pre-booking conflict check
- Cross-linked from OSCAR REST Bridge Section 10
[3.2.2] - 2026-02-13¶
Documentation¶
OSCAR Database ERD & Bridge Mapping¶
- Added full OSCAR database entity relationship diagram to OSCAR REST Bridge (Section 2)
- Documented all core tables:
provider,demographic,appointment,allergies,drugs,measurements,measurementsExt,measurementType - Added schedule subsystem ERD:
scheduledate→scheduletemplate→scheduletemplatecodeJOIN architecture - Added detailed SOAP-to-REST bridge mapping tables (Section 6) showing exact SOAP method calls for all endpoints
- Added bridge internal data flow diagram showing Routes → Services → SOAP Client / DB Service paths
- Documented notable table quirks (varchar birth dates, Aria engine, no FK constraints, etc.)
- Added bridge data flow diagram to Data Flow & Guardrails
[3.2.1] - 2026-02-12¶
Security Hardening Sprint (Post-Review)¶
5 targeted fixes addressing the highest-priority findings from the architecture review.
Fix 1: Production Security Enforcement¶
- Set
NODE_ENV=production— activates fail-fast secret validation via Zod - Generated and configured
ENCRYPTION_KEYfor AES-256-GCM credential encryption - HMAC-SHA256 webhook verification now mandatory (was skipped in dev mode)
Fix 2: Waitlist Database Persistence¶
addToWaitlisttool handler now writes to PostgreSQL via Prisma (WaitlistEntry.create)- Previously the Prisma call was commented out — patients were told they were added but nothing persisted
Fix 3: PHI Log Redaction¶
- Added
redactPhi()helper that strips names, DOB, phone, email, health cards from all log output - Redacted 7 log sites in
vapi-webhook.tsthat were dumping full patient data - Caller phone logged as
[SET]/[NOT SET]instead of actual number - End-of-call-report logs only
callIdanddurationSeconds
Fix 4: OSCAR Route Authentication¶
- Moved 15
/api/oscar/*routes to a dedicated sub-router with explicitauthMiddleware GET /api/oscar/healthremains public (monitoring)- All other OSCAR proxy routes now require JWT authentication
Fix 5: Graceful Shutdown Handler¶
- Added SIGTERM/SIGINT handler that drains in-flight requests before exit
- 10-second forced shutdown timeout with
.unref()to prevent Node.js hang - Critical for
update_appointmentwhich does book-new + cancel-old (non-atomic)
Production Launch Backlog Documented¶
| ID | Issue | Priority |
|---|---|---|
| BL-01 | JWT token revocation | Medium |
| BL-02 | Redis-backed rate limiting | Medium |
| BL-03 | Multi-tenant OSCAR wiring | High |
| BL-08 | Webhook integration tests | High |
| BL-09 | Monitoring + alerting | High |
[3.2.0] - 2026-02-12¶
Fixed - Phone Number Linking & Human Handover (Theme 7)¶
Bug Fix¶
- transfer-destination-request webhook now returns the actual clinic phone number for call transfers, fixing human handover routing
Added¶
Vapi Phone Number Listing
- New GET /api/admin/vapi/phone-numbers endpoint — lists all Vapi phone numbers (admin only)
- Server-side VapiService method to fetch phone numbers from Vapi API
Client API Methods
- New client API methods for Vapi phone management (getVapiPhoneNumbers, assignPhoneToClinic, unassignPhoneFromClinic)
Admin Phone Management Page (/admin/phones)
- Stat cards: total phone numbers, assigned, available, clinics without phone
- Clinic assignments table with assign/unassign actions
- Vapi phone numbers table showing all numbers with assignment status
- Assign modal for linking unassigned phone numbers to clinics
Database Backup Scripts
- scripts/backup-db.sh — PostgreSQL backup script with retention
- scripts/install-cron.sh — Cron job installer for automated daily backups
[3.1.0] - 2026-02-11¶
Added - Platform Maturity (5 Themes)¶
Complete platform hardening across compliance, reliability, onboarding, clinical control, and support — transforming from prototype to production-grade multi-tenant SaaS.
Theme 2: Compliance (PIPEDA/PIPA)¶
Credential Encryption (AES-256-GCM)
- New lib/crypto.ts: encrypt(), decrypt(), isEncrypted() — AES-256-GCM with random IV
- OSCAR credentials (oscarConsumerSecretEnc, oscarTokenSecretEnc) encrypted at rest
- ENCRYPTION_KEY (32-byte hex) required in production; dev warns on missing key
- API responses mask encrypted fields (never expose plaintext)
Audit Logging
- New middleware/audit.ts: Auto-captures POST/PUT/DELETE → AuditLog table
- Redacts password, secret, key, token fields from stored details
- New services/audit.service.ts: Non-blocking writes, paginated admin queries
- New GET /api/admin/audit with date/action/user filters
Privacy & Retention
- Privacy officer fields: privacyOfficerName, privacyOfficerEmail, privacyOfficerPhone
- BAA/DPA tracking: baaVapiSigned, baaHostingSigned with timestamps
- Data retention: transcriptRetentionDays (default 90), callLogRetentionDays (default 365)
- New jobs/data-retention.ts + jobs/scheduler.ts: node-cron daily 3 AM purge
- Nulls transcripts after retention period, deletes call logs after longer period
Documentation
- Compliance requirements page (2-compliance/requirements.md)
- BAA/DPA templates (2-compliance/baa-templates.md)
- Breach response plan (2-compliance/breach-response.md)
Theme 3: Reliability & Production Standards¶
Security Hardening
- Helmet security headers (CSP, HSTS, X-Frame-Options, etc.)
- Rate limiting: 5/min auth, 300/min webhooks, 100/min API
- Env validation: Zod schema in config/env.ts, fail-fast on missing secrets in production
Observability
- Pino structured logging (lib/logger.ts) — JSON in prod, pretty-print in dev
- pino-http request logger with x-request-id correlation
- Replaced ~30 console.log/error calls with structured logger
Resilience
- Circuit breaker (Opossum) wrapping all OSCAR Bridge calls
- Real health checks: DB ping + OSCAR Bridge /health + Vapi API check with latency
- PostgreSQL backup automation (scripts/backup-db.sh, daily 2 AM, 14 retained)
Validation
- 18 Zod schemas with .strict() enforcement in validation/schemas.ts
- validate() middleware factory for all POST/PUT endpoints
- Schemas: login, provider, waitlist, schedule, EMR config, Vapi, privacy officer, BAA, retention, clinical settings, onboarding, clinic creation, ticket CRUD, ticket messages
Theme 1: Onboarding¶
Backend
- New services/onboarding.service.ts: getProgress(), updateStep(), validatePreLaunch(), goLive()
- 8-point pre-launch validation (clinic info, hours, providers, EMR, Vapi, privacy officer, credentials, test call)
- POST /api/admin/clinics — Transaction creating Clinic + User + ClinicConfig + OnboardingProgress + 7 ClinicHours
Frontend
- 5-step onboarding wizard (pages/clinic/Onboarding.tsx)
- Step 1: Clinic Info (name, phone, address, timezone)
- Step 2: Business Hours (7-day grid, open/close selectors)
- Step 3: Providers (EMR sync, manual add, OSCAR ID mapping)
- Step 4: EMR Connection (credentials, test connection, Vapi assignment)
- Step 5: Go Live (8-point checklist, test call button, go-live gate)
- StepIndicator component for progress visualization
- Dashboard "Complete Setup" banner for pending clinics
Theme 4: Clinical Control¶
- ClinicConfig fields:
customGreeting,customGreetingZh,transferPhoneNumber,defaultProviderId,preferredPharmacy*,appointmentTypeMappings PUT /api/clinic/clinical-settingsendpoint- Clinical Settings page (
pages/clinic/settings/ClinicalSettings.tsx) — greeting, pharmacy, appointment type editor - Sidebar navigation: Settings > Clinical Settings
Theme 5: Support & Notifications¶
Support Ticketing
- New Prisma models: SupportTicket, TicketMessage, Notification
- New services/support.service.ts: Ticket CRUD, messages, internal notes, auto-notifications
- 11 route endpoints (4 clinic, 4 admin, 3 notifications)
- isInternal enforced server-side — clinic routes always set false, admin routes support both
- Zod schemas: createTicketSchema, updateTicketSchema, createTicketMessageSchema
Frontend — Clinic Support (pages/clinic/Support.tsx)
- Ticket list with status/priority filter pills, pagination
- Create ticket modal (title, description, priority)
- Ticket detail with threaded messages and reply box
Frontend — Admin Support (pages/admin/Support.tsx)
- All-tickets view with status + priority filters
- Status/priority dropdown controls
- Internal notes toggle (checkbox + Lock icon)
- Internal messages highlighted in amber
Notification System
- NotificationBell.tsx component in header
- Unread badge (red circle, "9+" cap), dropdown with relative timestamps
- Click-through navigation to relevant page
- "Mark all read" button
- 30-second polling via GET /api/notifications
- Auto-created on: ticket creation, replies, status changes
Database Changes¶
| Migration | New Models | New ClinicConfig Fields |
|---|---|---|
| Audit log | AuditLog |
— |
| Privacy/retention | — | privacyOfficer*, transcriptRetentionDays, callLogRetentionDays, baaVapi*, baaHosting* |
| Onboarding | OnboardingProgress |
— |
| Clinical control | — | customGreeting*, transferPhoneNumber, defaultProviderId, preferredPharmacy*, appointmentTypeMappings |
| Support tickets | SupportTicket, TicketMessage |
— |
| Notifications | Notification |
— |
Total models: 8 -> 13
NPM Packages Added¶
| Package | Purpose |
|---|---|
helmet |
Security headers |
express-rate-limit |
Brute-force protection |
pino + pino-http + pino-pretty |
Structured logging |
opossum |
Circuit breaker |
zod |
Schema validation |
node-cron |
Scheduled jobs |
Files Summary¶
- ~17 new files created
- ~30 files modified
- 6 database migrations
- 3 new documentation pages + 1 doc overhaul
- 18 Zod validation schemas
- 9 new services
- 22 React pages total
[3.0.0] - 2026-02-10¶
Added - Dual-Track Bilingual Voice Agent (v3.0)¶
9-Agent Dual-Track Squad Architecture¶
- New squad: 9 assistants organized as Router + 4 roles x 2 language tracks (EN/ZH)
- Squad ID:
13fdfd19-a2cd-4ca4-8e14-ad2275095e32 - Router (vitara-router-v3): Pure language gate — detects EN/ZH from first utterance, routes to correct track
- Patient-ID (EN/ZH): Identifies caller by phone, detects intent, routes to role agent
- Booking (EN/ZH): Finds slots, books appointments with
create_appointment - Modification (EN/ZH): Consolidated reschedule + cancel + check (was 2 separate agents)
- Registration (EN/ZH): Collects 7 fields, registers new patients
- Confirmation agent eliminated —
log_call_metadataabsorbed into every role agent
Per-Language STT/TTS Configuration¶
- Router STT: AssemblyAI Universal (bilingual auto-detect)
- EN STT: Deepgram nova-2
en(language-specific for higher accuracy) - ZH STT: Deepgram nova-2
zh(language-specific for higher accuracy) - EN TTS: ElevenLabs eleven_multilingual_v2 (voice
fQj4gJSexpu8RDE2Ii5m) - ZH TTS: Azure
zh-CN-XiaoxiaoNeural(native Mandarin quality)
ZH Endpointing Tuning¶
- Mandarin speech patterns require longer pauses before agent responds
- Standard ZH agents: waitSeconds=1.0, onPunctuationSeconds=0.6, onNoPunctuationSeconds=1.5, numWords=3
- Registration agents: waitSeconds=1.6, onNoPunctuationSeconds=2.5 (for spelling flows)
Vapi GitOps (Config-as-Code)¶
- All 9 assistants, 14 tools, and squad YAML managed in
vapi-gitops/directory - Slug-based tool references (e.g.,
find-earliest-appointment-7fc7534d) - Environment separation (dev/staging/prod)
- Push via:
cd vapi-gitops && npm run push:dev
Server-Side: Call Metadata Cache¶
callMetadataCache: In-memory Map bridging tool-call and end-of-call-report webhookssetCallMetadata(callId, { language, outcome, demographicId, appointmentId })— set during tool callsgetCallMetadata(callId)— read insaveCallLogto merge into DB- Fallback:
create_appointmentandregister_new_patientalso cachelanguage+demographicId
Server-Side: v3 Parameter Support¶
create_appointmentnow acceptsdemographicId,providerId,startTime(ISO 8601),appointmentType,reason,languageupdate_appointmentnow acceptsappointmentId,newStartTime,newProviderIdcancel_appointmentnow acceptsappointmentIdregister_new_patientnow acceptshealthCardType(BC,OUT_OF_PROVINCE,PRIVATE)log_call_metadatanow acceptscallOutcome,language,demographicId,appointmentId- All endpoints accept both v3.0 and legacy parameter names (backward-compatible)
Server-Side: Appointment Type Validation¶
appointmentTypevalidated against['B', '2', '3', 'P']- Invalid values silently default to
'B'(general visit)
Server-Side: Dual Squad Resolution¶
- Added
vapi_squad_id_v3column toclinic_configtable findClinicByVapiSquadnow checks bothvapi_squad_idandvapi_squad_id_v3- Both v2.3.0 and v3.0 squads resolve to the same clinic
Server-Side: callId Threading¶
callIdextracted frommessage.call.idand passed tohandleToolCall- Enables per-call metadata caching across tool invocations
Webhook Header Comment Updated¶
- File header documents both v2.3.0 (6 assistants) and v3.0 (9 assistants) squad architectures
20 Handoff Routes¶
- Router -> Patient-ID-EN/ZH (language gate)
- Patient-ID -> Booking/Modification/Registration (intent routing)
- Booking <-> Modification (cross-intent redirect)
- Registration -> Booking (post-registration booking offer)
- Any agent -> transfer_call (error fallback)
Files Changed¶
| File | Description |
|---|---|
vapi-gitops/resources/assistants/*.md |
9 assistant prompt files (Router, Patient-ID x2, Booking x2, Modification x2, Registration x2) |
vapi-gitops/resources/squads/vitaravox-v3.yml |
Squad YAML with 20 handoff routes |
vapi-gitops/resources/tools/*.yml |
14 tool definitions |
vapi-gitops/.vapi-state.dev.json |
Deployed Vapi resource IDs |
admin-dashboard/server/src/routes/vapi-webhook.ts |
callMetadataCache, callId threading, appointmentType validation, v3 parameters |
admin-dashboard/server/src/services/clinic.service.ts |
Dual squad resolution (vapi_squad_id_v3) |
[2.2.0] - 2026-02-06¶
Added - Voice Agent Server Consolidation & Multi-Clinic Hardening¶
IEmrAdapter Pattern (ADR-003) — TypeScript Rewrite¶
- New adapter layer with canonical EMR-agnostic types (Patient, Provider, Appointment, etc.)
IEmrAdapter.ts— Interface defining all EMR operationsOscarUniversalAdapter.ts— OSCAR Bridge adapter with bidirectional data transformationEmrAdapterFactory.ts— Clinic-scoped adapter factory with 5-minute TTL cache- Enables future EMR backends (Oscar Pro, Telus Health, Juno) without changing webhook code
Caller Phone Auto-Detection¶
- LLM doesn't know the caller's real phone number — it comes from Telnyx metadata in
call.customer.number - Server-side extraction bypasses LLM hallucination (e.g., LLM sends "0000000000", server uses real "+12367770690")
search_patient_by_phonealways prefers real caller phone over LLM argument
find_earliest_appointment — Smart Slot Finder¶
- Returns exactly ONE slot per call for concise voice interactions
- New filter parameters:
startDate,endDate,excludeDates,timeOfDay,providerName - Past-date clamping: GPT-4o doesn't know current date — if LLM sends 2023, server clamps to today
- Provider name resolution: Fuzzy matches "Dr. Chen" against provider list (strips "Dr." prefix)
- Non-numeric providerId: Uses regex
/^\d+$/— "any", "任何" all map to "search all providers" - Skips weekends, filters system/test providers (ID > 999 or < 0)
- 30-day search window (up from 14)
6-Assistant Squad Architecture¶
- Squad expanded from 5 to 6 assistants: Router, Booking, Reschedule, Cancel, Registration, Confirmation
- All assistants now have
Today's date is 2026-02-06in prompts (prevents past-date issues) - Temperature reduced from 0.7 to 0.5 across all squad members
- Languages expanded: English, Mandarin, Cantonese, French, Punjabi
Squad Prompt Improvements¶
- Router: Auto-identifies patient by phone on call start (no asking for phone number)
- Router:
firstMessagechanged to "Welcome to the clinic! Let me look up your information, one moment." - Booking: Immediately finds earliest slot with NO filters on handoff — no questions first
- Booking: Handles confirmation inline (no handoff to confirmation assistant)
- All assistants: Silent transfers — never mention "transferring" or assistant names to caller
- All assistants: Handle "anything else?" and goodbye inline
Multi-Auth Webhook Middleware (new file)¶
vapi-auth.ts— Supports 3 auth methods (checked in order):- HMAC-SHA256 signature (
x-vapi-signature+x-vapi-timestamp) - API key (
x-api-keyheader) - Bearer token (
Authorization: Bearer) - Constant-time string comparison (prevents timing attacks)
- 5-minute replay window for HMAC timestamps
Robust Appointment Booking¶
create_appointmentaccepts bothpatientId/demographicIdandappointmentTime/startTime- Robust time parsing: ISO 8601, date+time, bare time formats
update_appointmentreschedule: book-new-first, then cancel-old (safer strategy)
Route Mounting¶
- Catch-all
/api/vapi/*prefix handles all tool-specific URLs - Legacy
/vapi-webhookpreserved for backward compatibility - Router handles both
POST /andPOST /:path
Comprehensive Code Comments¶
- Heavy JSDoc and inline comments on all key code sections
- Documented design decisions, edge cases, and debug tips
- Architecture overview in file header with full call flow
OSCAR Schedule Data Population¶
- Schedule templates created for providers 100 and 101 (Feb 7-20, 2026)
- OSCAR Bridge SQL JOIN fix for schedule reading
- 24 slots per doctor per day now available
Files Changed¶
| File | Description |
|---|---|
src/routes/vapi-webhook.ts |
Major rewrite: 1131 lines, 18+ tool handlers, comprehensive comments |
src/adapters/IEmrAdapter.ts |
New: Canonical EMR interface |
src/adapters/OscarUniversalAdapter.ts |
New: OSCAR Bridge adapter |
src/adapters/EmrAdapterFactory.ts |
New: Adapter factory with caching |
src/adapters/index.ts |
New: Barrel export |
src/middleware/vapi-auth.ts |
New: Multi-method webhook auth |
src/index.ts |
Updated: Catch-all /api/vapi routing, comments |
src/config/env.ts |
Updated: OSCAR Bridge + webhook secret config |
src/services/oscar.service.ts |
Refactored: Bridge API compatibility |
src/services/provider.service.ts |
Updated: New adapter pattern |
prisma/schema.prisma |
Updated: emrType field, unique Vapi phone |
[2.1.0] - 2026-02-03¶
Added - Admin Vapi Management & Call Log Integration¶
Admin Vapi-Clinic Mapping System¶
- 1 Assistant to 1 Clinic linking in admin dashboard
- New database fields in
clinic_config: vapi_assistant_id(unique) - Links one Vapi assistant to one clinicvapi_squad_id(unique) - Links one Vapi squad to one clinicvapi_webhook_secret- For webhook verificationvapi_connection_verified- Connection status flagvapi_last_verified_at- Last verification timestamp
Admin API Endpoints (Vitara Admin only)¶
| Endpoint | Method | Purpose |
|---|---|---|
/api/admin/vapi/mappings |
GET | List all clinic-assistant mappings |
/api/admin/clinics/:id/vapi |
PUT | Update Vapi config for a clinic |
/api/admin/clinics/:id/vapi/test |
POST | Test Vapi connection |
/api/admin/clinics/:id/vapi |
DELETE | Remove Vapi config from clinic |
Webhook Call Log Saving¶
- Automatic clinic resolution:
metadata.clinicId→assistantId→squadId→phoneNumber - Call logs saved to database on
end-of-call-report - Includes: transcript, summary, duration, cost, intent, outcome
VitaraVox Demo Clinic Linked¶
{
"clinicId": "vitaravox-demo",
"vapiPhone": "+1 (604) 555-8888",
"vapiAssistantId": "45f98810-2ff3-4c25-9cf0-54a2d2822d37",
"vapiConnected": true,
"oscarConnected": true
}
OSCAR Bridge Integration Fixes¶
- Fixed
OscarProviderinterface to useproviderId(matches actual API response) - Fixed health check to include API key header
- Fixed provider sync to properly map OSCAR provider IDs
- EMR TEST and SYNC buttons now fully functional
Test Results¶
- 37 tests passing (API, Auth, Webhook, Admin endpoints)
- 1 expected failure (OSCAR Bridge single provider endpoint not implemented)
Files Changed¶
| File | Description |
|---|---|
prisma/schema.prisma |
Added Vapi config fields to ClinicConfig |
src/routes/api.ts |
Added admin Vapi management endpoints |
src/routes/vapi-webhook.ts |
Added clinic resolution and call log saving |
src/services/clinic.service.ts |
Added Vapi mapping methods |
src/services/oscar.service.ts |
Fixed providerId mapping, health check header |
src/services/provider.service.ts |
Fixed EMR test/sync with correct response handling |
prisma/seed.ts |
Linked VitaraVox clinic to Vapi Squad Leader |
[2.0.0] - 2026-02-02¶
Changed - Voice Agent Squad Architecture v2.0¶
5-Agent Squad Architecture¶
- Squad Leader Router - Greeting, clinic settings check, emergency/frustration detection
- Patient Identification - Mandatory first step for all callers, DOB verification
- Patient Registration - New patient registration with phonetic confirmation
- Appointment Booking - Book with preference handling ("next Wednesday morning")
- Appointment Modification - Reschedule/cancel with explicit confirmation
New Tool Handlers (vapi-webhook.ts)¶
getClinicSettings- Check clinic hours, new patient acceptance on call startcheckNewPatientAcceptance- Verify if registrations allowedfindEarliestAppointment- Search next 14 days for available slotsfindAppointmentByPreference- Parse natural language ("next week", "星期三上午")getPatientAppointments- Get patient's upcoming appointments for modificationaddToWaitlist- Add to waitlist when clinic not accepting
Language Handling¶
- Automatic detection: English and Mandarin Chinese (普通话)
- Mid-conversation language switching supported
- Global prompt blurb on ALL agents:
Key Behaviors¶
- Patient ID mandatory before any booking/modification
- Phonetic spelling confirmation for registration (A for Apple style)
- 90-day limit on appointment search with transfer fallback
- Emergency detection triggers standard message + call end
- Frustration detection (3+ exchanges) offers live transfer
- Silent handoffs between agents (no announcements)
Files Created/Updated¶
| File | Description |
|---|---|
admin-dashboard/server/src/routes/vapi-webhook.ts |
6 new tool handlers |
docs/VAPI-SQUAD-V2-PROMPTS.md |
Complete system prompts for 5 agents |
docs/vapi-tools-v2.json |
JSON tool definitions for Vapi API |
[1.5.2] - 2026-01-21¶
Added - Marketing Website Documentation¶
Documentation Updates¶
- Added marketing website documentation (
3-whats-built/marketing-website.md) - Created comprehensive code review for React frontend (
7-code-review/website-review.md) - Updated navigation and indexes to include new sections
Marketing Website Code Review¶
- Architecture analysis: React 19.2, TypeScript 5.9, Vite 7.2, Tailwind CSS 4.1
- Identified 20 issues (2 critical, 4 high, 6 medium, 8 low)
- Critical: CSRF vulnerability in contact form, hardcoded API endpoint
- High: Weak input validation, console.error in production
- Created remediation backlog with prioritized fixes
Scores¶
| Metric | Score |
|---|---|
| Architecture | 8/10 |
| TypeScript | 8/10 |
| Code Quality | 6/10 |
| Security | 5/10 |
| Performance | 8/10 |
[1.5.1] - 2026-01-16¶
Fixed - Admin Dashboard Data Display¶
API Response Handling¶
- Fixed pagination preservation in
api.jsresponse unwrapping - Paginated endpoints now return
{ data: [...], pagination: {...} }structure - Non-paginated endpoints continue to return unwrapped data directly
Frontend Field Name Mapping¶
- Updated
ClinicsPage.jsxto use PostgreSQL column names (clinic_id,clinic_name,clinic_created_at) - Updated
UsersPage.jsxclinic dropdown to useclinic_idandclinic_name - Updated
AuditLogsPage.jsxfor new response structure
JSONB Parsing Fix¶
- Added
safeJsonParse()helper inauditLogs.jsroute - Handles PostgreSQL
pgdriver auto-parsing of JSONB columns - Prevents "Unexpected token o in JSON at position 1" errors
Nginx Proxy Configuration¶
- Added
proxy_set_header Authorization $http_authorization;to API locations - JWT tokens now properly forwarded through nginx to backend
Seed Data Enhancement¶
- Added Calgary Health Partners as 5th clinic
- Added Emily Brown as 5th clinic manager
- Added 22 diverse audit log entries for dashboard activity widget
Files Changed¶
| File | Changes |
|---|---|
admin-ui/src/services/api.js |
Preserve pagination in response unwrapping |
admin-ui/src/pages/ClinicsPage.jsx |
Use backend field names |
admin-ui/src/pages/UsersPage.jsx |
Use backend field names in dropdown |
admin-ui/src/pages/AuditLogsPage.jsx |
Handle new response structure |
routes/admin/auditLogs.js |
Add safeJsonParse helper |
nginx/conf.d/api.conf |
Forward Authorization header |
migrations/003_seed_data.sql |
Add 5th clinic, user, diverse audit logs |
[1.5.0] - 2026-01-14¶
Added - Admin System with Per-Clinic EMR Control¶
Multi-Tenant Admin Dashboard¶
- React-based admin UI served from
/admin/ - Two user roles: Vitara Admin (platform-wide) and Clinic Manager (single clinic)
- Role-based access control (RBAC) with middleware enforcement
- Responsive design with Tailwind CSS
Authentication System¶
- PassportJS + JWT authentication
- Access tokens (1 hour) + Refresh tokens (7 days)
- bcrypt password hashing (cost factor 12)
- Account lockout: 5 failed attempts = 15 minute lock
- Password requirements: 8+ chars, letter + number
Database Schema Additions¶
clinic_config- Enhanced withemr_live,emr_type,emr_config, preferencesadmin_users- User accounts with roles and clinic assignmentsaudit_log- Immutable append-only audit trail
API Endpoints¶
/api/auth/*- Login, logout, refresh, change password, get current user/api/admin/clinics/*- CRUD, EMR config, go-live workflow (Vitara Admin)/api/admin/users/*- User management, password reset, unlock (Vitara Admin)/api/admin/audit-logs/*- Query and summarize audit logs (Vitara Admin)/api/clinic/*- Self-service preferences and go-live request (Clinic Manager)
Per-Clinic EMR Live Status¶
emr_liveflag inclinic_configtable controls EMR integration- Demo mode when
emr_live = false- returns mock data - Go-live validation workflow with checklist
- Voice agent checks
emr_livebefore real EMR operations
EmrService Demo Mode Integration¶
_isEmrLive()check on all EMR operations- Demo responses for all endpoints (search, booking, providers)
- Demo patient: "Demo Patient" (DEMO-001)
- Demo provider: "Dr. Demo Doctor" (DEMO-DR-001)
Comprehensive Test Suite¶
- 125 new unit tests for admin system
- Validators: 58 tests (Joi schemas)
- AdminUserRepository: 23 tests
- AuditLogRepository: 20 tests
- Auth Middleware: 24 tests
Configuration¶
| Variable | Default | Description |
|---|---|---|
JWT_SECRET |
(required) | Access token signing key |
JWT_REFRESH_SECRET |
(required) | Refresh token signing key |
JWT_EXPIRES_IN |
1h |
Access token expiry |
JWT_REFRESH_EXPIRES_IN |
7d |
Refresh token expiry |
EMR_DEMO_MODE |
true |
Enable demo responses for non-live clinics |
Deployment Notes¶
# Run database migrations
psql -d vitara_db -f migrations/002_admin_system.sql
# Set JWT secrets (required!)
export JWT_SECRET="your-secure-secret-here"
export JWT_REFRESH_SECRET="your-refresh-secret-here"
# Access admin UI
open https://your-host/admin/
Files Created¶
| Path | Description |
|---|---|
db/migrations/002_admin_system.sql |
Database schema |
db/repositories/ClinicConfigRepository.js |
Clinic data access |
db/repositories/AdminUserRepository.js |
User data access |
db/repositories/AuditLogRepository.js |
Audit log data access |
validators/adminSchemas.js |
Joi validation schemas |
middleware/auth.js |
PassportJS + RBAC middleware |
routes/auth.js |
Authentication endpoints |
routes/admin/*.js |
Admin API endpoints |
routes/clinic/*.js |
Clinic Manager endpoints |
admin-ui/ |
React admin dashboard source |
public/admin/ |
Built admin UI static files |
[1.4.0] - 2026-01-14¶
Added - EMR Abstraction Layer (Epic 1.2)¶
Phase 1: Adapter Pattern Implementation¶
IEmrAdapter.js- Interface defining all EMR operationsBaseEmrAdapter.js- Base class with common functionalityOscarUniversalAdapter.js- OSCAR REST Bridge adapter (first implementation)EmrAdapterFactory.js- Factory pattern with adapter caching
Phase 1: Data Transformers¶
PatientTransformer.js- EMR ↔ canonical patient format conversionProviderTransformer.js- EMR ↔ canonical provider format conversionAppointmentTransformer.js- EMR ↔ canonical appointment format conversion- System user filtering (admin0, system, etc.)
Phase 2: Integration Layer (NEW)¶
services/EmrService.js- Integration layer bridging adapters with vapiEndpoints.js- Maintains backward compatibility with oscarRestService method signatures
- Response format translation (canonical → OSCAR-compatible)
- Per-clinic adapter configuration support
Phase 2: Feature Flags System (NEW)¶
config/featureFlags.js- Centralized feature flag configurationUSE_EMR_ADAPTER(env var) - Global toggle for new adapter patternEMR_ADAPTER_CLINICS(env var) - Comma-separated list for selective rollout- Helper functions:
shouldUseAdapterForClinic(),getFeatureFlagStatus()
Phase 2: Database Migrations (NEW)¶
migrations/001_add_emr_columns.sql- Add emr_type and emr_config columnsmigrations/001_add_emr_columns_rollback.sql- Rollback script- Supports per-clinic EMR configuration
Phase 2: vapiEndpoints.js Integration (NEW)¶
- Replaced
const oscar = require('./oscarRestService')with EmrService - All 14 Vapi tool endpoints now use EmrService for EMR operations
- Automatic fallback to legacy oscarRestService when adapter disabled
Comprehensive Unit Tests¶
- 224 total tests (160 Phase 1 + 64 Phase 2)
- 86% statement coverage, 80% branch coverage
__tests__/services/EmrService.test.js- 41 tests__tests__/config/featureFlags.test.js- 23 tests
Technical Details¶
- Decouples voice agent from OSCAR-specific code
- Enables future EMR integrations (Oscar Pro, Telus Health, Juno)
- 5-minute adapter cache with TTL management
- Circuit breaker integration for fault tolerance
- Structured logging with metrics collection
- Instant rollback via
USE_EMR_ADAPTER=false
Architecture Decision Record¶
- ADR-003: EMR Abstraction Layer approved and documented
- Phase 2 integration plan:
docs/PHASE2_INTEGRATION_PLAN.md - Database schema changes: emr_type, emr_config columns
Default Behavior (IMPORTANT)¶
By default, USE_EMR_ADAPTER=false (DISABLED)
This means the system uses the legacy oscarRestService unless explicitly enabled. The new EMR adapter pattern is opt-in for controlled rollout.
| Environment Variable | Default | Effect |
|---|---|---|
USE_EMR_ADAPTER |
false |
Legacy oscarRestService (no adapter) |
EMR_ADAPTER_CLINICS |
'' |
Empty = all clinics (when enabled) |
Deployment Notes¶
# DEFAULT (legacy mode) - oscarRestService used
# No env vars needed, this is the fallback
# Enable adapter for all clinics (explicit opt-in)
export USE_EMR_ADAPTER=true
# Selective rollout to specific clinics only
export USE_EMR_ADAPTER=true
export EMR_ADAPTER_CLINICS=clinic-1,clinic-2
# Rollback to legacy mode (explicit)
export USE_EMR_ADAPTER=false
# Apply database migration (required before enabling adapter)
psql -d vitara_db -f migrations/001_add_emr_columns.sql
[1.3.2] - 2026-01-14¶
Added - OSCAR REST Bridge v1.3.0¶
Admission Records on Patient Registration¶
- New patients automatically get an admission record
- Links patient to OSCAR Service program (ID 10034 by default)
- Patient appears in provider rosters immediately
- Response includes
admissionIdandprogramId
Configuration Centralization¶
- New environment variables with sensible defaults:
| Variable | Default | Purpose |
|---|---|---|
OSCAR_DEFAULT_PROGRAM_ID |
10034 |
Admission program |
OSCAR_DEFAULT_PROVIDER_ID |
(empty) | Fallback provider |
OSCAR_DEFAULT_PROVINCE |
ON |
Patient province |
OSCAR_DEFAULT_COUNTRY |
CA |
Patient country |
OSCAR_DEFAULT_LANGUAGE |
English |
Patient language |
OSCAR_CHART_PREFIX |
NEW |
Chart number prefix |
Health Check Improvements¶
- Uses singleton instances (no longer creates services per request)
- Verifies both SOAP and database connectivity
- Returns detailed service status in response
Graceful Shutdown¶
- Database connection pool closes on SIGTERM/SIGINT
- Clean container restarts in Docker/Kubernetes
- Proper logging during shutdown sequence
Changed¶
src/config/environment.js- Added database config and Oscar defaultssrc/services/database-service.js- AddedcreateAdmission(), uses configsrc/transformers/demographic-transformer.js- Uses config for defaultssrc/index.js- Singleton services, improved health check, graceful shutdown
[1.3.1] - 2026-01-13¶
Added - OSCAR REST Bridge v1.2.0 (DB-Based Availability)¶
Provider Availability Endpoint¶
GET /appointments/availability?providerId=&date=queries database directly- Bypasses buggy SOAP
getDayWorkSchedulemethod (returns empty for configured schedules) - Parses Oscar schedule patterns (48-char = 8AM start, 96-char = midnight)
- Returns actual time slots with appointment type codes
Schedule Pattern Parsing¶
- Each character = 15-minute slot
_= unavailable, letters = appointment type code- Example:
____BBBBBBBBBBBB________BBBBBBBBBBBB____________ - Looks up template codes in
scheduletemplatecodetable
Voice Agent Integration¶
oscarRestService.js- AddedgetAvailability()andgetAppointmentTypes()vapiEndpoints.js- find-earliest endpoint uses availability API- Fallback to legacy search if availability returns empty slots
Documentation¶
- Updated oscar-rest-bridge.md with architecture diagram
- Added "Why Two Data Sources?" explanation
- Documented Oscar schedule pattern encoding
- Known Issues section with SOAP bug workaround
[1.3.0] - 2026-01-13¶
Added - Vapi Production Integration¶
Bearer Token Authentication¶
- Replaced API Key auth with Bearer Token + Vapi credentialId
- Created Vapi credential:
02698381-2c38-494d-858e-f8c679ab803a - All 14 tools now use
server.credentialIdfor authentication VAPI_BEARER_TOKENenvironment variable in docker-compose.ymlauthenticateBearerToken()middleware in vapiEndpoints.js
Phone Number Normalization¶
- Caller ID normalization:
+12367770690→2367770690 - System prompt updated with phone handling rules
- Endpoint descriptions updated for Vapi tool calls
- Both formats work: with/without +1 prefix
Name Spelling Confirmation¶
- System prompt updated with spelling confirmation logic
- Handles similar-sounding names (Dawn vs Don, Lee vs Li)
- Spelling verification flow for failed searches
OSCAR Phone Search¶
- Added phone search to REST-SOAP bridge on remote server
GET /api/v1/demographics/search?phone=XXXnow works- Uses existing
findPatientByPhone()method - Normalizes phone before database lookup
Changed¶
- Transcriber: Gladia → Deepgram Nova-3 (multilingual)
- HIPAA Mode: Disabled for transcript storage
- Nginx: Fixed /api/vapi/* routing (removed rewrite, direct proxy)
- Tools: All 14 configured as separate Vapi records with toolIds
Infrastructure¶
- Production-ready Vapi integration validated
- End-to-end phone search tested successfully
- Bearer token auth tested with curl
[1.2.0] - 2026-01-13¶
Added - Infrastructure Hardening¶
Input Validation (Joi)¶
validators/schemas.js- 12 endpoint-specific validation schemas- Canadian healthcare patterns (health card, postal code, province codes)
- Phone number normalization and validation
middleware/validate.js- Validation middleware factory with sanitization
Structured Logging (Pino)¶
lib/logger.js- Pino-based structured logging- PHI field redaction (phone, healthCard, dateOfBirth)
- Request correlation IDs throughout request lifecycle
- Separate log streams for production vs development
Circuit Breaker (Opossum)¶
lib/circuitBreaker.js- OSCAR API circuit breaker- Configurable thresholds (5 failures / 30s window)
- Health status exposure for monitoring
- Graceful degradation during API outages
Health Checks (Kubernetes-ready)¶
lib/healthCheck.js- Comprehensive health check moduleGET /health- Full dependency check (DB, OSCAR, circuit breaker)GET /health/live- Kubernetes liveness probeGET /health/ready- Kubernetes readiness probe
Error Standardization¶
lib/errors.js- APIError class hierarchy- Voice-friendly error messages for Vapi
- Standardized JSON error response format
- Request ID correlation in all errors
Configuration Management¶
config/constants.js- Centralized configuration- Environment validation on startup
- Service metadata and timeouts
- HTTP status code constants
Changed¶
vapiEndpoints.js- Full validation, logging, rate limiting integrationoscarRestService.js- Circuit breaker and structured loggingserver.js- Health endpoints, graceful shutdown, global error handlers- Authentication now fail-closed in production mode
Security¶
- Timing-safe API key comparison (prevents timing attacks)
- Request rate limiting (100 req/min general, 20 req/min booking)
- XSS sanitization in validation middleware
- Removed 40+ console.log statements
Code Review Progress¶
- 32/65 backlog items complete (49%)
- Security: 11/12 items (92%)
- Reliability: 10/13 items (77%)
- Quality: 11/18 items (61%)
[1.1.0] - 2026-01-12¶
Added¶
- BC Health registration requirements (PHN, BC Services Card)
get_clinic_infoendpoint for registration status checkadd_to_waitlistendpoint for new patient queue- Clinic configuration table with registration toggle
- 3-second delay handling in voice agent
- Comprehensive compliance documentation (PIPEDA, PHIPA, SOC2)
Changed¶
- System prompt v2.0 - clinic-agnostic design
- Improved error messages for voice agent
- Updated tools definition to 14 endpoints
Fixed¶
- OSCAR REST Bridge response unwrapping
- Patient search by phone number format
[1.0.0] - 2025-12-29¶
Added¶
- Multi-clinic support with phone number routing
- PostgreSQL database for configuration
- New patient registration flow
- Waitlist management
- Mandarin Chinese language support
- Admin dashboard (basic)
- Call logging and analytics
- Docker Compose deployment
- NGINX reverse proxy with rate limiting
- SSL/TLS with Let's Encrypt
Database Schema¶
clinics- Clinic profilesclinic_config- Per-clinic settingsclinic_hours- Working hoursclinic_holidays- Holiday closuresclinic_providers- Provider display nameswaitlist- New patient queuecall_logs- Call analyticsusers- Admin accountsaudit_logs- Admin action tracking
[0.5.0] - 2025-12-19¶
Added¶
- Initial release
- Single-clinic appointment booking
- Patient lookup by phone (caller ID)
- Patient lookup by name + DOB verification
- Find earliest appointment
- Book appointment
- Reschedule appointment
- Cancel appointment
- Transfer to clinic staff
- English language support
- OSCAR EMR integration (OAuth 1.0a)
Technical¶
- Node.js Express webhook handler
- OSCAR REST Bridge client
- Basic health check endpoint
- PM2 process management
[3.3.0] - Planned¶
Planned Features¶
- LLM bake-off for ZH track (GPT-4o vs alternatives)
- French Canadian language track
- Cantonese language track
- Appointment reminders (outbound)
- SMS confirmation
Planned Technical¶
- Many-to-Many OSCAR routing
- Intelligent failover
- Load balancing
- Webhook retry logic
Completed (moved to v4.0.0)¶
- ~~Onboarding redesign (4-step wizard with validation)~~
- ~~Admin provisioning workflow~~
- ~~OSCAR Config management page~~
Version Numbering¶
Given a version number MAJOR.MINOR.PATCH:
| Component | Meaning |
|---|---|
| MAJOR | Incompatible API changes |
| MINOR | Backwards-compatible functionality |
| PATCH | Backwards-compatible bug fixes |
Release Schedule¶
| Version | Target | Status |
|---|---|---|
| v0.5.0 | Dec 19, 2025 | ✅ Released |
| v1.0.0 | Dec 29, 2025 | ✅ Released |
| v1.1.0 | Jan 12, 2026 | ✅ Released |
| v1.2.0 | Jan 13, 2026 | ✅ Released |
| v1.3.0 | Jan 13, 2026 | ✅ Released |
| v1.3.1 | Jan 13, 2026 | ✅ Released |
| v1.3.2 | Jan 14, 2026 | ✅ Released |
| v1.4.0 | Jan 14, 2026 | ✅ Released |
| v1.5.0 | Jan 14, 2026 | ✅ Released |
| v1.5.1 | Jan 16, 2026 | ✅ Released |
| v1.5.2 | Jan 21, 2026 | ✅ Released |
| v2.0.0 | Feb 02, 2026 | ✅ Released |
| v2.1.0 | Feb 03, 2026 | ✅ Released |
| v2.2.0 | Feb 06, 2026 | ✅ Released |
| v3.0.0 | Feb 10, 2026 | ✅ Released (deployed, testing) |
| v3.1.0 | Feb 11, 2026 | ✅ Released (5 themes: compliance, reliability, onboarding, clinical, support) |
| v3.2.0 | Feb 12, 2026 | ✅ Released (Theme 7: phone number linking, human handover) |
| v3.2.1 | Feb 12, 2026 | ✅ Released (Security hardening sprint: 5 fixes) |
| v3.2.2 | Feb 13, 2026 | ✅ Released (OSCAR ERD & bridge mapping docs) |
| v3.2.3 | Feb 13, 2026 | ✅ Released (OSCAR Schedule Deep Dive) |
| v3.2.4 | Feb 13, 2026 | ✅ Released (ADR-004: Booking Product Architecture) |
| v3.2.5 | Feb 13, 2026 | ✅ Released (Booking Engine Upgrade Master Plan) |
| v3.2.6 | Feb 14, 2026 | ✅ Released (OSCAR Data Architecture — entity reference) |
| v3.2.7 | Feb 14, 2026 | ✅ Released (REST API reference, known bugs, demo data spec) |
| v4.0.0 | Feb 15, 2026 | ✅ Released (Onboarding redesign, admin provisioning) |