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

4.7 KiB
Raw Permalink Blame History

Free tier enforcement (Descrybe v2)

How the forever-Free plan is packaged and gated versus paid plans.

Packaging (EnsureDefaultPlans / ProvisionFreePlan)

Plan Price Max products Monthly AI credits Notes
Free $0 50 0 New signups via ProvisionFreePlan
Starter $49/mo 1,000 1,000 ~50% cover; entry “lower fish”
Plus $199/mo 5,000 5,000 ~50% cover; Woo+Shopify
Growth $299/mo 25,000 25,000 Hero; near A1 absolute $; full stores + BYOK
Business $499/mo 50,000 50,000 Plytix-class SKUs; ~50% cover
Scale $999/mo 150,000 120,000 ~40% cover
Enterprise Custom Unlimited (null) 1,000,000 is_custom; large managed grant + BYOK

A1 legacy stays dump-faithful (PAYG, ~100 products in practice, Stores/AI integrations off) — not overwritten by EnsureDefaultPlans. Public plans are intentionally richer so A1s deal is not “better” than what new customers get.

Extra AI beyond the monthly grant: buyable one-time credit packs (GET /api/billing/credit-packs, Checkout { "pack": "…" }). See stripe-setup.md.

EnsureDefaultPlans upserts public plans by name (idempotent). Free intentionally grants no AI credits so signup never burns LLM cost. SKU/feed packaging follows the public ladder (50 SKUs on Free, etc.).

Existing Free wallets are not wiped on plan sync; only the plans.monthly_credits row is corrected. New cycles / AssignPlan allocate from the plan row.

Entitlements

Exposed on /api/auth/me → credits and /api/billing/credits:

Field Meaning
can_use_ai remaining_credits > 0 OR paid plan (not Free)
can_use_eprel Always true — EU EPREL is public free data on every plan (no credits). Platform may still disable the enricher via eprel.enabled.
is_free_plan / is_paid_plan Derived from active plan name

billing.AIBrandApplyAllowed already blocks brand-kit injection into AI prompts on Free.

Free vs paid matrix

Capability Free Paid (Starter+)
Signup / map feed / view products Yes Yes
Normalize / parse_specs / fill_fields Yes (no credit debit) Yes
ai_enhance (titles / descriptions / SEO copy) Skipped (can_use_ai=false) Yes (credits)
EPREL enrichment Yes (all plans) Yes
AI-only job (title, description, enhance_*) 402 ai_requires_upgrade Credits gate
EPREL-only job Yes (no upgrade) Yes
Email campaign AI generate 402 via can_use_ai / ErrAIRequiresUpgrade Credits / paid
SEO formula editors (config) Editable Editable
SEO AI apply (/api/seo/apply) 402 via can_use_ai Credits / paid
Email campaign AI generate 402 on Free (/api/campaigns/:id/generate AI mode) Credits / paid
Product SKU cap 100 Per plan
Upgrade banners Dashboard + Products Low-credit / limit banners

Processing behavior

  1. Start job — AssertCanStartProcessing always checks SKU cap. Credit wallet is checked only when RequiresAI / RequiresEPREL (AI-only or EPREL-only types).
  2. Full / attributes jobs on Free — allowed; pipeline StepPolicy sets AllowAI=false, AllowEPREL=false and appends clear notes (ai_enhance: skipped (Free plan…), eprel: skipped (paid plan…)).
  3. ConsumeCredits — no debit when !CanUseAI && tokenCount==0 (free normalize path).

Demo user

cmd/seed-demo ensures a standalone Platform Demo company (never renames A1), upserts demo@descrybe.test + demo@descrybe.local, binds them only to Platform Demo, and assigns the custom Platform Demo plan (~1,000,000 monthly AI credits, unlimited SKUs, all feature gates ON). Free plan definition for new signups remains monthly_credits=0. See demo-user.md and safe-test-fixtures.md.

UI

  • Products: Free info banner; AI options disabled with upgrade hint; process toast notes AI skip.
  • Dashboard: Free-specific banner (not “out of credits”).
  • Marketing pricing: Free lists 0 AI credits; EPREL included on all plans.
  • free-tier-verify.md — live smoke while demo is Enterprise

  • eprel.md — EPREL step details

  • demo-user.md — Enterprise credits for demo

  • Repo sibling PRICING-AND-USER-GROWTH.md (v1 docs) — commercial ladder; Free AI pack in that doc is overridden here to 0 for cost control

  • SEO apply: apps/api/internal/seo (can_use_ai)

  • Campaign AI: apps/api/internal/campaigns (ErrAIRequiresUpgrade on AI generate)