-- ========================================== -- Armature — 011 Triggers & Scheduled Tasks -- ========================================== -- ── Extension Triggers (event + webhook) ────── CREATE TABLE IF NOT EXISTS triggers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), package_id TEXT NOT NULL REFERENCES packages(id) ON DELETE CASCADE, type TEXT NOT NULL CHECK (type IN ('webhook', 'event')), enabled BOOLEAN NOT NULL DEFAULT true, -- Webhook triggers slug TEXT, secret TEXT, -- Event triggers event_pattern TEXT, -- Common entry_point TEXT NOT NULL, config JSONB NOT NULL DEFAULT '{}', fire_count INTEGER NOT NULL DEFAULT 0, last_fire_at TIMESTAMPTZ, last_error TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE(package_id, type, slug), UNIQUE(package_id, type, event_pattern) ); CREATE INDEX IF NOT EXISTS idx_triggers_package ON triggers(package_id); CREATE INDEX IF NOT EXISTS idx_triggers_type ON triggers(type); CREATE INDEX IF NOT EXISTS idx_triggers_enabled ON triggers(enabled) WHERE enabled = true; CREATE INDEX IF NOT EXISTS idx_triggers_webhook ON triggers(package_id, slug) WHERE type = 'webhook'; -- ── Scheduled Tasks (user-created cron) ─────── CREATE TABLE IF NOT EXISTS scheduled_tasks ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, description TEXT NOT NULL DEFAULT '', creator_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, run_as TEXT NOT NULL DEFAULT 'creator' CHECK (run_as IN ('creator', 'system')), cron_expr TEXT NOT NULL, next_fire_at TIMESTAMPTZ, last_fire_at TIMESTAMPTZ, enabled BOOLEAN NOT NULL DEFAULT true, script TEXT NOT NULL DEFAULT '', template_id TEXT, template_params JSONB NOT NULL DEFAULT '{}', fire_count INTEGER NOT NULL DEFAULT 0, last_error TEXT, last_duration_ms INTEGER, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_sched_tasks_creator ON scheduled_tasks(creator_id); CREATE INDEX IF NOT EXISTS idx_sched_tasks_enabled ON scheduled_tasks(enabled) WHERE enabled = true; CREATE INDEX IF NOT EXISTS idx_sched_tasks_next_fire ON scheduled_tasks(next_fire_at) WHERE enabled = true; -- ── Trigger Logs (unified execution log) ────── CREATE TABLE IF NOT EXISTS trigger_logs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), trigger_id UUID REFERENCES triggers(id) ON DELETE CASCADE, scheduled_task_id UUID REFERENCES scheduled_tasks(id) ON DELETE CASCADE, fired_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), duration_ms INTEGER, success BOOLEAN NOT NULL DEFAULT true, error TEXT, output TEXT, CHECK ( (trigger_id IS NOT NULL AND scheduled_task_id IS NULL) OR (trigger_id IS NULL AND scheduled_task_id IS NOT NULL) ) ); CREATE INDEX IF NOT EXISTS idx_trigger_logs_trigger ON trigger_logs(trigger_id); CREATE INDEX IF NOT EXISTS idx_trigger_logs_sched ON trigger_logs(scheduled_task_id); CREATE INDEX IF NOT EXISTS idx_trigger_logs_fired ON trigger_logs(fired_at);