Files
descrybe/docs/plan-permissions/09-dashboard-gating.md
T
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

4.2 KiB

09 — Dashboard gating (agent 9/10)

User-facing dashboard UI respects resolved plan capabilities (plan ∩ global).

Coordinates with: 01-feature-keys.json, 03-permission-contract.md, 05-api.md.


ASSUMPTIONS

  1. Primary source: credits.features on GET /api/auth/me (and /api/billing/credits), per contract §8.
  2. Secondary fetch once: GET /api/billing/capabilities from layout after /me (full registry + sections + etag). Safe if 404/unavailable.
  3. Fail behavior when features map is absent (pre-cutover or capabilities error without a map):
    • Fail-open for core Free-loop + account/billing/support keys (CORE_ALWAYS_ON).
    • Fail-closed for paid keys in PAID_FAIL_CLOSED (AI process, campaign AI/send, brand AI apply, SEO AI, BYOK, API keys, …) — matches agent-9 brief while keeping billing/settings reachable.
  4. When features map is present: enforce map + parent-prefix deny (disabled catalog.products hides children). Missing key → false.
  5. Admin shell (/admin/*) is out of scope.
  6. Meters unchanged: can_use_ai / wallet still compose with feature keys for AI actions.

Implementation

Piece Path
Helpers + route map apps/web/src/lib/plan-capabilities.ts
Session store (fetch once) apps/web/src/lib/plan-capabilities.svelte.ts
canFeature re-export apps/web/src/lib/plan-gates.ts
Types CreditBalance.features / disabled_features / feature_etag
Route guard PlanRouteGuard.svelte in dashboard layout
Upgrade CTA PlanUpgradePanel.svelte / FeatureGate.svelte
Nav filter Nav.svelte primary + More
Command palette CommandPalette.svelte
Settings tabs settings/+page.svelte
Section actions Products AI, Campaign AI, SEO AI, Brand AI apply, AI BYOK

Hydration: layout /api/auth/meplanCapabilities.hydrateFromCreditsplanCapabilities.refresh().


Gated routes

Path Feature key
/dashboard dashboard.overview
/products catalog.products
/feeds feeds.list
/feeds/[feedId]/mapping feeds.mapping
/export-feeds feeds.export_feeds
/files feeds.uploads
/stores stores.hub
/woocommerce stores.woocommerce
/woocommerce?tab=reviews marketing.reviews
/stores/shopify, /shopify stores.shopify
/processing, /tasks processing.monitor
/categories catalog.categories
/categories/[id]/title-formula catalog.categories.title_formula
/categories/[id]/description-formula catalog.categories.description_formula
/attributes catalog.attributes
/standard-fields catalog.standard_fields
/structured-descriptions catalog.structured_descriptions
/vector-categories catalog.vector_categories
/campaigns, /campaigns/new, /campaigns/[id] marketing.campaigns
/marketing/calendar marketing.content_calendar
/brand marketing.brand_kit
/seo marketing.seo
/integrations/ai integrations.ai
/integrations/email integrations.email
/billing billing.overview
/plans billing.plans_compare
/settings settings.profile (+ tab keys)
/settings?tab=api-keys settings.api_keys
/support support.center
/support/new support.ticket_create
/support/[ticketId] support.ticket_thread

Deep-link to a disabled route → in-place upgrade panel (not hard redirect).


Section gates (shared pages)

Surface Keys
Settings tabs settings.profile / company / alerts / api_keys / team
Products AI actions catalog.products.process_ai_* + capability.ai_processing
Campaign AI / send marketing.campaigns.generate_ai + capability.campaign_ai
SEO AI rewrite marketing.seo.ai_rewrite + capability.seo_ai_rewrite
Brand AI apply banner marketing.brand_ai_apply + capability.brand_ai_apply
AI BYOK modes integrations.ai.byok + capability.byok

Verification

  • npm run check in apps/web (svelte-check)
  • Manual: Free user — API keys tab hidden/upgraded; AI process locked; billing/settings reachable when capabilities 404