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.
83 lines
2.4 KiB
SQL
83 lines
2.4 KiB
SQL
-- name: CreatePlanLadder :one
|
|
INSERT INTO billing.plan_ladders (ladder_key, name, description, is_active)
|
|
VALUES ($1, $2, $3, $4)
|
|
RETURNING *;
|
|
|
|
-- name: ListPlanLadders :many
|
|
SELECT * FROM billing.plan_ladders
|
|
ORDER BY ladder_key ASC;
|
|
|
|
-- name: GetPlanLadderByID :one
|
|
SELECT * FROM billing.plan_ladders
|
|
WHERE plan_ladder_id = $1;
|
|
|
|
-- name: GetPlanLadderByKey :one
|
|
SELECT * FROM billing.plan_ladders
|
|
WHERE ladder_key = $1;
|
|
|
|
-- name: UpdatePlanLadder :one
|
|
UPDATE billing.plan_ladders
|
|
SET name = $2, description = $3, is_active = $4
|
|
WHERE plan_ladder_id = $1
|
|
RETURNING *;
|
|
|
|
-- name: DeletePlanLadder :exec
|
|
DELETE FROM billing.plan_ladders
|
|
WHERE plan_ladder_id = $1;
|
|
|
|
-- name: CreatePlanLadderTier :one
|
|
INSERT INTO billing.plan_ladder_tiers (plan_ladder_id, product_id, rank)
|
|
VALUES ($1, $2, $3)
|
|
RETURNING *;
|
|
|
|
-- name: ListTiersByLadder :many
|
|
SELECT * FROM billing.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.product_type, p.lifecycle_status
|
|
FROM billing.plan_ladder_tiers t
|
|
JOIN billing.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 billing.plan_ladder_tiers t
|
|
JOIN billing.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 billing.plan_ladder_tiers
|
|
WHERE plan_ladder_id = $1 AND product_id = $2;
|
|
|
|
-- name: GetTierByLadderRank :one
|
|
SELECT * FROM billing.plan_ladder_tiers
|
|
WHERE plan_ladder_id = $1 AND rank = $2;
|
|
|
|
-- name: ListPlanLaddersWithRankZeroProduct :many
|
|
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 billing.plan_ladders l
|
|
JOIN billing.plan_ladder_tiers t
|
|
ON t.plan_ladder_id = l.plan_ladder_id AND t.rank = 0
|
|
JOIN billing.products p ON p.product_id = t.product_id
|
|
ORDER BY l.ladder_key ASC;
|
|
|
|
-- name: UpdateTierRank :one
|
|
UPDATE billing.plan_ladder_tiers
|
|
SET rank = $3
|
|
WHERE plan_ladder_id = $1 AND product_id = $2
|
|
RETURNING *;
|
|
|
|
-- name: DeleteTier :exec
|
|
DELETE FROM billing.plan_ladder_tiers
|
|
WHERE plan_ladder_id = $1 AND product_id = $2;
|
|
|
|
-- name: GetProductKind :one
|
|
SELECT product_kind FROM billing.product_kinds
|
|
WHERE product_id = $1;
|