diff --git a/BACKLOG.md b/BACKLOG.md index be4e9df..71a60ea 100644 --- a/BACKLOG.md +++ b/BACKLOG.md @@ -309,7 +309,7 @@ Sami explicitly stated he wants email auth as an OPTION alongside TOTP, not a re ### DC-052: License-tier enforcement — Free caps user count at 3, gates share features on Pro - **status:** todo - **owner:** unclaimed -- **details:** Per `/root/dashcaddy/PRODUCT-SPEC-DECISIONS.md` (locked 2026-07-20): Free = up to 3 users, Pro = unlimited. The DC-048 user-store needs a `countUsers()` helper. The `/api/v1/auth/admin/invites` POST handler must check `if (users.count() >= 3 && !licenseManager.isPro()) throw new ValidationError('upgrade required', 'tier')`. Same check on `POST /admin/users` (pre-authorize). Share-link creation routes (DC-053) gate on `licenseManager.isPro()`. LIFETIME keys are admin-only — the license-keygen CLI does not expose `--lifetime` publicly; only Sami runs the `isLifetime` path on his dev machine. The API never accepts a LIFETIME code in production (rejects at `verifyCode` time if duration is 0 outside dev). +- **details:** Per `/root/dashcaddy/PRODUCT-SPEC-DECISIONS.md` (locked 2026-07-20): Free = up to 3 users, Pro = unlimited. The DC-048 user-store needs a `countUsers()` helper. The `/api/v1/auth/admin/invites` POST handler must check `if (users.count() >= 3 && !licenseManager.isPro()) throw new ValidationError('upgrade required', 'tier')`. Same check on `POST /admin/users` (pre-authorize). Share-link creation routes (DC-053) gate on `licenseManager.isPro()`. **Free has NO trial path** — there is no automatic Pro trial, no time-limited upsell. The user picks Free or Pro deliberately. **LIFETIME keys are creator-only**: the API rejects any LIFETIME code at `verifyCode` time in production. The `license-keygen.js --lifetime` path stays on Sami's dev machine only; it's never wired to Stripe Checkout. - **impact:** First pricing enforcement. Without this, Pro is just a label. With this, every upgrade path has a clear moment to upsell. - **prerequisite:** DC-048 (shipped). diff --git a/PRODUCT-SPEC-DECISIONS.md b/PRODUCT-SPEC-DECISIONS.md index 1d84883..a72cdad 100644 --- a/PRODUCT-SPEC-DECISIONS.md +++ b/PRODUCT-SPEC-DECISIONS.md @@ -19,6 +19,8 @@ - USD only (defer multi-currency to v1.1) - Stripe-standard 30-day refund - No launch pricing — list prices as-is +- **Free is completely free. No Pro trial. Pro is a deliberate paid choice.** +- **Lifetime keys are creator-only.** Only Sami (the creator) can issue a LIFETIME key via `license-keygen.js --lifetime` on his dev machine. The production API rejects any LIFETIME code at `verifyCode` time. No one else ever gets a permanent key — every other paid customer gets a 30/90/180/365-day key. ## 2. Tier features