# PRDv5 全流程时序图(严格依据 v5 文档与引用约束) 说明: - 本文仅使用 PRDv5 中明确存在的对象、状态与动作;不引入任何未在文档出现的状态或动作。 - 对象与状态集合(摘自 PRD): - Task.status ∈ {created, running, finished, failed, revoking, revoked} - Mention.status ∈ {active, invalid} - Candidate.status ∈ {pending, locked, orphaned} - Confirm.status ∈ {CONFIRMED, PUBLISHED, ROLLED_BACK} - sync_status ∈ {PENDING, SYNCING, SYNCED, FAILED} - 统一过滤约束:revoking / revoked 的查询/内部消费需执行过滤(参见 2.11)。 --- ## A. 端到端主流程(创建任务 → 回调写入 → 生成候选 → 审核确认 → 发布 → 图投影) ```mermaid sequenceDiagram autonumber actor Admin as Admin(管理员) participant UI as 前端UI participant API as 后端API(服务) participant PG_Task as PostgreSQL(kg_task) participant Ext as 外部抽取服务 participant PG_M as PostgreSQL(kg_entity_mention/kg_relation_mention) participant PG_Cand as PostgreSQL(kg_*_candidate) participant PG_Conf as PostgreSQL(kg_*_confirm) participant Audit as PostgreSQL(audit_log) participant SyncW as 同步Worker participant Neo4j as Neo4j(投影) Note over Admin,PG_Task: 任务创建与门禁(3.1.3.1 / 3.1.3.1.1) Admin->>UI: 配置任务Schema(ext_entity_codes / ext_relation_codes) UI->>API: 提交创建任务请求(创建门禁检查) API->>PG_Task: 创建kg_task(status=created,持久化tenant上下文) API-->>UI: 返回task信息(external_task_id在触发抽取时获取) Note over API,Ext: 任务运行期(status: running → finished/failed) API->>Ext: 触发抽取(外部异步执行,分配external_task_id) Ext-->>PG_Task: 任务状态更新(running → finished/failed)(由系统对接,P0仅约束状态口径) Note over Ext,API: 抽取结果回调(5.1 回调/导入) Ext->>API: POST /api/callback/extract(external_task_id, records...) API->>PG_Task: 基于external_task_id反查kg_task(仅接受status=finished) API->>PG_Task: 行级锁/门禁(单消费者/重复通知幂等处理) API->>PG_M: 同事务写入Mention activate API API->>API: Schema白名单裁决 + Task生命周期过滤\n→ mention.status=active/invalid(3.2.4) API->>Audit: 写审计(filtered_by_schema / callback_*) deactivate API API-->>Ext: 回调处理结果(成功/冲突) Note over Admin,PG_Cand: 候选生成(3.3 / 5.3) Admin->>UI: 在任务详情发起“由mentions生成candidate” UI->>API: POST /api/candidates/from-mentions API->>PG_M: 仅读取status=active 且 task非revoking/revoked 的mentions\n(统一可见性过滤 2.11) API->>PG_Cand: 单事务聚合去重 + 规范化 + 决策canonical\n→ candidate.status=pending(3.3.4) API-->>UI: 返回候选数据 Note over Admin,PG_Conf: 审核确认至Confirm(3.4 / 5.3) Admin->>UI: 在候选审核页选择通过(approve) UI->>API: POST /api/candidates/{id}/approve API->>PG_Conf: Confirm Upsert(复合键/UID)→ status=CONFIRMED\n统一置 sync_status='PENDING'(3.4/4.3) API->>PG_Cand: 将被锁定的候选设为locked(locked_by_confirm=true) API->>Audit: 写审计(review.accept / merge 等) API-->>UI: 返回审核结果 Note over Admin,PG_Conf: 发布(6.1 / 5.4) Admin->>UI: 发起发布(publish) UI->>API: POST /api/publish?task_id=...(影响预估/阻断策略) API->>PG_Conf: 事务内将相关Confirm置 status=PUBLISHED\n统一置 sync_status='PENDING' API->>Audit: 写审计(publish) API-->>UI: 返回发布受理结果 Note over SyncW,Neo4j: 同步器执行(4.3 指令集) SyncW->>PG_Conf: 扫描 sync_status IN ('PENDING','FAILED') SyncW->>PG_Conf: 原子置 SYNCING(加锁避免并发) alt status=PUBLISHED SyncW->>Neo4j: 幂等MERGE/SET(节点/关系及属性) else status=ROLLED_BACK SyncW->>Neo4j: 物理删除(DETACH DELETE) end SyncW->>PG_Conf: 写回 sync_status='SYNCED' 或 'FAILED' SyncW->>Audit: 写审计(action='sync',记录结果) ``` --- ## B. 回滚全过程(任务 → Mention → Candidate → Confirm → 投影清理) ```mermaid sequenceDiagram autonumber actor Admin as Admin(管理员) participant UI as 前端UI participant API as 后端API(服务) participant PG_Task as PostgreSQL(kg_task) participant PG_M as PostgreSQL(kg_*_mention) participant PG_Cand as PostgreSQL(kg_*_candidate) participant PG_Conf as PostgreSQL(kg_*_confirm) participant Audit as PostgreSQL(audit_log) participant SyncW as 同步Worker participant Neo4j as Neo4j(投影) Note over Admin,PG_Task: 回滚触发(6.2) Admin->>UI: 发起回滚(rollback) UI->>API: POST /api/rollback?task_id=...(影响预估/阻断策略) API->>PG_Task: 事务首步将task.status置为revoking(强中间态,可见) API->>Audit: 写审计(rollback 受理) Note over API,PG_M: 生命周期与可见性(2.11 / 3.2.4) API->>PG_M: 与该task关联的mentions在查询/下游消费中被过滤\n(revoking/revoked 全局过滤契约) API-->>UI: Candidate/图谱界面呈现“回撤处理中,只读提示” Note over API,PG_Conf: Confirm 源集合更新(3.4 / 6.2) API->>PG_Conf: 从source_tasks中移除该task_id;若为空→active_flag=false\n必要时关系随实体失活(按3.7.5约束) API->>PG_Conf: 统一置 sync_status='PENDING'(脏标记) API->>Audit: 写审计(rollback 细节) Note over API,PG_Task: 任务完成回撤 API->>PG_Task: 将task.status置为revoked(终态) API-->>UI: 返回回滚完成 Note over SyncW,Neo4j: 投影清理(4.3) SyncW->>PG_Conf: 扫描 sync_status IN ('PENDING','FAILED') SyncW->>PG_Conf: 原子置 SYNCING alt status=ROLLED_BACK SyncW->>Neo4j: 物理删除(DETACH DELETE) else status=PUBLISHED(保持发布态但属性/来源已变更) SyncW->>Neo4j: 幂等MERGE/SET(更新属性、来源集合) end SyncW->>PG_Conf: 写回 sync_status='SYNCED' 或 'FAILED' SyncW->>Audit: 写审计(action='sync') ``` 约束摘录: - revoking 首步可见(2.11 / 6.2),所有读取统一过滤(revoking/revoked 不可被消费)。 - 关系恢复与失活遵循 3.7.5:任一端实体失活 → 关系失活;回滚的物理扩散通过 sync_status=PENDING 驱动同步器清理 Neo4j。 --- ## C. 候选与确认的联动与并发安全(审核通过 → Confirm Upsert → 锁定候选) ```mermaid sequenceDiagram autonumber participant API as 后端API(服务) participant PG_Cand as PostgreSQL(kg_*_candidate) participant PG_Conf as PostgreSQL(kg_*_confirm) participant Audit as PostgreSQL(audit_log) API->>PG_Cand: 读取待审核候选(status=pending)\n(统一过滤:task非revoking/revoked) API->>PG_Conf: Upsert Confirm(实体或关系)\n- 命中ROLLED_BACK则复位为CONFIRMED(复活规则)\n- 统一置 sync_status='PENDING' API->>PG_Cand: 条件更新:pending→locked(locked_by_confirm=true) API->>Audit: 审计写入(review.accept / relation_uid_mismatch 等) ``` 并发与一致性要点(摘自 3.3.3、3.4、4.3): - 候选状态更新采用条件更新或行级锁,禁止盲写。 - Confirm Upsert、复活与脏标记(sync_status=PENDING)必须同事务完成。 - 审核拒绝不引入 Candidate 新状态(保持 pending),通过 audit_log 表达。 --- ## D. 同步器标准指令集(实体/关系投影的一致性保障) ```mermaid sequenceDiagram autonumber participant SyncW as 同步Worker participant PG_Conf as PostgreSQL(kg_*_confirm) participant Neo4j as Neo4j(投影) participant Audit as PostgreSQL(audit_log) SyncW->>PG_Conf: 扫描 sync_status ∈ {'PENDING','FAILED'}(批次/按租户) SyncW->>PG_Conf: 原子置 SYNCING(加锁防重) alt Confirm.status == 'PUBLISHED' SyncW->>Neo4j: MERGE 节点/关系 + SET 属性 + 合并source_tasks else Confirm.status == 'ROLLED_BACK' SyncW->>Neo4j: 物理删除(DETACH DELETE) else Confirm.status == 'CONFIRMED' Note right of SyncW: 保持仅事实确认不投影(不对图操作) end alt 成功 SyncW->>PG_Conf: 更新 sync_status='SYNCED' SyncW->>Audit: 写审计(action='sync', result='success') else 失败 SyncW->>PG_Conf: 更新 sync_status='FAILED' SyncW->>Audit: 写审计(action='sync', result='failed', error_msg) end ``` 要点(4.3): - 脏标记必须与业务写入同事务(PENDING 幂等)。 - 同步器不改变业务事实,仅保障投影一致性与可观测性。 --- ## E. 统一可见性过滤(跨层防脏读约束) ```mermaid sequenceDiagram autonumber participant DAO as 统一DAO/Service封装 participant PG_Task as PostgreSQL(kg_task) participant Reader as 读取者(Candidate生成器/查询) Reader->>DAO: selectVisible(...)(封装统一过滤) DAO->>PG_Task: Join kg_task 并过滤\nWHERE kg_task.status NOT IN ('revoking','revoked') DAO-->>Reader: 返回过滤后的可见数据集 ``` 要点(2.11 / 3.2.4 / 3.3.3): - 过滤逻辑必须统一封装调用(例如 baseMapper.selectVisible),禁止散落实现。 - Candidate 生成器、图谱读取等内部流程均需复用本封装。 --- ## F. 状态机摘录(对照PRD冻结口径) - Task(3.7.1) - created → running → finished/failed → revoking → revoked - Mention(3.7.2) - — → active(task.finished)\nactive → invalid(task.revoking/revoked)\ninvalid → active(task.re-import 同一任务) - Candidate(3.7.3) - — → pending(由mentions生成)\npending → locked(confirm.publish 或映射既有Confirm)\nlocked → locked/pending(rollback 后视 source_tasks 是否为空)\npending → orphaned(无来源孤立)\norphaned → pending(新来源出现) - Confirm(3.4、3.7.4/3.7.5) - CONFIRMED → PUBLISHED → ROLLED_BACK(复活:命中ROLLED_BACK时复位为CONFIRMED) - sync_status(4.3) - PENDING → SYNCING → SYNCED / FAILED(失败可重试) 以上时序与状态转换严格沿用 PRDv5 所定义的动作与状态集合。