-- name: GetProductByID :one SELECT * FROM core.products WHERE product_id = $1; -- name: ListActiveProducts :many SELECT * FROM core.products WHERE is_active = TRUE ORDER BY name ASC; -- name: ListPublicProducts :many SELECT * FROM core.products WHERE is_active = TRUE AND is_public = TRUE AND lifecycle_status = 'published' ORDER BY name ASC; -- name: ListPublicPlanProducts :many -- Plan products are those attached to a ladder via plan_ladder_tiers -- (Doc 31 Amendment #3); membership is the structural signal — -- display_category is presentation-only and never branched on. SELECT p.* FROM core.products p WHERE p.is_active = TRUE AND p.is_public = TRUE AND p.lifecycle_status = 'published' AND EXISTS ( SELECT 1 FROM core.plan_ladder_tiers t WHERE t.product_id = p.product_id ) ORDER BY p.name ASC; -- name: ListAllProducts :many SELECT * FROM core.products ORDER BY name ASC; -- name: CreateProduct :one -- `key` is the optional declarative address (entity-keys §3), root-scoped. -- Product names deliberately carry no uniqueness constraint (two ladders may -- each have a "Pro"), which is exactly why a caller outside the database -- needs a key to name one row. The operator create form does not collect -- one, so a UI-created product leaves it NULL. INSERT INTO core.products (name, description, display_category, is_active, is_public, entitlement_set_id, lifecycle_status, key) VALUES ($1, $2, $3, $4, $5, $6, $7, sqlc.narg(key)) RETURNING *; -- name: GetProductByKey :one -- Root key resolver (entity-keys §5). uq_products_key guarantees at most one -- row matches -- unlike GetProductByName, whose column has no unique -- constraint at all. SELECT * FROM core.products WHERE key = $1; -- name: UpdateProduct :one UPDATE core.products SET name = $2, description = $3, display_category = $4, is_active = $5, is_public = $6, entitlement_set_id = $7, metadata = $8 WHERE product_id = $1 RETURNING *; -- name: CountPublishedProducts :one -- Operator overview tile: the size of the live catalog. Counts only -- lifecycle_status='published' — drafts are work in progress and retired -- products are history, so neither belongs in a "what we sell today" number. SELECT COUNT(*) FROM core.products WHERE lifecycle_status = 'published'; -- name: GetProductShape :one -- Diagnostics view (migration 00006): independent structural dimensions per -- product. Readiness reads set_present and billing_shape. SELECT * FROM core.product_shape WHERE product_id = $1; -- name: AnyProduct :one -- Setup-checklist existence probe. SELECT EXISTS(SELECT 1 FROM core.products); -- name: AnyPublishedProduct :one -- Setup-checklist existence probe. SELECT EXISTS(SELECT 1 FROM core.products WHERE lifecycle_status = 'published'); -- name: ListProductsByNameCI :many -- Product duplicate-name warning (entity-keys): products may -- legitimately share a name (a "Pro" tier on two ladders), so -- core.products.name carries no uniqueness constraint -- this powers a live, -- non-blocking warning on the create/edit forms instead of a 422. Matches -- case-insensitively; when exclude_product_id is set (the edit form's own -- product), that product is excluded from its own duplicate check. LEFT -- JOINs the ladder tables so a matching product that is on no ladder still -- returns one row (ladder columns NULL); the caller groups rows by -- product_id in Go and collects each product's ladder names. SELECT p.product_id, p.name, p.is_active, l.plan_ladder_id AS ladder_id, l.name AS ladder_name FROM core.products p LEFT JOIN core.plan_ladder_tiers t ON t.product_id = p.product_id LEFT JOIN core.plan_ladders l ON l.plan_ladder_id = t.plan_ladder_id WHERE lower(p.name) = lower(sqlc.arg(name)::text) AND (sqlc.narg(exclude_product_id)::uuid IS NULL OR p.product_id <> sqlc.narg(exclude_product_id)::uuid) ORDER BY p.name ASC, l.name ASC; -- name: CountPublishedTierProducts :one -- Operator catalog overview (ux-ia-naming 2.1): how many published products -- are a tier on some plan ladder, vs. off-ladder. A product counts once even -- when it is shared across more than one ladder (DISTINCT). SELECT COUNT(DISTINCT t.product_id) FROM core.plan_ladder_tiers t JOIN core.products p ON p.product_id = t.product_id WHERE p.lifecycle_status = 'published';