PRODUCT-SPEC: clarify Free has no trial; LIFETIME is creator-only
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled

Sami's explicit decisions:
- Free is completely free — no Pro trial, no time-limited upsells.
  Pro is a deliberate paid choice. Update pricing language in
  PRODUCT-SPEC-DECISIONS.md so anyone reading it doesn't assume
  there's a hidden trial period.
- Lifetime keys are creator-only (Sami runs license-keygen.js
  --lifetime on his dev machine; the API rejects LIFETIME codes
  at verifyCode time). No paid customer can ever buy or receive
  a lifetime key — they get 30/90/180/365-day keys. Update both
  PRODUCT-SPEC-DECISIONS.md and DC-052 in BACKLOG.md to spell
  this out so the Stripe webhook (DC-054) doesn't accidentally
  generate a LIFETIME for a buyer.
This commit is contained in:
hermes
2026-07-20 21:22:34 -07:00
parent 4671e51465
commit b105d5abae
2 changed files with 3 additions and 1 deletions
+1 -1
View File
@@ -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 ### DC-052: License-tier enforcement — Free caps user count at 3, gates share features on Pro
- **status:** todo - **status:** todo
- **owner:** unclaimed - **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. - **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). - **prerequisite:** DC-048 (shipped).
+2
View File
@@ -19,6 +19,8 @@
- USD only (defer multi-currency to v1.1) - USD only (defer multi-currency to v1.1)
- Stripe-standard 30-day refund - Stripe-standard 30-day refund
- No launch pricing — list prices as-is - 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 ## 2. Tier features