handbook: narrow versioning design doc scope

Draft
PI
9d ago
+335-0

Review changes on top of #15332, based on feat-versioning so the diff is the rewrite only.

Decisions

  1. Full freeze for declarative-config orgs. No change reaches existing customers until they are explicitly moved. Dashboard-only orgs keep today's behavior. "Current state" now lists what really propagates today: benefit property edits, credit units at next renewal, benefit add/remove to past one-time buyers.
  2. No migrations DSL. Moving customers = bulk subscription update (a loop over today's subscription update) + a new one-time order endpoint. Declarative migrations get their own design doc built on these.
  3. New ID per version. Purchases stay pinned to their row. Checkout links and discounts are re-pointed in the publish transaction. Checkout creation accepts external_id.
  4. Draft lives in the API, config is its only writer. apply publishes at once, apply --draft uploads for read-only dashboard review/publish/discard. No conflict/force/pull rules.
  5. Live membership is derived from catalogs/catalog_products. No stored is_current; a partial unique index is mentioned as a possible cache.
  6. No meter versioning in v0. Today's last_billed_event lock stays. Balance carry-over on move is the M3 direction; a balance shared across meter versions is ruled out.
  7. New orgs only in v0. Adoption stays an open question.
  8. Grants are re-pointed by benefit external_id through the strategy's existing update, so license keys, Discord roles, etc. aren't revoked and reissued on a move. Blocking stricter benefits was considered and rejected.
  9. API hides versions. Lists return only the live catalog, no params. Draft rows only through catalog draft endpoints.
  10. Webhooks: product.created for the new row, product.updated for the row leaving the live catalog.

The benefit → product cascade is kept and now explained: grants are rebuilt from product.benefits on reactivation, seat claims, etc., so editing links in place would break the freeze for some customers.

Also adds a catalog_benefits membership table, since benefits are versioned too.

For @psincraian

Petru's latest commit (fix: answered questions) is merged in:

  • "Discounts already applied to existing subscriptions or checkouts don't change" → References section.
  • The credits answer (settle old usage, revoke old credit grant, grant new prorated credits, extra usage at new price) → "Moving customers", as the one exception to grant re-pointing. Please confirm this matches what you meant.

šŸ¤– Generated with Claude Code