feat(schedule): support KOL subscription targets and random time windows
Extend schedule tasks to dispatch KOL subscription prompts in addition to prompt rules, add daily/weekly scheduling with fixed or random time windows, and track dispatch outcomes (last run, status, consecutive failures). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
DROP INDEX IF EXISTS idx_schedule_task_subscription_prompt;
|
||||
DROP INDEX IF EXISTS idx_schedule_task_target;
|
||||
|
||||
ALTER TABLE schedule_tasks
|
||||
DROP CONSTRAINT IF EXISTS chk_schedule_tasks_consecutive_failures,
|
||||
DROP CONSTRAINT IF EXISTS chk_schedule_tasks_generation_input_json,
|
||||
DROP CONSTRAINT IF EXISTS chk_schedule_tasks_random_window,
|
||||
DROP CONSTRAINT IF EXISTS chk_schedule_tasks_schedule_time_mode,
|
||||
DROP CONSTRAINT IF EXISTS chk_schedule_tasks_schedule_days_json,
|
||||
DROP CONSTRAINT IF EXISTS chk_schedule_tasks_schedule_kind,
|
||||
DROP CONSTRAINT IF EXISTS chk_schedule_tasks_target_ref,
|
||||
DROP CONSTRAINT IF EXISTS chk_schedule_tasks_target_type;
|
||||
|
||||
ALTER TABLE schedule_tasks
|
||||
DROP COLUMN IF EXISTS consecutive_failures,
|
||||
DROP COLUMN IF EXISTS last_dispatch_error,
|
||||
DROP COLUMN IF EXISTS last_dispatch_status,
|
||||
DROP COLUMN IF EXISTS last_run_at,
|
||||
DROP COLUMN IF EXISTS generation_input_json,
|
||||
DROP COLUMN IF EXISTS random_window_end,
|
||||
DROP COLUMN IF EXISTS random_window_start,
|
||||
DROP COLUMN IF EXISTS schedule_time_mode,
|
||||
DROP COLUMN IF EXISTS schedule_days,
|
||||
DROP COLUMN IF EXISTS schedule_kind,
|
||||
DROP COLUMN IF EXISTS subscription_prompt_id,
|
||||
DROP COLUMN IF EXISTS target_type;
|
||||
@@ -0,0 +1,109 @@
|
||||
ALTER TABLE schedule_tasks
|
||||
ALTER COLUMN prompt_rule_id DROP NOT NULL;
|
||||
|
||||
ALTER TABLE schedule_tasks
|
||||
ADD COLUMN IF NOT EXISTS target_type VARCHAR(32) NOT NULL DEFAULT 'prompt_rule',
|
||||
ADD COLUMN IF NOT EXISTS subscription_prompt_id BIGINT REFERENCES kol_subscription_prompts(id),
|
||||
ADD COLUMN IF NOT EXISTS schedule_kind VARCHAR(20) NOT NULL DEFAULT 'daily',
|
||||
ADD COLUMN IF NOT EXISTS schedule_days JSONB NOT NULL DEFAULT '["mon","tue","wed","thu","fri","sat","sun"]'::jsonb,
|
||||
ADD COLUMN IF NOT EXISTS schedule_time_mode VARCHAR(20) NOT NULL DEFAULT 'fixed',
|
||||
ADD COLUMN IF NOT EXISTS random_window_start TIME NOT NULL DEFAULT '01:00:00',
|
||||
ADD COLUMN IF NOT EXISTS random_window_end TIME NOT NULL DEFAULT '05:00:00',
|
||||
ADD COLUMN IF NOT EXISTS generation_input_json JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
ADD COLUMN IF NOT EXISTS last_run_at TIMESTAMPTZ,
|
||||
ADD COLUMN IF NOT EXISTS last_dispatch_status VARCHAR(20),
|
||||
ADD COLUMN IF NOT EXISTS last_dispatch_error TEXT,
|
||||
ADD COLUMN IF NOT EXISTS consecutive_failures INT NOT NULL DEFAULT 0;
|
||||
|
||||
UPDATE schedule_tasks
|
||||
SET target_type = 'prompt_rule'
|
||||
WHERE target_type IS NULL OR btrim(target_type) = '';
|
||||
|
||||
UPDATE schedule_tasks
|
||||
SET schedule_kind = 'daily',
|
||||
schedule_days = '["mon","tue","wed","thu","fri","sat","sun"]'::jsonb
|
||||
WHERE schedule_days IS NULL
|
||||
OR jsonb_typeof(schedule_days) <> 'array'
|
||||
OR jsonb_array_length(schedule_days) = 0;
|
||||
|
||||
UPDATE schedule_tasks
|
||||
SET schedule_time_mode = 'fixed'
|
||||
WHERE schedule_time_mode IS NULL OR btrim(schedule_time_mode) = '';
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_schedule_tasks_target_type'
|
||||
) THEN
|
||||
ALTER TABLE schedule_tasks
|
||||
ADD CONSTRAINT chk_schedule_tasks_target_type
|
||||
CHECK (target_type IN ('prompt_rule', 'kol_subscription_prompt'));
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_schedule_tasks_target_ref'
|
||||
) THEN
|
||||
ALTER TABLE schedule_tasks
|
||||
ADD CONSTRAINT chk_schedule_tasks_target_ref
|
||||
CHECK (
|
||||
(target_type = 'prompt_rule' AND prompt_rule_id IS NOT NULL)
|
||||
OR (target_type = 'kol_subscription_prompt' AND subscription_prompt_id IS NOT NULL)
|
||||
);
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_schedule_tasks_schedule_kind'
|
||||
) THEN
|
||||
ALTER TABLE schedule_tasks
|
||||
ADD CONSTRAINT chk_schedule_tasks_schedule_kind
|
||||
CHECK (schedule_kind IN ('daily', 'weekly'));
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_schedule_tasks_schedule_days_json'
|
||||
) THEN
|
||||
ALTER TABLE schedule_tasks
|
||||
ADD CONSTRAINT chk_schedule_tasks_schedule_days_json
|
||||
CHECK (jsonb_typeof(schedule_days) = 'array' AND jsonb_array_length(schedule_days) BETWEEN 1 AND 7);
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_schedule_tasks_schedule_time_mode'
|
||||
) THEN
|
||||
ALTER TABLE schedule_tasks
|
||||
ADD CONSTRAINT chk_schedule_tasks_schedule_time_mode
|
||||
CHECK (schedule_time_mode IN ('fixed', 'random_window'));
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_schedule_tasks_random_window'
|
||||
) THEN
|
||||
ALTER TABLE schedule_tasks
|
||||
ADD CONSTRAINT chk_schedule_tasks_random_window
|
||||
CHECK (random_window_end > random_window_start);
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_schedule_tasks_generation_input_json'
|
||||
) THEN
|
||||
ALTER TABLE schedule_tasks
|
||||
ADD CONSTRAINT chk_schedule_tasks_generation_input_json
|
||||
CHECK (jsonb_typeof(generation_input_json) = 'object');
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_schedule_tasks_consecutive_failures'
|
||||
) THEN
|
||||
ALTER TABLE schedule_tasks
|
||||
ADD CONSTRAINT chk_schedule_tasks_consecutive_failures
|
||||
CHECK (consecutive_failures >= 0);
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_schedule_task_target
|
||||
ON schedule_tasks(tenant_id, target_type, created_at DESC)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_schedule_task_subscription_prompt
|
||||
ON schedule_tasks(tenant_id, subscription_prompt_id, created_at DESC)
|
||||
WHERE deleted_at IS NULL AND subscription_prompt_id IS NOT NULL;
|
||||
Reference in New Issue
Block a user