Repository navigation
Conversation
Block buying a Reset Pass above 95% of the monthly cycle credit allowance and redeeming one above 90%, since a pass restores a weekly cap with nothing left to spend against. Purchases were already tracked in the transaction table; unused passes can now be self-refunded within 7 days of purchase (tier-bound inventory must still hold the pass), leaving the DevPass plan untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E18J9zTY3MiR6SedFgY4aN
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (14)
WalkthroughReset Passes now have cycle-usage safeguards for purchase and redemption, seven-day self-refund eligibility with tier and usage validation, expanded API reason types, updated dashboard messaging, tests, and documentation. ChangesReset Pass safeguards and refunds
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Dashboard
participant purchaseResetPass
participant getDevPlanCycleUsageFraction
Dashboard->>purchaseResetPass: request Reset Pass purchase
purchaseResetPass->>getDevPlanCycleUsageFraction: calculate cycle usage
getDevPlanCycleUsageFraction-->>purchaseResetPass: return usage fraction
purchaseResetPass-->>Dashboard: allow purchase or return 95% usage error
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…imit-restriction-yc2kdk
## What Combines two related Reset Pass safeguards (this PR now includes theopenco#3119): A Reset Pass lifts the weekly premium cap, but the unlocked spend still draws from the plan's **monthly credit pool** — so near or at the end of the pool a pass delivers little or nothing. This PR gates purchase/redeem on cycle usage, replaces the pass card with an upgrade/PAYG promo once the pool is fully exhausted, and adds a self-refund path for unused passes. ## Cycle-usage gates (server + mirrored in UI) - **Purchase** rejected with 400 above **95%** cycle usage — the card is never charged. Buy button disabled with an explanatory tooltip. - **Redeem** rejected above **90%** cycle usage so a pass can't be burned against an empty pool; the pass keeps until credits renew. Redeem button disabled with tooltip. - Thresholds + `getDevPlanCycleUsageFraction` live in `@llmgateway/shared`, shared by API and dashboard. - The gated card is not a dead end: once redeeming is blocked (>90%), it shows a visible explanation and a primary CTA — upgrade to the next tier (Lite/Pro) or PAYG credits on llmgateway.io (Max) — matching the 100% promo. PostHog event `devpass_reset_gate_upgrade_clicked`. ## 100% exhausted → promo instead of passes When the monthly allowance is fully used ($87 Lite / $237 Pro / $537 Max), the Reset Pass card is hidden entirely and replaced with a passport-style promo: - **Lite/Pro** → upgrade CTA to the next tier (`/dashboard/billing`), highlighting that upgrading starts a fresh billing cycle immediately with the full new allowance. - **Max** → PAYG CTA to llmgateway.io, highlighting it works with the same coding agents — just swap the API key and buy credits. - Usage-bar and weekly-meter copy adjusted per state; PostHog events `devpass_allowance_exhausted_viewed` / `..._promo_clicked`. ## Self-refund of unused passes (7 days) - `dev_plan_reset_pass` is now self-refundable with a **7-day** window (vs 14 for plan payments), only while the tier-bound inventory still holds a pass; a redeemed pass returns `pass_already_used`. - Refund flows through the existing `charge.refunded` webhook bookkeeping (claws back the pass, leaves the DevPass subscription untouched); works after plan cancellation since purchased passes survive it. - DevPass billing history offers the refund on eligible rows with pass-specific dialog copy; ineligible rows explain why (redeemed / 7-day window expired / already refunded). Docs updated. ## Testing - `dev-plans-reset-passes.spec.ts` (32), `self-refund.spec.ts` (30), `packages/shared/dev-plans.spec.ts` (8) — 70/70 passing. - Full `pnpm build` (17 tasks) + `pnpm format` pass. - All dashboard states verified live; demo videos in session (promo cases + refund cases). https://claude.ai/code/session_011UftFFQDksranqTiWPNMBb <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added an “allowance reached” card and updated dashboard usage messaging/CTAs when monthly credits are exhausted. - Added cycle-usage boundary gating for Reset Pass purchase/redemption (redeem ~90%, purchase ~95%); buttons/copy adjust accordingly. - **Bug Fixes** - Blocked Reset Pass purchase/redemption when monthly usage is above the configured thresholds, with clearer boundary behavior. - Improved self-refund eligibility to reject already-used passes and updated refund UI/tooltips accordingly. - **Documentation** - Refreshed Reset Pass docs to describe the new monthly threshold behavior and refund timing. - **Tests** - Expanded coverage for cycle-usage gates and self-refund eligibility reasons. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude <noreply@anthropic.com>
Summary
A Reset Pass lifts the weekly premium cap, but the unlocked spend still draws from the plan's monthly credit pool — so near the end of the pool a pass delivers almost nothing, which only confuses (purchase) or frustrates (redeem) users. This PR adds cycle-usage gates around Reset Passes and a self-refund path for unused passes.
Cycle-usage gates
POST /dev-plans/reset-pass/purchase) is rejected with a 400 once more than 95% of the monthly cycle credit allowance is used — the card is never charged.POST /dev-plans/reset-pass/redeem) is rejected once more than 90% of the cycle allowance is used, so a pass can't be burned against an empty pool; the pass keeps until the credits renew.getDevPlanCycleUsageFractionhelper live in@llmgateway/sharedso the DevPass dashboard mirrors the server gates (disabled buttons with explanatory tooltips on the Reset Pass card).Transaction tracking
Reset Pass purchases were already recorded in the
transactiontable (type: dev_plan_reset_passwith the Stripe payment intent id) — verified, no change needed.Self-refund of unused passes (7 days)
dev_plan_reset_passis now a self-refundable transaction type with a 7-day window (vs. 14 days for plan payments).pass_already_used. The tier is recovered from the charged amount, which fulfilment validated against the tier's fixed price.charge.refundedwebhook bookkeeping, which claws back the pass and leaves the DevPass subscription untouched; refund also works after the plan ended, since purchased passes survive cancellation.Testing
vitest runonpackages/shared/src/dev-plans.spec.ts,apps/api/src/lib/self-refund.spec.ts,apps/api/src/routes/dev-plans-reset-passes.spec.ts(69 tests) plus the fullapps/api+packages/sharedunit suites (598 passed).pnpm build(all 17 tasks) andpnpm formatpass.🤖 Generated with Claude Code
https://claude.ai/code/session_01E18J9zTY3MiR6SedFgY4aN
Generated by Claude Code
Summary by CodeRabbit
New Features
Documentation