9501751792
三轮审查修复(60+ 项),相对远端 main(b536672)的关键变更:
- 安全: 数据面 SSRF 拨号防护(防 DNS rebinding)/上游凭据剥离/登录防枚举
与锁定态统一/可信代理(X-Forwarded-For)限流加固/会话版本失效机制/
撤销即时传播/弱密钥拒绝启动/脱敏字节级重写(保签名契约)
- 业务逻辑: 裸 body 上传 panic/bootstrap 审计管线卡死/定价通配符优先级/
全局工具可见性/调度器停机补跑/TOTP 挑战令牌消费顺序/熔断探针语义/
>4MB 响应 token 计量/管理员重置密码作废会话 等
- 前端: 新 logo(语枢 AI 网关主题)/Provider 凭据异常警示/删除入口/
后端错误消息透传/localStorage 敏感数据收敛
- 部署: CREDENTIAL_MASTER_KEY 持久化与弱值拒绝/Provider DELETE 接口/
nginx 安全头/worker 内存限制
- 新增迁移 000029(key_hash 索引)/000030(usage_daily 币种维度)
57 lines
3.0 KiB
SQL
57 lines
3.0 KiB
SQL
-- M8 P3: PostgreSQL-backed scheduled task definitions and durable execution queue.
|
|
|
|
CREATE TABLE IF NOT EXISTS gateway.scheduled_tasks (
|
|
id uuid PRIMARY KEY,
|
|
code text NOT NULL UNIQUE CHECK (code ~ '^[a-z][a-z0-9_-]{1,63}$'),
|
|
name text NOT NULL CHECK (length(name) BETWEEN 1 AND 128),
|
|
description text NOT NULL DEFAULT '' CHECK (length(description) <= 4000),
|
|
cron_expression text NOT NULL CHECK (length(cron_expression) <= 128),
|
|
timezone text NOT NULL DEFAULT 'UTC' CHECK (length(timezone) <= 128),
|
|
target_type text NOT NULL CHECK (target_type IN ('application', 'digital_employee')),
|
|
target_code text NOT NULL CHECK (length(target_code) BETWEEN 1 AND 64),
|
|
prompt text NOT NULL CHECK (length(prompt) BETWEEN 1 AND 100000),
|
|
variables jsonb NOT NULL DEFAULT '{}'::jsonb CHECK (jsonb_typeof(variables) = 'object'),
|
|
skill_ids uuid[] NOT NULL DEFAULT '{}',
|
|
mcp_server_ids uuid[] NOT NULL DEFAULT '{}',
|
|
conversation_id text NOT NULL DEFAULT '' CHECK (length(conversation_id) <= 128),
|
|
notification_channel_id uuid REFERENCES gateway.notification_channels(id) ON DELETE SET NULL,
|
|
encrypted_api_key bytea NOT NULL,
|
|
api_key_kek_version integer NOT NULL CHECK (api_key_kek_version > 0),
|
|
enabled boolean NOT NULL DEFAULT false,
|
|
next_run_at timestamptz,
|
|
last_run_at timestamptz,
|
|
last_status text NOT NULL DEFAULT '' CHECK (last_status IN ('', 'success', 'failed')),
|
|
last_error text NOT NULL DEFAULT '' CHECK (length(last_error) <= 4000),
|
|
created_by uuid NOT NULL REFERENCES gateway.admin_accounts(id),
|
|
revision bigint NOT NULL DEFAULT 1,
|
|
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
|
updated_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
|
CHECK ((enabled AND next_run_at IS NOT NULL) OR (NOT enabled))
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS scheduled_tasks_due_idx
|
|
ON gateway.scheduled_tasks (next_run_at, id) WHERE enabled;
|
|
|
|
CREATE TABLE IF NOT EXISTS gateway.scheduled_task_runs (
|
|
id uuid PRIMARY KEY,
|
|
task_id uuid NOT NULL REFERENCES gateway.scheduled_tasks(id) ON DELETE CASCADE,
|
|
trigger_type text NOT NULL CHECK (trigger_type IN ('scheduled', 'manual')),
|
|
scheduled_for timestamptz NOT NULL,
|
|
status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'running', 'success', 'failed')),
|
|
attempts integer NOT NULL DEFAULT 0 CHECK (attempts >= 0),
|
|
worker_id text NOT NULL DEFAULT '' CHECK (length(worker_id) <= 128),
|
|
started_at timestamptz,
|
|
finished_at timestamptz,
|
|
response jsonb,
|
|
error text NOT NULL DEFAULT '' CHECK (length(error) <= 4000),
|
|
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
|
UNIQUE (task_id, trigger_type, scheduled_for)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS scheduled_task_runs_pending_idx
|
|
ON gateway.scheduled_task_runs (created_at, id) WHERE status = 'pending';
|
|
CREATE INDEX IF NOT EXISTS scheduled_task_runs_history_idx
|
|
ON gateway.scheduled_task_runs (task_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS scheduled_task_runs_running_idx
|
|
ON gateway.scheduled_task_runs (started_at) WHERE status = 'running';
|