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.
119 lines
4.1 KiB
SQL
119 lines
4.1 KiB
SQL
-- name: CreatePlanLadder :one
|
|
INSERT INTO core.plan_ladders (ladder_key, name, description, is_active)
|
|
VALUES ($1, $2, $3, $4)
|
|
RETURNING *;
|
|
|
|
-- name: ListPlanLadders :many
|
|
SELECT * FROM core.plan_ladders
|
|
ORDER BY sort_order ASC, name ASC;
|
|
|
|
-- name: GetPlanLadderByID :one
|
|
SELECT * FROM core.plan_ladders
|
|
WHERE plan_ladder_id = $1;
|
|
|
|
-- name: GetPlanLadderByKey :one
|
|
SELECT * FROM core.plan_ladders
|
|
WHERE ladder_key = $1;
|
|
|
|
-- name: UpdatePlanLadder :one
|
|
UPDATE core.plan_ladders
|
|
SET name = $2, description = $3, is_active = $4
|
|
WHERE plan_ladder_id = $1
|
|
RETURNING *;
|
|
|
|
-- name: SetPlanLadderSortOrder :exec
|
|
-- Sets a single ladder's display order. Used by the topology reorder flow,
|
|
-- which renumbers ladders to a contiguous sequence; sort_order is deliberately
|
|
-- NOT writable via UpdatePlanLadder so editing a ladder never reorders it.
|
|
UPDATE core.plan_ladders
|
|
SET sort_order = $2
|
|
WHERE plan_ladder_id = $1;
|
|
|
|
-- name: DeletePlanLadder :exec
|
|
DELETE FROM core.plan_ladders
|
|
WHERE plan_ladder_id = $1;
|
|
|
|
-- name: CreatePlanLadderTier :one
|
|
-- Appends the tier at the end of the ladder: rank self-assigns to MAX+1 in the
|
|
-- INSERT itself (no read-then-write race). Reorder keeps ranks contiguous
|
|
-- 0..N-1, so MAX+1 == COUNT; operators position tiers by drag-and-drop.
|
|
INSERT INTO core.plan_ladder_tiers (plan_ladder_id, product_id, rank)
|
|
VALUES ($1, $2, (
|
|
SELECT COALESCE(MAX(rank) + 1, 0)
|
|
FROM core.plan_ladder_tiers
|
|
WHERE plan_ladder_id = $1
|
|
))
|
|
RETURNING *;
|
|
|
|
-- name: ListTiersByLadder :many
|
|
SELECT * FROM core.plan_ladder_tiers
|
|
WHERE plan_ladder_id = $1
|
|
ORDER BY rank ASC;
|
|
|
|
-- name: ListTiersByLadderWithProducts :many
|
|
SELECT t.plan_ladder_id, t.product_id, t.rank, t.created_at, t.updated_at,
|
|
p.name AS product_name, p.display_category, p.lifecycle_status
|
|
FROM core.plan_ladder_tiers t
|
|
JOIN core.products p ON p.product_id = t.product_id
|
|
WHERE t.plan_ladder_id = $1
|
|
ORDER BY t.rank ASC;
|
|
|
|
-- name: ListLaddersByProduct :many
|
|
SELECT t.*, l.ladder_key, l.name AS ladder_name
|
|
FROM core.plan_ladder_tiers t
|
|
JOIN core.plan_ladders l ON l.plan_ladder_id = t.plan_ladder_id
|
|
WHERE t.product_id = $1
|
|
ORDER BY l.ladder_key ASC;
|
|
|
|
-- name: GetTier :one
|
|
SELECT * FROM core.plan_ladder_tiers
|
|
WHERE plan_ladder_id = $1 AND product_id = $2;
|
|
|
|
-- name: GetTierByLadderRank :one
|
|
SELECT * FROM core.plan_ladder_tiers
|
|
WHERE plan_ladder_id = $1 AND rank = $2;
|
|
|
|
-- name: ListPlanLaddersWithRankZeroProduct :many
|
|
-- LEFT JOINs on purpose: a ladder whose rank-0 tier was deleted must still
|
|
-- appear (product columns NULL) so surfaces that reference it — notably an
|
|
-- org type's configured default — can show it as broken instead of silently
|
|
-- dropping it from a dropdown and NULLing the stored value on save.
|
|
SELECT l.plan_ladder_id, l.ladder_key, l.name AS ladder_name, l.is_active,
|
|
t.product_id, p.name AS rank_zero_product_name
|
|
FROM core.plan_ladders l
|
|
LEFT JOIN core.plan_ladder_tiers t
|
|
ON t.plan_ladder_id = l.plan_ladder_id AND t.rank = 0
|
|
LEFT JOIN core.products p ON p.product_id = t.product_id
|
|
ORDER BY l.ladder_key ASC;
|
|
|
|
-- name: UpdateTierRank :one
|
|
UPDATE core.plan_ladder_tiers
|
|
SET rank = $3
|
|
WHERE plan_ladder_id = $1 AND product_id = $2
|
|
RETURNING *;
|
|
|
|
-- name: DeleteTier :exec
|
|
DELETE FROM core.plan_ladder_tiers
|
|
WHERE plan_ladder_id = $1 AND product_id = $2;
|
|
|
|
-- name: ListSharedTierProducts :many
|
|
-- Products that are a tier in more than one ladder (the many-to-many made
|
|
-- legible for the operator topology overview). Returns one row per
|
|
-- (shared product, ladder) membership, ordered for stable grouping in Go.
|
|
SELECT t.product_id, p.name AS product_name,
|
|
t.plan_ladder_id, l.ladder_key, l.name AS ladder_name, t.rank
|
|
FROM core.plan_ladder_tiers t
|
|
JOIN core.products p ON p.product_id = t.product_id
|
|
JOIN core.plan_ladders l ON l.plan_ladder_id = t.plan_ladder_id
|
|
WHERE t.product_id IN (
|
|
SELECT product_id FROM core.plan_ladder_tiers
|
|
GROUP BY product_id
|
|
HAVING COUNT(*) > 1
|
|
)
|
|
ORDER BY p.name ASC, l.sort_order ASC, l.name ASC;
|
|
|
|
-- name: AnyRankZeroTier :one
|
|
-- Setup-checklist existence probe: a ladder delivers only through its rank-0
|
|
-- tier, so "ladder exists" alone is not the step.
|
|
SELECT EXISTS(SELECT 1 FROM core.plan_ladder_tiers WHERE rank = 0);
|