You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Big Pickle — Overall Verdict on the Booking Subsystem (HLD + LLD)
Companion to#1421[Big Pickle][finance] Overall Verdict on the Financial Subsystem. This is the booking verdict in the same series. Together #1421 + this issue cover the whole bookable-deliverable + money surface.
Parents/umbrellas referenced:#1319 (booking + maintenance wave-5 umbrella, OPEN), #1332 (booking + payments architecture tracker, OPEN). #837 (B2C state-machine hardening) and #687 (invoice-funded credit-risk) are CLOSED/merged — their live threads live on in the issues they spawned.
Scope rule (per product): DST / IANA-TZID work is excluded from launch — most customers are Indian before foreigners. It stays as #872 (post-MVP) + #1168 (schedulingTimezone grid, post-MVP). Not re-scoped here.
1. Executive verdict
The booking subsystem is architecturally sound and launch-safe for its core booking path:
Three-layer concurrency defense is in place and reviewed: Redis lock → GiST EXCLUDE constraint → Serializable SSI with retry. This is the right shape for a double-booking-prone system.
Hold-then-confirm two-phase (tentative slots held at booking, confirmed on payment) is correct and matches how the availability/occupancy model is taught in docs/booking/03-slot-math.
CAS state machine is the single source of truth (lib/booking/transitions.ts) and is applied across most transitions.
Refund front doors and explicit org scoping are enforced per the booking-doctrine.
What remains is NOT a rebuild — it is a set of pre-launch P0/P1 correctness + display items and a P2/P3 backlog. The most important patterns:
Money/consent/wallet failures are invisible to customers (P1, UI): WALLET_FROZEN, CONSENT_REQUIRED, CONSENT_WITHDRAWN degrade to a generic "Something Went Wrong"; wallet-freeze has no org-side banner. This is the single biggest launch risk in the customer-facing layer.
Two crons bypass the CAS/audit discipline (P1, backend): the expire-stale and reconcile-slot scripts use raw updateMany. They can silently overwrite a concurrent writer's state and leave NO audit trail.
Tentative (held-pending-payment) state is mis-rendered (P1, UI): SessionTimeline drops all tentative sessions, so a held booking looks unscheduled with no urgency CTA.
Nothing in this verdict changes the previously-frozen acceptance posture: no db push against the shared Supabase project; verify against the seeded dev-server + mock payments (see booking-verification runbook).
2. Verified-correct posture (do NOT regress)
These were re-confirmed against the current code and are considered correct by design:
CAS status transitions through the seven helpers for the interactive path (booking, approval, reschedule, cancel, refund issuance).
Hold-then-confirm ordering with Payment.expiresAt tentativeness — tentative holds release on expiry.
Explicit org scoping on B2B-funded booking writes.
PENDING_TRUST earnings are NOT stranded — jobs/cleanup/release-pending-trust-earnings.ts promotes PENDING_TRUST → PENDING once the sponsoring org activates or pays an invoice, with CAS + fail-closed cron lock. (An earlier hypothesis that this was a bug is withdrawn — verified handled.)
PENDING_TRUST badge is correctly surfaced (lib/labels/session-labels.ts:445-448).
Non-INR pending-payment display and rate-null currency safety are correct (no double-conversion / no INR-relabel as USD).
3. P0 — launch blockers
Nothing in this audit is a new P0 of its own beyond what is already filed. The existing P0s stand:
No dunning-suspend banner / consent pre-flight on org-funded surfaces — blocks only appear at failed checkout (P1 the moment ENABLE_DUNNING_SUSPEND ships)
Group-event (webinar/class) cancellation refunds/notifies nobody; attendee earnings never reversed
5.4 Backlog items not yet filed (tracker candidates)
Collaborator TDS split across HOST orgs — revenue split vs statutory TDS deduction for a collaborator belonging to a different org than the plan host: open question, needs a decision (B2B, consider filing separately with a design doc).
Handoff doc — wave-5 status, open residuals, next moves
documentation
7. Backend-core vs UI split (executive view)
Backend core is healthy; the highest-risk defect class is in the UI/display layer, specifically where a backend business-rejection or state is not surfaced:
Recommended emphasis: schedule the four P1 UI items (#1426, #1427, #1428, #1429) together as one "customer-facing booking fidelity" workstream, and the two cron bypasses (#1423, #1424) together with #1341/#1411/#1413 as the "cron correctness" workstream.
8. New findings filed in this verdict (this series)
These are the 10 findings this audit added, all now open as individual issues (per the #1421[Big Pickle] pattern):
Per the booking-verification runbook: changes to any P0/P1 item above must be proven against the seeded dev-server + mock payments (never db push against the shared Supabase project), with the jest suites under __tests__/booking-algorithm, __tests__/booking, __tests__/payments, and __tests__/enterprise as the correctness gate. The UI findings (#1426-#1430) additionally need a visual check on the affected surfaces (appointment detail, org billing, checkout).
Big Pickle — Overall Verdict on the Booking Subsystem (HLD + LLD)
1. Executive verdict
The booking subsystem is architecturally sound and launch-safe for its core booking path:
EXCLUDEconstraint → Serializable SSI with retry. This is the right shape for a double-booking-prone system.docs/booking/03-slot-math.lib/booking/transitions.ts) and is applied across most transitions.What remains is NOT a rebuild — it is a set of pre-launch P0/P1 correctness + display items and a P2/P3 backlog. The most important patterns:
WALLET_FROZEN,CONSENT_REQUIRED,CONSENT_WITHDRAWNdegrade to a generic "Something Went Wrong"; wallet-freeze has no org-side banner. This is the single biggest launch risk in the customer-facing layer.updateMany. They can silently overwrite a concurrent writer's state and leave NO audit trail.SessionTimelinedrops all tentative sessions, so a held booking looks unscheduled with no urgency CTA.Nothing in this verdict changes the previously-frozen acceptance posture: no
db pushagainst the shared Supabase project; verify against the seeded dev-server + mock payments (seebooking-verificationrunbook).2. Verified-correct posture (do NOT regress)
These were re-confirmed against the current code and are considered correct by design:
Payment.expiresAttentativeness — tentative holds release on expiry.jobs/cleanup/release-pending-trust-earnings.tspromotes PENDING_TRUST → PENDING once the sponsoring org activates or pays an invoice, with CAS + fail-closed cron lock. (An earlier hypothesis that this was a bug is withdrawn — verified handled.)lib/labels/session-labels.ts:445-448).3. P0 — launch blockers
Nothing in this audit is a new P0 of its own beyond what is already filed. The existing P0s stand:
openForAppointmentIddanglingsum(legs) === Payment.amountmoney invariant4. P1 — must fix before/at launch
4.1 Backend core
updateManybypass the CAS state machine AND the audit trail; APPROVED→EXPIRED is undocumented intransitions.tsisTentativewith a blindupdateMany— TOCTOU, no parent-status re-check4.2 UI — customer-facing (money/consent/wallet/tentative)
WALLET_FROZEN/CONSENT_REQUIRED/CONSENT_WITHDRAWN→ generic "Something Went Wrong" (classification + toast map)moneyMoveBlockedignores it4.3 Availability / slot segmentation (B2C)
startDaysemantics inconsistent across write/read/display/validationutcOffsetMinutes(UTC-3 on IST consultant)5. P2 — first 90 days
5.1 Backend core
mintRefundCreditNoteXNOR guard inverted (!refundId === !disputeId) — latentcalculateRequiredSlotssilently defaults consultation/webinar to 2 atoms on missing duration (class throws)5.2 UI — customer-facing
isTentative=false(party asymmetry); detail "Pay Now" skips branded checkout; slot-picker lacks TRIAL typeENABLE_DUNNING_SUSPENDships)5.3 B2B / org-funded
5.4 Backlog items not yet filed (tracker candidates)
6. P3 / tech-debt / deferred
7. Backend-core vs UI split (executive view)
Backend core is healthy; the highest-risk defect class is in the UI/display layer, specifically where a backend business-rejection or state is not surfaced:
WALLET_FROZEN,CONSENT_REQUIRED, 409s) — but the front-end mangles them into a generic toast ([booking][P1 HIGH] WALLET_FROZEN / CONSENT_REQUIRED / CONSENT_WITHDRAWN checkout errors fall through to a generic 'Something Went Wrong' toast #1426).Recommended emphasis: schedule the four P1 UI items (#1426, #1427, #1428, #1429) together as one "customer-facing booking fidelity" workstream, and the two cron bypasses (#1423, #1424) together with #1341/#1411/#1413 as the "cron correctness" workstream.
8. New findings filed in this verdict (this series)
These are the 10 findings this audit added, all now open as individual issues (per the #1421
[Big Pickle]pattern):isTentativeclear, TOCTOUmintRefundCreditNoteinverted XNOR guardcalculateRequiredSlotssilent 2-atom default (consultation/webinar)9. Prioritized remediation index (P0 → P3)
SlotAllocationService(4,357 LOC) andcheckout.ts(3,808 LOC) #1375, Consultant planner has no archive path for booked plans #1058, [RESILIENCE] Session overrun detection and conflict prevention #472, Draw the slot grid in schedulingTimezone so the columns match the caps being enforced #1168, DST / IANA-TZID: reader flip over the dual-written local availability columns (post-MVP) #872, [HANDOFF] Booking productionization wave 5 → next session: status, what is correct, open defects, recommended next moves (2026-09-03) #133810. Verification posture
Per the booking-verification runbook: changes to any P0/P1 item above must be proven against the seeded dev-server + mock payments (never
db pushagainst the shared Supabase project), with the jest suites under__tests__/booking-algorithm,__tests__/booking,__tests__/payments, and__tests__/enterpriseas the correctness gate. The UI findings (#1426-#1430) additionally need a visual check on the affected surfaces (appointment detail, org billing, checkout).