Add overview counts and system-health queries

Back the operator landing surface with live deployment counts and
integration health signals, one sqlc query per owning module.

CountDeliveringGrants joins core.pool_provisions rather than filtering
grants.status: grants.status is an issuance ledger recording what was
written down and whether it was later revoked, not whether service is
flowing. The current-delivery fact lives on pool_provisions.status, and a
grant can sit at status='active' with every provision ended. Counting the
ledger alone would overstate delivery.

CountClaimsByLifecycle and CountOutboxByStatus each return their buckets
in a single row, so the halves that get printed together are read at the
same instant and the landing surface pays one round trip rather than one
per bucket.
This commit is contained in:
2026-07-25 15:44:21 -05:00
parent 22c2b02316
commit 56a743fb32
22 changed files with 298 additions and 0 deletions
+15
View File
@@ -13,6 +13,21 @@ import (
"github.com/sqlc-dev/pqtype"
)
const countPublishedProducts = `-- name: CountPublishedProducts :one
SELECT COUNT(*) FROM core.products
WHERE lifecycle_status = 'published'
`
// 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.
func (q *Queries) CountPublishedProducts(ctx context.Context) (int64, error) {
row := q.db.QueryRowContext(ctx, countPublishedProducts)
var count int64
err := row.Scan(&count)
return count, err
}
const createProduct = `-- name: CreateProduct :one
INSERT INTO core.products (name, description, display_category, is_active, is_public, entitlement_set_id, lifecycle_status)
VALUES ($1, $2, $3, $4, $5, $6, $7)
+8
View File
@@ -18,6 +18,14 @@ type Querier interface {
// MarkDefaultPrice (clear before set, so the partial unique index never sees
// two defaults for one product).
ClearDefaultPrice(ctx context.Context, productID string) error
// Operator overview tile. 'active' and 'trialing' are the two statuses that
// mean the subscription is presently owed service — the same pair
// operator_billing.go treats as live when it renders a subscription badge.
CountLiveSubscriptions(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)
CreateBillingAccount(ctx context.Context, arg CreateBillingAccountParams) (Account, error)
CreateInvoice(ctx context.Context, arg CreateInvoiceParams) (Invoice, error)
CreateInvoiceLineItem(ctx context.Context, arg CreateInvoiceLineItemParams) (InvoiceLineItem, error)
+7
View File
@@ -42,6 +42,13 @@ SET name = $2, description = $3, display_category = $4, is_active = $5, is_publi
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.
@@ -39,3 +39,10 @@ SELECT
FROM core.subscriptions s
JOIN core.accounts ba ON s.billing_account_id = ba.billing_account_id
ORDER BY s.created_at DESC;
-- name: CountLiveSubscriptions :one
-- Operator overview tile. 'active' and 'trialing' are the two statuses that
-- mean the subscription is presently owed service — the same pair
-- operator_billing.go treats as live when it renders a subscription badge.
SELECT COUNT(*) FROM core.subscriptions
WHERE status IN ('active', 'trialing');
+15
View File
@@ -11,6 +11,21 @@ import (
"time"
)
const countLiveSubscriptions = `-- name: CountLiveSubscriptions :one
SELECT COUNT(*) FROM core.subscriptions
WHERE status IN ('active', 'trialing')
`
// Operator overview tile. 'active' and 'trialing' are the two statuses that
// mean the subscription is presently owed service — the same pair
// operator_billing.go treats as live when it renders a subscription badge.
func (q *Queries) CountLiveSubscriptions(ctx context.Context) (int64, error) {
row := q.db.QueryRowContext(ctx, countLiveSubscriptions)
var count int64
err := row.Scan(&count)
return count, err
}
const createSubscription = `-- name: CreateSubscription :one
INSERT INTO core.subscriptions (billing_account_id, status, current_period_start, current_period_end)
VALUES ($1, $2, $3, $4)
+23
View File
@@ -14,6 +14,29 @@ import (
"github.com/lib/pq"
)
const countClaimsByLifecycle = `-- name: CountClaimsByLifecycle :one
SELECT
COUNT(*) FILTER (WHERE status = 'active') AS live_count,
COUNT(*) FILTER (WHERE status = 'pending') AS pending_count
FROM domains.claims
`
type CountClaimsByLifecycleRow struct {
LiveCount int64 `json:"live_count"`
PendingCount int64 `json:"pending_count"`
}
// Operator overview tile, deployment-wide. Both halves come back in one round
// trip because the tile prints them together ("N live · M awaiting
// verification") and they must be read at the same instant to stay coherent.
// Terminal statuses (expired/canceled/released) are history and are excluded.
func (q *Queries) CountClaimsByLifecycle(ctx context.Context) (CountClaimsByLifecycleRow, error) {
row := q.db.QueryRowContext(ctx, countClaimsByLifecycle)
var i CountClaimsByLifecycleRow
err := row.Scan(&i.LiveCount, &i.PendingCount)
return i, err
}
const countPendingClaimsByWorkspace = `-- name: CountPendingClaimsByWorkspace :one
SELECT COUNT(*) FROM domains.claims
WHERE workspace_id = $1 AND status = 'pending'
+5
View File
@@ -11,6 +11,11 @@ import (
)
type Querier interface {
// Operator overview tile, deployment-wide. Both halves come back in one round
// trip because the tile prints them together ("N live · M awaiting
// verification") and they must be read at the same instant to stay coherent.
// Terminal statuses (expired/canceled/released) are history and are excluded.
CountClaimsByLifecycle(ctx context.Context) (CountClaimsByLifecycleRow, error)
// Soft cap on concurrent external verifications — each is a live 24-hour
// polling workflow.
CountPendingClaimsByWorkspace(ctx context.Context, workspaceID string) (int64, error)
+10
View File
@@ -65,6 +65,16 @@ JOIN core.organizations o ON o.org_id = w.org_id
WHERE c.status IN ('pending', 'active')
ORDER BY (c.status = 'pending') DESC, c.created_at DESC;
-- name: CountClaimsByLifecycle :one
-- Operator overview tile, deployment-wide. Both halves come back in one round
-- trip because the tile prints them together ("N live · M awaiting
-- verification") and they must be read at the same instant to stay coherent.
-- Terminal statuses (expired/canceled/released) are history and are excluded.
SELECT
COUNT(*) FILTER (WHERE status = 'active') AS live_count,
COUNT(*) FILTER (WHERE status = 'pending') AS pending_count
FROM domains.claims;
-- name: CountPendingClaimsByWorkspace :one
-- Soft cap on concurrent external verifications — each is a live 24-hour
-- polling workflow.
+23
View File
@@ -14,6 +14,29 @@ import (
"github.com/sqlc-dev/pqtype"
)
const countDeliveringGrants = `-- name: CountDeliveringGrants :one
SELECT COUNT(DISTINCT g.grant_id) FROM core.grants g
JOIN core.pool_provisions pp ON pp.grant_id = g.grant_id
WHERE pp.status = 'active'
`
// Operator overview tile: grants that are actually delivering entitlement
// right now.
//
// grants.status is an issuance LEDGER — it records what was written and
// whether it was later revoked, not whether service is flowing today. The
// current-delivery fact lives on core.pool_provisions.status, so this counts
// distinct grants that own at least one active provision rather than
// filtering grants.status alone. A grant can sit at status='active' with
// every provision ended (nothing delivering), which is exactly the
// overstatement this join avoids.
func (q *Queries) CountDeliveringGrants(ctx context.Context) (int64, error) {
row := q.db.QueryRowContext(ctx, countDeliveringGrants)
var count int64
err := row.Scan(&count)
return count, err
}
const createGrant = `-- name: CreateGrant :one
INSERT INTO core.grants (product_id, granted_to_org_id, granted_by_person_id, grant_reason, description, quantity, valid_from, valid_until, extends_grant_id)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
@@ -11,6 +11,22 @@ import (
"github.com/google/uuid"
)
const countDeliveringProvisions = `-- name: CountDeliveringProvisions :one
SELECT COUNT(*) FROM core.pool_provisions
WHERE status = 'active'
`
// Operator overview tile: how many pool provisions are delivering right now.
// pool_provisions.status is the authoritative "currently delivering" flag —
// grants.status is an issuance ledger and must not be used for this — so the
// overview counts this table directly.
func (q *Queries) CountDeliveringProvisions(ctx context.Context) (int64, error) {
row := q.db.QueryRowContext(ctx, countDeliveringProvisions)
var count int64
err := row.Scan(&count)
return count, err
}
const getActivePoolProvisionsByPoolID = `-- name: GetActivePoolProvisionsByPoolID :many
SELECT provision_id, pool_id, billing_account_id, subscription_id, purchase_id, grant_id, quantity, status, activated_at, suspended_at, ended_at, created_at, updated_at, entitlement_set_id, product_id FROM core.pool_provisions
WHERE pool_id = $1 AND status = 'active'
+16
View File
@@ -16,6 +16,22 @@ type Querier interface {
AtomicIncrementUsage(ctx context.Context, arg AtomicIncrementUsageParams) (sql.Result, error)
CountActiveAttachmentsByLadder(ctx context.Context, planLadderID string) (int64, error)
CountActiveAttachmentsByTier(ctx context.Context, arg CountActiveAttachmentsByTierParams) (int64, error)
// Operator overview tile: grants that are actually delivering entitlement
// right now.
//
// grants.status is an issuance LEDGER — it records what was written and
// whether it was later revoked, not whether service is flowing today. The
// current-delivery fact lives on core.pool_provisions.status, so this counts
// distinct grants that own at least one active provision rather than
// filtering grants.status alone. A grant can sit at status='active' with
// every provision ended (nothing delivering), which is exactly the
// overstatement this join avoids.
CountDeliveringGrants(ctx context.Context) (int64, error)
// Operator overview tile: how many pool provisions are delivering right now.
// pool_provisions.status is the authoritative "currently delivering" flag —
// grants.status is an issuance ledger and must not be used for this — so the
// overview counts this table directly.
CountDeliveringProvisions(ctx context.Context) (int64, error)
CreateEntitlementSet(ctx context.Context, arg CreateEntitlementSetParams) (EntitlementSet, error)
CreateEntitlementSetRule(ctx context.Context, arg CreateEntitlementSetRuleParams) (EntitlementSetRule, error)
CreateGrant(ctx context.Context, arg CreateGrantParams) (Grant, error)
+15
View File
@@ -104,6 +104,21 @@ WHERE granted_to_org_id IS NOT NULL
ORDER BY created_at DESC
LIMIT $1;
-- name: CountDeliveringGrants :one
-- Operator overview tile: grants that are actually delivering entitlement
-- right now.
--
-- grants.status is an issuance LEDGER — it records what was written and
-- whether it was later revoked, not whether service is flowing today. The
-- current-delivery fact lives on core.pool_provisions.status, so this counts
-- distinct grants that own at least one active provision rather than
-- filtering grants.status alone. A grant can sit at status='active' with
-- every provision ended (nothing delivering), which is exactly the
-- overstatement this join avoids.
SELECT COUNT(DISTINCT g.grant_id) FROM core.grants g
JOIN core.pool_provisions pp ON pp.grant_id = g.grant_id
WHERE pp.status = 'active';
-- name: ListAllGrants :many
SELECT * FROM core.grants
ORDER BY created_at DESC;
@@ -31,6 +31,14 @@ SELECT * FROM core.pool_provisions
WHERE subscription_id = $1 AND status <> 'ended'
ORDER BY created_at ASC;
-- name: CountDeliveringProvisions :one
-- Operator overview tile: how many pool provisions are delivering right now.
-- pool_provisions.status is the authoritative "currently delivering" flag —
-- grants.status is an issuance ledger and must not be used for this — so the
-- overview counts this table directly.
SELECT COUNT(*) FROM core.pool_provisions
WHERE status = 'active';
-- name: GetLivePoolProvisionsByProductID :many
-- Live (non-ended) provisions delivering a product. Tier add/remove aligns
-- each of these to the product's new conferral shape.
+15
View File
@@ -9,6 +9,21 @@ import (
"context"
)
const countActivePersons = `-- name: CountActivePersons :one
SELECT COUNT(*) FROM core.persons
WHERE status = 'active'
`
// Operator overview tile: how many people the deployment currently serves.
// Mirrors LookupPersons' status='active' filter so the headline number and
// the lookup affordance above it are counting the same population.
func (q *Queries) CountActivePersons(ctx context.Context) (int64, error) {
row := q.db.QueryRowContext(ctx, countActivePersons)
var count int64
err := row.Scan(&count)
return count, err
}
const createPerson = `-- name: CreatePerson :one
INSERT INTO core.persons (user_id, display_name, primary_email, primary_email_verified)
VALUES ($1, $2, $3, $4)
+4
View File
@@ -9,6 +9,10 @@ import (
)
type Querier interface {
// Operator overview tile: how many people the deployment currently serves.
// Mirrors LookupPersons' status='active' filter so the headline number and
// the lookup affordance above it are counting the same population.
CountActivePersons(ctx context.Context) (int64, error)
CreatePerson(ctx context.Context, arg CreatePersonParams) (Person, error)
CreateUser(ctx context.Context, oidcSubject string) (User, error)
// Idempotently insert the reserved system person that owns the System tenant
+7
View File
@@ -43,3 +43,10 @@ ORDER BY
CASE WHEN primary_email = $1 THEN 0 ELSE 1 END,
display_name
LIMIT 20;
-- name: CountActivePersons :one
-- Operator overview tile: how many people the deployment currently serves.
-- Mirrors LookupPersons' status='active' filter so the headline number and
-- the lookup affordance above it are counting the same population.
SELECT COUNT(*) FROM core.persons
WHERE status = 'active';
+46
View File
@@ -0,0 +1,46 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
// source: outbox.sql
package integration
import (
"context"
)
const countOutboxByStatus = `-- name: CountOutboxByStatus :one
SELECT
COUNT(*) FILTER (WHERE status = 'pending') AS pending_count,
COUNT(*) FILTER (WHERE status = 'failed') AS failed_count,
COUNT(*) FILTER (WHERE status = 'dead_letter') AS dead_letter_count
FROM core.outbox
`
type CountOutboxByStatusRow struct {
PendingCount int64 `json:"pending_count"`
FailedCount int64 `json:"failed_count"`
DeadLetterCount int64 `json:"dead_letter_count"`
}
// Operator overview "System" panel: the health of the integration delivery
// queue in one round trip.
//
// The three buckets mean different things to an operator and are therefore
// reported separately rather than summed:
//
// pending — enqueued, not yet attempted or waiting on next_attempt_at.
// A steady non-zero value is normal.
// failed — attempted and errored, still inside max_attempts, so the
// poller will retry. In-flight, not lost.
// dead_letter — exhausted its retries. Nothing will move this without an
// operator, so it is the only bucket that warrants an alarm.
//
// Enqueue-side writes go through integration.Enqueue (internal/integration/
// outbox.go); this is a read-only health probe over the same table.
func (q *Queries) CountOutboxByStatus(ctx context.Context) (CountOutboxByStatusRow, error) {
row := q.db.QueryRowContext(ctx, countOutboxByStatus)
var i CountOutboxByStatusRow
err := row.Scan(&i.PendingCount, &i.FailedCount, &i.DeadLetterCount)
return i, err
}
+15
View File
@@ -11,6 +11,21 @@ import (
type Querier interface {
AddProviderOperation(ctx context.Context, arg AddProviderOperationParams) error
AddProviderState(ctx context.Context, arg AddProviderStateParams) error
// Operator overview "System" panel: the health of the integration delivery
// queue in one round trip.
//
// The three buckets mean different things to an operator and are therefore
// reported separately rather than summed:
// pending — enqueued, not yet attempted or waiting on next_attempt_at.
// A steady non-zero value is normal.
// failed — attempted and errored, still inside max_attempts, so the
// poller will retry. In-flight, not lost.
// dead_letter — exhausted its retries. Nothing will move this without an
// operator, so it is the only bucket that warrants an alarm.
//
// Enqueue-side writes go through integration.Enqueue (internal/integration/
// outbox.go); this is a read-only health probe over the same table.
CountOutboxByStatus(ctx context.Context) (CountOutboxByStatusRow, error)
DeleteConfigOverride(ctx context.Context, key string) (int64, error)
// Boot reconciliation: drop operations a provider no longer declares.
DeleteProviderOperationsNotIn(ctx context.Context, arg DeleteProviderOperationsNotInParams) error
+20
View File
@@ -0,0 +1,20 @@
-- name: CountOutboxByStatus :one
-- Operator overview "System" panel: the health of the integration delivery
-- queue in one round trip.
--
-- The three buckets mean different things to an operator and are therefore
-- reported separately rather than summed:
-- pending — enqueued, not yet attempted or waiting on next_attempt_at.
-- A steady non-zero value is normal.
-- failed — attempted and errored, still inside max_attempts, so the
-- poller will retry. In-flight, not lost.
-- dead_letter — exhausted its retries. Nothing will move this without an
-- operator, so it is the only bucket that warrants an alarm.
--
-- Enqueue-side writes go through integration.Enqueue (internal/integration/
-- outbox.go); this is a read-only health probe over the same table.
SELECT
COUNT(*) FILTER (WHERE status = 'pending') AS pending_count,
COUNT(*) FILTER (WHERE status = 'failed') AS failed_count,
COUNT(*) FILTER (WHERE status = 'dead_letter') AS dead_letter_count
FROM core.outbox;
@@ -9,6 +9,20 @@ import (
"context"
)
const countActiveOrganizations = `-- name: CountActiveOrganizations :one
SELECT COUNT(*) FROM core.organizations
WHERE status = 'active'
`
// Operator overview tile. Counts only status='active' rows so suspended or
// archived organizations don't inflate the headline number.
func (q *Queries) CountActiveOrganizations(ctx context.Context) (int64, error) {
row := q.db.QueryRowContext(ctx, countActiveOrganizations)
var count int64
err := row.Scan(&count)
return count, err
}
const createOrganization = `-- name: CreateOrganization :one
INSERT INTO core.organizations (name, slug, org_type, owner_person_id)
VALUES ($1, $2, $3, $4)
+3
View File
@@ -9,6 +9,9 @@ import (
)
type Querier interface {
// Operator overview tile. Counts only status='active' rows so suspended or
// archived organizations don't inflate the headline number.
CountActiveOrganizations(ctx context.Context) (int64, error)
CountWorkspacesByOrgID(ctx context.Context, orgID string) (int64, error)
CreateOrgMember(ctx context.Context, arg CreateOrgMemberParams) (OrgMember, error)
CreateOrganization(ctx context.Context, arg CreateOrganizationParams) (Organization, error)
@@ -25,6 +25,12 @@ SELECT * FROM core.organizations
WHERE org_type = $1
ORDER BY name;
-- name: CountActiveOrganizations :one
-- Operator overview tile. Counts only status='active' rows so suspended or
-- archived organizations don't inflate the headline number.
SELECT COUNT(*) FROM core.organizations
WHERE status = 'active';
-- name: EnsureSystemOrganization :exec
-- Idempotently insert the singleton System organization (keyed on the unique
-- slug). Read back with GetOrganizationBySlug.