chore(booking): the two refunding sweeps are gated in DEGRADED maintenance, no-show cancels write history, and the doctrine text matches the sweeps (#1506) - #1516
Conversation
…nance, and no-show cancels write history (#1506) Gates expire-stale-requests in FINANCIAL_JOB_NAMES alongside detect-consultant-no-shows (#1505), adds a registry pin that greps scripts/** for callers of the four refund front doors and asserts each one's withCronLock name is gated, drops the status override on two more money-twin routes per #1390, and routes the no-show cancel through transitionConsultationRequest so it appends a BookingStatusHistory row (#1493). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EyngsXG829TRTBof4CSGT1
…train changelog is consolidated (#1420) Corrects two stale doctrine paragraphs in .claude/skills/booking/SKILL.md (rule 2's hard-delete claim, superseded by #1380/#1424's soft-cancel; rule 5's counter-example, superseded by #1423's CAS fix), corrects the reschedule section of docs/booking/18-state-machines.md (COUNTERED has no writer, AUTO_ACCEPTED exists), links the slots-and-sessions glossary from docs/booking/README.md, notes the DEGRADED gate for the two refunding sweeps in both cron references, and adds one consolidated changelog section for the 2026-09-05 booking closure train while fixing the stale "only surviving MANUAL_REVIEW path" sentence #1513 obsoletes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EyngsXG829TRTBof4CSGT1
✅ Deploy Preview for familiarise ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Warning Review limit reachedNext included review available in 21 minutes. View limit detailsLimit details: You’ve used the included review currently available. Your 90 included PR review attempts over the past 7 days set your current allowance at 1 review per hour. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Essentials Run ID: 📒 Files selected for processing (13)
Comment |
…t summarises (#1506) The summary table said twenty jobs were on the financial list while the set already held twenty-two before this PR and holds twenty-four after it; the number is recounted from FINANCIAL_JOB_NAMES. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EyngsXG829TRTBof4CSGT1
|
@coderabbitai full review |
|
|
…1523) ## Summary Release of the 2026-09-05/06 booking backlog closure train plus the fixes found by the end-to-end pass on the dev deploy. Base: prod at 576b97c; head: dev at 9b45a82. ## Schema Additive only, already pushed to the shared database on 2026-09-06 with sidecars applied and asserted (45 constraints / 6 indexes / 3 triggers): `CancellationPolicy`, `CancellationPolicyTier`, `Appointment.cancellationPolicyId` (+ index), enum `CancellationPolicyStatus`. The platform default policy row is provisioned. Backup: `familiarise-pre-schema-push-20260906-0423.dump`. No push is needed for this release. ## Commits (dev not in prod) - 9b45a82 fix(booking): allocation-lock deserialization, reschedule auto-confirm diagnostics, Razorpay CSP, planner class dates (#1520) - ea46cd9 fix(booking): the initial-allocation advisory lock runs through $executeRaw so nothing deserialises a void column (#1518) (#1519) - 363e074 chore(booking): the two refunding sweeps are gated in DEGRADED maintenance, no-show cancels write history, and the doctrine text matches the sweeps (#1506) (#1516) - eee250e feat(booking): cancellation terms are typed versioned rows with per-org tiers, and a credit-funded partial cancel restores the credit in full (#1499, #1500, #1372) (#1513) - a800874 fix(booking): the allocator no longer declines the reschedule proposal it is confirming, and accept serialises on the appointment lock (#1340) (#1515) - 7a0bf0a fix(booking): the cancel and reschedule routes move status through the CAS helpers, and cancelled slots are tombstoned (#1383) - 01a3773 fix(booking): weekly availability rows mean the consultant's local day everywhere, and day segments are half-open (#1343, #1342, #1326, #1348, #1415, #1416) (#1512) - 73c0d9f fix(dashboard): the consultant Home badge counts personal requests like the card below it, class cards show their first session, and a trial's Pay Now lands on the branded checkout (#1345, #1346, #1429) (#1514) - a0d6c09 fix(booking): auto-complete hands an unattended consultation to the no-show detector instead of closing it first (#1504) (#1505) - a7c36ec fix(content): honest public stats, and a plan title instead of a UUID in the payment-success notification (#1484, #1485) (#1489) - fe0c476 chore(skills,agents): reorganise Claude Code skills and agents into a domain hierarchy (#1483) - b760943 chore(ci): make Claude review/mention workflows on-demand, not a red check (#1480) - 9dc665a feat(plans): sole-owner archive/restore for consultation, subscription, webinar and class plans (#1507) ## Verification - Every PR merged green (Lint, TypeScript/Tests/Build, SonarCloud gate OK, CodeRabbit threads triaged and resolved). - End-to-end on the dev branch deploy (Chrome DevTools + Supabase MCP): availability day anchoring, Home badge parity, org tier editor incl. negative cases, org-funded checkout stamping the org policy version and refunding 100% on the INTERNAL rail, personal booking stamping the platform row, DEGRADED-gate probe 401, no console errors or 5xx. - Post-fix re-verification on the same deploy (9b45a82): planner class cards show the first session (payload `firstSessionAt` 2026-09-10T10:00Z, card 3:30 PM IST); a consultee proposal on a green slot auto-confirms (`autoConfirmed: true`, request `AUTO_ACCEPTED`, slots moved, history rows PENDING → RESCHEDULED ×2 → APPROVED → AUTO_ACCEPTED). ## Owner items unchanged by this release - Novu: production uses the Development environment key and the account's workflow limit blocks creating the two missing workflows (#1511). - Resend key (#1298), Razorpay LIVE keys (#1377), load gate (#874). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01EyngsXG829TRTBof4CSGT1




Summary
expire-stale-requestsjoinsFINANCIAL_JOB_NAMES. ItsexpirePaymentPendingRequests/expireApprovedUnallocatedSubscriptionspasses callrefundPaymentsForExpired, a refund front-door caller like every other job already in the set, so DEGRADED maintenance now holds it with the rest.detect-consultant-no-showswas already there via fix(booking): auto-complete hands an unattended consultation to the no-show detector instead of closing it first (#1504) #1505.__tests__/maintenance/cron-lock-registry.test.tsgains one assertion that grepsscripts/**/*.tsfor callers ofrefundBookingPayment(,refundWholeEventPayments(,refundRemovedAttendeeSeat(, andrefundPaymentsForExpired(, and asserts each caller'swithCronLockname is inFINANCIAL_JOB_NAMES.status: () => 200override.app/api/cleanup/process-payouts/route.tsand.../sweep-abandoned-overage-charges/route.tsnow fall through tocleanup-route.ts's defaultstatusFor, which readsresult.success, mirroringrelease-earnings/sync-payment-earningsunder chore(cron): a Netlify scheduled ticker drives the sub-hourly money sweeps #1390.BookingStatusHistoryrow.claimConsultantNoShowinscripts/appointments/detect-consultant-no-shows.tsnow runs the CANCELLED transition throughtransitionConsultationRequestinsideprisma.$transaction, instead of a bareconsultation.updateMany. The zero-row "someone else moved it" outcome is preserved viaIllegalTransitionErrorcatch. Candidate query, grace/handoff constants, refund call and notifications are untouched..claude/skills/booking/SKILL.md. Rule 2 no longer claimsexpire-stale-requests.ts/cleanup-tentative-slots.tshard-delete tentative holds (fixed by fix(booking): free the last tentative holds by status, and route the last bare slot-status writes through the CAS helpers #1380/[booking][P1 HIGH] reconcile-slot-availability clears isTentative with a blind updateMany — no parent-status/CAS re-check (TOCTOU on paid-tentative slots) #1424's soft-cancel viatransitionSlotCompletion). Rule 5 no longer namesexpirePaymentPendingRequestsas the doctrine's counter-example (fixed by [booking][P1 HIGH] expire-stale-requests crons bypass the CAS state machine and the audit trail (raw updateMany, APPROVED->EXPIRED undocumented) #1423's CAS + money-predicate rewrite).docs/booking/18-state-machines.md's reschedule section corrected.COUNTEREDis noted as an unreachable enum edge with no writer (the counter-round was removed perlib/booking/reschedule-proposals.ts), andAUTO_ACCEPTEDis documented as the second terminal-acceptance state.docs/booking/README.mdlinksdocs/enterprise/00-foundations/07-slots-sessions-glossary.mdunder Core Concepts.docs/booking/13-cron-jobs-and-background-tasks.md's Safety paragraphs anddocs/maintenance/04-cron-jobs-reference.md's table rows for both jobs now say they are held during DEGRADED as well as OFFLINE.## Changelog: 2026-09-05 — booking closure trainsection indocs/booking/05-troubleshooting-and-changelog.md, with one subsection per train PR (fix(booking): weekly availability rows mean the consultant's local day everywhere, and day segments are half-open (#1343, #1342, #1326, #1348, #1415, #1416) #1512, feat(booking): cancellation terms are typed versioned rows with per-org tiers, and a credit-funded partial cancel restores the credit in full (#1499, #1500, #1372) #1513, fix(dashboard): the consultant Home badge counts personal requests like the card below it, class cards show their first session, and a trial's Pay Now lands on the branded checkout (#1345, #1346, #1429) #1514, fix(booking): the allocator no longer declines the reschedule proposal it is confirming, and accept serialises on the appointment lock (#1340) #1515, this PR), written from each PR's merged/open body. Also fixes the stale "only survivingMANUAL_REVIEWpath" sentence that feat(booking): cancellation terms are typed versioned rows with per-org tiers, and a credit-funded partial cancel restores the credit in full (#1499, #1500, #1372) #1513 obsoletes.Files
lib/maintenance-cron.tsapp/api/cleanup/process-payouts/route.tsapp/api/cleanup/sweep-abandoned-overage-charges/route.tsscripts/appointments/detect-consultant-no-shows.ts__tests__/maintenance/cron-lock-registry.test.ts__tests__/booking/no-show-refund-front-door.test.ts__tests__/maintenance/no-show-auto-complete-handoff.test.ts.claude/skills/booking/SKILL.mddocs/booking/18-state-machines.mddocs/booking/README.mddocs/booking/13-cron-jobs-and-background-tasks.mddocs/maintenance/04-cron-jobs-reference.mddocs/booking/05-troubleshooting-and-changelog.mdVerification
rm tsconfig.tsbuildinfo && NODE_OPTIONS=--max-old-space-size=8192 npx tsc --noEmit(after rebase onto01a377342)npx eslinton all 7 changed/new code filesnpx prettier --checkon all 7 changed/new code filesnpx prettier --checkon the 6 changed docs filesdocs/booking/18-state-machines.mdwas already Prettier-dirty onorigin/dev(unpadded tables and a wrapped bullet outside the section I touched) and is left as-is per the existing project pattern (see #1514's note on the same posture); the lines I added are themselves Prettier-cleannpx jest __tests__/maintenance __tests__/booking __tests__/appointments(after rebase)$transaction(__tests__/booking/no-show-refund-front-door.test.ts,__tests__/maintenance/no-show-auto-complete-handoff.test.ts)$transaction,consultation.findUnique, andbookingStatusHistory.createrather than weakening any assertionNot done
Closes #1506
Part of #1338
Part of #1493
Part of #1420
🤖 Generated with Claude Code
https://claude.ai/code/session_01EyngsXG829TRTBof4CSGT1