# 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 所定义的动作与状态集合。