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
* fix(billing): platform billing cleanup (#468)
Address the platform-billing correctness/consistency items from issue #468
(Phase 4 cleanup of epic #458):
- instructions_sent / payment_received were rendered in the UI but never
written. Add a super-admin `sendPaymentInstructions` action (pending →
instructions_sent + in-app notification to tenant admins) and advance a
request to payment_received when the school uploads transfer proof, so the
intermediate manual-flow states are actually reachable.
- forceTenantPlanChange updated tenants.plan + revenue_splits but left
platform_subscriptions pointing at the old plan. It now syncs the
subscription row atomically (updates plan_id on the existing row, cancels it
when forcing to free, or creates a manual override row when none exists).
- Stripe checkout/portal success/cancel/return URLs hardcoded /en/. Thread the
requester's locale (from the POST body, with a referer fallback) via a shared
resolveRequestLocale helper, validated against the supported locale set.
- Surface the plan's current price next to the snapshotted request amount on
the super-admin confirm view so price drift is visible at confirm time.
The hardcoded 10/90 split on cancellation (item 3) was already resolved on
master by lib/billing/downgrade-tenant.ts (reads the free plan's
transaction_fee_percent); verified, no change needed. The price snapshot itself
(item 5) already exists as platform_payment_requests.amount; only confirm-time
visibility was missing.
Pre-existing no-explicit-any lint errors in the touched files are not
introduced by this change (repo lint baseline is non-blocking; npm run build
passes clean).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTd2ffE5QnJphufL8YD7KV
* fix(billing): make forced plan overrides indefinite so the expiry cron can't undo them
forceTenantPlanChange created its manual override row with a +1 month
current_period_end, which put it squarely in the path of the
expire-platform-subscriptions cron (#471): the school would get renewal
reminders for a payment it never requested, then be silently downgraded
back to free a month later. The reactivation branch had the same bug via
a stale period end on a previously-canceled row.
Every cron phase filters on `.not('current_period_end', 'is', null)`, so
a NULL period end is the natural "indefinite override" marker: the row is
never reminded, never lapses, never auto-downgrades. Keep a real period
only when reactivating a sub already on a live paid cycle; a school that
later pays via confirmManualPayment upserts a dated cycle over the row.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HveVmDShzscMQVQdd9LuDZ
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
'Bank transfer instructions for your plan payment are on the way. Check your email, complete the transfer, then upload your proof of payment from the billing page.',
0 commit comments