feat(license): metered licensing — catalogue, entitlements, and enforcement
Server Deploy / deploy (push) Successful in 5m22s
Server Deploy / deploy (push) Successful in 5m22s
Implements spec 7 tasks 2-10 on top of the six-plan payload from task 1. Admin: plans re-keyed on (deployment, tier); new catalogue collection holds every Paddle price ID (one row per priceable component); new entitlements collection holds desired beside granted. admin/internal/catalogue owns both folds — entitlement to licence limits, and entitlement to Paddle line items — so the base allowance is subtracted in exactly one place. licensing.Issue now snapshots the instance's granted entitlement, never desired. Free is enforced per account AND deployment. Staff endpoints for plans, catalogue and entitlements; Free self-hosted can be claimed and renewed on its annual term; the reaper stays cloud-only. Server: enforces the monitor cap, audit-log retention (daily sweep, skips Unlimited and lapsed instances), and gates the OIDC callback. Unset limits are filled from the seed plan at the single decode site so old blobs never read as zero. Frontends: adminsite gains a catalogue price-ID editor, six-plan allowance screen, and a catalogue-driven PlanConfigurator mounted on the staff instance page. web shows monitors, audit retention and support level on the licence page. Docs: CLAUDE.md, spec index and plan 5 preamble updated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,15 +10,20 @@
|
||||
|
||||
---
|
||||
|
||||
## ⚠ REVISED BY SPEC 7 — DO NOT EXECUTE AS WRITTEN
|
||||
## ⚠ REVISED BY SPEC 7 — WHICH HAS SHIPPED
|
||||
|
||||
[Spec 7, metered-licensing](../specs/2026-07-26-metered-licensing-design.md), was
|
||||
designed on 2026-07-26, after this plan and before any of it was implemented.
|
||||
`admin/internal/paddle` and `admin/internal/billing` do not exist, so nothing here
|
||||
has shipped and nothing needs unpicking.
|
||||
Spec 7 landed on 2026-07-27. The data model this plan assumed no longer exists:
|
||||
`plans` is keyed on `(deployment, tier)`, every price ID lives in `catalogue`,
|
||||
and `entitlements` holds what a licence is signed from. `admin/internal/catalogue`
|
||||
already provides both folds, including `ResolveItems`, which is what replaces this
|
||||
plan's price-ID-to-tier lookup.
|
||||
|
||||
**Spec 7 must be built first, and this plan is then regenerated against it.** The
|
||||
break is structural rather than cosmetic: this plan assumes **one price per
|
||||
**Re-derive tasks 1, 3, 4, 5, 7, 8 and 10 against the shipped code before
|
||||
executing them.** Tasks 2, 6 and 9 stand as written.
|
||||
|
||||
`admin/internal/paddle` and `admin/internal/billing` still do not exist, so the
|
||||
Paddle client, webhooks and checkout remain entirely this plan's work. The break
|
||||
with what was written here is structural: this plan assumes **one price per
|
||||
subscription**, and a metered plan has three or more — a base fee, a per-server
|
||||
unit at quantity N, and an item per paid feature. Every place that maps a price
|
||||
ID to a tier changes shape.
|
||||
|
||||
@@ -12,7 +12,7 @@ Build in this order. Specs 0a–5 were designed 2026-07-24; spec 6 on 2026-07-26
|
||||
| 4 | [admin-site](2026-07-24-admin-site-design.md) | — | ready to start |
|
||||
| 5 | [paddle-billing](2026-07-24-paddle-billing-design.md) | [plan](../plans/2026-07-26-paddle-billing.md) | ready to start, **but revised by 7** — its "signup migration off sitesvc" section is superseded by 6, and its single-price-per-subscription assumption by 7 |
|
||||
| 6 | [cloud-instance-creation](2026-07-26-cloud-instance-creation-design.md) | — | ready to start |
|
||||
| 7 | [metered-licensing](2026-07-26-metered-licensing-design.md) | — | designed; **build before 5**, whose plan it revises |
|
||||
| 7 | [metered-licensing](2026-07-26-metered-licensing-design.md) | [plan](../plans/2026-07-26-metered-licensing.md) | **shipped** — staff can configure and issue any of the six plans; no customer can buy one until 5 lands |
|
||||
|
||||
Specs 1 and 2 together give working licensing with licences cut by hand with
|
||||
`lkctl` — no admin service needed. 4 and 5 can run in parallel once 3 lands.
|
||||
|
||||
Reference in New Issue
Block a user