{ "schemaVersion": "1.0", "id": "billing", "title": "Billing and Subscriptions", "classification": "core", "status": "proposed", "owner": "core-pruning", "description": "Minimal Stripe-backed subscription, pricing settings, subscription settings, and webhook handling.", "rationale": [ "A SaaS boilerplate usually needs billing as a default capability.", "The retained surface should be minimal and separate from marketing pricing presentation." ], "codeAreas": [ "apps/web/app/routes/subscribe.$tenant*", "apps/web/app/routes/app.$tenant/settings/subscription.tsx", "apps/web/app/routes/admin/settings/pricing*", "apps/api/src/app.ts", "/v1/billing/stripe/webhooks", "apps/web/app/application/pricing (admin billing-plan metadata, not public marketing pricing)", "apps/web/app/components/core/pricing (admin billing-plan configuration)", "apps/web/app/components/core/settings/subscription", "stripe" ], "dependencies": [ "auth-tenancy", "transactional-mail" ], "consumers": [ "core", "admin-app-shell" ], "integration": { "ownership": "hybrid", "surfaces": { "adminRoutes": [ "apps/web/app/routes/admin/settings/pricing*" ], "tenantRoutes": [ "apps/web/app/routes/app.$tenant/settings/subscription.tsx", "apps/web/app/routes/subscribe.$tenant*" ], "publicRoutes": [], "apiRoutes": [ "apps/api/src/app.ts", "/v1/billing/stripe/webhooks" ] }, "configuration": { "admin": [ "Plans, prices, billing policy" ], "tenant": [ "Subscription selection and billing portal actions" ], "environment": [ "STRIPE_SK", "STRIPE_WEBHOOK_SIGNING_SECRET", "STRIPE_ACCOUNT_COUNTRY" ], "secrets": [ "Stripe keys are platform/admin-owned, never tenant-owned." ] }, "workers": { "required": false, "queues": [], "jobs": [], "notes": [ "Webhook handling is request-driven unless later converted to queue processing." ] }, "externalProviders": [ "stripe" ], "permissions": [ "admin.pricing.*", "app.settings.subscription.*" ], "auditEvents": [ "billing.plan.updated", "billing.subscription.updated", "billing.webhook.received" ], "billingImpacts": [ "Owns subscription and pricing foundation." ], "uat": [ "Admin can configure pricing.", "Tenant can view/update subscription.", "Stripe webhook updates subscription state." ] }, "boundaries": { "mustKeep": [ "Stripe subscription and webhook foundation", "Admin pricing configuration", "Tenant subscription settings" ], "mayMoveToPlugin": [ "Portal-oriented pricing flows not required by the app shell", "Provider-specific billing extensions beyond Stripe", "Advanced billing analytics beyond subscription state" ], "mustNotTouch": [ "Tenant subscription checkout and success routes", "Navigation changes owned by parallel workers" ] }, "pruning": { "phase": "1", "action": "keep", "notes": [ "Keep billing as core. Public marketing pricing was pruned; admin pricing and tenant subscription flows remain." ] }, "validation": { "source": [ "docs/feature-inventory.md" ], "lastReviewed": "2026-05-05" } }