Skip to content

refactor: extract cloud billing behind host extension points - #119

Merged
KingDoxik merged 1 commit into
mainfrom
feat/billing-extraction
Jul 28, 2026
Merged

refactor: extract cloud billing behind host extension points#119
KingDoxik merged 1 commit into
mainfrom
feat/billing-extraction

Conversation

@KingDoxik

Copy link
Copy Markdown
Contributor

Summary

Removes every trace of cloud billing from this repository so the hosted deployment can ship billing and pricing changes independently. Companion PR in the mono wires the other side (see voidhash-mono PR referenced below).

  • OrganizationBillingPort → billing-agnostic OrganizationLifecyclePort (organizationCreated hook, noop community layer). OrganizationService calls it non-fatally exactly as before.
  • generate-id.ts exports createIdGenerator so host packages mint prefixed ids without registering prefixes here; the billing prefixes are gone.
  • The five billing tables (organization_billing, usage_record, usage_aggregate, billing_webhook_event, billing_provider_meter) leave schema.ts/types.ts/relations.ts. The new 20260728120000_remove_billing_tables migration is deliberately a no-op — the tables are owned by the hosting deployment and keep their data. drizzle.config.ts tablesFilter entries (with an explanatory comment) guard against any future generated drop.
  • BackendRuntimeCapabilities is now a generic Readonly<Record<string, boolean>>; the community backend serves { enterprise: {} } and selfhost/smoke.mts asserts that.
  • Studio sidebar extension entries come from a new organization-nav-slot module and marketing nav links from marketing-nav-config (both empty here; the hosted app vite-aliases them). The cloud /pricing page, its pricing-preview harness, the dead organization-settings-sidebar file, unused billing API error contracts, the packages/shared billing tombstone, and the stale POLAR_ACCESS_TOKEN turbo env entry are removed. routeTree.gen.ts hand-mirrored.

Untouched by design: product payment semantics — App Store / Google Play / Stripe billing-retry and grace-period handling, Play Billing SDK bindings, StoreKit PAY_AS_YOU_GO offer types.

Validation

  • tsc --noEmit clean in packages/core, packages/db, packages/shared, packages/api-contracts, apps/backend, apps/www.
  • Unit tests pass (packages/core organizations + generate-id: 54).
  • Exhaustive residue sweep: remaining billing/autumn/polar hits are only product payment semantics, historical migration snapshots, and the documented tablesFilter guard.
  • Reviewed by two independent review passes (general + adversarial migration/deploy verification).

🤖 Generated with Claude Code

Cloud billing no longer lives in this repository. The hosting deployment
owns it end-to-end and plugs in through generic extension points:

- OrganizationBillingPort is replaced by the billing-agnostic
  OrganizationLifecyclePort (organizationCreated hook, noop community
  layer); generate-id gains createIdGenerator so hosts mint their own
  prefixed ids without registering prefixes here.
- The five billing tables (organization_billing, usage_record,
  usage_aggregate, billing_webhook_event, billing_provider_meter) leave
  the schema. The new migration is deliberately a no-op: the tables are
  owned by the hosting deployment and keep their data; drizzle
  tablesFilter entries guard against future generated drops.
- BackendRuntimeCapabilities becomes a generic Record<string, boolean>;
  the community backend advertises {} and the selfhost smoke asserts
  that.
- The studio sidebar takes extension nav items from a slot module, the
  marketing nav from a config module (both empty here, aliased by the
  hosted app), and the cloud /pricing page plus the pricing-preview
  harness and unused billing API error contracts are removed.

Product payment semantics (App Store / Google Play / Stripe billing
retry, grace periods, Play Billing SDK) are untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@github-actions

Copy link
Copy Markdown

Thank you for following the naming conventions for pull request titles! 🙏

@github-actions

Copy link
Copy Markdown

Install the packages built from acb469f:

@voidhash/paywalls

pnpm add @voidhash/paywalls@https://pkg.voidha.sh/paywalls/acb469f

@voidhash/node

pnpm add @voidhash/node@https://pkg.voidha.sh/node/acb469f

@voidhash/web

pnpm add @voidhash/web@https://pkg.voidha.sh/web/acb469f

voidhash-cli

pnpm add voidhash-cli@https://pkg.voidha.sh/cli/acb469f

@voidhash/react-native

pnpm add @voidhash/react-native@https://pkg.voidha.sh/react-native/acb469f

Internal workspace deps (generated-clients, shared, studio) are published at the same sha and resolved automatically.

Replace the sha with pr-119 or the branch name to always get the latest build of this PR.

@KingDoxik
KingDoxik merged commit 88897ca into main Jul 28, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant