-- Webhook subscriptions: external endpoints that receive event notifications CREATE TABLE IF NOT EXISTS webhook_subscriptions ( id TEXT PRIMARY KEY, account_id TEXT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE, url TEXT NOT NULL, secret TEXT NOT NULL, -- HMAC-SHA256 signing secret (hex-encoded) events TEXT[] NOT NULL DEFAULT '{}', -- e.g. '{billing.payment.completed,agent.task.finished}' enabled BOOLEAN NOT NULL DEFAULT true, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- Webhook delivery log: tracks each delivery attempt CREATE TABLE IF NOT EXISTS webhook_deliveries ( id TEXT PRIMARY KEY, subscription_id TEXT NOT NULL REFERENCES webhook_subscriptions(id) ON DELETE CASCADE, event TEXT NOT NULL, payload JSONB NOT NULL DEFAULT '{}', response_status INTEGER, response_body TEXT, attempts INTEGER NOT NULL DEFAULT 0, delivered_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_webhook_subscriptions_account ON webhook_subscriptions(account_id); CREATE INDEX IF NOT EXISTS idx_webhook_subscriptions_events ON webhook_subscriptions USING gin(events); CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_pending ON webhook_deliveries(subscription_id) WHERE delivered_at IS NULL;