Subscriptions don't grant a counter — they grant ledger entries. CreditLedger + CreditLedgerEntry record HOLD, HOLD_RELEASE, USE and RENEWAL events with deterministic idempotency keys per appointment. Reschedule preserves the original ledgerHoldEntryId so a webhook retry or a UI double-click can never double-credit. Cancel inside the configured 24-hour window writes a HOLD_RELEASE; complete writes both HOLD_RELEASE and USE. Renewals are gated on exact-period payment evidence — no payment, no credit grant; the subscription flips to PAST_DUE.
- HOLD on book; HOLD_RELEASE + USE on complete; HOLD_RELEASE on cancel-in-window.
- Deterministic dedupe keys per appointment — retries safe.
- Reschedule preserves ledgerHoldEntryId.
- Renewal credits gated on payment evidence; PAST_DUE on miss.
- Replaces a counter with an auditable journal.
- 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 · 03
Encryption at rest
AES-256-GCM via a single EncryptionService, shared across messages, therapist notes, and Daily-room join payloads. Round-trip + tamper-detection unit tests.
- 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.