Repository navigation
Hosted: billing simplify pass from the review - #1421
Merged
Merged
Conversation
…d by server and page Plan/isPlan live beside BILLING_PLANS; PLAN_NAMES and planInterval beside the Tiers; checkout's offers spread the Tiers. The server reads every Price's plan and dollars from one priceCatalog built per billing run, in place of publishedPrice, priceUsd, usableChanges, and two recognized-Price lists. GET /api/billing's body is a shared no-I/O type the route satisfies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ns, and Stripe ids One run() for raw statements, one DAY_MS, and idOf for expanded Stripe references; smallBody and isRecentLogin come from account-gate for the Relay approval, closure, and billing routes. The summary holds the subscription itself instead of a flag and non-null assertions, and ENDED_STATUSES, the complement of CURRENT_STATUSES, is gone. Test-only re-exports and exports only their own file used are dropped, readCapped uses concatBytes, and CLOSE_UNAVAILABLE names SUPPORT_EMAIL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d plan actions Facts renders the plan confirmation's and both withdrawal cards' term lists; refundWindow states the guarantee checkout and the confirmation both quote, from REFUND_DAYS, now beside the other shared policy values. day, CHECK_CLASS, ManageBilling, and ChoosePlan each have one copy, signing out and closing share forgetAccount, and the closed-checkout line reads CHECKOUT_CLOSED. The pages render as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /api/billing answers 200 { closed: true } while billing is closed, and
every billing change but leaving the founders row answers 409
CHECKOUT_CLOSED, as a closure holding a subscription answers 409
CLOSE_UNAVAILABLE. The page's request() drops pass503 and billingRefused's
message sniffing: any 5xx is an outage. Stripe's webhook and the public
cohort read still answer 503 while closed, so events wait for billing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Migration 020 adds the withdrawal notice kind, recorded in the statement that records the withdrawal and leased, sent, and retried by the notice pass like the others; existing acknowledgements move over and acknowledgedAt is dropped. The withdraw route sends the account's pending notices, then settles; the cron settles unsettled withdrawals (settleWithdrawals replaces retryWithdrawals). The acknowledgement email is byte-identical, now composed by noticeMessage with a term-list block. FAIL IF S289 names the new mechanism. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The billing page reuses the open cohort for COHORT_CACHE_MS per isolate; a refused changed price and any webhook event forget it. - withBilling reuses the scheduled price changes for a minute per isolate (resolved rows only); the cron reads them afresh, and its stale-owner query runs on the same connection. - The cohort snapshot counts purchases and reads the founders row in parallel, without the price changes, and keeps a picture already loaded from the same source across answers instead of refetching it each minute. - sendNotices leases its batch in the statement that picks it and reads each account's contact from Stripe once per pass; a withdrawal's acknowledgement reuses the contact its offer just read. - The account page re-reads the plan only after signing in or leaving the founders row, not after a change that cannot move it or while following an approval, and one refresh answers both of a tab return's events. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deploying mouseterm with
|
| Latest commit: |
31568bd
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://24bd89ea.mouseterm.pages.dev |
| Branch Preview URL: | https://billing-review-simplify.mouseterm.pages.dev |
dormouse-bot
left a comment
Collaborator
There was a problem hiding this comment.
The consolidation, the closed-billing state, and the withdrawal notice all look right. Two of the new "fewer round trips" caches add per-isolate state, mode flags, and invalidation sites, and nothing reachable calls for them. Billing still ships dark, and neither the PR nor the code points at load that needs them. I'd drop both unless there's a measured cost behind them. The inline comments give the specifics.
Review of #1421: withBilling reads the scheduled price changes on every run, with no per-isolate cache or read mode; the billing page reads the open cohort fresh, so it shows the current price; and every account refresh reads billing again, since a superseded refresh could otherwise swallow a plan read. One refresh still answers both of a tab return's events. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dormouse-bot
approved these changes
Oct 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
/simplifypass over the whole billing range (#1405–#1414), stacked on #1420. Billing still ships dark.priceCatalog) replacespublishedPrice,priceUsd,usableChanges, and the two recognized-Price lists;Plan/isPlanlive in policy-constants,PLAN_NAMES/planIntervalbeside the Tiers; checkout's offers come from the Tiers. The/api/billingbody is a shared no-I/O type (hosted/server/billing-summary.ts) the routesatisfies.run,DAY_MS,idOf,smallBody,isRecentLogin; no moreheld!assertions orENDED_STATUSES; test-only and file-local exports dropped;readCappedusesconcatBytes.Facts,refundWindow,day,CHECK_CLASS,ManageBilling,ChoosePlan,forgetAccount, theCHECKOUT_CLOSEDtext.GET /api/billinganswers 200{ closed: true }, mutations 409 (closure's refusal too), so the sharedrequest()losespass503. The webhook and cohort routes still answer 503 so Stripe and the page retry.withdrawalnotice (migration 020), recorded in the withdrawal's own statement and sent by the notices outbox;acknowledgedAtandretryWithdrawalsare gone. The email is byte-identical (all 13 notice/acknowledgement outputs snapshotted before and after). FAIL IFS289reworded to the mechanism.Notes: migration 020 backfills already-sent acknowledgements with
email = ''(no address was stored); a failed notice send now waits out its 5-minute lease. Left for the pgstencil 0.4.2 adoption: the three cancel-now copies,endForRefund's double reconcile, the accounts join. Skipped: the metric SAVEPOINT (keeps the never-fails-the-webhook guarantee). Edge-caching/api/hosted/*needs S81 amended.Tests: hosted
pnpm test304, websitepnpm test461, tsc (hosted, website, lib), spec-lint, md-unwrap, lint:public-docs; new tests mutation-checked.🤖 Generated with Claude Code