Files
member-console/internal/billing/plan_ladders.sql.go
T
cgalo5758 dd3962990b Adopt entity keys and add invoice numbers
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.
2026-08-29 20:12:04 -05:00

594 lines
17 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
// source: plan_ladders.sql
package billing
import (
"context"
"database/sql"
"time"
"github.com/google/uuid"
)
const anyRankZeroTier = `-- name: AnyRankZeroTier :one
SELECT EXISTS(SELECT 1 FROM core.plan_ladder_tiers WHERE rank = 0)
`
// Setup-checklist existence probe: a ladder delivers only through its rank-0
// tier, so "ladder exists" alone is not the step.
func (q *Queries) AnyRankZeroTier(ctx context.Context) (bool, error) {
row := q.db.QueryRowContext(ctx, anyRankZeroTier)
var exists bool
err := row.Scan(&exists)
return exists, err
}
const createPlanLadder = `-- name: CreatePlanLadder :one
INSERT INTO core.plan_ladders (name, description, is_active, key)
VALUES ($1, $2, $3, $4)
RETURNING plan_ladder_id, key, name, description, is_active, created_at, updated_at, sort_order
`
type CreatePlanLadderParams struct {
Name string `json:"name"`
Description sql.NullString `json:"description"`
IsActive bool `json:"is_active"`
Key sql.NullString `json:"key"`
}
// `key` is the optional declarative address (entity-keys §3), root-scoped.
// The operator create form asks for a name only, so a UI-created ladder
// leaves it NULL; a seed or a configuration loader supplies it.
func (q *Queries) CreatePlanLadder(ctx context.Context, arg CreatePlanLadderParams) (PlanLadder, error) {
row := q.db.QueryRowContext(ctx, createPlanLadder,
arg.Name,
arg.Description,
arg.IsActive,
arg.Key,
)
var i PlanLadder
err := row.Scan(
&i.PlanLadderID,
&i.Key,
&i.Name,
&i.Description,
&i.IsActive,
&i.CreatedAt,
&i.UpdatedAt,
&i.SortOrder,
)
return i, err
}
const createPlanLadderTier = `-- name: CreatePlanLadderTier :one
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 plan_ladder_id, product_id, rank, created_at, updated_at
`
type CreatePlanLadderTierParams struct {
PlanLadderID string `json:"plan_ladder_id"`
ProductID string `json:"product_id"`
}
// 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.
func (q *Queries) CreatePlanLadderTier(ctx context.Context, arg CreatePlanLadderTierParams) (PlanLadderTier, error) {
row := q.db.QueryRowContext(ctx, createPlanLadderTier, arg.PlanLadderID, arg.ProductID)
var i PlanLadderTier
err := row.Scan(
&i.PlanLadderID,
&i.ProductID,
&i.Rank,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const deletePlanLadder = `-- name: DeletePlanLadder :exec
DELETE FROM core.plan_ladders
WHERE plan_ladder_id = $1
`
func (q *Queries) DeletePlanLadder(ctx context.Context, planLadderID string) error {
_, err := q.db.ExecContext(ctx, deletePlanLadder, planLadderID)
return err
}
const deleteTier = `-- name: DeleteTier :exec
DELETE FROM core.plan_ladder_tiers
WHERE plan_ladder_id = $1 AND product_id = $2
`
type DeleteTierParams struct {
PlanLadderID string `json:"plan_ladder_id"`
ProductID string `json:"product_id"`
}
func (q *Queries) DeleteTier(ctx context.Context, arg DeleteTierParams) error {
_, err := q.db.ExecContext(ctx, deleteTier, arg.PlanLadderID, arg.ProductID)
return err
}
const ensurePlanLadderTier = `-- name: EnsurePlanLadderTier :exec
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
))
ON CONFLICT (plan_ladder_id, product_id) DO NOTHING
`
type EnsurePlanLadderTierParams struct {
PlanLadderID string `json:"plan_ladder_id"`
ProductID string `json:"product_id"`
}
// Idempotent tier membership for a seed (entity-keys §6 as amended by §9 A1:
// a seed ensures a row exists and never overwrites one). A tier has no key of
// its own: it is a relationship, and its identity is the pair (§2 class E),
// which is also its primary key. Rank self-assigns to MAX+1 exactly as
// CreatePlanLadderTier does, so a caller inserting tiers in ascending order
// gets 0..N-1; a second run conflicts on the pair and does nothing, leaving
// an operator's own reordering alone.
func (q *Queries) EnsurePlanLadderTier(ctx context.Context, arg EnsurePlanLadderTierParams) error {
_, err := q.db.ExecContext(ctx, ensurePlanLadderTier, arg.PlanLadderID, arg.ProductID)
return err
}
const getPlanLadderByID = `-- name: GetPlanLadderByID :one
SELECT plan_ladder_id, key, name, description, is_active, created_at, updated_at, sort_order FROM core.plan_ladders
WHERE plan_ladder_id = $1
`
func (q *Queries) GetPlanLadderByID(ctx context.Context, planLadderID string) (PlanLadder, error) {
row := q.db.QueryRowContext(ctx, getPlanLadderByID, planLadderID)
var i PlanLadder
err := row.Scan(
&i.PlanLadderID,
&i.Key,
&i.Name,
&i.Description,
&i.IsActive,
&i.CreatedAt,
&i.UpdatedAt,
&i.SortOrder,
)
return i, err
}
const getPlanLadderByKey = `-- name: GetPlanLadderByKey :one
SELECT plan_ladder_id, key, name, description, is_active, created_at, updated_at, sort_order FROM core.plan_ladders
WHERE key = $1
`
// Root key resolver (entity-keys §5). uq_plan_ladders_key guarantees at most
// one row matches.
func (q *Queries) GetPlanLadderByKey(ctx context.Context, key sql.NullString) (PlanLadder, error) {
row := q.db.QueryRowContext(ctx, getPlanLadderByKey, key)
var i PlanLadder
err := row.Scan(
&i.PlanLadderID,
&i.Key,
&i.Name,
&i.Description,
&i.IsActive,
&i.CreatedAt,
&i.UpdatedAt,
&i.SortOrder,
)
return i, err
}
const getTier = `-- name: GetTier :one
SELECT plan_ladder_id, product_id, rank, created_at, updated_at FROM core.plan_ladder_tiers
WHERE plan_ladder_id = $1 AND product_id = $2
`
type GetTierParams struct {
PlanLadderID string `json:"plan_ladder_id"`
ProductID string `json:"product_id"`
}
func (q *Queries) GetTier(ctx context.Context, arg GetTierParams) (PlanLadderTier, error) {
row := q.db.QueryRowContext(ctx, getTier, arg.PlanLadderID, arg.ProductID)
var i PlanLadderTier
err := row.Scan(
&i.PlanLadderID,
&i.ProductID,
&i.Rank,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getTierByLadderRank = `-- name: GetTierByLadderRank :one
SELECT plan_ladder_id, product_id, rank, created_at, updated_at FROM core.plan_ladder_tiers
WHERE plan_ladder_id = $1 AND rank = $2
`
type GetTierByLadderRankParams struct {
PlanLadderID string `json:"plan_ladder_id"`
Rank int32 `json:"rank"`
}
func (q *Queries) GetTierByLadderRank(ctx context.Context, arg GetTierByLadderRankParams) (PlanLadderTier, error) {
row := q.db.QueryRowContext(ctx, getTierByLadderRank, arg.PlanLadderID, arg.Rank)
var i PlanLadderTier
err := row.Scan(
&i.PlanLadderID,
&i.ProductID,
&i.Rank,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const listLaddersByProduct = `-- name: ListLaddersByProduct :many
SELECT t.plan_ladder_id, t.product_id, t.rank, t.created_at, t.updated_at, 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.name ASC
`
type ListLaddersByProductRow struct {
PlanLadderID string `json:"plan_ladder_id"`
ProductID string `json:"product_id"`
Rank int32 `json:"rank"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
LadderName string `json:"ladder_name"`
}
func (q *Queries) ListLaddersByProduct(ctx context.Context, productID string) ([]ListLaddersByProductRow, error) {
rows, err := q.db.QueryContext(ctx, listLaddersByProduct, productID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListLaddersByProductRow{}
for rows.Next() {
var i ListLaddersByProductRow
if err := rows.Scan(
&i.PlanLadderID,
&i.ProductID,
&i.Rank,
&i.CreatedAt,
&i.UpdatedAt,
&i.LadderName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listPlanLadders = `-- name: ListPlanLadders :many
SELECT plan_ladder_id, key, name, description, is_active, created_at, updated_at, sort_order FROM core.plan_ladders
ORDER BY sort_order ASC, name ASC
`
func (q *Queries) ListPlanLadders(ctx context.Context) ([]PlanLadder, error) {
rows, err := q.db.QueryContext(ctx, listPlanLadders)
if err != nil {
return nil, err
}
defer rows.Close()
items := []PlanLadder{}
for rows.Next() {
var i PlanLadder
if err := rows.Scan(
&i.PlanLadderID,
&i.Key,
&i.Name,
&i.Description,
&i.IsActive,
&i.CreatedAt,
&i.UpdatedAt,
&i.SortOrder,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listPlanLaddersWithRankZeroProduct = `-- name: ListPlanLaddersWithRankZeroProduct :many
SELECT l.plan_ladder_id, 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.name ASC
`
type ListPlanLaddersWithRankZeroProductRow struct {
PlanLadderID string `json:"plan_ladder_id"`
LadderName string `json:"ladder_name"`
IsActive bool `json:"is_active"`
ProductID uuid.NullUUID `json:"product_id"`
RankZeroProductName sql.NullString `json:"rank_zero_product_name"`
}
// 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.
func (q *Queries) ListPlanLaddersWithRankZeroProduct(ctx context.Context) ([]ListPlanLaddersWithRankZeroProductRow, error) {
rows, err := q.db.QueryContext(ctx, listPlanLaddersWithRankZeroProduct)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListPlanLaddersWithRankZeroProductRow{}
for rows.Next() {
var i ListPlanLaddersWithRankZeroProductRow
if err := rows.Scan(
&i.PlanLadderID,
&i.LadderName,
&i.IsActive,
&i.ProductID,
&i.RankZeroProductName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listSharedTierProducts = `-- name: ListSharedTierProducts :many
SELECT t.product_id, p.name AS product_name,
t.plan_ladder_id, 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
`
type ListSharedTierProductsRow struct {
ProductID string `json:"product_id"`
ProductName string `json:"product_name"`
PlanLadderID string `json:"plan_ladder_id"`
LadderName string `json:"ladder_name"`
Rank int32 `json:"rank"`
}
// 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.
func (q *Queries) ListSharedTierProducts(ctx context.Context) ([]ListSharedTierProductsRow, error) {
rows, err := q.db.QueryContext(ctx, listSharedTierProducts)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListSharedTierProductsRow{}
for rows.Next() {
var i ListSharedTierProductsRow
if err := rows.Scan(
&i.ProductID,
&i.ProductName,
&i.PlanLadderID,
&i.LadderName,
&i.Rank,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listTiersByLadder = `-- name: ListTiersByLadder :many
SELECT plan_ladder_id, product_id, rank, created_at, updated_at FROM core.plan_ladder_tiers
WHERE plan_ladder_id = $1
ORDER BY rank ASC
`
func (q *Queries) ListTiersByLadder(ctx context.Context, planLadderID string) ([]PlanLadderTier, error) {
rows, err := q.db.QueryContext(ctx, listTiersByLadder, planLadderID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []PlanLadderTier{}
for rows.Next() {
var i PlanLadderTier
if err := rows.Scan(
&i.PlanLadderID,
&i.ProductID,
&i.Rank,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listTiersByLadderWithProducts = `-- 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
`
type ListTiersByLadderWithProductsRow struct {
PlanLadderID string `json:"plan_ladder_id"`
ProductID string `json:"product_id"`
Rank int32 `json:"rank"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ProductName string `json:"product_name"`
DisplayCategory sql.NullString `json:"display_category"`
LifecycleStatus string `json:"lifecycle_status"`
}
func (q *Queries) ListTiersByLadderWithProducts(ctx context.Context, planLadderID string) ([]ListTiersByLadderWithProductsRow, error) {
rows, err := q.db.QueryContext(ctx, listTiersByLadderWithProducts, planLadderID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListTiersByLadderWithProductsRow{}
for rows.Next() {
var i ListTiersByLadderWithProductsRow
if err := rows.Scan(
&i.PlanLadderID,
&i.ProductID,
&i.Rank,
&i.CreatedAt,
&i.UpdatedAt,
&i.ProductName,
&i.DisplayCategory,
&i.LifecycleStatus,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const setPlanLadderSortOrder = `-- name: SetPlanLadderSortOrder :exec
UPDATE core.plan_ladders
SET sort_order = $2
WHERE plan_ladder_id = $1
`
type SetPlanLadderSortOrderParams struct {
PlanLadderID string `json:"plan_ladder_id"`
SortOrder int32 `json:"sort_order"`
}
// 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.
func (q *Queries) SetPlanLadderSortOrder(ctx context.Context, arg SetPlanLadderSortOrderParams) error {
_, err := q.db.ExecContext(ctx, setPlanLadderSortOrder, arg.PlanLadderID, arg.SortOrder)
return err
}
const updatePlanLadder = `-- name: UpdatePlanLadder :one
UPDATE core.plan_ladders
SET name = $2, description = $3, is_active = $4
WHERE plan_ladder_id = $1
RETURNING plan_ladder_id, key, name, description, is_active, created_at, updated_at, sort_order
`
type UpdatePlanLadderParams struct {
PlanLadderID string `json:"plan_ladder_id"`
Name string `json:"name"`
Description sql.NullString `json:"description"`
IsActive bool `json:"is_active"`
}
func (q *Queries) UpdatePlanLadder(ctx context.Context, arg UpdatePlanLadderParams) (PlanLadder, error) {
row := q.db.QueryRowContext(ctx, updatePlanLadder,
arg.PlanLadderID,
arg.Name,
arg.Description,
arg.IsActive,
)
var i PlanLadder
err := row.Scan(
&i.PlanLadderID,
&i.Key,
&i.Name,
&i.Description,
&i.IsActive,
&i.CreatedAt,
&i.UpdatedAt,
&i.SortOrder,
)
return i, err
}
const updateTierRank = `-- name: UpdateTierRank :one
UPDATE core.plan_ladder_tiers
SET rank = $3
WHERE plan_ladder_id = $1 AND product_id = $2
RETURNING plan_ladder_id, product_id, rank, created_at, updated_at
`
type UpdateTierRankParams struct {
PlanLadderID string `json:"plan_ladder_id"`
ProductID string `json:"product_id"`
Rank int32 `json:"rank"`
}
func (q *Queries) UpdateTierRank(ctx context.Context, arg UpdateTierRankParams) (PlanLadderTier, error) {
row := q.db.QueryRowContext(ctx, updateTierRank, arg.PlanLadderID, arg.ProductID, arg.Rank)
var i PlanLadderTier
err := row.Scan(
&i.PlanLadderID,
&i.ProductID,
&i.Rank,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}