Files

229 lines
7.9 KiB
JSON
Raw Permalink Normal View History

{
"agent": "02",
"title": "Plans/packages/permissions extension points",
"sibling_docs_status": "docs/plan-permissions/ empty at write time (no 01-* / 03-* yet)",
"recommended_approach": "Extend Entitlements + Plan/UpsertPlan + AssertCanStartProcessing-style gates; expose via CreditsOverview/me; admin billing UI; do not add a parallel packages/permissions system.",
"extension_points": [
{
"priority": 1,
"role": "capability_source_of_truth",
"path": "apps/api/internal/billing/entitlements.go",
"symbols": [
"Entitlements",
"ComputeEntitlements",
"EntitlementsForCompany",
"IsFreePlanName",
"ProcessingTypeRequiresAI",
"ProcessingTypeRequiresEPREL"
],
"intent": "Add plan feature/section booleans here; keep pure ComputeEntitlements testable."
},
{
"priority": 1,
"role": "plan_catalog_and_meters",
"path": "apps/api/internal/billing/service.go",
"symbols": [
"Plan",
"CreditsOverview",
"defaultPublicPlans",
"IsPublicProductPlan",
"EnsureDefaultPlans",
"ListPlans",
"ListPublicPlans",
"UpsertPlan",
"AssignPlan",
"ProvisionFreePlan",
"AssertCanStartProcessing",
"ProcessingGateOpts",
"AIBrandApplyAllowed",
"ConsumeCredits",
"EnsureDefaultCosts",
"EnterpriseUnlimitedCredits"
],
"intent": "Extend Plan fields / defaults; SKU+AI gates; wallet assignment; public vs deal listing."
},
{
"priority": 1,
"role": "schema",
"path": "apps/api/sql/schema/001_platform.sql",
"symbols": ["plans", "company_plans", "credit_balances", "processing_costs", "billing_cycles"],
"intent": "Add feature/permission columns or JSON on plans; optionally wire unused custom_monthly_credits / custom_max_products."
},
{
"priority": 2,
"role": "schema_stripe",
"path": "apps/api/sql/schema/016_stripe_billing.sql",
"symbols": ["company_plans.stripe_subscription_id", "company_plans.stripe_price_id"],
"intent": "Preserve Stripe linkage when altering company_plans."
},
{
"priority": 1,
"role": "admin_http",
"path": "apps/api/internal/httpapi/billing_handlers.go",
"symbols": [
"handleListPlans",
"handleListPublicPlans",
"handleUpsertPlan",
"handleAssignPlan",
"handleAddCredits",
"handleCreditsOverview"
],
"intent": "Accept/return new plan permission fields on admin upsert and credits overview."
},
{
"priority": 1,
"role": "route_mount",
"path": "apps/api/internal/httpapi/server.go",
"symbols": ["Router", "RequirePlatformAdmin"],
"intent": "Keep /api/admin/plans* under platform admin; tenant /api/billing/plans public ladder."
},
{
"priority": 1,
"role": "processing_enforcement",
"path": "apps/api/internal/processing/pipeline.go",
"symbols": ["StartJob", "processOne"],
"intent": "Primary AssertCanStartProcessing + step AllowAI policy; add section asserts near StartJob."
},
{
"priority": 2,
"role": "http_402_mapping",
"path": "apps/api/internal/httpapi/processing_handlers.go",
"symbols": ["handleStartProcessingJob", "planGateCode"],
"intent": "Reuse 402 + code mapping for new plan_gate errors."
},
{
"priority": 2,
"role": "v1_process",
"path": "apps/api/internal/httpapi/v1_process_handlers.go",
"symbols": ["handleV1StartProcess", "startV1Jobs"],
"intent": "Same gate errors as SPA processing."
},
{
"priority": 2,
"role": "seo_gate",
"path": "apps/api/internal/seo/service.go",
"symbols": ["Report", "Apply"],
"intent": "Section toggle for SEO AI; already uses EntitlementsForCompany + ConsumeCredits."
},
{
"priority": 2,
"role": "seo_http",
"path": "apps/api/internal/httpapi/seo_handlers.go",
"symbols": [],
"intent": "Map billing insufficient / upgrade errors for SEO routes."
},
{
"priority": 2,
"role": "campaigns_gate",
"path": "apps/api/internal/campaigns/generate_send.go",
"symbols": ["Generate"],
"intent": "Section toggle for campaign AI; already checks CanUseAI / IsFreePlan."
},
{
"priority": 2,
"role": "brand_gate",
"path": "apps/api/internal/httpapi/brand_handlers.go",
"symbols": ["brandResponse", "AIBrandApplyAllowed"],
"intent": "Pattern for soft feature flag exposed to UI (ai_apply_allowed)."
},
{
"priority": 1,
"role": "admin_ui",
"path": "apps/web/src/routes/admin/billing/+page.svelte",
"symbols": ["createPlan", "assignPlan", "reload", "customPlanCount", "maxProductsLabel"],
"intent": "Add edit + permission toggles; send full Plan including id/max_products."
},
{
"priority": 2,
"role": "admin_nav",
"path": "apps/web/src/lib/components/AdminNav.svelte",
"symbols": [],
"intent": "Entry to /admin/billing already present."
},
{
"priority": 1,
"role": "tenant_display_and_client_gates",
"path": "apps/web/src/lib/billing-display.ts",
"symbols": [
"canUseAIFromCredits",
"isFreePlan",
"isEnterprisePlan",
"isSelfServeCheckoutPlan",
"formatSkuCap",
"withUpgradeHint"
],
"intent": "Mirror new entitlement flags for UX gating/hints."
},
{
"priority": 2,
"role": "tenant_types",
"path": "apps/web/src/lib/types.ts",
"symbols": [],
"intent": "Extend credits/plan TypeScript shapes."
},
{
"priority": 2,
"role": "tenant_nav",
"path": "apps/web/src/lib/components/Nav.svelte",
"symbols": [],
"intent": "Optional hide/disable tabs from me.credits entitlements."
},
{
"priority": 2,
"role": "me_embedding",
"path": "apps/api/internal/httpapi/auth_handlers.go",
"symbols": ["handleMe"],
"intent": "Already embeds CreditsOverview; new flags flow to SPA automatically if added to struct."
},
{
"priority": 3,
"role": "seed_demo",
"path": "apps/api/cmd/seed-demo/main.go",
"symbols": ["EnsureDefaultPlans", "AssignPlan"],
"intent": "Keep Free=0 / Enterprise demo invariants when changing defaults."
},
{
"priority": 3,
"role": "migrator",
"path": "apps/api/cmd/migrator/main.go",
"symbols": ["loadPlans", "loadCompanyPlans"],
"intent": "Map new plan columns from MySQL if present."
},
{
"priority": 3,
"role": "missing_plans_repair",
"path": "apps/api/internal/billing/missing_plans.go",
"symbols": ["AssignPlanIfMissing", "PlanIDByName", "HasActivePlan"],
"intent": "Assignment helpers for tenants without active plans."
},
{
"priority": 3,
"role": "stripe_assign",
"path": "apps/api/internal/billing/stripe.go",
"symbols": ["applyPlanPurchase", "downgradeToFree", "CreateCheckoutSession"],
"intent": "Checkout must remain public-ladder-only; custom deals stay admin-assign."
},
{
"priority": 3,
"role": "tests",
"path": "apps/api/internal/billing/gate_test.go",
"symbols": [
"TestComputeEntitlements",
"TestDefaultPublicPlansEnterpriseUnlimited",
"TestDefaultPublicPlansFreeZeroCredits"
],
"intent": "Extend entitlement/default-plan tests for new flags."
}
],
"do_not_duplicate": [
"Separate packages table parallel to plans",
"Frontend-only permission checks without EntitlementsForCompany",
"New Free/paid heuristics outside IsFreePlanName / ComputeEntitlements",
"Second SKU limit path ignoring plans.max_products / AssertCanStartProcessing"
],
"unused_schema_to_consider": [
"company_plans.custom_monthly_credits",
"company_plans.custom_max_products"
]
}