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.
594 lines
17 KiB
Go
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
|
|
}
|