Prioritized list of issues from the January 2026 code review, with current status as of February 12, 2026.
Progress Summary
Last Updated: February 12, 2026
| Phase |
Total Items |
Completed |
Progress |
| Phase 1: Security |
12 |
12 |
✅ 100% |
| Phase 2: Compliance |
12 |
9 |
🟢 75% |
| Phase 3: Reliability |
13 |
10 |
🟢 77% |
| Phase 4: Performance |
10 |
0 |
⬜ 0% |
| Phase 5: Quality |
18 |
12 |
🟢 67% |
| Total |
65 |
43 |
66% |
Key Milestones
- Jan 13, 2026 — Initial review complete, 13/65 items done (20%)
- Jan 14-21 — v1.2.0–v1.5.2: Validation, logging, circuit breaker, health checks, admin system
- Feb 02-06 — v2.0.0–v2.2.0: Squad architecture, multi-auth webhook, EMR adapter pattern
- Feb 10-11 — v3.0.0–v3.1.0: Dual-track voice agent, compliance (encryption, audit, retention), Zod schemas
- Feb 12 — v3.2.1: Security hardening sprint (5 targeted fixes)
Phase 1: Security Foundation — ✅ COMPLETE
1.1 Fix Authentication Bypasses
| ID |
Task |
Status |
Resolution |
| SEC-001 |
Remove webhook secret placeholder bypass |
✅ DONE |
vapi-auth.ts HMAC-SHA256 mandatory in prod |
| SEC-002 |
Remove API key bypass |
✅ DONE |
Fail-closed in production mode |
| SEC-003 |
Fail startup if secrets not configured |
✅ DONE |
Zod validation in config/env.ts |
| SEC-004 |
Add JWT secret validation |
✅ DONE |
Zod enforces min 16 chars in production |
1.2 Lock Down CORS
| ID |
Task |
Status |
Resolution |
| SEC-005 |
Replace wildcard CORS with whitelist |
✅ DONE |
CORS_ORIGIN configured |
| SEC-006 |
Configure allowed origins per environment |
✅ DONE |
Via env var |
| ID |
Task |
Status |
Resolution |
| SEC-007 |
Add Zod schemas for all endpoints |
✅ DONE |
18 schemas in validation/schemas.ts |
| SEC-008 |
Validate phone number formats |
✅ DONE |
Zod string patterns |
| SEC-009 |
Validate date/time formats |
✅ DONE |
Zod date/string validation |
| SEC-010 |
Sanitize patient name inputs |
✅ DONE |
Zod .strict() enforcement |
| ID |
Task |
Status |
Resolution |
| SEC-011 |
Add helmet.js middleware |
✅ DONE |
helmet() in index.ts |
| SEC-012 |
Configure CSP headers |
✅ DONE |
Via Helmet defaults |
Phase 2: Compliance — 🟢 75%
2.1 Implement Audit Logging
| ID |
Task |
Status |
Resolution |
| COMP-001 |
Create audit log service |
✅ DONE |
services/audit.service.ts |
| COMP-002 |
Log all PHI access |
✅ DONE |
middleware/audit.ts on all POST/PUT/DELETE |
| COMP-003 |
Log all admin actions |
✅ DONE |
Auto-captured via middleware |
| COMP-004 |
Make audit logs immutable |
✅ DONE |
Append-only, no DELETE endpoint |
| COMP-005 |
Add audit log retention policy |
✅ DONE |
jobs/data-retention.ts (node-cron, 3 AM daily) |
2.2 Encrypt Stored Credentials
| ID |
Task |
Status |
Resolution |
| COMP-006 |
Implement encryption service |
✅ DONE |
lib/crypto.ts AES-256-GCM |
| COMP-007 |
Encrypt OAuth secrets at rest |
✅ DONE |
oscarConsumerSecretEnc, oscarTokenSecretEnc |
| COMP-008 |
Implement key rotation |
⬜ TODO |
Deferred — requires KMS/Vault |
| COMP-009 |
Migrate existing plaintext secrets |
✅ DONE |
Encrypted on save |
2.3 Add RBAC Enforcement
| ID |
Task |
Status |
Resolution |
| COMP-010 |
Define permission matrix |
✅ DONE |
VITARA_ADMIN, CLINIC_MANAGER roles |
| COMP-011 |
Implement permission checks |
⬜ TODO |
Basic role checks exist, granular permissions pending |
| COMP-012 |
Add clinic isolation checks |
⬜ TODO |
clinicId scoping exists but not enforced at DB layer |
Phase 3: Reliability — 🟢 77%
3.1 Add Rate Limiting
| ID |
Task |
Status |
Resolution |
| REL-001 |
Add rate limiting to webhook endpoint |
✅ DONE |
express-rate-limit 300/min |
| REL-002 |
Implement per-clinic rate limits |
⬜ TODO |
Global limits only |
| REL-003 |
Use Redis for rate limit storage |
⬜ TODO |
In-memory (fine for single instance) |
3.2 Implement Circuit Breaker
| ID |
Task |
Status |
Resolution |
| REL-004 |
Add opossum circuit breaker |
✅ DONE |
Wraps all OSCAR Bridge calls |
| REL-005 |
Configure breaker thresholds |
✅ DONE |
5 failures / 30s window |
| REL-006 |
Add breaker status to health check |
✅ DONE |
/health includes circuit breaker state |
3.3 Fix Connection Pooling
| ID |
Task |
Status |
Resolution |
| REL-007 |
Create shared pool module |
✅ DONE |
Prisma ORM with connection pooling |
| REL-008 |
Remove duplicate pool creations |
✅ DONE |
Single Prisma client |
| REL-009 |
Add pool monitoring |
✅ DONE |
Via health service DB ping |
3.4 Improve Health Checks
| ID |
Task |
Status |
Resolution |
| REL-010 |
Add database health check |
✅ DONE |
health.service.ts DB ping |
| REL-011 |
Add OSCAR connectivity check |
✅ DONE |
Bridge /health + latency |
| REL-012 |
Add Redis health check |
⬜ TODO |
No Redis in stack yet |
| REL-013 |
Return proper HTTP codes |
✅ DONE |
200 healthy, 200 degraded, 503 down |
Deferred until post-launch. Current scale does not require these optimizations.
| ID |
Task |
Status |
Notes |
| PERF-001 |
Add Redis caching |
⬜ TODO |
Not needed at demo scale |
| PERF-002 |
Cache clinic config |
⬜ TODO |
EmrAdapterFactory has 5-min cache |
| PERF-003 |
Cache provider list |
⬜ TODO |
— |
| PERF-004 |
Add cache invalidation |
⬜ TODO |
— |
| PERF-005 |
Refactor getClinicInfo to use JOINs |
⬜ TODO |
Prisma handles joins |
| PERF-006 |
Batch provider queries |
⬜ TODO |
find_earliest N+1 (works at scale) |
| PERF-007 |
Add query performance logging |
⬜ TODO |
— |
| PERF-008 |
Add request queue for OSCAR |
⬜ TODO |
— |
| PERF-009 |
Move long operations to workers |
⬜ TODO |
— |
| PERF-010 |
Add request timeout handling |
⬜ TODO |
Circuit breaker provides fallback |
Phase 5: Quality — 🟢 67%
5.1 Replace Debug Logging
| ID |
Task |
Status |
Resolution |
| QUAL-001 |
Add structured logger (pino) |
✅ DONE |
lib/logger.ts Pino + pino-http |
| QUAL-002 |
Replace all console.log |
✅ DONE |
~30 replaced with structured logger |
| QUAL-003 |
Add log redaction for PHI |
✅ DONE |
redactPhi() in vapi-webhook.ts (v3.2.1) |
| QUAL-004 |
Configure log levels per environment |
✅ DONE |
JSON prod, pretty-print dev |
5.2 Consolidate Code
| ID |
Task |
Status |
Resolution |
| QUAL-005 |
Identify canonical vapiEndpoints |
✅ DONE |
vapi-webhook.ts (TypeScript rewrite) |
| QUAL-006 |
Merge functionality |
✅ DONE |
Single route handler file |
| QUAL-007 |
Delete dead versions |
✅ DONE |
All -updated.js, -vitara.js removed |
| QUAL-008 |
Standardize error response format |
✅ DONE |
{ success, message } + global error handler |
5.3 Fix Schema Drift
| ID |
Task |
Status |
Resolution |
| QUAL-009 |
Choose canonical schema |
✅ DONE |
Prisma schema.prisma (13 models) |
| QUAL-010 |
Create migration path |
✅ DONE |
Prisma Migrate |
| QUAL-011 |
Remove deprecated schema |
✅ DONE |
Old SQL files removed |
| QUAL-012 |
Add schema validation in CI |
⬜ TODO |
No CI pipeline yet |
5.4 Add Test Suite
| ID |
Task |
Status |
Resolution |
| QUAL-013 |
Set up test framework |
✅ DONE |
Jest configured (v1.5.0) |
| QUAL-014 |
Write unit tests for utils |
⬜ TODO |
— |
| QUAL-015 |
Write unit tests for validators |
✅ DONE |
58 validator tests |
| QUAL-016 |
Write integration tests for endpoints |
⬜ TODO |
Critical gap: webhook handlers |
| QUAL-017 |
Add test coverage reporting |
⬜ TODO |
— |
| QUAL-018 |
Set minimum coverage threshold (60%) |
⬜ TODO |
— |
5.5 Move Hardcoded Values
| ID |
Task |
Status |
Resolution |
| QUAL-019 |
Create constants config file |
✅ DONE |
config/env.ts Zod-validated |
| QUAL-020 |
Extract all magic numbers |
⬜ TODO |
Most moved, some remain in webhook handlers |
| QUAL-021 |
Document all configuration options |
✅ DONE |
Handoff package + env template |
Production Launch Backlog (v3.2.1+)
Additional items identified during the February 2026 hardening sprint:
| ID |
Issue |
Priority |
Notes |
| BL-01 |
JWT token revocation (server-side blacklist) |
Medium |
1h window acceptable for demo |
| BL-02 |
Redis-backed rate limiting |
Medium |
In-memory fine for single PM2 instance |
| BL-03 |
Multi-tenant OSCAR wiring (full OAuth creds in adapter) |
High |
Required before onboarding second clinic |
| BL-04 |
Query optimization: find_earliest N+1 |
Medium |
Works at demo scale |
| BL-05 |
Clinic timezone in adapter (hardcoded America/Vancouver) |
Medium |
Needed before non-BC clinic |
| BL-06 |
Remove dead stub tools (getUpcomingAppointments, sendConfirmationSMS) |
Low |
Not in v3 squad |
| BL-07 |
Appointment booking idempotency (atomic check-and-create) |
Medium |
Race condition only under Vapi retry |
| BL-08 |
Webhook handler integration tests |
High |
Zero test coverage on most critical code |
| BL-09 |
Monitoring + alerting (Prometheus/Grafana) |
High |
No visibility into production health |
| BL-10 |
Run install-cron.sh for backup automation |
Low |
Operational task |
| BL-11 |
Investigate OSCAR EMR REST API gaps vs REST Bridge |
Research |
API coverage review |
Definition of Done
An item is complete when:
- Code changes implemented
- Unit tests written and passing (where applicable)
- TypeScript compiles cleanly (
npx tsc --noEmit)
- PM2 restart successful + health check passes
- Documentation updated
- Verified in running environment
Backlog created: January 13, 2026
Last updated: February 12, 2026 (v3.2.1)