Drop redundant schema prefixes from all sqlc-generated Go types. Since each module generates into its own package, the package already provides the namespace — billing.Account is unambiguous without billing.BillingAccount. Changes: - Add rename: blocks to all 6 sqlc.yaml files mapping schema-prefixed names to clean idiomatic names (e.g. BillingBillingAccount → Account, IdentityPerson → Person, OrganizationOrganization → Organization) - Rename billing.billing_accounts → billing.accounts (table name repeated the schema; the schema already provides that context) - Rename integration.integration_outbox → integration.outbox (same reason) - Regenerate all sqlc output across billing, identity, organization, entitlements, stripe, and fedwiki modules - Update all calling code (server, workflows, provisioning, tests) to use the new names - Add internal/db/sqlc_schemas.sql — sqlc-only schema declarations so every module can resolve schema-qualified names without including the full db migrations - Update docs/database-management.md with the naming convention and standard sqlc.yaml template Convention going forward: table names must not repeat the schema name; generated types carry no schema prefix; the Go package provides the namespace (like http.Request, not http.HttpRequest).
74 lines
3.1 KiB
SQL
74 lines
3.1 KiB
SQL
-- +goose Up
|
|
-- +goose StatementBegin
|
|
|
|
-- webhook_events: idempotent inbound webhook capture, partitioned monthly.
|
|
-- Processors poll by status; partitioning keeps old data manageable.
|
|
CREATE TABLE integration.webhook_events (
|
|
id BIGINT GENERATED ALWAYS AS IDENTITY,
|
|
provider TEXT NOT NULL, -- e.g. 'stripe'
|
|
provider_event_id TEXT NOT NULL, -- Stripe event ID (evt_…)
|
|
event_type TEXT NOT NULL, -- e.g. 'invoice.paid'
|
|
payload JSONB NOT NULL DEFAULT '{}',
|
|
status TEXT NOT NULL DEFAULT 'received', -- received | processing | completed | skipped | failed
|
|
retry_count INT NOT NULL DEFAULT 0,
|
|
error_message TEXT,
|
|
received_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
processed_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT webhook_events_pkey PRIMARY KEY (id, received_at),
|
|
CONSTRAINT webhook_events_provider_event_uniq UNIQUE (provider, provider_event_id, received_at)
|
|
) PARTITION BY RANGE (received_at);
|
|
|
|
-- Create initial partitions: current month + next 2 months.
|
|
-- Future partitions are created by application boot or a scheduler.
|
|
DO $$
|
|
DECLARE
|
|
m_start DATE;
|
|
m_end DATE;
|
|
part TEXT;
|
|
BEGIN
|
|
FOR i IN 0..2 LOOP
|
|
m_start := DATE_TRUNC('month', NOW()) + (i || ' months')::INTERVAL;
|
|
m_end := m_start + '1 month'::INTERVAL;
|
|
part := 'integration.webhook_events_' || TO_CHAR(m_start, 'YYYY_MM');
|
|
EXECUTE FORMAT(
|
|
'CREATE TABLE IF NOT EXISTS %s PARTITION OF integration.webhook_events
|
|
FOR VALUES FROM (%L) TO (%L)',
|
|
part, m_start, m_end
|
|
);
|
|
END LOOP;
|
|
END$$;
|
|
|
|
CREATE INDEX idx_webhook_events_status_received
|
|
ON integration.webhook_events (status, received_at)
|
|
WHERE status IN ('received', 'failed');
|
|
|
|
CREATE INDEX idx_webhook_events_provider_event
|
|
ON integration.webhook_events (provider, provider_event_id);
|
|
|
|
-- outbox: transactional outbound actions with retry + dead-letter.
|
|
CREATE TABLE integration.outbox (
|
|
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
provider TEXT NOT NULL, -- e.g. 'stripe'
|
|
action_type TEXT NOT NULL, -- e.g. 'create_customer'
|
|
payload JSONB NOT NULL DEFAULT '{}',
|
|
status TEXT NOT NULL DEFAULT 'pending', -- pending | processing | completed | failed | dead_letter
|
|
attempts INT NOT NULL DEFAULT 0,
|
|
max_attempts INT NOT NULL DEFAULT 5,
|
|
next_attempt_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
error_message TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_outbox_pending
|
|
ON integration.outbox (status, next_attempt_at)
|
|
WHERE status IN ('pending', 'failed');
|
|
|
|
-- +goose StatementEnd
|
|
|
|
-- +goose Down
|
|
DROP TABLE IF EXISTS integration.outbox;
|
|
DROP TABLE IF EXISTS integration.webhook_events;
|