Files
member-console/internal/billing/queries/plan_ladders.sql
T
cgalo5758 71818de0bd Add setup checklist and empty-state guidance
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.
2026-08-23 03:06:11 -05:00

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);