Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
9.6 KiB
9.6 KiB
06 — Default plan feature matrix (agent 6/10)
Seeds / defaults for dashboard feature permissions. Coordinates with 01-feature-keys.json, 03-permission-contract.md, and backend DefaultPlanFeatures / EnsureDefaultFeatureSeeds.
Machine-readable twin: 06-defaults-matrix.json.
PROBLEM
Built-in packages must expose the features each plan allows; custom packages enable all registry keys; global section switches default ON.
ASSUMPTIONS
- No
features_customizedflag. Non-emptyplans.featuresJSON = admin customization —EnsureDefaultFeatureSeeds/EnsureDefaultPlansnever overwrite it. Empty'{}'= unset →DefaultPlanFeatures(name, is_custom)at resolve. - Enterprise is public ladder with
is_custom=true→ all features ON (same as named client deals). - EPREL (
capability.eprel) is ON for all plans (matchesCanUseEPREL);docs/free-tier.mdstill says paid-only — code wins. - Meters (SKU cap, monthly credits, feed/export/storage counts) stay on
planscolumns / marketing copy; feature keys gate UI/API access only. - Global gates: missing
platform_feature_gatesrow ⇒ enabled. Seeder inserts section rows asenabled=truewithON CONFLICT DO NOTHING(preserves admin OFF).
Implementation map
| Piece | Location |
|---|---|
| Registry keys / Free+Starter deny lists | apps/api/internal/billing/feature_catalog.go |
DefaultPlanFeatures / resolve |
apps/api/internal/billing/plan_features.go |
| Global section seed + sparse helpers | apps/api/internal/billing/default_plan_features_seed.go |
| Hooked from | EnsureDefaultPlans → EnsureDefaultFeatureSeeds |
| Schema | apps/api/sql/schema/026_plan_features.sql |
Plan packaging (meters)
| Plan | SKU cap | Monthly AI credits | is_custom |
|---|---|---|---|
| Free | 50 | 0 | false |
| Starter | 100 | 100 | false |
| Plus | 400 | 400 | false |
| Growth | 1,200 | 1,200 | false |
| Business | 4,000 | 4,000 | false |
| Scale | 12,000 | 12,000 | false |
| Enterprise | unlimited | 1,000,000 | true |
| Custom deals | deal | deal | true |
Denied keys (sparse false)
Free
capability.ai_processingcapability.api_accesscapability.brand_ai_applycapability.byokcapability.campaign_aicapability.email_live_sendcapability.seo_ai_rewritecatalog.products.process_ai_descriptionscatalog.products.process_ai_titlesintegrations.ai.byokmarketing.brand_ai_applymarketing.campaigns.generate_aimarketing.campaigns.sendmarketing.seo.ai_rewritesettings.api_keys
Starter
capability.byokintegrations.ai.byok
Growth / Business / Enterprise / Custom
No denials — all registry keys ON (Enterprise/Custom via is_custom).
Full matrix
Legend: ON = allowed by DefaultPlanFeatures / custom-all-on; OFF = denied until upgrade or admin override.
| feature_key | Free | Starter | Growth | Business | Enterprise/Custom |
|---|---|---|---|---|---|
shell.navigation |
ON | ON | ON | ON | ON |
shell.command_palette |
ON | ON | ON | ON | ON |
shell.company_switcher |
ON | ON | ON | ON | ON |
shell.support_notifications |
ON | ON | ON | ON | ON |
shell.tutorial |
ON | ON | ON | ON | ON |
shell.account_menu |
ON | ON | ON | ON | ON |
shell.billing_recovery_banner |
ON | ON | ON | ON | ON |
dashboard.overview |
ON | ON | ON | ON | ON |
dashboard.stats |
ON | ON | ON | ON | ON |
dashboard.quick_links |
ON | ON | ON | ON | ON |
dashboard.recent_jobs |
ON | ON | ON | ON | ON |
dashboard.news_feed |
ON | ON | ON | ON | ON |
dashboard.activation_checklist |
ON | ON | ON | ON | ON |
dashboard.migrated_checklist |
ON | ON | ON | ON | ON |
dashboard.etl_gaps |
ON | ON | ON | ON | ON |
dashboard.store_reconnect |
ON | ON | ON | ON | ON |
dashboard.upgrade_banners |
ON | ON | ON | ON | ON |
catalog.products |
ON | ON | ON | ON | ON |
catalog.products.tab_processed |
ON | ON | ON | ON | ON |
catalog.products.tab_needs_review |
ON | ON | ON | ON | ON |
catalog.products.tab_error |
ON | ON | ON | ON | ON |
catalog.products.tab_processing |
ON | ON | ON | ON | ON |
catalog.products.tab_unprocessed |
ON | ON | ON | ON | ON |
catalog.products.process_categories |
ON | ON | ON | ON | ON |
catalog.products.process_attributes |
ON | ON | ON | ON | ON |
catalog.products.process_ai_titles |
OFF | ON | ON | ON | ON |
catalog.products.process_ai_descriptions |
OFF | ON | ON | ON | ON |
catalog.products.enrichment_review |
ON | ON | ON | ON | ON |
catalog.products.export_selection |
ON | ON | ON | ON | ON |
catalog.products.upgrade_prompt |
ON | ON | ON | ON | ON |
catalog.categories |
ON | ON | ON | ON | ON |
catalog.categories.title_formula |
ON | ON | ON | ON | ON |
catalog.categories.description_formula |
ON | ON | ON | ON | ON |
catalog.attributes |
ON | ON | ON | ON | ON |
catalog.attributes.bulk_import |
ON | ON | ON | ON | ON |
catalog.standard_fields |
ON | ON | ON | ON | ON |
catalog.standard_fields.groups |
ON | ON | ON | ON | ON |
catalog.structured_descriptions |
ON | ON | ON | ON | ON |
catalog.vector_categories |
ON | ON | ON | ON | ON |
feeds.list |
ON | ON | ON | ON | ON |
feeds.add_url |
ON | ON | ON | ON | ON |
feeds.add_csv |
ON | ON | ON | ON | ON |
feeds.sync |
ON | ON | ON | ON | ON |
feeds.mapping |
ON | ON | ON | ON | ON |
feeds.mapping.select_item |
ON | ON | ON | ON | ON |
feeds.mapping.map_fields |
ON | ON | ON | ON | ON |
feeds.export_feeds |
ON | ON | ON | ON | ON |
feeds.export_feeds.create |
ON | ON | ON | ON | ON |
feeds.export_feeds.generate |
ON | ON | ON | ON | ON |
feeds.uploads |
ON | ON | ON | ON | ON |
stores.hub |
ON | ON | ON | ON | ON |
stores.woocommerce |
ON | ON | ON | ON | ON |
stores.woocommerce.connection |
ON | ON | ON | ON | ON |
stores.woocommerce.categories |
ON | ON | ON | ON | ON |
stores.woocommerce.attributes |
ON | ON | ON | ON | ON |
stores.woocommerce.orders |
ON | ON | ON | ON | ON |
stores.woocommerce.reviews |
ON | ON | ON | ON | ON |
stores.woocommerce.settings |
ON | ON | ON | ON | ON |
stores.shopify |
ON | ON | ON | ON | ON |
stores.shopify.connection |
ON | ON | ON | ON | ON |
stores.shopify.orders |
ON | ON | ON | ON | ON |
stores.shopify.settings |
ON | ON | ON | ON | ON |
processing.monitor |
ON | ON | ON | ON | ON |
marketing.campaigns |
ON | ON | ON | ON | ON |
marketing.campaigns.create |
ON | ON | ON | ON | ON |
marketing.campaigns.generate_ai |
OFF | ON | ON | ON | ON |
marketing.campaigns.send |
OFF | ON | ON | ON | ON |
marketing.content_calendar |
ON | ON | ON | ON | ON |
marketing.brand_kit |
ON | ON | ON | ON | ON |
marketing.brand_ai_apply |
OFF | ON | ON | ON | ON |
marketing.seo |
ON | ON | ON | ON | ON |
marketing.seo.template_fill |
ON | ON | ON | ON | ON |
marketing.seo.ai_rewrite |
OFF | ON | ON | ON | ON |
marketing.reviews |
ON | ON | ON | ON | ON |
integrations.ai |
ON | ON | ON | ON | ON |
integrations.ai.byok |
OFF | OFF | ON | ON | ON |
integrations.email |
ON | ON | ON | ON | ON |
integrations.email.test |
ON | ON | ON | ON | ON |
integrations.email.blast |
ON | ON | ON | ON | ON |
billing.overview |
ON | ON | ON | ON | ON |
billing.customer_portal |
ON | ON | ON | ON | ON |
billing.quick_upgrade |
ON | ON | ON | ON | ON |
billing.plans_compare |
ON | ON | ON | ON | ON |
billing.checkout |
ON | ON | ON | ON | ON |
settings.profile |
ON | ON | ON | ON | ON |
settings.company |
ON | ON | ON | ON | ON |
settings.alerts |
ON | ON | ON | ON | ON |
settings.api_keys |
OFF | ON | ON | ON | ON |
settings.team |
ON | ON | ON | ON | ON |
settings.team_invite |
ON | ON | ON | ON | ON |
support.center |
ON | ON | ON | ON | ON |
support.ticket_create |
ON | ON | ON | ON | ON |
support.ticket_thread |
ON | ON | ON | ON | ON |
capability.sku_cap |
ON | ON | ON | ON | ON |
capability.ai_credits |
ON | ON | ON | ON | ON |
capability.ai_processing |
OFF | ON | ON | ON | ON |
capability.eprel |
ON | ON | ON | ON | ON |
capability.normalize_specs_fill |
ON | ON | ON | ON | ON |
capability.campaign_ai |
OFF | ON | ON | ON | ON |
capability.email_live_send |
OFF | ON | ON | ON | ON |
capability.brand_ai_apply |
OFF | ON | ON | ON | ON |
capability.seo_ai_rewrite |
OFF | ON | ON | ON | ON |
capability.feed_source_limit |
ON | ON | ON | ON | ON |
capability.export_feed_limit |
ON | ON | ON | ON | ON |
capability.storage_limit |
ON | ON | ON | ON | ON |
capability.api_access |
OFF | ON | ON | ON | ON |
capability.byok |
OFF | OFF | ON | ON | ON |
Global section defaults
All section masters default ON: shell, dashboard, catalog, feeds, stores, processing, marketing, integrations, billing, settings, support, capabilities.
Seeder behavior
EnsureDefaultPlansupserts ladder meters without writingplans.features.- Then
EnsureDefaultFeatureSeedsinserts missing section gates as enabled (ON CONFLICT DO NOTHING). - Empty
featuresleft empty — resolve expands viaDefaultPlanFeatures. - Custom create/update “enable all” helpers (
EnableAllPlanFeatures) owned with agent 7; matrix already returns all-true foris_custom.
Verification
- Unit:
TestDefaultPlanFeaturesMatrix(Free/Starter/Growth/Custom). go test ./internal/billing/ -count=1 -run DefaultPlanFeatures