Files

132 lines
8.3 KiB
SQL

-- =============================================================================
-- 医疗器械受控文档治理引擎 (Document Governance & Approval Lifecycle)
-- 包含:
-- 1. 受控文档台账与三级责任人模型 (Author, Reviewer, Approver 各且仅一人)
-- 2. 文档状态生命周期与锁定机制 (Drafting -> Reviewing -> Approving -> Approved)
-- 3. 文档认领状态 (Claiming State: Unclaimed vs Claimed)
-- 4. 审核/批准批注与修改意见 (Document Comments / Annotations)
-- 5. 已认领文档变更提案与人机确认闭环 (Change Proposals)
-- 6. 文档全生命周期审计流 (Document Audit Logs)
-- =============================================================================
-- -----------------------------------------------------------------------------
-- 7. 受控文档台账与生命周期表 (Document Records)
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS document_records (
id BIGSERIAL PRIMARY KEY,
doc_id TEXT NOT NULL UNIQUE, -- 业务唯一标识,如 doc_proj1_feasibility_reg_v1
project_id BIGINT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
task_key TEXT NOT NULL, -- 任务标识: feasibility_reg, intake, cdo_quote
title TEXT NOT NULL, -- 交付物标题
stage TEXT NOT NULL DEFAULT 'V0.5_feasibility',
version INT NOT NULL DEFAULT 1,
current_state TEXT NOT NULL DEFAULT 'drafting', -- drafting, reviewing, approving, approved, rejected
is_locked BOOLEAN NOT NULL DEFAULT FALSE, -- 锁定状态 (reviewing/approving/approved 期间禁止直接修改)
is_template_only BOOLEAN NOT NULL DEFAULT TRUE, -- 是否仅为骨架模板 (模板状态即使查看也不算认领)
content_sha256 TEXT NOT NULL DEFAULT '', -- 当前版本正文哈希
work_dir TEXT NOT NULL DEFAULT '', -- 工作区相对路径
-- 三级责任人(各有且仅有一人)
author_id BIGINT REFERENCES users(id) ON DELETE SET NULL,
author_name TEXT NOT NULL DEFAULT '',
reviewer_id BIGINT REFERENCES users(id) ON DELETE SET NULL,
reviewer_name TEXT NOT NULL DEFAULT '',
approver_id BIGINT REFERENCES users(id) ON DELETE SET NULL,
approver_name TEXT NOT NULL DEFAULT '',
-- 认领状态 (Claiming State)
author_claimed BOOLEAN NOT NULL DEFAULT FALSE, -- 编制人是否已认领 (非模板状态被查看或编辑后为 true)
author_claimed_at TIMESTAMPTZ,
author_last_viewed_at TIMESTAMPTZ,
author_last_edited_at TIMESTAMPTZ,
reviewer_claimed BOOLEAN NOT NULL DEFAULT FALSE, -- 审核人是否已认领审核
reviewer_claimed_at TIMESTAMPTZ,
approver_claimed BOOLEAN NOT NULL DEFAULT FALSE, -- 批准人是否已认领批准
approver_claimed_at TIMESTAMPTZ,
-- 审核/批准最后意见与驳回原因
last_rejected_reason TEXT NOT NULL DEFAULT '', -- 驳回原因 (驳回时必填)
last_rejected_by_role TEXT NOT NULL DEFAULT '', -- reviewer, approver
last_rejected_by_name TEXT NOT NULL DEFAULT '',
last_rejected_at TIMESTAMPTZ,
approved_at TIMESTAMPTZ,
-- 可配置项 (Config JSONB)
config JSONB NOT NULL DEFAULT '{"reject_rollback_to": "drafting", "allow_approver_to_reviewer": true}'::jsonb,
-- 编辑租约 (运行时互斥,正交于 is_locked)
lease_holder_type TEXT NOT NULL DEFAULT '',
lease_holder_id TEXT NOT NULL DEFAULT '',
lease_work_dir TEXT NOT NULL DEFAULT '',
lease_expires_at TIMESTAMPTZ,
lease_heartbeat_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_doc_records_pid ON document_records(project_id);
CREATE INDEX IF NOT EXISTS idx_doc_records_task ON document_records(task_key);
CREATE INDEX IF NOT EXISTS idx_doc_records_state ON document_records(current_state);
CREATE INDEX IF NOT EXISTS idx_doc_records_author ON document_records(author_id);
CREATE INDEX IF NOT EXISTS idx_doc_records_reviewer ON document_records(reviewer_id);
CREATE INDEX IF NOT EXISTS idx_doc_records_approver ON document_records(approver_id);
-- -----------------------------------------------------------------------------
-- 8. 批注与修改意见表 (Document Comments & Annotations)
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS document_comments (
id BIGSERIAL PRIMARY KEY,
doc_id TEXT NOT NULL REFERENCES document_records(doc_id) ON DELETE CASCADE,
user_id BIGINT REFERENCES users(id) ON DELETE SET NULL,
user_name TEXT NOT NULL DEFAULT '',
user_role TEXT NOT NULL, -- author, reviewer, approver, advisor
target_section TEXT NOT NULL DEFAULT '', -- 批注针对的章节或锚点 (如 "## 结论")
comment_type TEXT NOT NULL DEFAULT 'comment', -- comment(普通批注), suggestion(修改建议), reject_reason(驳回理由)
content TEXT NOT NULL, -- 批注或意见正文
status TEXT NOT NULL DEFAULT 'open', -- open, resolved, accepted, rejected
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_doc_comments_doc ON document_comments(doc_id);
CREATE INDEX IF NOT EXISTS idx_doc_comments_user ON document_comments(user_id);
-- -----------------------------------------------------------------------------
-- 9. 智能体修改变更提案表 (Change Proposals for Claimed Documents)
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS document_change_proposals (
id BIGSERIAL PRIMARY KEY,
proposal_id TEXT NOT NULL UNIQUE, -- 变更提案唯一标识
doc_id TEXT NOT NULL REFERENCES document_records(doc_id) ON DELETE CASCADE,
project_id BIGINT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
triggered_by TEXT NOT NULL DEFAULT 'agent_squad', -- 触发来源 (agent_squad, stage_sync, user_request)
proposed_changes TEXT NOT NULL, -- 拟修改地方及差异摘要
impact_analysis TEXT NOT NULL, -- 影响范围与后果分析
risk_assessment TEXT NOT NULL, -- 潜在风险预警
status TEXT NOT NULL DEFAULT 'pending_author_approval', -- pending_author_approval, approved_by_author, rejected_by_author, applied
author_decision_reason TEXT NOT NULL DEFAULT '', -- 编制人拍板同意或拒绝修改的原因
decided_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_change_proposals_doc ON document_change_proposals(doc_id);
CREATE INDEX IF NOT EXISTS idx_change_proposals_status ON document_change_proposals(status);
-- -----------------------------------------------------------------------------
-- 10. 文档治理全生命周期审计流表 (Document Audit Logs)
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS document_audit_logs (
id BIGSERIAL PRIMARY KEY,
doc_id TEXT NOT NULL REFERENCES document_records(doc_id) ON DELETE CASCADE,
action TEXT NOT NULL, -- view, edit, claim, submit_review, review_approve, review_reject, approver_approve, approver_reject, propose_change, decide_change
actor_id BIGINT,
actor_name TEXT NOT NULL DEFAULT '',
actor_role TEXT NOT NULL DEFAULT '', -- author, reviewer, approver, system
from_state TEXT NOT NULL DEFAULT '',
to_state TEXT NOT NULL DEFAULT '',
details JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_doc_audit_doc_time ON document_audit_logs(doc_id, created_at DESC);