CREATE TABLE IF NOT EXISTS ias_schedules ( id BIGSERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, schedule_type VARCHAR(32) NOT NULL, expression TEXT NOT NULL, target_topic TEXT NOT NULL, payload JSONB NOT NULL DEFAULT '{}', enabled BOOLEAN NOT NULL DEFAULT TRUE, last_fired_at TIMESTAMPTZ, next_fire_at TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT ias_schedules_type_check CHECK (schedule_type IN ('cron', 'interval')) ); CREATE INDEX IF NOT EXISTS idx_ias_schedules_due ON ias_schedules(next_fire_at) WHERE enabled = TRUE; CREATE UNIQUE INDEX IF NOT EXISTS idx_ias_schedules_name_unique ON ias_schedules(name); CREATE TABLE IF NOT EXISTS ias_schedule_fires ( fire_id TEXT PRIMARY KEY, schedule_id BIGINT NOT NULL REFERENCES ias_schedules(id) ON DELETE CASCADE, fire_time TIMESTAMPTZ NOT NULL, status VARCHAR(32) NOT NULL DEFAULT 'publishing', attempt_count INTEGER NOT NULL DEFAULT 0, published_at TIMESTAMPTZ, error TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_ias_schedule_fires_schedule_time ON ias_schedule_fires(schedule_id, fire_time DESC); CREATE INDEX IF NOT EXISTS idx_ias_schedule_fires_reclaim ON ias_schedule_fires(status, updated_at) WHERE status IN ('failed', 'publishing'); CREATE TABLE IF NOT EXISTS ias_assistant_turns ( operation_key TEXT PRIMARY KEY, channel TEXT NOT NULL, account_id TEXT NOT NULL, from_user_id TEXT NOT NULL, turn_id TEXT NOT NULL, trace_id TEXT NOT NULL DEFAULT '', status VARCHAR(32) NOT NULL DEFAULT 'active', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT ias_assistant_turns_status_check CHECK (status IN ('active', 'completed', 'cancelled')) ); CREATE INDEX IF NOT EXISTS idx_ias_assistant_turns_status_updated ON ias_assistant_turns(status, updated_at DESC);