Repository navigation
Hosted: billing core, closed by default - #1405
Conversation
Adds @pgstencil/stripe 0.4.1 and its stripe peer, composes the billing migrations into Hosted's, and builds the Billing construction: no trial, Stripe Billing with Stripe Tax (automaticTax), never Managed Payments, founding offered at the open cohort's Price. A cohort now closes on its gross purchases and counts seats left from the net, so a refund right after a cohort closes no longer reopens the cheaper step. The five STRIPE_* bindings reach only the production account Worker's mapper; without all of them billing is closed and the new ten-minute resync cron does nothing. A malformed, repeated, or wrong-length Price list throws, and live mode comes from the key prefix. The entitlement is now the account's subscription, as status() reads it (exactly one current subscription, active or trialing before its end, by the database clock), ORed with the ADMIN_EMAIL comp. The relay and voice roles get the subscription columns it reads; db:migrate grants the account's dormouse_app the billing schema. verifyPackages and the npm attestation step cover all three pgstencil packages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hosted.md states the subscription entitlement with the ADMIN_EMAIL comp, and a Billing section for the closed-by-default bindings, the Price checks, no trial or Managed Payments with Stripe Tax, the founding cohort's gross/net rule, the resync cron, and the account role's billing grant. pricing.md promotes the built half of "Checkout and entitlement" and the cohort rules above the fold; checkout itself stays under Future. security-hosted.md adds S281 (Stripe bindings only on the production account; relay and voice never import billing) and S282 (the entitlement rule), widens S110 to the subscription columns, and S118/S119 to all three pgstencil packages. Ratchets hosted.md and security-hosted.md for the new rules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deploying mouseterm with
|
| Latest commit: |
2be11e1
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://ed89ba8a.mouseterm.pages.dev |
| Branch Preview URL: | https://hosted-billing-core.mouseterm.pages.dev |
dormouse-bot
left a comment
There was a problem hiding this comment.
The nightly hosted audit still scopes its package check to two packages. .github/audit/hosted.md says "Check the installed pgstencil and @pgstencil/auth packages against "Deployment boundary"", but this PR widens S118 and S119 to "any installed pgstencil package (core, auth, stripe)". An auditor following its prompt never reads @pgstencil/stripe's dist/provenance.json, so those two rules go unchecked for the new package. That line is outside the diff, so it can't take a suggestion. Adding @pgstencil/stripe to it is enough, and I can push that commit if you'd like.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Added |
Billing PR 1 of 4, on top of #1403 (pgstencil 0.4.1). Billing stays closed: with no
STRIPE_*bindings set, nothing here opens it.@pgstencil/stripe@^0.4.1andstripe, composes the billing migrations (001–006), and regenerates the dependency disclosure.verifyPackagesand the release workflow's attestation check now cover all three pgstencil packages.hosted/server/billing.ts:billingSetupkeeps billing closed unless all fiveSTRIPE_*bindings are set. It throws on a wrong founding-ladder length, a malformed Price id, or a repeated Price, and sets live mode from the key prefix.withBillingbuildsBillingwith no trial,managedPayments: falseandautomaticTax: true(Stripe Tax).openCohortfix: a cohort closes on gross purchases, and seats left come from the net count. A refund right after a cohort closes no longer reopens the cheaper step.resyncBillingruns on the account Worker's cron every 10 minutes.billing-dev.ts) backs the tests.activewithperiod_end > now(), ortrialingwithtrial_end > now()), or holds theADMIN_EMAILcomp.past_duegrants nothing, as the Terms say.ADMIN_EMAIL-only check, but while the bindings stay unset no account can have a subscription.STRIPE_*, and the relay and voice Workers never import billing.runtime-roles.sqlgrants the relay and voice roles the subscription columns they read, withoutprice_id, which neither reads; a test pins that it is refused. It also grantsdormouse_appthepgstencil_billingschema, only if that role exists and never revoking. Without it, the account Worker's entitlement queries would fail with permission errors on deploy. Please look closely at this grant: it changes what an existing production role can read.hosted.mdhas a rewritten "Entitlement" section and a new "Billing" section.pricing.mdmoves the built half of "Checkout and entitlement" and the cohort rules above the fold.security-hosted.mdgets FAIL IFS281(Stripe bindings; relay and voice never import billing) andS282(entitlement), and widensS110,S118andS119.Next: routes and webhook (PR 2), the account app (PR 3), then the website switch and legal gates (PR 4).
🤖 Generated with Claude Code