Files
descrybe/docs/free-tier.md
T

79 lines
4.7 KiB
Markdown
Raw Normal View 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](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](demo-user.md) and [safe-test-fixtures.md](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.
## Related
- [free-tier-verify.md](free-tier-verify.md) — live smoke while demo is Enterprise
- [eprel.md](eprel.md) — EPREL step details
- [demo-user.md](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)