Files
member-console/internal/billing/billing_accounts.sql.go
T
cgalo5758 257955c9d3 Add operator list-scale contract and People directory
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.
2026-08-24 03:58:18 -05:00

293 lines
8.8 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
// source: billing_accounts.sql
package billing
import (
"context"
"database/sql"
"encoding/json"
"time"
"github.com/lib/pq"
)
const createBillingAccount = `-- name: CreateBillingAccount :one
INSERT INTO core.accounts (org_id, name, status, metadata)
VALUES ($1, $2, $3, $4)
RETURNING billing_account_id, org_id, name, status, metadata, created_at, updated_at
`
type CreateBillingAccountParams struct {
OrgID string `json:"org_id"`
Name string `json:"name"`
Status string `json:"status"`
Metadata json.RawMessage `json:"metadata"`
}
func (q *Queries) CreateBillingAccount(ctx context.Context, arg CreateBillingAccountParams) (Account, error) {
row := q.db.QueryRowContext(ctx, createBillingAccount,
arg.OrgID,
arg.Name,
arg.Status,
arg.Metadata,
)
var i Account
err := row.Scan(
&i.BillingAccountID,
&i.OrgID,
&i.Name,
&i.Status,
&i.Metadata,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getBillingAccountByID = `-- name: GetBillingAccountByID :one
SELECT billing_account_id, org_id, name, status, metadata, created_at, updated_at FROM core.accounts
WHERE billing_account_id = $1
`
func (q *Queries) GetBillingAccountByID(ctx context.Context, billingAccountID string) (Account, error) {
row := q.db.QueryRowContext(ctx, getBillingAccountByID, billingAccountID)
var i Account
err := row.Scan(
&i.BillingAccountID,
&i.OrgID,
&i.Name,
&i.Status,
&i.Metadata,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getLatestInvoiceByBillingAccountID = `-- name: GetLatestInvoiceByBillingAccountID :one
SELECT invoice_id, billing_account_id, subscription_id, status, amount_due, amount_paid, currency, period_start, period_end, due_date, paid_at, voided_at, created_at, updated_at FROM core.invoices
WHERE billing_account_id = $1
ORDER BY created_at DESC
LIMIT 1
`
// Most recent invoice for a billing account (any status). Used by the
// per-org composite's billing-summary section.
func (q *Queries) GetLatestInvoiceByBillingAccountID(ctx context.Context, billingAccountID string) (Invoice, error) {
row := q.db.QueryRowContext(ctx, getLatestInvoiceByBillingAccountID, billingAccountID)
var i Invoice
err := row.Scan(
&i.InvoiceID,
&i.BillingAccountID,
&i.SubscriptionID,
&i.Status,
&i.AmountDue,
&i.AmountPaid,
&i.Currency,
&i.PeriodStart,
&i.PeriodEnd,
&i.DueDate,
&i.PaidAt,
&i.VoidedAt,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getLatestSubscriptionByBillingAccountID = `-- name: GetLatestSubscriptionByBillingAccountID :one
SELECT subscription_id, billing_account_id, status, current_period_start, current_period_end, cancel_at_period_end, canceled_at, ended_at, created_at, updated_at, commitment_end, commitment_renewal, early_termination_policy FROM core.subscriptions
WHERE billing_account_id = $1
ORDER BY created_at DESC
LIMIT 1
`
// Most recent subscription for a billing account (any status). Used by the
// per-org composite's billing-summary section.
func (q *Queries) GetLatestSubscriptionByBillingAccountID(ctx context.Context, billingAccountID string) (Subscription, error) {
row := q.db.QueryRowContext(ctx, getLatestSubscriptionByBillingAccountID, billingAccountID)
var i Subscription
err := row.Scan(
&i.SubscriptionID,
&i.BillingAccountID,
&i.Status,
&i.CurrentPeriodStart,
&i.CurrentPeriodEnd,
&i.CancelAtPeriodEnd,
&i.CanceledAt,
&i.EndedAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.CommitmentEnd,
&i.CommitmentRenewal,
&i.EarlyTerminationPolicy,
)
return i, err
}
const getOutstandingBalanceByBillingAccountID = `-- name: GetOutstandingBalanceByBillingAccountID :one
SELECT COALESCE(SUM(amount_due - amount_paid), 0)::BIGINT AS outstanding_balance
FROM core.invoices
WHERE billing_account_id = $1
AND status = 'open'
`
// 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.
func (q *Queries) GetOutstandingBalanceByBillingAccountID(ctx context.Context, billingAccountID string) (int64, error) {
row := q.db.QueryRowContext(ctx, getOutstandingBalanceByBillingAccountID, billingAccountID)
var outstanding_balance int64
err := row.Scan(&outstanding_balance)
return outstanding_balance, err
}
const listBillingAccountsByOrgID = `-- name: ListBillingAccountsByOrgID :many
SELECT billing_account_id, org_id, name, status, metadata, created_at, updated_at FROM core.accounts
WHERE org_id = $1
ORDER BY created_at ASC
`
func (q *Queries) ListBillingAccountsByOrgID(ctx context.Context, orgID string) ([]Account, error) {
rows, err := q.db.QueryContext(ctx, listBillingAccountsByOrgID, orgID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []Account{}
for rows.Next() {
var i Account
if err := rows.Scan(
&i.BillingAccountID,
&i.OrgID,
&i.Name,
&i.Status,
&i.Metadata,
&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 listBillingAccountsPage = `-- name: ListBillingAccountsPage :many
SELECT a.billing_account_id, a.org_id, a.name, a.status, a.metadata, a.created_at, a.updated_at,
count(*) OVER() AS total_count
FROM core.accounts a
WHERE ($1::text IS NULL
OR a.name ILIKE '%' || $1::text || '%'
OR a.org_id = ANY($2::uuid[]))
ORDER BY a.created_at DESC
LIMIT $4::int OFFSET $3::int
`
type ListBillingAccountsPageParams struct {
Q sql.NullString `json:"q"`
OrgIds []string `json:"org_ids"`
PageOffset int32 `json:"page_offset"`
PageLimit int32 `json:"page_limit"`
}
type ListBillingAccountsPageRow struct {
BillingAccountID string `json:"billing_account_id"`
OrgID string `json:"org_id"`
Name string `json:"name"`
Status string `json:"status"`
Metadata json.RawMessage `json:"metadata"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
TotalCount int64 `json:"total_count"`
}
// 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).
func (q *Queries) ListBillingAccountsPage(ctx context.Context, arg ListBillingAccountsPageParams) ([]ListBillingAccountsPageRow, error) {
rows, err := q.db.QueryContext(ctx, listBillingAccountsPage,
arg.Q,
pq.Array(arg.OrgIds),
arg.PageOffset,
arg.PageLimit,
)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListBillingAccountsPageRow{}
for rows.Next() {
var i ListBillingAccountsPageRow
if err := rows.Scan(
&i.BillingAccountID,
&i.OrgID,
&i.Name,
&i.Status,
&i.Metadata,
&i.CreatedAt,
&i.UpdatedAt,
&i.TotalCount,
); 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 updateBillingAccountStatus = `-- name: UpdateBillingAccountStatus :one
UPDATE core.accounts
SET status = $2
WHERE billing_account_id = $1
RETURNING billing_account_id, org_id, name, status, metadata, created_at, updated_at
`
type UpdateBillingAccountStatusParams struct {
BillingAccountID string `json:"billing_account_id"`
Status string `json:"status"`
}
func (q *Queries) UpdateBillingAccountStatus(ctx context.Context, arg UpdateBillingAccountStatusParams) (Account, error) {
row := q.db.QueryRowContext(ctx, updateBillingAccountStatus, arg.BillingAccountID, arg.Status)
var i Account
err := row.Scan(
&i.BillingAccountID,
&i.OrgID,
&i.Name,
&i.Status,
&i.Metadata,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}