-- ============================================================================= -- 医疗器械受控文档治理引擎 (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);