Replace the entity slugs on organizations, workspaces, resource pools,
and
plan ladders with nullable `key` columns and add keys to products,
prices,
and entitlement sets. Rename `providers.slug` to `provider` and add
partial
unique indexes for system and org role names.
Assign invoice numbers per billing account from a gapless transactional
counter; Stripe's number moves to the invoice mapping as an external
reference.
Seeds, fixtures, and the operator lookup address rows by key, and the
returning-login resync no longer blanks a display name when the IdP
sends
no `name` claim.
Implement the ux-first-run change: a state-derived setup checklist on
/operator/setup with a landing region that recedes once required steps
are done, and empty states that distinguish blocked from empty across
operator and member surfaces. Also add production deployment and
environment reference docs, plus a config-key completeness test.
Replace product-kind branching and direct position writes with enclosed
database functions driven by structural product shape.
Migrate grant and provision data, unify operator issuance, update
subscription and expiry flows, and add migration and integration proofs.
Squash the pre-production migration history into fresh core, fedwiki,
and stripe baselines and reduce the canonical source list to those
three streams.
Update sqlc configs, generated queries, raw SQL, tests, and docs while
keeping provider tables schema-qualified.
BREAKING: existing local database volumes must be wiped because goose
version history restarts from the new baselines.
Show ladders that lost their rank-0 tier as broken instead of dropping
them from org type forms. Reject selecting them as new defaults while
allowing existing saved defaults to be re-saved safely.
Fix the rank-collision UX bug at the source.
- Append-at-end: CreatePlanLadderTier INSERT uses COALESCE(MAX(rank)+1, 0);
handler drops the rank input and template shows a drag-to-position hint.
- Renumber-on-delete: DeletePlanLadderTier renumbers remaining tiers inline
so ranks stay contiguous after deletion.
- Confirm dialog copy is now honest: deleting the top tier explicitly
promotes the next tier to the new-org default.
- Friendly errors: map duplicate-product and rank-collision constraints
to 422 field errors via web.FieldErrorsFromDB.
- All fixtures updated for append-at-end order.
Closes: openspec/changes/ladder-tier-append
- Add SortableJS drag-to-reorder for ladder columns on the topology
overview page
- Remove the manual "Sort order" input from the ladder edit form
- Add SetPlanLadderSortOrder SQL query and remove sort_order from
UpdatePlanLadder
- Update templates, CSS, specs, and tests to support the new flow
Add a read-only operator surface at GET /operator/plan-topology with a
server-rendered cross-ladder grid (ladders by sort_order × ranks).
Include
shared-product detection via a new sqlc query (ListSharedTierProducts),
sticky rank-column CSS, add-on strip, org-type provisioning summary, and
a
reverse index of shared memberships. Register route/nav, add handler,
template, tests, specs, and docs.
Add sort_order to billing.plan_ladders and a migration.
Reshape models, queries, handlers and templates to group plans by
plan ladder (service axis) in rank order. Track the current rung per
ladder and render per-tier move affordances; only the free→paid path
is enabled, other moves render disabled with an explanatory reason.
Include operator sort_order edit, tests, docs and image assets.
Add default_plan_ladder_id with a forward data migration and update
the runtime to resolve the ladder's rank-0 tier at use-time. Regenerate
sqlc, update auto-provisioning, ReapplyDefaultsForPool, operator UI and
tests; add GetTierByLadderRank and pool/provision query helpers. Add a
CSP-safe confirm-action modal and wire operator actions to it. Close
plan-sole-writer safety gaps and serialize IssueGrant with a FOR UPDATE
pool lock to prevent ladder races.
Introduce DB migrations for ladder and pool-attachment tables and an
audit log for provision transitions. Make product_type nullable and add
lifecycle_status plus a product_kinds view. Implement Transition and
ReapplyDefaultsForPool primitives, SQLC queries/models, webhook and
Temporal workflow integration, and accompanying unit/integration tests.