Sensitive payloads are never persisted in cleartext. The api ships an EncryptionService keyed by a single ENCRYPTION_KEY env, used by MessageService for chat bodies, NotesService for therapist notes, and the join-payload service for video-room links. The same service is wired with round-trip and tamper-detection tests; rotating the key is a runbook step rather than a code change. Combined with Stripe-signed raw-body webhook verification and JWT-signed upload / download tokens, the data plane stays defensible even if the database is leaked.
- AES-256-GCM, single env-keyed service.
- Used by chat, notes, and video-room join-payloads.
- Tamper-detection + round-trip tests in CI.
- Rotation = runbook, not code.
- JWT-signed upload / download tokens for resources.
- Deep dive · 01
Three-app monorepo
web · api · worker, plus one shared zod-contracts package. Postgres 16 + Redis 7 underneath. npm workspaces, no Turborepo.
- Deep dive · 02
Credit ledger booking model
Every booking action emits a typed ledger entry with a deterministic key. Reschedule preserves the hold; cancel inside the window writes a release; complete writes release + use.
- Deep dive · 04
Stripe webhook + payment ledger
Adapter pattern with a Mock twin for local. Signature-verified raw-body Nest route. Payment.eventId unique. Renewal pipeline gates credits on exact-period payment evidence.
- Deep dive · 05
Tick-loop worker
One tsx loop runs four jobs per tick — reminder scan, renewal scan, no-show sweep, notification dispatch. NotificationEvent rows carry unique dedupeKeys for safe retries.
- Deep dive · 06
Hardened, reproducible deploy
CI typechecks + tests every push and builds signed images for the three apps. One shell script on the host pulls + migrates + restarts. Edge proxy isolates everything behind automated TLS.
Got something
this size?
Big ambitions, we match the energy. Drop a brief — reply within one working day.