Files
Agent-System/deploy/postgres/migrations/2026-09-11-project-workflows-and-lineage.sql
T

101 lines
5.2 KiB
SQL

-- 2026-09-11: 项目多工作流体系、创建人权威化与文档血缘追溯
-- 支持:项目创建人权限、三层工作流模型、工作流原子激活与审计、智能产品经理与测试经理文档血缘追踪
-- 1. 为 projects 表添加创建人与工作流激活控制字段
ALTER TABLE projects ADD COLUMN IF NOT EXISTS creator_user_id BIGINT REFERENCES users(id);
ALTER TABLE projects ADD COLUMN IF NOT EXISTS active_workflow_key TEXT NOT NULL DEFAULT 'main';
ALTER TABLE projects ADD COLUMN IF NOT EXISTS workflow_selection_version INT NOT NULL DEFAULT 1;
ALTER TABLE projects ADD COLUMN IF NOT EXISTS active_workflow_changed_at TIMESTAMPTZ;
ALTER TABLE projects ADD COLUMN IF NOT EXISTS active_workflow_changed_by BIGINT REFERENCES users(id);
CREATE INDEX IF NOT EXISTS idx_projects_creator ON projects(creator_user_id);
CREATE INDEX IF NOT EXISTS idx_projects_active_workflow ON projects(active_workflow_key);
-- 2. 项目工作流实例表 (挂载到项目的可用工作流实例与局部状态)
CREATE TABLE IF NOT EXISTS project_workflows (
id BIGSERIAL PRIMARY KEY,
project_id BIGINT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
workflow_key TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'ready', -- ready | active | disabled
enabled BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
CONSTRAINT uq_project_workflow UNIQUE(project_id, workflow_key)
);
CREATE INDEX IF NOT EXISTS idx_project_workflows_pid ON project_workflows(project_id);
-- 3. 工作流执行运行实例表 (追踪执行历史、步骤与产出文档)
CREATE TABLE IF NOT EXISTS workflow_runs (
id BIGSERIAL PRIMARY KEY,
run_id TEXT NOT NULL UNIQUE,
project_id BIGINT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
workflow_key TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending', -- pending | running | completed | failed | cancelled
started_by BIGINT REFERENCES users(id),
stage_key TEXT NOT NULL DEFAULT '',
task_key TEXT NOT NULL DEFAULT '',
input_manifest JSONB NOT NULL DEFAULT '{}'::jsonb,
output_doc_id TEXT NOT NULL DEFAULT '',
output_summary TEXT NOT NULL DEFAULT '',
error_message TEXT NOT NULL DEFAULT '',
started_at TIMESTAMPTZ,
finished_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_workflow_runs_pid ON workflow_runs(project_id);
CREATE INDEX IF NOT EXISTS idx_workflow_runs_status ON workflow_runs(status);
-- 4. 工作流激活切换审计日志 (只追加写入,记录切换人、版本变化与原因)
CREATE TABLE IF NOT EXISTS workflow_activation_audits (
id BIGSERIAL PRIMARY KEY,
project_id BIGINT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
from_workflow_key TEXT NOT NULL DEFAULT '',
to_workflow_key TEXT NOT NULL,
changed_by BIGINT REFERENCES users(id),
version_before INT NOT NULL,
version_after INT NOT NULL,
reason TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_workflow_activation_audits_pid ON workflow_activation_audits(project_id);
-- 5. 文档血缘与 Stale 追溯表 (上下游依赖、版本快照哈希与过期标记)
CREATE TABLE IF NOT EXISTS document_lineage (
id BIGSERIAL PRIMARY KEY,
project_id BIGINT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
downstream_doc_id TEXT NOT NULL,
downstream_version INT NOT NULL DEFAULT 1,
upstream_doc_id TEXT NOT NULL,
upstream_version INT NOT NULL DEFAULT 1,
upstream_sha256 TEXT NOT NULL DEFAULT '',
is_stale BOOLEAN NOT NULL DEFAULT false,
stale_reason TEXT NOT NULL DEFAULT '',
stale_detected_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
CONSTRAINT uq_doc_lineage UNIQUE(downstream_doc_id, downstream_version, upstream_doc_id, upstream_version)
);
CREATE INDEX IF NOT EXISTS idx_doc_lineage_downstream ON document_lineage(downstream_doc_id, downstream_version);
CREATE INDEX IF NOT EXISTS idx_doc_lineage_upstream ON document_lineage(upstream_doc_id, upstream_version);
CREATE INDEX IF NOT EXISTS idx_doc_lineage_stale ON document_lineage(is_stale);
-- 6. 历史数据回填:为缺失创建人的历史项目回填默认创建人 (关联首个会话或设为管理员 1)
UPDATE projects p
SET creator_user_id = COALESCE(
(SELECT cs.user_id FROM chat_sessions cs WHERE cs.project_id = p.id AND cs.user_id IS NOT NULL ORDER BY cs.id ASC LIMIT 1),
1
)
WHERE p.creator_user_id IS NULL;
-- 7. 历史数据回填:为已有项目自动挂载三个标准工作流实例 (main, product_manager, test_manager)
INSERT INTO project_workflows (project_id, workflow_key, status, enabled)
SELECT p.id, w.key,
CASE WHEN w.key = COALESCE(p.active_workflow_key, 'main') THEN 'active' ELSE 'ready' END,
true
FROM projects p
CROSS JOIN (VALUES ('main'), ('product_manager'), ('test_manager')) AS w(key)
ON CONFLICT (project_id, workflow_key) DO NOTHING;