feat(saas): add webhook event notification system (@unplugged)
Webhook infrastructure for external event notifications: - SQL migration: webhook_subscriptions + webhook_deliveries tables - Types: CreateWebhookRequest, UpdateWebhookRequest, WebhookDelivery - Service: CRUD operations + trigger_webhooks + HMAC-SHA256 signing - Handlers: REST API endpoints (CRUD + delivery logs) - Worker: WebhookDeliveryWorker with exponential retry (max 3) NOT YET INTEGRATED: needs mod registration in lib.rs + workers/mod.rs, hmac crate dependency, and route mounting. Code is ready for future integration after stabilization phase completes.
This commit is contained in:
28
crates/zclaw-saas/migrations/20260403000002_webhooks.sql
Normal file
28
crates/zclaw-saas/migrations/20260403000002_webhooks.sql
Normal file
@@ -0,0 +1,28 @@
|
||||
-- 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 idx_webhook_subscriptions_account ON webhook_subscriptions(account_id);
|
||||
CREATE INDEX idx_webhook_subscriptions_events ON webhook_subscriptions USING gin(events);
|
||||
CREATE INDEX idx_webhook_deliveries_pending ON webhook_deliveries(subscription_id) WHERE delivered_at IS NULL;
|
||||
Reference in New Issue
Block a user