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:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user