Governed operator lists (organizations, grants, people, billing×4) gain
server-side search, status filters, and 50-row pages with true totals
from count(*) OVER(); state is URL-addressable, out-of-range pages
clamp,
and no-match is distinct from true-empty.
People is the eighth flat sidebar entry: /operator/persons lists persons
newest-joined first (excluding the reserved system person), rows linking
to the existing detail.
Billing gains an operator invoice detail at
/operator/billing/invoices/{invoiceID} reusing the member projection;
open invoices past due present as Overdue (derived, filterable, stored
status untouched); all four views lead with the linked organization and
mute object IDs.
Grants filter over the derived Live/Superseded/Inactive state, the SQL
HAVING predicate pinned to the Go derivation by test. Embedded lists
(org composite ledger, Tier changes) adopt the shared controls under
namespaced params with sibling-state-preserving URLs and scoped htmx
swaps that hold the viewport.
Review corrections: blocked ladder Delete renders disabled with tooltip
and mutations fire toasts; collapse triggers paint their open state;
sections use outside headings; plan topology drops the orphan-product
check; domains policy collapses behind a disclosure.
254 lines
18 KiB
Go
254 lines
18 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.29.0
|
|
|
|
package billing
|
|
|
|
import (
|
|
"context"
|
|
)
|
|
|
|
type Querier interface {
|
|
// Setup-checklist existence probe.
|
|
AnyActivePrice(ctx context.Context) (bool, error)
|
|
// Setup-checklist existence probe.
|
|
AnyProduct(ctx context.Context) (bool, error)
|
|
// Setup-checklist existence probe.
|
|
AnyPublishedProduct(ctx context.Context) (bool, error)
|
|
// Setup-checklist existence probe: a ladder delivers only through its rank-0
|
|
// tier, so "ladder exists" alone is not the step.
|
|
AnyRankZeroTier(ctx context.Context) (bool, error)
|
|
// Webhook-primary closeout: when a subscription actually ends (Stripe fires
|
|
// customer.subscription.deleted at period end), mark its still-pending scheduled
|
|
// changes applied so the intent ledger reflects what happened.
|
|
ApplyScheduledChangesForSubscription(ctx context.Context, subscriptionID string) error
|
|
CancelScheduledChange(ctx context.Context, scheduledChangeID string) (SubscriptionScheduledChange, error)
|
|
// First half of the make-default handshake; run in the same transaction as
|
|
// MarkDefaultPrice (clear before set, so the partial unique index never sees
|
|
// two defaults for one product).
|
|
ClearDefaultPrice(ctx context.Context, productID string) error
|
|
// Both halves of the operator overview's Monthly recurring caption in one
|
|
// read: 'active' and 'trialing' are the two statuses that mean the
|
|
// subscription is presently owed service (the pair operator_billing.go
|
|
// treats as live), but only active ones contribute money, so the caption
|
|
// needs them separately.
|
|
CountLiveSubscriptionsByStatus(ctx context.Context) (CountLiveSubscriptionsByStatusRow, error)
|
|
// Receivables headline for the operator landing surface. `open` is the only
|
|
// actionable non-terminal invoice status (design/billing/model.md): draft is
|
|
// not yet issued, and paid/void/uncollectible/refunded are settled or written
|
|
// off. A count, not a balance sum — currency is per-row, and a cross-currency
|
|
// sum would be a number the tile could not stand behind.
|
|
CountOpenInvoices(ctx context.Context) (int64, error)
|
|
// 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.
|
|
CountPublishedProducts(ctx context.Context) (int64, error)
|
|
// 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).
|
|
CountPublishedTierProducts(ctx context.Context) (int64, error)
|
|
CreateBillingAccount(ctx context.Context, arg CreateBillingAccountParams) (Account, error)
|
|
CreateInvoice(ctx context.Context, arg CreateInvoiceParams) (Invoice, error)
|
|
CreateInvoiceLineItem(ctx context.Context, arg CreateInvoiceLineItemParams) (InvoiceLineItem, error)
|
|
CreatePayment(ctx context.Context, arg CreatePaymentParams) (Payment, error)
|
|
CreatePaymentMethod(ctx context.Context, arg CreatePaymentMethodParams) (PaymentMethod, error)
|
|
CreatePlanLadder(ctx context.Context, arg CreatePlanLadderParams) (PlanLadder, error)
|
|
// 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.
|
|
CreatePlanLadderTier(ctx context.Context, arg CreatePlanLadderTierParams) (PlanLadderTier, error)
|
|
// The first price a product gets becomes its default automatically (there is
|
|
// nothing else to offer members); subsequent prices are created non-default
|
|
// and promoted explicitly via Clear/MarkDefaultPrice. The NOT EXISTS probe
|
|
// also self-heals a product that somehow lost its default: the next price
|
|
// created becomes it. The partial unique index
|
|
// (idx_prices_one_default_per_product) backstops concurrent creation races.
|
|
CreatePrice(ctx context.Context, arg CreatePriceParams) (Price, error)
|
|
CreateProduct(ctx context.Context, arg CreateProductParams) (Product, error)
|
|
CreateScheduledChange(ctx context.Context, arg CreateScheduledChangeParams) (SubscriptionScheduledChange, error)
|
|
CreateSubscription(ctx context.Context, arg CreateSubscriptionParams) (Subscription, error)
|
|
CreateSubscriptionChange(ctx context.Context, arg CreateSubscriptionChangeParams) (SubscriptionChange, error)
|
|
CreateSubscriptionItem(ctx context.Context, arg CreateSubscriptionItemParams) (SubscriptionItem, error)
|
|
// Handlers must refuse to deactivate the default price (members would lose
|
|
// the purchase path); the is_default guard here backstops that rule.
|
|
DeactivatePrice(ctx context.Context, priceID string) (Price, error)
|
|
DeletePlanLadder(ctx context.Context, planLadderID string) error
|
|
DeleteTier(ctx context.Context, arg DeleteTierParams) error
|
|
GetBillingAccountByID(ctx context.Context, billingAccountID string) (Account, error)
|
|
GetDefaultPriceByProduct(ctx context.Context, productID string) (Price, error)
|
|
GetInvoiceByID(ctx context.Context, invoiceID string) (Invoice, error)
|
|
GetInvoiceLineItemsByInvoiceID(ctx context.Context, invoiceID string) ([]InvoiceLineItem, error)
|
|
GetInvoicesByBillingAccountID(ctx context.Context, billingAccountID string) ([]Invoice, error)
|
|
// Most recent invoice for a billing account (any status). Used by the
|
|
// per-org composite's billing-summary section.
|
|
GetLatestInvoiceByBillingAccountID(ctx context.Context, billingAccountID string) (Invoice, error)
|
|
// Most recent subscription for a billing account (any status). Used by the
|
|
// per-org composite's billing-summary section.
|
|
GetLatestSubscriptionByBillingAccountID(ctx context.Context, billingAccountID string) (Subscription, error)
|
|
// Sum of (amount_due - amount_paid) across invoices with status='open' — the
|
|
// only actionable non-terminal invoice status per design/billing/model.md.
|
|
// Returns 0 if no open invoices exist.
|
|
GetOutstandingBalanceByBillingAccountID(ctx context.Context, billingAccountID string) (int64, error)
|
|
GetPaymentByID(ctx context.Context, paymentID string) (Payment, error)
|
|
GetPaymentMethodByID(ctx context.Context, paymentMethodID string) (PaymentMethod, error)
|
|
GetPaymentMethodsByBillingAccountID(ctx context.Context, billingAccountID string) ([]PaymentMethod, error)
|
|
GetPaymentsByInvoiceID(ctx context.Context, invoiceID string) ([]Payment, error)
|
|
GetPlanLadderByID(ctx context.Context, planLadderID string) (PlanLadder, error)
|
|
GetPlanLadderByKey(ctx context.Context, ladderKey string) (PlanLadder, error)
|
|
GetPrice(ctx context.Context, priceID string) (Price, error)
|
|
GetProductByID(ctx context.Context, productID string) (Product, error)
|
|
GetProductByName(ctx context.Context, name string) (Product, error)
|
|
// Diagnostics view (migration 00006): independent structural dimensions per
|
|
// product. Readiness reads set_present and billing_shape.
|
|
GetProductShape(ctx context.Context, productID string) (CoreProductShape, error)
|
|
GetScheduledChangeByID(ctx context.Context, scheduledChangeID string) (SubscriptionScheduledChange, error)
|
|
GetSubscriptionByID(ctx context.Context, subscriptionID string) (Subscription, error)
|
|
GetSubscriptionChangesBySubscriptionID(ctx context.Context, subscriptionID string) ([]SubscriptionChange, error)
|
|
GetSubscriptionItemByID(ctx context.Context, subscriptionItemID string) (SubscriptionItem, error)
|
|
GetSubscriptionItemsBySubscriptionID(ctx context.Context, subscriptionID string) ([]SubscriptionItem, error)
|
|
GetSubscriptionsByBillingAccountID(ctx context.Context, billingAccountID string) ([]Subscription, error)
|
|
GetTier(ctx context.Context, arg GetTierParams) (PlanLadderTier, error)
|
|
GetTierByLadderRank(ctx context.Context, arg GetTierByLadderRankParams) (PlanLadderTier, error)
|
|
ListActiveProducts(ctx context.Context) ([]Product, error)
|
|
ListActiveScheduledChangesBySubscription(ctx context.Context, subscriptionID string) ([]SubscriptionScheduledChange, error)
|
|
ListAllProducts(ctx context.Context) ([]Product, error)
|
|
ListBillingAccountsByOrgID(ctx context.Context, orgID string) ([]Account, error)
|
|
// Operator billing-accounts view, paged and searched (operator-list-scale
|
|
// UX-4; operator-billing-views D8). No status facet: core.accounts.status
|
|
// carries no CHECK-enforced vocabulary and operator-list-scale's "Status
|
|
// filters exist where a status vocabulary exists" requirement does not
|
|
// name accounts, so this query offers search + pagination only.
|
|
//
|
|
// sqlc.narg(q): NULL matches every row; set, a case-insensitive substring
|
|
// match against the account's own name, or its organization via
|
|
// sqlc.narg(org_ids) (design D3: "billing: organization name plus the
|
|
// view's leading identifier"). Organization-name search resolves through
|
|
// a pre-resolved ID array rather than a join to core.organizations: no
|
|
// existing internal/billing query crosses that module boundary
|
|
// (grep 'core\.' internal/billing/queries/ turns up none), so
|
|
// operator_billing.go's matchingOrgIDs resolves matching org IDs in Go and
|
|
// passes them here, mirroring the grants lane's product-name pattern.
|
|
// count(*) OVER() carries the true total for the filtered set (design D2).
|
|
ListBillingAccountsPage(ctx context.Context, arg ListBillingAccountsPageParams) ([]ListBillingAccountsPageRow, error)
|
|
// Sweeper backstop: due, not-yet-fired rows. Concurrency safety comes from the
|
|
// per-row claim (MarkScheduledChangeApplied), not row locking, so a plain read
|
|
// is sufficient.
|
|
ListDueScheduledChanges(ctx context.Context) ([]SubscriptionScheduledChange, error)
|
|
// Operator invoices view, paged/searched/filtered (operator-list-scale
|
|
// UX-4; operator-billing-views D5/D8). Carries ba.org_id so the handler can
|
|
// resolve and link the organization without a cross-module join (see
|
|
// billing_accounts.sql's ListBillingAccountsPage comment for why).
|
|
//
|
|
// sqlc.narg(q): NULL matches every row; set, a case-insensitive substring
|
|
// match against the billing account's name (the view's leading identifier
|
|
// pre-reorder) or its organization via sqlc.narg(org_ids), pre-resolved in
|
|
// Go (operator_billing.go: matchingOrgIDs).
|
|
// sqlc.narg(status): NULL matches every status. The stored status
|
|
// vocabulary (design/data-model.md: draft, open, paid, void,
|
|
// uncollectible, refunded -- core.invoices carries no CHECK constraint,
|
|
// this is the documented closed set) matches exactly; the sentinel value
|
|
// 'overdue' instead selects the derived predicate design D5 defines --
|
|
// status = 'open' AND due_date IS NOT NULL AND due_date < now() -- so the
|
|
// Overdue filter's total is computed in SQL, never after LIMIT (the same
|
|
// predicate operator_billing.go's invoiceIsOverdue applies in Go for
|
|
// per-row presentation; a test pins their agreement).
|
|
// count(*) OVER() carries the true total for the filtered set (design D2).
|
|
ListInvoicesPage(ctx context.Context, arg ListInvoicesPageParams) ([]ListInvoicesPageRow, error)
|
|
ListLaddersByProduct(ctx context.Context, productID string) ([]ListLaddersByProductRow, error)
|
|
// Operator payments view, paged and searched (operator-list-scale UX-4;
|
|
// operator-billing-views D8). No status facet: the operator-list-scale
|
|
// spec's "Status filters exist where a status vocabulary exists"
|
|
// requirement enumerates grants/invoices/subscriptions/organizations, not
|
|
// payments, so this query offers search + pagination only. Carries
|
|
// ba.org_id so the handler can resolve and link the organization without a
|
|
// cross-module join (see billing_accounts.sql's ListBillingAccountsPage
|
|
// comment for why).
|
|
//
|
|
// sqlc.narg(q): NULL matches every row; set, a case-insensitive substring
|
|
// match against the billing account's name (the view's leading identifier
|
|
// pre-reorder) or its organization via sqlc.narg(org_ids), pre-resolved in
|
|
// Go (operator_billing.go: matchingOrgIDs).
|
|
// count(*) OVER() carries the true total for the filtered set (design D2).
|
|
ListPaymentsPage(ctx context.Context, arg ListPaymentsPageParams) ([]ListPaymentsPageRow, error)
|
|
ListPlanLadders(ctx context.Context) ([]PlanLadder, error)
|
|
// 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.
|
|
ListPlanLaddersWithRankZeroProduct(ctx context.Context) ([]ListPlanLaddersWithRankZeroProductRow, error)
|
|
ListPricesByProduct(ctx context.Context, productID string) ([]Price, error)
|
|
// 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.
|
|
ListPublicPlanProducts(ctx context.Context) ([]Product, error)
|
|
ListPublicProducts(ctx context.Context) ([]Product, error)
|
|
// Recent invoices for the operator landing activity timeline. Joins to
|
|
// core.accounts to resolve the org_id (same schema, safe for sqlc).
|
|
ListRecentInvoices(ctx context.Context, limit int32) ([]ListRecentInvoicesRow, error)
|
|
// Recent payments for the operator landing activity timeline. Joins to
|
|
// core.accounts to resolve the org_id (same schema, safe for sqlc).
|
|
ListRecentPayments(ctx context.Context, limit int32) ([]ListRecentPaymentsRow, error)
|
|
// 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.
|
|
ListSharedTierProducts(ctx context.Context) ([]ListSharedTierProductsRow, error)
|
|
// Operator subscriptions view, paged/searched/filtered (operator-list-scale
|
|
// UX-4; operator-billing-views D8). Carries ba.org_id so the handler can
|
|
// resolve and link the organization without a cross-module join (see
|
|
// billing_accounts.sql's ListBillingAccountsPage comment for why).
|
|
//
|
|
// sqlc.narg(q): NULL matches every row; set, a case-insensitive substring
|
|
// match against the billing account's name (the view's leading identifier
|
|
// pre-reorder) or its organization via sqlc.narg(org_ids), pre-resolved in
|
|
// Go (operator_billing.go: matchingOrgIDs).
|
|
// sqlc.narg(status): NULL matches every status; set, an exact match
|
|
// against the subscription's CHECK-constrained status vocabulary
|
|
// (00010_schema_hardening.sql: chk_subscriptions_status_valid --
|
|
// incomplete, incomplete_expired, trialing, active, past_due, canceled,
|
|
// unpaid, paused).
|
|
// count(*) OVER() carries the true total for the filtered set (design D2).
|
|
ListSubscriptionsPage(ctx context.Context, arg ListSubscriptionsPageParams) ([]ListSubscriptionsPageRow, error)
|
|
ListTiersByLadder(ctx context.Context, planLadderID string) ([]PlanLadderTier, error)
|
|
ListTiersByLadderWithProducts(ctx context.Context, planLadderID string) ([]ListTiersByLadderWithProductsRow, error)
|
|
// Second half of the make-default handshake. Scoped to (price_id, product_id)
|
|
// so a stale/forged price ID from another product cannot be promoted; the
|
|
// is_active guard keeps a deactivated price from becoming the default.
|
|
MarkDefaultPrice(ctx context.Context, arg MarkDefaultPriceParams) (Price, error)
|
|
MarkPaymentMethodDetached(ctx context.Context, paymentMethodID string) error
|
|
// Idempotency guard / claim: the status transition scheduled->applied is the
|
|
// claim. A second firer (webhook vs sweeper) gets sql.ErrNoRows and no-ops.
|
|
MarkScheduledChangeApplied(ctx context.Context, scheduledChangeID string) (SubscriptionScheduledChange, error)
|
|
// 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.
|
|
SetPlanLadderSortOrder(ctx context.Context, arg SetPlanLadderSortOrderParams) error
|
|
// The Monthly recurring headline, per currency — the caller displays the
|
|
// largest bucket and acknowledges the rest (cross-currency conversion is
|
|
// explicitly out of scope: issues.md). Monthly-normalized: month prices at
|
|
// face value, year at one-twelfth, each times item quantity. Active only —
|
|
// trialing subscriptions pay nothing today and counting their money would
|
|
// overstate.
|
|
SumMonthlyRecurringByCurrency(ctx context.Context) ([]SumMonthlyRecurringByCurrencyRow, error)
|
|
// Outstanding receivables for the Open invoices caption, per currency —
|
|
// the caller applies the same largest-bucket display rule as the Monthly
|
|
// recurring headline.
|
|
SumOpenInvoiceBalanceByCurrency(ctx context.Context) ([]SumOpenInvoiceBalanceByCurrencyRow, error)
|
|
// A new scheduled change (or an immediate action) supersedes any still-pending
|
|
// intent on the same subscription.
|
|
SupersedeActiveScheduledChanges(ctx context.Context, subscriptionID string) error
|
|
UpdateBillingAccountStatus(ctx context.Context, arg UpdateBillingAccountStatusParams) (Account, error)
|
|
UpdateInvoicePaid(ctx context.Context, arg UpdateInvoicePaidParams) (Invoice, error)
|
|
UpdateInvoiceStatus(ctx context.Context, arg UpdateInvoiceStatusParams) (Invoice, error)
|
|
UpdateInvoiceVoided(ctx context.Context, arg UpdateInvoiceVoidedParams) (Invoice, error)
|
|
UpdatePaymentMethodSafeFields(ctx context.Context, arg UpdatePaymentMethodSafeFieldsParams) (PaymentMethod, error)
|
|
UpdatePlanLadder(ctx context.Context, arg UpdatePlanLadderParams) (PlanLadder, error)
|
|
UpdateProduct(ctx context.Context, arg UpdateProductParams) (Product, error)
|
|
// Converge a core item row after an in-place Stripe price modification (paid->paid
|
|
// switch): the Stripe item id is unchanged but it now carries a new price/product.
|
|
UpdateSubscriptionItemPriceProduct(ctx context.Context, arg UpdateSubscriptionItemPriceProductParams) (SubscriptionItem, error)
|
|
UpdateSubscriptionStatus(ctx context.Context, arg UpdateSubscriptionStatusParams) (Subscription, error)
|
|
UpdateTierRank(ctx context.Context, arg UpdateTierRankParams) (PlanLadderTier, error)
|
|
}
|
|
|
|
var _ Querier = (*Queries)(nil)
|