Files
greeneclipse 8580c996c3 Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
2026-08-09 22:47:43 +02:00

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

  1. No features_customized flag. Non-empty plans.features JSON = admin customization — EnsureDefaultFeatureSeeds / EnsureDefaultPlans never overwrite it. Empty '{}' = unset → DefaultPlanFeatures(name, is_custom) at resolve.
  2. Enterprise is public ladder with is_custom=true → all features ON (same as named client deals).
  3. EPREL (capability.eprel) is ON for all plans (matches CanUseEPREL); docs/free-tier.md still says paid-only — code wins.
  4. Meters (SKU cap, monthly credits, feed/export/storage counts) stay on plans columns / marketing copy; feature keys gate UI/API access only.
  5. Global gates: missing platform_feature_gates row ⇒ enabled. Seeder inserts section rows as enabled=true with ON 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 EnsureDefaultPlansEnsureDefaultFeatureSeeds
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_processing
  • capability.api_access
  • capability.brand_ai_apply
  • capability.byok
  • capability.campaign_ai
  • capability.email_live_send
  • capability.seo_ai_rewrite
  • catalog.products.process_ai_descriptions
  • catalog.products.process_ai_titles
  • integrations.ai.byok
  • marketing.brand_ai_apply
  • marketing.campaigns.generate_ai
  • marketing.campaigns.send
  • marketing.seo.ai_rewrite
  • settings.api_keys

Starter

  • capability.byok
  • integrations.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

  1. EnsureDefaultPlans upserts ladder meters without writing plans.features.
  2. Then EnsureDefaultFeatureSeeds inserts missing section gates as enabled (ON CONFLICT DO NOTHING).
  3. Empty features left empty — resolve expands via DefaultPlanFeatures.
  4. Custom create/update “enable all” helpers (EnableAllPlanFeatures) owned with agent 7; matrix already returns all-true for is_custom.

Verification

  • Unit: TestDefaultPlanFeaturesMatrix (Free/Starter/Growth/Custom).
  • go test ./internal/billing/ -count=1 -run DefaultPlanFeatures