Skip to content

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

Merged
teetangh merged 6 commits into
devfrom
chore/booking-cron-money-gates-and-doctrine-drift
Sep 5, 2026
Merged

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
teetangh merged 6 commits into
devfrom
chore/booking-cron-money-gates-and-doctrine-drift

Conversation

@teetangh

@teetangh teetangh commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Summary

  1. expire-stale-requests joins FINANCIAL_JOB_NAMES. Its expirePaymentPendingRequests/expireApprovedUnallocatedSubscriptions passes call refundPaymentsForExpired, 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-shows was already there via fix(booking): auto-complete hands an unattended consultation to the no-show detector instead of closing it first (#1504) #1505.
  2. A registry pin gates every future refund-front-door caller, not just today's two. __tests__/maintenance/cron-lock-registry.test.ts gains one assertion that greps scripts/**/*.ts for callers of refundBookingPayment(, refundWholeEventPayments(, refundRemovedAttendeeSeat(, and refundPaymentsForExpired(, and asserts each caller's withCronLock name is in FINANCIAL_JOB_NAMES.
  3. Two more money-twin routes drop their status: () => 200 override. app/api/cleanup/process-payouts/route.ts and .../sweep-abandoned-overage-charges/route.ts now fall through to cleanup-route.ts's default statusFor, which reads result.success, mirroring release-earnings/sync-payment-earnings under chore(cron): a Netlify scheduled ticker drives the sub-hourly money sweeps #1390.
  4. The no-show cancel writes a BookingStatusHistory row. claimConsultantNoShow in scripts/appointments/detect-consultant-no-shows.ts now runs the CANCELLED transition through transitionConsultationRequest inside prisma.$transaction, instead of a bare consultation.updateMany. The zero-row "someone else moved it" outcome is preserved via IllegalTransitionError catch. Candidate query, grace/handoff constants, refund call and notifications are untouched.
  5. Doctrine text corrected in .claude/skills/booking/SKILL.md. Rule 2 no longer claims expire-stale-requests.ts/cleanup-tentative-slots.ts hard-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 via transitionSlotCompletion). Rule 5 no longer names expirePaymentPendingRequests as 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).
  6. docs/booking/18-state-machines.md's reschedule section corrected. COUNTERED is noted as an unreachable enum edge with no writer (the counter-round was removed per lib/booking/reschedule-proposals.ts), and AUTO_ACCEPTED is documented as the second terminal-acceptance state.
  7. Glossary linked. docs/booking/README.md links docs/enterprise/00-foundations/07-slots-sessions-glossary.md under Core Concepts.
  8. DEGRADED gate noted in both cron references. docs/booking/13-cron-jobs-and-background-tasks.md's Safety paragraphs and docs/maintenance/04-cron-jobs-reference.md's table rows for both jobs now say they are held during DEGRADED as well as OFFLINE.
  9. Consolidated train changelog. One new ## Changelog: 2026-09-05 — booking closure train section in docs/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 surviving MANUAL_REVIEW path" 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.ts
  • app/api/cleanup/process-payouts/route.ts
  • app/api/cleanup/sweep-abandoned-overage-charges/route.ts
  • scripts/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.md
  • docs/booking/18-state-machines.md
  • docs/booking/README.md
  • docs/booking/13-cron-jobs-and-background-tasks.md
  • docs/maintenance/04-cron-jobs-reference.md
  • docs/booking/05-troubleshooting-and-changelog.md

Verification

Check Result
rm tsconfig.tsbuildinfo && NODE_OPTIONS=--max-old-space-size=8192 npx tsc --noEmit (after rebase onto 01a377342) exit 0, no errors
npx eslint on all 7 changed/new code files 0 problems
npx prettier --check on all 7 changed/new code files clean
npx prettier --check on the 6 changed docs files 5 clean; docs/booking/18-state-machines.md was already Prettier-dirty on origin/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-clean
npx jest __tests__/maintenance __tests__/booking __tests__/appointments (after rebase) exit 0 — 87 suites, 1348 tests passed
Two suites mocked Prisma without $transaction (__tests__/booking/no-show-refund-front-door.test.ts, __tests__/maintenance/no-show-auto-complete-handoff.test.ts) extended the mocks with $transaction, consultation.findUnique, and bookingStatusHistory.create rather than weakening any assertion

Not done

  • None of the six numbered spec items were skipped.

Closes #1506
Part of #1338
Part of #1493
Part of #1420

🤖 Generated with Claude Code

https://claude.ai/code/session_01EyngsXG829TRTBof4CSGT1

teetangh and others added 2 commits September 5, 2026 23:54
…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
@netlify

netlify Bot commented Sep 5, 2026

Copy link
Copy Markdown

Deploy Preview for familiarise ready!

Name Link
🔨 Latest commit e5c4441
🔍 Latest deploy log https://app.netlify.com/projects/familiarise/deploys/6a9ca12d621afa0008f4d5c3
😎 Deploy Preview https://deploy-preview-1516--familiarise.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 30 (🔴 down 23 from production)
Accessibility: 90 (no change from production)
Best Practices: 83 (no change from production)
SEO: 90 (🟢 up 8 from production)
PWA: -
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 21 minutes.

Check out review usage here.

View limit details

Limit 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.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Essentials

Run ID: e448a50f-b9a3-43c4-ab81-4c24efaa97dd

📥 Commits

Reviewing files that changed from the base of the PR and between eee250e and e5c4441.

📒 Files selected for processing (13)
  • .claude/skills/booking/SKILL.md
  • __tests__/booking/no-show-refund-front-door.test.ts
  • __tests__/maintenance/cron-lock-registry.test.ts
  • __tests__/maintenance/no-show-auto-complete-handoff.test.ts
  • app/api/cleanup/process-payouts/route.ts
  • app/api/cleanup/sweep-abandoned-overage-charges/route.ts
  • docs/booking/05-troubleshooting-and-changelog.md
  • docs/booking/13-cron-jobs-and-background-tasks.md
  • docs/booking/18-state-machines.md
  • docs/booking/README.md
  • docs/maintenance/04-cron-jobs-reference.md
  • lib/maintenance-cron.ts
  • scripts/appointments/detect-consultant-no-shows.ts

Comment @coderabbitai help to get the list of available commands.

…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
@teetangh
teetangh marked this pull request as ready for review September 5, 2026 18:28
@teetangh

teetangh commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. Your current included review allowance is based on your included PR review attempts over the past 7 days. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 40 minutes.

@sonarqubecloud

sonarqubecloud Bot commented Sep 5, 2026

Copy link
Copy Markdown

@teetangh
teetangh merged commit 363e074 into dev Sep 5, 2026
8 checks passed
@teetangh
teetangh deleted the chore/booking-cron-money-gates-and-doctrine-drift branch September 5, 2026 23:41
teetangh added a commit that referenced this pull request Sep 6, 2026
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant