docs: add fix-double-finalize-and-bindings-api implementation plan

This commit is contained in:
wren
2026-04-28 11:44:31 +08:00
parent 1b4e0ec00a
commit be9fc4856b
15 changed files with 5733 additions and 0 deletions
@@ -0,0 +1,306 @@
# LeAudit YAML 规则在线编辑设计
## 1. 背景
`LeAudit` 内核当前以本地 YAML/DSL 文件作为规则输入载体执行评查流程。现阶段 **不修改 `leaudit` 核心**,但平台侧需要逐步具备以下能力:
- 在线查看 YAML 规则内容
- 在线编辑 YAML 规则
- 校验规则语法与 DSL 语义
- 规则版本化保存
- 规则发布、回滚、审计
因此需要在 `leaudit-platform` 中补充一套“**规则管理真相源**”方案,使平台能够支持规则后台,而运行时仍然兼容 `leaudit` 只读取本地 YAML 的既有行为。
---
## 2. 结论
**可以不改 `leaudit` 核心,同时把 DSL YAML 存储到 OSS,并把路径、版本、哈希等元数据存入数据库。**
运行时通过 bridge 层完成一次“远端规则 → 本地临时文件”的转换:
```text
数据库读取规则版本信息
→ 获取 rules.yaml 的 oss_url
→ 从 OSS 下载到本地临时文件
→ 调用 leaudit.dsl.loader.load_rules_file(local_tmp_path)
→ 交给 leaudit 原生执行链继续处理
```
也就是说:
- **规则真相源**:OSS + 数据库
- **执行载体**:本地临时 YAML 文件
- **LeAudit 输入接口**:保持不变
这是当前约束下最稳妥、最容易演进的方案。
---
## 3. 为什么不能继续把本地 `rules/` 目录作为正式真相源
如果未来要开放 YAML 在线编辑界面,本地目录方案会迅速暴露问题:
### 3.1 不利于在线编辑
- 前端编辑后的内容最终仍要人工写回服务器目录
- 多实例部署时,需要同步到多台机器
- 容器化部署时,本地文件可能不是稳定持久层
### 3.2 不利于版本管理
- 难以明确记录“这次评查到底使用了哪一版规则”
- 覆盖同一路径的 `rules.yaml` 后,历史执行很难追溯
- 回滚通常会退化为“手工替换文件”
### 3.3 不利于审计与权限
- 谁改的、何时改的、为什么发布,很难形成正式审计链
- 无法自然承载“编辑 / 审核 / 发布 / 回滚”权限流程
### 3.4 不利于多实例一致性
- API 节点 A 和 Worker 节点 B 可能读取到不同版本本地文件
- 扩容后所有节点都要同步规则目录,运维成本高
因此,本地 `rules/` 目录更适合保留为:
- 种子规则导入源
- 紧急回退备份
- 开发环境本地调试资源
而不应该继续承担正式规则真相源角色。
---
## 4. 为什么采用“OSS + DB + 本地临时文件”模式
该方案同时兼顾了 **不改核心****平台化管理** 两个目标。
### 4.1 对 `leaudit` 零侵入
`leaudit` 仍然读取本地 YAML 文件,无需改造其解析器、执行器或 DSL 加载逻辑。
### 4.2 支持在线编辑界面
前端提交 YAML 文本后,平台可以执行标准流程:
```text
编辑
→ 保存草稿
→ 语法校验
→ DSL 语义校验
→ 上传 OSS
→ 写入规则版本表
→ 发布 / 回滚
```
这让规则成为“平台可管理资产”,而不是“服务器磁盘文件”。
### 4.3 规则版本可追溯
每次评查运行都可以记录:
- `rule_set_id`
- `rule_version_id`
- `rule_source_oss_url`
- `rule_source_sha256`
这样可以准确回答:
- 这个结果用的是哪一版规则?
- 规则文件是否被篡改?
- 是否可以按历史版本回放?
### 4.4 发布与回滚简单
- 发布:切换 `leaudit_rule_sets.current_version_id`
- 回滚:切回旧版本 ID
无需登录服务器替换目录文件,也不要求应用重新发版。
### 4.5 多实例一致
所有 API / Worker 都从同一份 DB + OSS 真相源取规则,不再依赖本地目录是否同步。
---
## 5. 建议的系统分层
### 5.1 真相源
- **OSS**:存储 `rules.yaml` 正文文件
- **数据库**:存储规则集、规则版本、绑定关系、发布状态、哈希、编辑人、发布时间等元数据
### 5.2 执行层
- bridge 层负责把 OSS 文件下载到本地临时路径
- 临时路径交给 `leaudit.dsl.loader.load_rules_file()` 使用
### 5.3 回退层
- 本地 `rules/` 目录保留为 fallback 或 emergency backup
- 当 OSS 不可用或某些历史规则尚未迁移时可临时使用
---
## 6. 在线编辑功能设计
### 6.1 目标能力
平台应逐步具备以下功能:
- 查看规则集列表
- 查看规则版本历史
- 查看某版本 YAML 内容
- 在线编辑 YAML
- 保存草稿版本
- 校验 YAML 语法
- 校验 LeAudit DSL 语义
- 发布指定版本
- 回滚到历史版本
- 查看发布日志与校验日志
### 6.2 推荐流程
#### 编辑保存
```text
前端提交 YAML 文本
→ 后端做 YAML 语法校验
→ 后端做 LeAudit DSL 语义校验
→ 生成新版本号 / version_seq
→ 上传 rules.yaml 到 OSS
→ 写 leaudit_rule_versions
→ 返回版本信息
```
#### 发布生效
```text
选择版本发布
→ 更新 leaudit_rule_sets.current_version_id
→ 记录发布日志
→ 清理规则缓存
→ 后续新 run 自动使用新版本
```
#### 回滚
```text
选择旧版本
→ 切换 current_version_id 到旧版本
→ 写回滚日志
→ 清理规则缓存
```
---
## 7. 运行时加载设计
### 7.1 核心原则
运行时不直接让 `leaudit` 读取 OSS,也不直接读取数据库文本;而是通过 bridge 统一适配。
### 7.2 推荐加载链路
```text
document/type 确定
→ leaudit_rule_type_bindings 查规则集
→ leaudit_rule_sets.current_version_id
→ leaudit_rule_versions.oss_url
→ 下载 OSS 文件到本地临时目录
→ 校验 sha256
→ load_rules_file(local_path)
→ 执行 leaudit pipeline
```
### 7.2.1 当前项目已落地状态
当前 bridge 已按这条路线开始落地,分成两条对称链路:
- 文档文件链:
- `leaudit_document_files.local_path / oss_url`
- 下载或读取后落本地临时文件
- 再交给原生 `AuditCtx.file_path`
- 规则文件链:
- `leaudit_rule_type_bindings`
- `leaudit_rule_sets.current_version_id`
- `leaudit_rule_versions.oss_url`
- 下载到本地临时 `rules.yaml`
- `RulesLoader.load(local_path)`
- `NativeRunner -> AuditService.audit(ctx)`
这意味着后续开放 YAML 在线编辑界面时,不需要改 `leaudit` 核心,只要继续维护 “OSS + DB + 本地临时文件” 这条桥接链即可。
### 7.3 为什么必须保留“本地临时文件”
因为当前约束是:
- 不修改 `leaudit` 核心
- `leaudit` 仍以本地路径作为 DSL 加载输入
所以本地临时文件不是“倒退”,而是一个必要的兼容层。
---
## 8. 与现有文档的一致性
该方案与当前 `docs/leaudit` 目录中的设计方向保持一致:
- `docs/leaudit/dsl_rule_schema_design.md`
- 已提出“规则真相源 = OSS 文件 + 数据库索引”
- 已提出“运行时 DB → OSS → 本地临时 YAML → LeAudit loader”
- `docs/leaudit/bridge_directory_design.md`
- 已明确 bridge 负责规则加载与缓存
- `docs/leaudit/processing_logic.md`
- 已明确 rules resolve 属于桥接层职责
本文件的重点是把“**为了未来开放 YAML 编辑界面,为什么必须这样设计**”单独说明清楚。
---
## 9. 当前项目建议
### 9.1 短期
- 保持本地 `rules/` 目录可用,确保现有流程可运行
- 将其视为 fallback,而非长期正式真相源
### 9.2 中期
- 增加规则内容查看 / 编辑 / 保存 / 发布接口
- 补齐 `leaudit_rule_versions` 的 OSS 文件上传和版本切换能力
- 补统一 OSS 客户端与 presign / upload / version publish 能力
### 9.3 长期
- 后台提供完整 YAML 在线编辑器
- 支持草稿、发布、回滚、审计
- 清理本地硬编码规则映射,统一走规则绑定表
---
## 10. 最终结论
如果未来要开放 YAML 编辑界面,那么当前项目最合适的规则架构不是“继续依赖本地目录”,而是:
- **OSS 存规则文件正文**
- **数据库存路径、版本、哈希、状态、发布信息**
- **运行时下载到本地临时文件后交给 `leaudit` 执行**
这样既能保证:
- 不修改 `leaudit`
- 兼容现有 DSL 加载方式
又能保证:
- 在线编辑方便
- 版本管理清晰
- 发布回滚简单
- 多实例一致
- 运行结果可审计可追溯
这是当前项目向“规则可运营平台”演进时最合理的方案。
@@ -0,0 +1,296 @@
# 为什么仍然需要 Bridge 适配层
## 1. 结论先行
即使当前项目已经确认:
- 后续应使用 `leaudit` 原生 `AuditCtx`
- 后续不应继续由平台自己手写主流程编排
- 正式执行入口应收敛到 `AuditService.audit(ctx)`
**也仍然需要保留 Bridge / 适配层。**
原因不是因为不用原生 CTX,而恰恰是因为:
> **要正确使用原生 CTX,就更应该把它封装在 Bridge 里。**
也就是说,正确架构不是:
```text
平台层 -> 直接调用 leaudit AuditCtx / AuditService
```
而是:
```text
平台层 -> Bridge 适配层 -> leaudit AuditCtx / AuditService
```
---
## 2. 误区澄清
一个很容易出现的误区是:
- 既然 `leaudit` 已经有原生 `AuditCtx`
- 那平台直接调用它就好了
- Bridge 似乎没有必要
这个判断看起来简化了结构,但实际上会把平台和 `leaudit` 深度耦合起来,后续维护成本更高。
**真正应该取消的是:**
- 平台自己重写 7 阶段编排
**不应该取消的是:**
- 平台和 `leaudit` 之间的正式边界层
所以:
- **不要自己编排**
- **但要保留适配层**
---
## 3. 适配层到底在适配什么
Bridge 的本质,是把“平台世界”翻译成“引擎世界”,再把“引擎结果”翻译回“平台世界”。
## 3.1 平台世界
平台里实际关心的是这些对象:
- `document_id`
- `document_file_id`
- `rule_set_id`
- `rule_version_id`
- `oss_url`
- `run_id`
- 用户触发信息
- 权限信息
- 数据库记录
- 前端 DTO / VO
## 3.2 引擎世界
`leaudit` 原生执行关心的是这些对象:
- `file_path`
- `rules_file`
- `AuditServices`
- `AuditConfig`
- `AuditCtx`
- `AuditService.audit(ctx)`
这两套概念体系并不相同,因此天然需要一层转换。
---
## 4. 为什么不能让平台层直接碰 leaudit 原生对象
## 4.1 会导致架构边界失守
如果 Controller / Service / Model 层直接构造 `AuditCtx`,那就意味着:
- 平台业务代码开始直接依赖 `leaudit`
- `leaudit` 的内部概念会渗透到整个项目
- 后面任何原生字段调整都会扩散到平台层
这会破坏当前项目一直强调的边界原则:
- 平台层不直接感知 `leaudit` 内核细节
- `leaudit_bridge/` 是唯一正式桥接层
---
## 4.2 会让平台逻辑和引擎逻辑搅在一起
平台侧还必须处理这些事情:
- 文档文件从哪里取
- OSS 文件如何下载
- 规则版本从哪里查
- run 如何创建
- run 如何更新状态
- 结果如何写回 `leaudit_*`
- 前端如何查询结果
这些都不是 `leaudit` 原生 CTX 的职责。
如果平台层直接碰 `AuditCtx`,这些平台职责和引擎职责就会混在同一个 service 里,结构会越来越乱。
---
## 4.3 会让未来升级风险更大
如果以后 `leaudit` 升级:
- `AuditCtx` 字段变更
- `AuditService` 签名调整
- `AuditServices` 装配方式变化
- `AuditConfig` 配置项增加
那么:
- 如果只有 bridge 感知这些对象,改动范围很小
- 如果平台层很多地方直接依赖这些对象,改动会扩散全项目
因此,适配层的价值就在于:
> 把 `leaudit` 变化锁死在边界层里。
---
## 5. Bridge 的正确职责
确认使用原生 CTX 后,Bridge 的职责应该重新定义为:
## 5.1 输入适配
- 根据 `document_id` 找到待执行文档
- 根据 `document_file_id` 找到文件真源
- 如有需要,从 OSS 下载文档到本地临时路径
- 根据 `type_id` / `rule_type_binding` 找到本次评查规则版本
- 从 OSS 下载规则 YAML
- 解析出 `RulesFile`
## 5.2 运行装配
- 创建 `AuditServices`
- 创建 `AuditConfig`
- 创建原生 `AuditCtx`
- 调用 `AuditService.audit(ctx)`
## 5.3 输出适配
- 从最终 `ctx` 读取:
- `normalized_doc`
- `extraction`
- `phase`
- `evaluation`
- `fallback_tasks`
- `timing`
- 写入:
- `leaudit_audit_runs`
- `leaudit_rule_results`
- `leaudit_field_results`
- `leaudit_artifacts`
- `leaudit_run_metrics`
- `leaudit_run_errors`
## 5.4 边界保护
- 平台 Controller / Service 不直接 import `leaudit.services.*`
- 只有 `leaudit_bridge/` 感知原生 `AuditCtx``AuditService``AuditServices`
---
## 6. 三层结构图
推荐的结构应该是三层,而不是两层:
```text
┌────────────────────────────────────────────┐
│ 平台层 │
│ Controller / Service / Model / API / DB │
│ 文档、规则、权限、任务、结果查询 │
└──────────────────┬─────────────────────────┘
┌────────────────────────────────────────────┐
│ Bridge 适配层 │
│ file resolve / rules resolve / ctx build │
│ AuditServices / AuditConfig / AuditCtx │
│ persist ctx outputs to leaudit_* │
└──────────────────┬─────────────────────────┘
┌────────────────────────────────────────────┐
│ leaudit 原生内核层 │
│ AuditCtx / AuditService / Evaluation / │
│ Extraction / Rescue / DSL loader │
└────────────────────────────────────────────┘
```
这个结构的关键点是:
- 平台层不直接碰 `leaudit` 细节
- `leaudit` 不直接感知平台数据库和 OSS
- 所有翻译工作都集中在 Bridge
---
## 7. 为什么这比“平台直接调原生 CTX”更稳
### 优势 1:边界清晰
- 平台只管业务
- `leaudit` 只管评查
- Bridge 只管适配
### 优势 2:变化可控
- `leaudit` 升级时改 Bridge
- 平台结构基本不动
### 优势 3:便于替换
将来如果评查引擎变化:
- 平台不需要全面改造
- 只需替换适配层实现
### 优势 4:测试更容易
Bridge 可以单独测试:
- 是否正确组装 `AuditCtx`
- 是否正确调用 `AuditService.audit(ctx)`
- 是否正确写回平台结果表
---
## 8. 对当前项目的直接要求
既然已经确认:
- 必须使用原生 `AuditCtx`
- 不能继续自己编排主流程
那么当前项目应该同步修正为:
### 不再推荐的方向
-`fastapi_modules/fastapi_leaudit/leaudit_bridge/pipeline.py` 中继续手写 7 阶段流程
- 在平台侧继续直接串联:
- OCR
- Extract
- Phase
- Evaluate
- Rescue
### 推荐的方向
- `pipeline.py` 改造成薄包装器
- 新增 `audit_ctx_builder.py`
- 新增 `audit_service_factory.py`
- 由 bridge 统一:
- build ctx
- run audit
- persist result
---
## 9. 最终结论
确认使用原生 `AuditCtx` 之后,不是 Bridge 就没用了,反而说明:
> **Bridge 不该负责重写编排,但必须负责原生编排的接入适配。**
所以最终应该坚持这条原则:
- **主流程执行:交给 `leaudit` 原生 `AuditService.audit(ctx)`**
- **平台边界控制:交给 `leaudit_bridge/`**
这才是当前项目最稳妥、最可维护的长期方案。
@@ -0,0 +1,610 @@
# 原生 AuditCtx 接入重构方案
## 1. 目标
基于对 `/home/wren-dev/Porject/leaudit/src` 源码的核对,确认当前 `leaudit` 的正式执行模型应视为:
- `AuditCtx`
- `AuditServices`
- `AuditConfig`
- `AuditService.audit(ctx)`
因此,`leaudit-platform` 后续不应继续由平台自己手写主流程编排,而应重构为:
```text
平台层
→ Bridge 适配层
→ build AuditServices
→ build AuditConfig
→ build AuditCtx
→ call AuditService.audit(ctx)
→ persist ctx outputs
→ 返回 run / result
```
本文档用于说明:
- 为什么要重构
- 重构后的目标架构
- 现有文件怎么迁移
- 建议新增哪些文件
- 如何分阶段实施,避免一次性推翻现有代码
---
## 2. 关键结论
## 2.1 必须使用原生 CTX
这一点已经可以下明确结论:
- 后续应使用 `leaudit.services.audit_ctx.AuditCtx`
- 后续应通过 `leaudit.services.audit_service.AuditService.audit(ctx)` 执行主流程
- 不建议平台继续手工串接:
- OCR
- Extract
- Phase
- Evaluate
- Rescue
- Persist
## 2.2 但 Bridge 不能取消
Bridge 仍然是必须保留的正式边界层。
Bridge 的职责应改为:
- 平台对象 -> 原生 `AuditCtx`
- 原生 `ctx` -> 平台数据库结果
也就是说:
- **不要自己编排**
- **但要自己适配**
---
## 3. 当前实现与目标实现的差异
## 3.1 当前实现(过渡态)
当前 `fastapi_modules/fastapi_leaudit/leaudit_bridge/pipeline.py` 的角色,是平台侧自编排器:
```text
file_path + rules_file
→ OCR
→ Extraction
→ Phase detection
→ Evaluation
→ Save results
```
特点:
- 直接调用 engine / extraction / evaluation 低层函数
- 部分阶段逻辑由平台维护
- rescue / finalize 语义未完整对齐原生服务层
- 结果写入与运行编排耦合较高
## 3.2 目标实现(正式态)
目标应改成:
```text
document + file + rule version
→ build AuditServices
→ build AuditConfig
→ build AuditCtx
→ await AuditService.audit(ctx)
→ persist final ctx
```
特点:
- 主流程交给 `leaudit` 原生编排器
- Bridge 只负责适配与持久化
- 平台不再复制 `leaudit` 的阶段编排语义
- 后续升级风险更小
---
## 4. 目标架构图
```text
┌────────────────────────────────────────────┐
│ 平台层 │
│ Controller / Service / ORM / API / DB │
│ 文档上传、规则管理、任务触发、结果查询 │
└──────────────────┬─────────────────────────┘
┌────────────────────────────────────────────┐
│ Bridge 适配层 │
│ │
│ 1. resolve document file │
│ 2. resolve rule version │
│ 3. download doc / yaml to local temp │
│ 4. build AuditServices / AuditConfig │
│ 5. build AuditCtx │
│ 6. call AuditService.audit(ctx) │
│ 7. persist ctx outputs to leaudit_* │
└──────────────────┬─────────────────────────┘
┌────────────────────────────────────────────┐
│ leaudit 原生服务层 │
│ AuditCtx / AuditServices / AuditService │
│ normalization / extraction / evaluation │
│ rescue / finalize │
└────────────────────────────────────────────┘
```
---
## 5. Bridge 重构后的职责边界
## 5.1 Bridge 负责的事情
- 从平台数据库找到本次执行的文档与文件版本
- 从平台规则表找到当前生效规则版本
- 从 OSS 下载文档文件与规则文件到本地临时路径
- 构造 `AuditServices`
- 构造 `AuditConfig`
- 构造原生 `AuditCtx`
- 调用 `AuditService.audit(ctx)`
- 将最终 `ctx` 中的结果持久化到 `leaudit_*`
### 5.1.1 当前已落地到代码的链路
当前项目已经完成第一批骨架接入:
- 文档文件:
- `auditServiceImpl.py` 中从 `LeauditDocumentFile` 解析文件来源
- `fileSourceResolver.py` 已支持 `localPath``ossUrl`
- `tasks.py` 执行前统一写入本地临时文档文件
- 规则文件:
- `auditServiceImpl.py` 创建 `LeauditAuditRun` 时锁定 `ruleVersionId` / `ruleSourceOssUrl`
- `ruleVersionResolver.py``run_id` 解析规则版本来源
- `tasks.py` 已支持 `OSS URL -> 本地临时 YAML -> RulesLoader -> NativeRunner`
因此当前 bridge 的真实职责已经不只是“理论适配层”,而是运行期真正负责把平台侧 DB/OSS 语义转换成 `leaudit` 原生可消费的本地文件输入。
## 5.2 Bridge 不再负责的事情
- 不再手工定义 7 个 stage 的顺序
- 不再自己负责 phase 判定与 rescue 调度的业务语义
- 不再自己维护与原生服务层重复的一套编排逻辑
## 5.3 平台层不应直接做的事情
- 不直接构造 `AuditCtx`
- 不直接调用 `AuditService.audit(ctx)`
- 不直接 import `leaudit.services.*`
---
## 6. 建议新增的核心文件
## 6.1 `audit_ctx_builder.py`
建议新增:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/audit_ctx_builder.py`
职责:
- 把平台运行对象组装成原生 `AuditCtx`
建议输入:
- `run_id`
- `document_id`
- `document_file_id`
- `rule_version_id`
- `local_file_path`
- `rules_file`
- `services`
- `audit_config`
建议输出:
- `AuditCtx`
建议职责细分:
- `build_services(...)`
- `build_config(...)`
- `build_ctx(...)`
---
## 6.2 `audit_service_factory.py`
建议新增:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/audit_service_factory.py`
职责:
- 构造原生 `AuditService` 及其依赖服务
建议内部负责:
- `DocNormalizationService`
- `ExtractionService`
- `EvaluationService`
- `RescueService`
- `AuditServices`
- `AuditService`
目标是让平台不直接感知 `leaudit` 服务装配细节。
---
## 6.3 `file_source_resolver.py`
建议新增:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/file_source_resolver.py`
职责:
- 根据 `document_file_id` 找到文件真源
- 必要时从 OSS 下载到本地临时路径
说明:
当前 `ctx_builder.py` 有一部分类似职责,但建议拆得更明确:
- 文档文件解析
- 规则文件解析
- 原生 ctx 组装
不要混在一个“万能 builder”里。
---
## 6.4 `rule_version_resolver.py`
建议新增:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/rule_version_resolver.py`
职责:
- 根据 `document.type_id` / `binding` 找到当前生效规则版本
- 从 OSS 下载 `rules.yaml`
- 解析为 `RulesFile`
说明:
当前 `rules_loader.py` 偏向本地路径加载器;后续建议保留它做“底层 YAML 解析器”,但把“版本解析 + 规则定位”职责上移到 resolver。
---
## 7. 现有文件的重构策略
## 7.1 `pipeline.py`
文件:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/pipeline.py`
### 当前问题
- 现在是平台自编排器
- 直接串低层 stage
### 目标定位
重构后应退化为“薄包装器”。
建议最终形态:
```python
ctx = build_audit_ctx(...)
ctx = await audit_service.audit(ctx)
return ctx
```
也就是说:
- 保留 `pipeline.py` 文件名可以
- 但不再保留其“自定义主编排器”角色
### 建议处理方式
- 第一阶段:保留现有 `LauditPipeline`,但新增原生 `AuditCtxPipeline`
- 第二阶段:调用方切换到新实现
- 第三阶段:删除或降级旧自编排逻辑
---
## 7.2 `tasks.py`
文件:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py`
### 当前问题
- 现在既负责任务分发,又负责规则路径解析,又直接触发旧 pipeline
- 仍依赖 `LEAUDIT_RULES_DIR``_TYPE_ID_RULES_MAP`
### 重构目标
把它变成真正的“任务入口层”:
- 创建执行上下文
- 调 bridge 执行服务
- 更新 run 状态
### 建议改造
- `dispatch_leaudit_task()` 只做任务分发
- `leaudit_process_document()` 只做:
- resolve run inputs
- call bridge runner
- update run status
不要在这里继续放太多规则解析与 pipeline 内部细节。
---
## 7.3 `ctx_builder.py`
文件:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/ctx_builder.py`
### 当前问题
- 当前 `ExecutionContext` 不是原生 `AuditCtx`
- 更像平台内部轻量执行输入对象
### 重构目标
有两种方案:
#### 方案 A:保留并改名
- 保留文件,但改成“平台预上下文 builder”
- 只负责收集文档/文件/规则/本地路径
#### 方案 B:拆分
推荐拆分成:
- `file_source_resolver.py`
- `rule_version_resolver.py`
- `audit_ctx_builder.py`
我更建议方案 B,更清晰。
---
## 7.4 `rules_loader.py`
文件:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/rules_loader.py`
### 当前问题
- 更偏“本地 YAML 加载器”
- 还没有真正承担“规则版本解析器”职责
### 重构目标
让它只做一件事:
- 输入本地路径 / YAML 文本
- 输出 `RulesFile`
而以下职责交给 resolver
- 查绑定表
- 查规则版本
- 查 OSS 路径
- 下载本地临时文件
---
## 7.5 `storage_adapter.py`
文件:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py`
### 当前问题
- 结果写入还依赖“按 `document_id` 查最新 run”
- 与当前平台自编排写法耦合较深
### 重构目标
让它变成“最终 ctx 持久化器”。
建议接口风格:
- `persist_run_start(...)`
- `persist_ctx_outputs(run_id, ctx, meta)`
- `persist_failure(run_id, err)`
其中 `persist_ctx_outputs()` 从原生 `ctx` 中读取:
- `normalized_doc`
- `extraction`
- `phase`
- `evaluation`
- `fallback_tasks`
- `timing`
统一落表。
---
## 8. 目标执行链路
重构后的理想执行链如下:
```text
AuditServiceImpl.Run()
→ 创建 leaudit_audit_runs
→ dispatch_leaudit_task(run_id, ...)
→ bridge runner
→ resolve document file
→ resolve rule version
→ build AuditServices
→ build AuditConfig
→ build AuditCtx
→ await AuditService.audit(ctx)
→ persist ctx outputs
→ 返回 run_id
```
这里的关键点是:
- 平台仍然围绕 run 管理
- 引擎仍然围绕 ctx 管理
- bridge 负责把两者接起来
---
## 9. 推荐实施步骤
## 阶段 1:并行引入原生 CTX 路线
目标:
- 不马上删旧 `pipeline.py`
- 先把原生接入链做出来
建议动作:
- 新增 `audit_ctx_builder.py`
- 新增 `audit_service_factory.py`
- 新增一个新的 bridge runner
例如:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/native_runner.py`
职责:
- 一次性跑通原生 CTX 执行
---
## 阶段 2:让任务入口切到 native runner
目标:
- `tasks.py` 不再调用旧自编排 pipeline
- 改成调用原生 ctx 路线
建议动作:
-`dispatch_leaudit_task()`
-`leaudit_process_document()`
- 保留旧 pipeline 作为 fallback 一小段时间
---
## 阶段 3:让结果持久化围绕最终 ctx 收口
目标:
- `storage_adapter.py` 从“阶段中途写”转成“最终 ctx 聚合写”
建议动作:
- 显式传 `run_id`
- 从 ctx 中统一提取产物与汇总
---
## 阶段 4:删除旧自编排主链
目标:
- 彻底避免出现两套主流程语义
建议动作:
- 删除旧 `LauditPipeline.run()` 中的核心编排
- 或保留文件但只做代理包装
---
## 10. 风险与注意事项
## 10.1 不要一次性重写全部文件
建议采用“双轨过渡”:
- 旧 pipeline 先保留
- 新 native runner 并行引入
- 验证结果一致后再切换
## 10.2 不要把平台字段直接塞进原生 CTX
例如:
- `run_id`
- `trigger_user_id`
- `biz_document_id`
这些属于平台字段,不应该污染 `AuditCtx` 本身。
建议放在:
- bridge 层本地元数据对象
- 或持久化上下文对象
## 10.3 不要让平台业务代码直接 import `leaudit.services.*`
这条边界必须守住。
即使未来 100% 使用原生 `AuditCtx`,也应该只允许 `leaudit_bridge/` 感知这些类型。
## 10.4 规则与文件都要先落成本地路径
原生 `AuditCtx` 依旧是文件路径驱动:
- 文档文件要落地成本地路径
- 规则文件也要落地成本地 YAML 路径
不要试图让 `leaudit` 直接理解 OSS / DB。
---
## 11. 与现有文档的关系
本方案是以下文档的进一步收敛:
- `docs/规则编辑/yaml规则在线编辑设计.md`
- `docs/规则编辑/跑通全流程所需准备项.md`
- `docs/规则编辑/开发任务拆解清单.md`
- `docs/规则编辑/为什么仍然需要Bridge适配层.md`
它的核心新增点是:
- 不再停留在“Bridge 保留 / 自编排废弃”的原则层
- 而是把“如何迁移到原生 AuditCtx 模式”具体化
---
## 12. 最终结论
当前项目的 Bridge 应该正式转向下面这条路线:
- **平台负责 run / OSS / DB / 权限 / API**
- **Bridge 负责 AuditCtx 接入适配**
- **`leaudit` 原生服务层负责评查执行**
所以重构的最终方向不是“继续完善旧 pipeline”,而是:
> **用原生 `AuditCtx + AuditService.audit(ctx)` 替代平台自编排主链,并把 Bridge 重塑为适配层。**
这是当前项目最稳、最可维护、最符合 `leaudit` 演进方向的接入方案。
@@ -0,0 +1,711 @@
# LeAudit 开发任务拆解清单
## 1. 目标
基于以下两份文档,进一步拆出一份可执行的开发任务清单,并尽量精确到建议修改文件:
- `docs/规则编辑/yaml规则在线编辑设计.md`
- `docs/规则编辑/跑通全流程所需准备项.md`
本清单覆盖的目标不是单点“规则编辑”,而是完整业务链路:
```text
上传文档
→ 获取文件真源
→ OCR
→ 抽取
→ 评查
→ 结果落库
→ 查询运行状态 / 结果
→ 再扩展到 YAML 在线编辑 / 发布 / 回滚
```
---
## 2. 当前代码现状摘要
在开始任务前,先明确当前代码的真实状态。
> 2026-04-27 补充结论:结合 `/home/wren-dev/Porject/leaudit/src` 源码确认,
> 当前 `leaudit` 的正式执行入口应视为:
> `AuditCtx` + `AuditService.audit(ctx)`。
> 因此本清单中的后续任务,默认都以“保留 Bridge,但禁止平台自己重写主流程编排”为前提。
### 2.1 已有骨架
- 评查控制器:
- `fastapi_modules/fastapi_leaudit/controllers/auditController.py`
- 评查服务接口/实现:
- `fastapi_modules/fastapi_leaudit/services/auditService.py`
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
- bridge 层:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/pipeline.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/rules_loader.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/ctx_builder.py`
- 模型:
- `fastapi_modules/fastapi_leaudit/models/leauditDocument.py`
- `fastapi_modules/fastapi_leaudit/models/leauditDocumentFile.py`
- `fastapi_modules/fastapi_leaudit/models/leauditAuditRun.py`
- 规则服务接口骨架:
- `fastapi_modules/fastapi_leaudit/services/ruleService.py`
- `fastapi_modules/fastapi_leaudit/domian/vo/ruleVo.py`
### 2.2 当前主要缺口
- `AuditServiceImpl.Run()` 已可创建 run 并触发 NativeRunner 任务
- `GetResult()` 已可查询 `leaudit_rule_results`
- 规则文件主链已开始支持 `run -> rule_version -> oss_url -> 本地临时 YAML`
- `tasks.py` 仍保留 `LEAUDIT_RULES_DIR``_TYPE_ID_RULES_MAP` 作为 fallback
- 尚未看到规则编辑控制器与 `RuleServiceImpl`
- 尚未形成统一 OSS 文件服务
- 结果写入仍有“按 document_id 找最新 run”的简化逻辑
因此,任务拆解应该分两层:
- **P0:先把上传 → OCR → 抽取 → 评查 → 查询打通**
- **P1/P2:再把规则 OSS 化、版本化、在线编辑化**
---
## 3. 分阶段开发任务清单
## P0:先打通最小评查闭环
目标:
```text
上传文档
→ 创建 document / file / run
→ bridge 执行 OCR / 抽取 / 评查
→ 落库
→ 查到 run 状态与结果
```
---
### P0-1:补齐评查服务入口
#### 任务说明
`POST /api/audit/run` 从“只抛异常”改成真正可执行的评查入口。
#### 需要修改
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
- `fastapi_modules/fastapi_leaudit/services/auditService.py`
- `fastapi_modules/fastapi_leaudit/domian/Dto/auditDto.py`
- `fastapi_modules/fastapi_leaudit/domian/vo/auditVo.py`
#### 具体工作
-`Run()` 中完成:
- 校验文档是否存在
- 查当前可执行文件版本
- 计算 `run_no`
- 创建 `leaudit_audit_runs`
- 调用 `dispatch_leaudit_task()`
- 返回 `AuditRunVO`
- 调整 `IAuditService.Run()` 的接口定义,使其与实现参数一致
- 如有必要,为 `AuditRunDTO` 增加可选字段:
- `documentFileId`
- `force`
- `ruleType`
- `ruleVersionId`(可选,便于指定版本重跑)
#### 产出目标
- 调用 `/api/audit/run` 不再报 “Celery 任务集成待实现”
- 至少能创建 run 并触发 bridge 层执行
---
### P0-2:补齐 run 创建与状态更新逻辑
#### 任务说明
把 run 作为整条链的中心对象,保证每次执行都能明确追踪。
#### 需要修改
- `fastapi_modules/fastapi_leaudit/models/leauditAuditRun.py`
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py`
#### 具体工作
- 在触发评查前创建 `leaudit_audit_runs`
- 明确 run 初始字段:
- `status=pending`
- `phase=normalize` 或空
- `startedAt`
- `documentFileId`
- `ruleSetId`
- `ruleVersionId`
- 执行链中显式传递 `run_id`
- `storage_adapter.py` 所有落库方法改为:
- 不再“按 `document_id` 查最新 run”
- 统一显式使用 `run_id`
#### 产出目标
- 所有结果写入能严格绑定到唯一 `run_id`
- 避免多次重跑 / 并发时结果串写
---
### P0-3:补齐文件输入链
#### 任务说明
在执行 OCR 前,明确“这次评查使用哪一个文件”。
#### 需要修改
- `fastapi_modules/fastapi_leaudit/models/leauditDocument.py`
- `fastapi_modules/fastapi_leaudit/models/leauditDocumentFile.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/ctx_builder.py`
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
#### 建议新增
- `fastapi_modules/fastapi_leaudit/services/documentService.py`
- `fastapi_modules/fastapi_leaudit/services/impl/documentServiceImpl.py`
- `fastapi_modules/fastapi_leaudit/services/fileService.py`
- `fastapi_modules/fastapi_leaudit/services/impl/fileServiceImpl.py`
#### 具体工作
- 增加“获取当前有效文件”的服务方法
- 根据 `document_id` 找到当前激活的 `leaudit_document_files`
- 如果文件在 OSS,先下载到本地临时路径
- 给 pipeline 提供稳定的 `file_path`
#### 产出目标
- 评查入口不依赖调用方直接传原始字节
- 可以从数据库+文件真源独立还原执行输入
---
### P0-4:打通 bridge 任务入口
#### 任务说明
`dispatch_leaudit_task()` 真正成为评查执行入口,而不是演示性同步封装。
但注意:这里的“执行入口”不是继续扩写平台自编排 pipeline,而是逐步过渡到:
```text
build AuditCtx
→ call AuditService.audit(ctx)
→ persist ctx outputs
```
#### 需要修改
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/__init__.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/pipeline.py`
#### 建议新增
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/audit_ctx_builder.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/audit_service_factory.py`
#### 具体工作
- 统一 `dispatch_leaudit_task()` 的入参:
- `run_id`
- `document_id`
- `document_file_id`
- `rules_path``rule_version_id`
- 可选 `trigger_user_id`
- 逐步去掉 `source_port` 作为主上下文依赖
- 允许先同步执行,后续再切 Celery
- 逐步让 `pipeline.py` 退化为薄包装层,而不是 7 阶段自编排器
- 在 bridge 内部统一完成:
- `AuditServices` 构造
- `AuditConfig` 构造
- 原生 `AuditCtx` 构造
- `AuditService.audit(ctx)` 调用
#### 产出目标
- 业务层只调一个稳定入口
- bridge 层掌控实际执行上下文
- 主流程编排回归 `leaudit` 原生服务层
---
### P0-5:补齐结果查询接口
#### 任务说明
不仅要能跑,还要能看到结果。
#### 需要修改
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
- `fastapi_modules/fastapi_leaudit/controllers/auditController.py`
- `fastapi_modules/fastapi_leaudit/domian/vo/auditVo.py`
#### 具体工作
- `GetRunStatus()` 查询真实 run 状态
- `GetResult()` 从以下表联合查询:
- `leaudit_audit_runs`
- `leaudit_rule_results`
- 可选 `leaudit_field_results`
-`rules=[]` 改成真实规则级返回
- 如有必要,为 `AuditResultVO` 增加:
- `timing`
- `fields`
- `errors`
#### 产出目标
- `/api/audit/result/{RunId}` 能返回真实评查结果
---
### P0-6:补齐结果落库结构
#### 任务说明
当前 `StorageAdapter` 已有雏形,但还需要工程化加固。
#### 需要修改
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/result_adapter.py`
#### 具体工作
- 所有保存方法显式接收 `run_id`
-`run_metrics` 写入
-`run_errors` 写入
- 梳理 `artifacts``field_results` 的最小必要字段
- 保持 `rule_results``AuditResultVO` 的结构一致
#### 产出目标
- 结果写入不再依赖“最新 run”猜测
- 后续前端查询更稳定
---
## P1:把规则执行链切到 OSS + DB
目标:
```text
文档类型
→ 绑定表
→ 规则集
→ 当前版本
→ OSS YAML
→ 下载本地临时文件
→ leaudit 执行
```
---
### P1-1:补规则读取服务
#### 任务说明
把规则加载从“本地目录路径”升级成“DB + OSS + 临时文件”。
#### 当前状态
这一项已经完成第一阶段落地:
- `auditServiceImpl.py` 会在建 run 时锁定 `ruleVersionId``ruleSourceOssUrl`
- `tasks.py` 会优先按 `run_id` 解析规则来源
- `ruleVersionResolver.py` 会把 OSS YAML 下载到本地临时文件
- `RulesLoader.load(local_path)` 已接入执行链
当前剩余工作已经从“能不能执行”变成“如何把上传 / 发布 / 缓存 / 回收做完整”。
#### 需要修改
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/nativeRunner.py`
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
#### 建议新增
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/ruleVersionResolver.py`
#### 具体工作
- 根据 run 锁定的 `rule_version_id` / `rule_source_oss_url` 解析规则来源
- 下载 YAML 到本地临时文件
- 校验 `rule_source_sha256`
-`load_rules_file(local_path)`
- 继续保留本地 `rules/` 作为 fallback
#### 产出目标
- 执行时优先走 run 绑定规则版本,而不是 `_TYPE_ID_RULES_MAP`
- 原生 `AuditCtx.rules_file` 由 bridge 正式注入,而不是平台手工绕过服务编排层
---
### P1-2:补统一 OSS 文件服务
#### 任务说明
项目当前有 OSS 配置,但缺少统一文件服务。
#### 需要修改
- `fastapi_admin/config/_settings.py`(仅在配置不够时)
#### 建议新增
- `fastapi_common/fastapi_common_storage/__init__.py`
- `fastapi_common/fastapi_common_storage/oss_client.py`
- `fastapi_common/fastapi_common_storage/oss_path_utils.py`
如果不想放到 `fastapi_common/`,也可以先放:
- `fastapi_modules/fastapi_leaudit/services/ossService.py`
- `fastapi_modules/fastapi_leaudit/services/impl/ossServiceImpl.py`
#### 具体工作
- 提供统一方法:
- 上传文件到 OSS
- 下载到本地临时文件
- 计算 / 校验 sha256
- 删除临时文件
- 同时兼容:
- 规则文件
- 原始文档
- 评查产物
#### 产出目标
- 文档文件和规则文件都可以共用一套对象存储服务
---
### P1-3:补规则版本与绑定的查询模型
#### 任务说明
当前代码里还没有看到对应规则表的 ORM / 查询对象,后续查询会比较痛苦。
#### 建议新增
- `fastapi_modules/fastapi_leaudit/models/leauditRuleSet.py`
- `fastapi_modules/fastapi_leaudit/models/leauditRuleVersion.py`
- `fastapi_modules/fastapi_leaudit/models/leauditRuleTypeBinding.py`
- 更新 `fastapi_modules/fastapi_leaudit/models/__init__.py`
#### 具体工作
- 为规则集、规则版本、绑定表建立 ORM
- 后续服务层不必到处手写 SQL
#### 产出目标
- 规则管理服务、规则解析服务都能清晰建模
---
## P2:开放 YAML 在线编辑 / 发布 / 回滚
目标:
让规则成为后台可管理资产,而不是服务器上的裸文件。
---
### P2-1:补规则控制器与服务实现
#### 任务说明
当前只有 `IRuleService` 接口,需要真正落地规则后台。
#### 需要修改
- `fastapi_modules/fastapi_leaudit/services/ruleService.py`
- `fastapi_modules/fastapi_leaudit/domian/vo/ruleVo.py`
#### 建议新增
- `fastapi_modules/fastapi_leaudit/controllers/ruleController.py`
- `fastapi_modules/fastapi_leaudit/services/impl/ruleServiceImpl.py`
- `fastapi_modules/fastapi_leaudit/domian/Dto/ruleDto.py`
#### 具体工作
- 完成接口:
- 列表
- 版本历史
- 查看内容
- 保存版本
- 校验
- 发布
- 回滚
- 为 controller 增加路由
#### 产出目标
- 后台可以真正管理规则
---
### P2-2:补规则内容查看/保存接口
#### 建议新增
- `fastapi_modules/fastapi_leaudit/domian/Dto/ruleContentDto.py`
#### 具体工作
- 定义:
- 保存 YAML 文本请求 DTO
- 规则校验响应 VO
- 规则内容响应 VO
- 从 OSS 读回内容展示给前端
- 新版本保存时先写 OSS,再写 DB
#### 产出目标
- 前端可以拿到 YAML 文本并保存新版本
---
### P2-3:补 YAML 语法校验 + DSL 语义校验
#### 建议新增
- `fastapi_modules/fastapi_leaudit/services/ruleValidationService.py`
- `fastapi_modules/fastapi_leaudit/services/impl/ruleValidationServiceImpl.py`
#### 具体工作
- YAML 解析校验
- `leaudit` DSL schema 校验
- 提取 metadata 快照
- 形成标准错误列表
#### 产出目标
- 发布前可拦截坏规则
---
### P2-4:补发布、回滚、审计
#### 需要修改
- `fastapi_modules/fastapi_leaudit/services/impl/ruleServiceImpl.py`
#### 建议新增
- `fastapi_modules/fastapi_leaudit/models/leauditRulePublishLog.py`
- `fastapi_modules/fastapi_leaudit/models/leauditRuleValidationLog.py`
如果暂时不建 ORM,也至少需要:
- 对应 SQL migration / 建表脚本
#### 具体工作
- 发布时更新 `current_version_id`
- 写发布日志
- 回滚时写回滚日志
- 记录操作者与时间
#### 产出目标
- 规则变更具备可审计性
---
## P3:补平台级工程能力
目标:
让系统从“能跑”升级到“可持续运行”。
---
### P3-1Celery / Redis 正式接入
#### 需要修改
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py`
- `fastapi_modules/fastapi_leaudit/tasks/__init__.py`
- `fastapi_admin/config/_settings.py`
#### 建议新增
- `fastapi_common/fastapi_common_cache/redis_pool.py`
- `fastapi_modules/fastapi_leaudit/tasks/celery_app.py`
#### 具体工作
- 同步任务改为异步分发
- 配置任务超时 / 重试 / 队列
---
### P3-2:规则缓存与发布失效
#### 需要修改
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/rules_loader.py`
- `fastapi_modules/fastapi_leaudit/services/impl/ruleServiceImpl.py`
#### 具体工作
- 规则缓存 key 改为 `rule_version_id``oss_url + sha256`
- 发布后清缓存
- 多 worker 时设计统一失效策略
---
### P3-3:结果增强与诊断能力
#### 需要修改
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py`
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
#### 具体工作
- 完整落 `run_metrics`
- 完整落 `run_errors`
-`rescue_outcomes`
- 前端可查看错误详情、阶段耗时
---
## 4. 建议新增文件总表
下面是我建议优先考虑新增的文件,便于你按模块建任务:
### 规则管理
- `fastapi_modules/fastapi_leaudit/controllers/ruleController.py`
- `fastapi_modules/fastapi_leaudit/services/impl/ruleServiceImpl.py`
- `fastapi_modules/fastapi_leaudit/services/ruleValidationService.py`
- `fastapi_modules/fastapi_leaudit/services/impl/ruleValidationServiceImpl.py`
- `fastapi_modules/fastapi_leaudit/services/ruleResolverService.py`
- `fastapi_modules/fastapi_leaudit/services/impl/ruleResolverServiceImpl.py`
- `fastapi_modules/fastapi_leaudit/domian/Dto/ruleDto.py`
- `fastapi_modules/fastapi_leaudit/domian/Dto/ruleContentDto.py`
### 规则 ORM
- `fastapi_modules/fastapi_leaudit/models/leauditRuleSet.py`
- `fastapi_modules/fastapi_leaudit/models/leauditRuleVersion.py`
- `fastapi_modules/fastapi_leaudit/models/leauditRuleTypeBinding.py`
- `fastapi_modules/fastapi_leaudit/models/leauditRulePublishLog.py`
- `fastapi_modules/fastapi_leaudit/models/leauditRuleValidationLog.py`
### 文件与存储
- `fastapi_common/fastapi_common_storage/oss_client.py`
- `fastapi_common/fastapi_common_storage/oss_path_utils.py`
### 原生 AuditCtx 接入
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/audit_ctx_builder.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/audit_service_factory.py`
### 文档执行输入
- `fastapi_modules/fastapi_leaudit/services/documentService.py`
- `fastapi_modules/fastapi_leaudit/services/impl/documentServiceImpl.py`
### 异步任务 / 缓存
- `fastapi_modules/fastapi_leaudit/tasks/celery_app.py`
- `fastapi_common/fastapi_common_cache/redis_pool.py`
---
## 5. 建议优先修改文件总表
如果按“先把主链跑通”的角度,最优先改的文件是:
1. `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
2. `fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py`
3. `fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py`
4. `fastapi_modules/fastapi_leaudit/leaudit_bridge/rules_loader.py`
5. `fastapi_modules/fastapi_leaudit/leaudit_bridge/ctx_builder.py`
6. `fastapi_modules/fastapi_leaudit/domian/vo/auditVo.py`
7. `fastapi_modules/fastapi_leaudit/services/ruleService.py`
8. `fastapi_modules/fastapi_leaudit/domian/vo/ruleVo.py`
9. `fastapi_modules/fastapi_leaudit/models/__init__.py`
10. `fastapi_admin/config/_settings.py`
---
## 6. 推荐执行顺序
如果按最稳妥的方式推进,我建议这样做:
### 第一阶段:只做主链闭环
-`AuditServiceImpl`
-`tasks.py`
- 新增 `audit_ctx_builder.py`
- 新增 `audit_service_factory.py`
-`storage_adapter.py`
-`GetResult()`
目标:先能跑通上传后评查与结果查询。
### 第二阶段:切规则到 OSS + DB
- 补规则 ORM
-`rules_loader.py`
- 加 OSS 文件服务
目标:评查执行真正使用数据库发布的规则版本。
### 第三阶段:开放规则后台
-`ruleController.py`
-`RuleServiceImpl`
- 加校验服务
- 加发布/回滚日志
目标:前端可编辑、发布、回滚 YAML。
### 第四阶段:工程化增强
- Celery / Redis
- 缓存失效
- 审计
- metrics / errors / rescue
目标:从“能跑”变成“可运营”。
---
## 7. 一句话结论
如果你要的是“基于当前代码库,把功能拆成能开发的任务”,那么真正的主线不是先做编辑器,而是:
1. 先把 `auditServiceImpl + bridge + storageAdapter` 打通
2. 再把 `rules_loader` 从本地目录切到 `OSS + DB`
3. 最后再做 `ruleController + RuleServiceImpl + 校验/发布/回滚`
也就是说:
- **第一优先级是评查主链**
- **第二优先级是规则执行链**
- **第三优先级才是规则编辑后台**
这样开发成本最低,验证路径也最清晰。
@@ -0,0 +1,721 @@
## 背景
当前 `leaudit-platform` 已经完成第一阶段原生执行链接入:
- 文档文件已开始支持 `ossUrl -> 本地临时文件 -> NativeRunner`
- 规则文件已开始支持 `run -> rule_source_oss_url -> 本地临时 YAML -> NativeRunner`
- 执行核心已经切到原生 `AuditCtx` / `AuditService`
- `leaudit` 核心不修改,平台继续通过 bridge 适配
但当前仍有三个关键缺口没有真正完成闭环:
1. 还没有统一 OSS 服务,文档/规则下载仍是临时实现
2. 还没有完整的规则 YAML 管理后端能力
3. 还没有把“上传 → OCR → 抽取 → 评查 → 查询结果”整条链路正式联调跑通
因此需要制定一份统一实施计划,按依赖顺序把这三块一起完成。
---
## 总目标
本轮实施的目标分为三部分:
### 目标 1:统一 OSS 服务
把当前 bridge 中分散的下载逻辑收敛成统一的 OSS / MinIO 能力层,供文档文件、规则 YAML、运行产物三类对象复用。
### 目标 2:补齐规则管理后端
支持规则 YAML 的:
- 内容校验
- 新版本上传
- 版本持久化
- 当前版本发布
- 历史版本回滚
- 版本正文读取
并为后续在线编辑界面提供稳定后端。
### 目标 3:打通完整评查流程
跑通最小完整业务闭环:
```text
上传文档
-> 文档入库
-> 文件入 OSS / 或存在可访问真源
-> 创建 run
-> 下载文档到本地临时文件
-> 下载规则 YAML 到本地临时文件
-> Native AuditCtx 执行
-> OCR / 抽取 / 评查
-> 结果写回 leaudit_*
-> 查询运行状态和结果
```
---
## 当前已完成基线
### 已完成
- `AuditServiceImpl.Run()` 已可创建 `leaudit_audit_runs` 并触发执行
- `AuditServiceImpl.GetResult()` 已可读取 `leaudit_rule_results`
- 文档文件执行链已接入:
- `LeauditDocumentFile.localPath`
- `LeauditDocumentFile.ossUrl`
- 规则文件执行链已接入:
- `LeauditAuditRun.ruleVersionId`
- `LeauditAuditRun.ruleSourceOssUrl`
- `run -> oss_url -> 本地临时 YAML -> RulesLoader -> NativeRunner`
- bridge 层已经新增:
- `auditCtxBuilder.py`
- `auditServiceFactory.py`
- `nativeRunner.py`
- `fileSourceResolver.py`
- `ruleVersionResolver.py`
### 尚未完成
- 统一 OSS client / path utils 还未落地
- 规则上传 / 发布 / 回滚 / 读正文接口还未落地
- YAML 语法校验和 DSL 语义校验还未形成正式服务
- `run_metrics` / `run_errors` / `rescue_outcomes` 持久化还未补齐
- 全流程 E2E 还未完成真实联调
### 当前实施进展(2026-04-27
- `M1` 已开始落地:
- 已补 `OSS_USE_SSL` / `OSS_PRESIGN_EXPIRE_SECONDS` 等配置项
- 已新增统一 `OssClient``OssPathUtils`
- `fileSourceResolver.py` / `ruleVersionResolver.py` 已开始接统一 OSS 服务
- `M2` 已开始落地:
- 已新增 `ruleValidator.py`
- 已补 `ruleServiceImpl.py`
- 已新增 `ruleController.py`
- 已补规则版本创建 / 校验 / 发布 / 回滚 / 正文读取接口骨架
- `M3` 已开始落地:
- 已按 `docs/AuditCtx深度解读-2026-04-27.html` 复用原生 `AuditCtx` 语义
- 已开始把 `ctx.timing` / `ctx.fallback_tasks` / 抽取错误落库到运行级表
- `M4` 仍待继续实施
---
## 总体实施分期
建议分 4 个里程碑实施:
- `M1`:统一 OSS 基础设施
- `M2`:规则管理后端能力
- `M3`:执行链正式化与结果持久化补齐
- `M4`:全流程联调与验收
实施顺序必须按依赖推进,不建议跳步。
---
## M1:统一 OSS 基础设施
### M1-1 配置模型标准化
#### 目标
统一 OSS / MinIO 的配置读取方式,为后续文档和规则服务提供底层能力。
#### 需要处理
- 新增或确认 OSS 配置项
- 保证配置能从 `app.toml` / 环境变量进入 Settings
- 补齐 `__init__.pyi` 类型声明
#### 建议配置项
- `OSS_ENDPOINT`
- `OSS_BUCKET`
- `OSS_ACCESS_KEY`
- `OSS_SECRET_KEY`
- `OSS_REGION`
- `OSS_USE_SSL`
- `OSS_PUBLIC_BASE_URL`
- `OSS_PRESIGN_EXPIRE_SECONDS`
#### 需要修改的文件
- `fastapi_admin/config/_settings.py`
- `fastapi_admin/config/__init__.pyi`
- 环境配置文件(如有)
#### 完成标准
- 业务代码可以统一 import OSS 配置
- IDE 类型可识别
- 开发 / 测试 / 生产环境可分离
### M1-2 统一 OSS Client
#### 目标
提供平台统一的上传、下载、presign 和对象存在性判断能力。
#### 建议新增文件
- `fastapi_common/fastapi_common_storage/oss_client.py`
- `fastapi_common/fastapi_common_storage/oss_path_utils.py`
#### 最低能力要求
- 上传 bytes
- 上传文本
- 上传本地文件
- 下载 bytes
- 下载到本地临时文件
- 判断对象是否存在
- 生成 presigned URL
- 统一返回 object key / url
#### 完成标准
- 规则和文档两条链都能复用同一套 OSS 接口
- bridge 代码中不再直接写 `urlopen`
### M1-3 统一 OSS 路径生成工具
#### 目标
把文档中约定的路径规范落实为代码工具,避免业务层散写路径字符串。
#### 路径规范
```text
bdocs/{region}/{type_code}/{doc_id}/{version}/{file_role}.{ext}
artifacts/{region}/{run_id}/{artifact_type}/{detail}.{ext}
rules/{rule_type}/{version_no}/rules.yaml
rules/{rule_type}/{version_no}/validation_report.json
```
#### 需要实现的方法
- `BuildBusinessDocKey(...)`
- `BuildArtifactKey(...)`
- `BuildRuleYamlKey(...)`
- `BuildRuleValidationReportKey(...)`
#### 完成标准
- 上传文档、上传规则、记录产物时统一生成 key
- 路径规范不再散落在业务代码中
### M1-4 接管当前 bridge 下载逻辑
#### 目标
把 bridge 中当前临时下载逻辑接到统一 OSS 服务。
#### 需要修改的文件
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/fileSourceResolver.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/ruleVersionResolver.py`
#### 完成标准
- 文档下载统一经 OSS client
- 规则下载统一经 OSS client
- 支持正式私有桶而不只依赖公开 HTTP/HTTPS
---
## M2:规则管理后端能力
### M2-1 补规则服务接口
#### 目标
把规则服务从当前骨架扩展为完整规则生命周期服务。
#### 建议能力
- 查询规则集列表
- 查询规则版本列表
- 查询指定版本正文
- 校验 YAML
- 创建新规则版本
- 发布规则版本
- 回滚规则版本
#### 需要修改或新增的文件
- `fastapi_modules/fastapi_leaudit/services/ruleService.py`
- `fastapi_modules/fastapi_leaudit/services/impl/ruleServiceImpl.py`
#### 完成标准
- Service 层接口稳定
- 后续 controller 只做 DTO 拆值与返回
### M2-2 补 DTO / VO / BO
#### 目标
为规则管理接口提供规范化入参与出参。
#### 建议新增文件
- `fastapi_modules/fastapi_leaudit/domian/Dto/ruleVersionCreateDto.py`
- `fastapi_modules/fastapi_leaudit/domian/Dto/ruleValidateDto.py`
- `fastapi_modules/fastapi_leaudit/domian/Dto/rulePublishDto.py`
- `fastapi_modules/fastapi_leaudit/domian/vo/ruleVersionVo.py`
- `fastapi_modules/fastapi_leaudit/domian/vo/ruleContentVo.py`
- `fastapi_modules/fastapi_leaudit/domian/bo/ruleVersionCreateBo.py`
#### 完成标准
- 字段统一 lowerCamelCase
- Controller 只接 DTO
- Service 返回 VO / BO
### M2-3 实现规则校验服务
#### 目标
为在线编辑和发布提供保存前 / 发布前的双层校验能力。
#### 校验层次
##### 第一层:YAML 语法校验
- 缩进
- 基本结构
- 能否解析
##### 第二层:LeAudit DSL 语义校验
- `metadata` 是否完整
- `type_id` / `name` / `version` 是否有效
- rule / extract / stage 结构是否合法
- 字段引用是否一致
- phase / risk / score / activate_if 是否符合 DSL 约束
#### 建议新增文件
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/ruleValidator.py`
#### 完成标准
- 非法 YAML 不能发布
- 校验错误可返回给前端展示
### M2-4 实现规则版本上传与落库
#### 目标
让规则版本真正以“OSS 存正文、DB 存索引”的方式保存。
#### 处理步骤
```text
接收 YAML 文本
-> 语法校验
-> DSL 校验
-> 计算 sha256 / file_size
-> 生成 rules/{rule_type}/{version_no}/rules.yaml
-> 上传 OSS
-> 写 leaudit_rule_versions
-> 需要时写 validation_report.json
```
#### 需要修改的文件
- `fastapi_modules/fastapi_leaudit/services/impl/ruleServiceImpl.py`
- `fastapi_common/fastapi_common_storage/oss_path_utils.py`
#### 完成标准
- `leaudit_rule_versions` 中完整记录:
- `oss_url`
- `file_sha256`
- `file_size`
- `metadata_type_id`
- `metadata_name`
- `metadata_version`
### M2-5 实现发布与回滚
#### 目标
通过切换 `leaudit_rule_sets.current_version_id` 管理当前生效版本。
#### 处理要求
- 发布时更新当前生效版本
- 回滚时切换回历史版本
- 保留审计信息
- 不影响历史 run 对旧版本的追溯
#### 完成标准
- 新 run 会自动使用新版本
- 老 run 仍保留历史规则来源
### M2-6 暴露规则管理控制器
#### 目标
为后续规则编辑页面提供 API。
#### 建议新增文件
- `fastapi_modules/fastapi_leaudit/controllers/ruleController.py`
#### 建议接口
- `GET /api/leaudit/rule-sets`
- `GET /api/leaudit/rule-sets/{ruleType}/versions`
- `GET /api/leaudit/rule-versions/{versionId}/content`
- `POST /api/leaudit/rule-sets/{ruleType}/validate`
- `POST /api/leaudit/rule-sets/{ruleType}/versions`
- `POST /api/leaudit/rule-sets/{ruleType}/publish`
- `POST /api/leaudit/rule-sets/{ruleType}/rollback`
#### 完成标准
- 前端可直接基于这些接口做查看、编辑、发布、回滚
- 响应统一走 `Result`
---
## M3:执行链正式化与持久化补齐
### M3-1 文档来源解析正式接入 OSS 服务
#### 目标
`fileSourceResolver.py` 从临时 URL 下载升级为正式存储接入。
#### 处理优先级
1. 优先 `localPath`
2. 否则走 `ossUrl` / object key
3. 落本地临时文件或 bytes 交给执行链
#### 需要修改的文件
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/fileSourceResolver.py`
#### 完成标准
- 文档来源解析不再直接依赖 `urllib`
- 后续换 OSS 实现无需改业务层
### M3-2 规则来源解析正式接入 OSS 服务
#### 目标
`ruleVersionResolver.py` 升级为正式的规则版本来源解析器。
#### 标准链路
```text
run_id
-> leaudit_audit_runs.rule_version_id
-> leaudit_audit_runs.rule_source_oss_url
-> 下载规则 YAML
-> sha256 校验
-> 写本地临时 YAML
-> RulesLoader.load(local_path)
```
#### 需要修改的文件
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/ruleVersionResolver.py`
#### 完成标准
- 执行优先绑定具体规则版本
- 不再主要依赖 `_TYPE_ID_RULES_MAP`
### M3-3 补全运行结果持久化
#### 目标
把 NativeRunner 当前未落库的数据继续补齐。
#### 需要补的内容
- `leaudit_run_metrics`
- `leaudit_run_errors`
- `rescue_outcomes`
- `finishedAt`
- `resultStatus`
- 必要的 artifact 索引
#### 需要修改的文件
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/nativeRunner.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py`
#### 完成标准
- 一次 run 的关键结果和错误都能追溯
- 不再只落 `ocr/extract/evaluate/rule_results`
### M3-4 明确 run 状态机
#### 目标
统一 run 的状态与 phase 更新逻辑。
#### 建议状态
- `pending`
- `running`
- `completed`
- `failed`
#### 需要修改的文件
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py`
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
#### 完成标准
- 前端轮询可看到真实运行进度
- 失败时能准确落状态和错误信息
---
## M4:全流程联调与验收
### M4-1 梳理上传入口
#### 目标
确认现有上传能力到底走哪些 controller / service,以及上传后是否已形成:
- `leaudit_documents`
- `leaudit_document_files`
- 文件来源记录
- 当前活跃版本标记
#### 需要重点检查的位置
- `fastapi_modules/fastapi_leaudit/controllers/`
- `fastapi_modules/fastapi_leaudit/services/`
- 文档上传相关 service / controller
#### 完成标准
- 明确上传后如何进入评查系统
### M4-2 接通上传后触发评查
#### 目标
形成稳定用户操作路径。
#### 最小可接受路径
##### 路径 A:两步操作
```text
上传文档
-> 手工点击触发评查
```
##### 路径 B:一步自动触发
```text
上传文档
-> 自动创建 run 并触发评查
```
#### 完成标准
- 至少有一种路径可稳定跑通
### M4-3 补结果查询展示所需字段
#### 目标
确保前端能拿到完整结果展示数据。
#### 至少要能查到
- run 基本状态
- 总分 / 通过数 / 失败数 / 跳过数
- 规则明细
- 失败原因
- 产物地址(如有)
#### 需要重点修改的文件
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
- 对应 controller / VO
#### 完成标准
- 前端拿 `runId` 可以完成结果展示
### M4-4 准备联调样例
#### 目标
准备一套可重复使用的联调数据。
#### 至少需要
- 1 份真实文档样例
- 1 条有效规则绑定
- 1 份可访问规则 YAML
- 1 套可运行配置
#### 完成标准
- 能稳定复现成功链路
- 能稳定复现失败链路
### M4-5 完成一次真实 E2E 验证
#### 验证目标链
```text
上传文档
-> document / file 入库
-> 文件可下载
-> 规则 YAML 可下载
-> Native AuditCtx 执行
-> OCR / 抽取 / 评查完成
-> 结果写回 DB
-> 查询结果成功
```
#### 完成标准
- 至少成功跑通 1 个真实样例
- 至少验证 1 个失败样例
- 形成一份验收记录文档
---
## 推荐实施顺序
本轮开发建议严格按以下顺序执行:
### 第一阶段:先做 M1
- M1-1 配置模型
- M1-2 OSS client
- M1-3 路径工具
- M1-4 接管现有 bridge 下载逻辑
原因:
- 这是后续规则管理和全流程联调的共同底座
### 第二阶段:做 M2
- M2-1 规则服务接口
- M2-2 DTO / VO / BO
- M2-3 规则校验
- M2-4 新版本上传
- M2-5 发布 / 回滚
- M2-6 控制器接口
原因:
- 先把规则后端能力做实,再给前端接口
### 第三阶段:做 M3
- M3-1 文档来源正式接入
- M3-2 规则来源正式接入
- M3-3 持久化补齐
- M3-4 run 状态机
原因:
- 这是把“能跑”升级为“可维护、可观察”
### 第四阶段:做 M4
- M4-1 上传入口梳理
- M4-2 上传后触发
- M4-3 结果查询补齐
- M4-4 样例准备
- M4-5 E2E 联调
原因:
- 最后做整体验收,避免中途反复返工
---
## 高优先级文件清单
### 一定会修改的文件
- `fastapi_admin/config/_settings.py`
- `fastapi_admin/config/__init__.pyi`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/fileSourceResolver.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/ruleVersionResolver.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/nativeRunner.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py`
- `fastapi_modules/fastapi_leaudit/services/ruleService.py`
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
### 大概率新增的文件
- `fastapi_common/fastapi_common_storage/oss_client.py`
- `fastapi_common/fastapi_common_storage/oss_path_utils.py`
- `fastapi_modules/fastapi_leaudit/services/ossService.py`
- `fastapi_modules/fastapi_leaudit/services/impl/ossServiceImpl.py`
- `fastapi_modules/fastapi_leaudit/services/impl/ruleServiceImpl.py`
- `fastapi_modules/fastapi_leaudit/controllers/ruleController.py`
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/ruleValidator.py`
- `fastapi_modules/fastapi_leaudit/domian/Dto/ruleVersionCreateDto.py`
- `fastapi_modules/fastapi_leaudit/domian/Dto/ruleValidateDto.py`
- `fastapi_modules/fastapi_leaudit/domian/Dto/rulePublishDto.py`
- `fastapi_modules/fastapi_leaudit/domian/vo/ruleVersionVo.py`
- `fastapi_modules/fastapi_leaudit/domian/vo/ruleContentVo.py`
- `fastapi_modules/fastapi_leaudit/domian/bo/ruleVersionCreateBo.py`
---
## 验收口径
### M1 验收
- 文档和规则都经统一 OSS 服务访问
- bridge 中不再散落临时下载逻辑
### M2 验收
- 可以新建规则版本、读内容、发布、回滚
- YAML 正式存 OSS,元数据正式存 DB
### M3 验收
- run 与 rule version 绑定关系稳定
- 运行结果持久化完整
- 运行状态与 phase 可查询
### M4 验收
- 真实上传到评查结束可跑通
- 查询结果成功
- 有联调 / 验收记录
---
## 实施结论
本轮开发不再继续扩散平台手写评查逻辑,而是坚持以下原则:
- `leaudit` 核心不改
- 平台负责 DB / OSS / API / 权限 / 任务入口
- bridge 负责把平台语义转换成原生 `AuditCtx` 输入
- 文档与规则都采用“OSS 真源 + 数据库存索引 + 本地临时文件执行”的模式
按本计划推进后,既能保证当前原生执行链继续稳定,也能为后续 YAML 在线编辑界面和完整评查业务闭环打下正式基础。
@@ -0,0 +1,520 @@
# LeAudit 跑通全流程所需准备项
## 1. 范围说明
本文记录的不是“仅把 YAML 规则搬到 OSS”这一件事,而是 **跑通 LeAudit 整个业务链路** 所需要补齐的能力。
这里的“跑通全流程”明确指:
```text
上传文档
→ 获取文件真源
→ OCR
→ 规则解析
→ 字段抽取
→ 评查
→(可选)Rescue
→ 结果落库
→ 前端查询运行状态和结果
```
也就是说,目标不是只做“规则编辑”,而是要让下面这条链条在当前项目内真实可执行:
- 用户上传文档
- 平台找到该文档对应的规则版本
- Bridge 调用 `leaudit` 引擎执行 OCR / Extract / Evaluate
- 结果写入 `leaudit_*`
- 前端可以查询 run 状态和评查结果
---
## 2. 当前状态判断
当前项目的设计方向是对的,但距离“整条链真正可跑通”还有明显缺口。
> 2026-04-27 补充结论:结合 `/home/wren-dev/Porject/leaudit/src` 源码确认,`leaudit`
> 当前已经形成正式的服务编排层:`AuditCtx` +
> `AuditService.audit(ctx)`。因此本项目后续不应长期维持“平台自己手搓
> OCR / Extract / Evaluate / Rescue 编排”的模式,而应保留 bridge,
> 但把 bridge 改造成“平台对象 -> 原生 AuditCtx -> 原生 AuditService -> 平台持久化”的适配层。
### 2.1 已具备的基础
- 已有 `docs/leaudit/` 一整套设计文档
- 已有 `leaudit_*` 相关表设计与部分模型
- 已有 bridge 目录骨架:
- `pipeline.py`
- `tasks.py`
- `rules_loader.py`
- `storage_adapter.py`
- 已有规则集 / 规则版本 / 绑定表设计
- 已有 YAML 在线编辑设计文档:`docs/规则编辑/yaml规则在线编辑设计.md`
### 2.2 当前仍未闭环的关键问题
- 评查服务入口还没有真正触发可执行任务
- 规则加载仍以本地目录 / 硬编码过渡方案为主
- OSS 规则文件上传 / 下载 / 校验链未补齐
- 规则后台控制面未落地
- 运行结果与 `run_id` 的强绑定还不够严格
- 上传文件 → 文件真源 → 本地临时文件 → pipeline 的输入链还未完全收口
所以现在更准确的说法是:
- **架构蓝图已成型**
- **部分代码骨架已存在**
- **但全流程尚未真正打通**
---
## 3. 跑通整个流程,必须补齐的 8 大能力块
## 3.1 上传链路与文档真源
要跑通 OCR / 抽取 / 评查,首先必须保证上传文档在系统里成为一个稳定的“可执行输入”。
### 需要准备的能力
- 上传接口能够接收主文档 / 附件
- 上传后写入 `leaudit_documents`
- 文件元数据写入 `leaudit_document_files`
- 原始文件上传到 OSS 或稳定本地真源
- 为每个运行锁定 `document_file_id`
- 需要时可把文档从 OSS 下载到本地临时路径供 `leaudit` 读取
### 为什么这是前提
`leaudit` 执行时依赖本地文件路径,因此即便业务真源在 OSS,执行阶段仍要有:
```text
document_file.oss_url
→ 下载到本地临时文件
→ pipeline.run(file_path=local_tmp_path)
```
如果这一层不稳定,后面 OCR、抽取、评查都无从谈起。
---
## 3.2 评查运行主线(Run)管理
整条链必须围绕 `leaudit_audit_runs` 来组织,否则运行结果会失去可追踪性。
### 需要准备的能力
- 触发评查时先创建一条 `leaudit_audit_runs`
- 记录:
- `document_id`
- `document_file_id`
- `run_no`
- `trigger_source`
- `status`
- `rule_set_id`
- `rule_version_id`
- `rule_source_oss_url`
- `rule_source_sha256`
- 运行中逐步更新:
- `status`
- `phase`
- `started_at`
- `finished_at`
- 汇总统计字段
### 当前项目缺口
当前 `AuditServiceImpl.Run()` 还没有真正创建和分发 run,只是直接抛出“Celery 任务集成待实现”:
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
因此,当前“触发评查”这一步实际上还没有闭环。
---
## 3.3 规则管理控制面
如果未来要做 YAML 在线编辑,那么规则一定不能只是本地 `rules/` 目录,而必须成为平台管理对象。
### 需要准备的能力
- 规则集列表
- 规则版本列表
- 查看某个版本 YAML 内容
- 保存草稿版本
- 发布指定版本
- 回滚到历史版本
- 规则编辑 / 发布权限控制
- 发布 / 回滚审计
### 建议最少接口
- `GET /rule-sets`
- `GET /rule-sets/{rule_type}/versions`
- `GET /rule-versions/{id}/content`
- `POST /rule-sets/{rule_type}/versions`
- `POST /rule-sets/{rule_type}/validate`
- `POST /rule-sets/{rule_type}/publish`
- `POST /rule-sets/{rule_type}/rollback`
### 当前项目缺口
当前只有规则服务接口定义的一小部分骨架:
- `fastapi_modules/fastapi_leaudit/services/ruleService.py`
尚未形成完整规则后台能力。
---
## 3.4 规则文件存储链(OSS + DB
这部分是“在线编辑”和“运行执行”之间的核心桥梁。
### 需要准备的能力
- YAML 文本上传到 OSS
- OSS 路径写入 `leaudit_rule_versions.oss_url`
- 同步保存:
- `file_sha256`
- `file_size`
- `metadata_type_id`
- `metadata_name`
- `metadata_version`
- 下载规则文件到本地临时目录
- 下载后校验 sha256
- 发布后能根据 `current_version_id` 找到正在生效的版本
### 运行时目标链路
```text
leaudit_rule_type_bindings
→ leaudit_rule_sets.current_version_id
→ leaudit_rule_versions.oss_url
→ 下载到本地临时文件
→ load_rules_file(local_path)
→ 执行 pipeline
```
### 当前项目状态
当前项目已经开始按“原生 AuditCtx + Bridge 适配”方向落地两条来源链:
- 文档文件:
- 已支持 `leaudit_document_files.local_path`
- 也已支持 `leaudit_document_files.oss_url`
- Worker 执行前会统一落为本地临时文件
- 规则文件:
- 已支持 `leaudit_audit_runs.rule_source_oss_url`
- 运行时按 `run -> rule_version -> oss_url` 下载 YAML 到本地临时文件
- 再交给 `RulesLoader.load(local_path)``NativeRunner` 执行
当前仍保留 fallback
- `LEAUDIT_RULES_DIR`
- `_TYPE_ID_RULES_MAP`
- 本地 `rules/` 目录
也就是说,“DB + OSS -> 本地临时 YAML”的正式主链已经接入,旧本地目录逻辑仅作为兼容回退。
---
## 3.5 规则校验链
规则编辑能力一旦开放,就必须要有保存前 / 发布前校验,否则很容易把错误 YAML 发到线上。
### 至少需要两层校验
#### 1YAML 语法校验
- 缩进是否正确
- 结构是否可解析
- 基本字段是否存在
#### 2LeAudit DSL 语义校验
- `metadata` 是否完整
- `type_id` / `version` / `name` 是否可识别
- rule / stage / extract 结构是否符合 `leaudit` 的 DSL 约束
- 规则中引用的字段是否存在
- phase / activate_if / score / risk 等配置是否合理
### 需要准备的结果形式
- 校验是否通过
- 错误列表
- 警告列表
- 可选:抽取出的 metadata 快照
---
## 3.6 执行链:OCR → 抽取 → 评查 → Rescue
这是整个系统真正的“核心业务流水线”。
### 需要准备的能力
- OCR 客户端可正常调用
- 文档分类 / rules resolve 可正常执行
- `dispatch_extract()` 能跑通字段抽取
- `evaluate_extraction()` 能完成规则评查
- 如果平台定义最终结果包含 Rescue,则补齐 rescue 阶段
- 执行链中每个阶段都要能记录错误与耗时
### 当前项目情况
`pipeline.py` 已有主链骨架:
- OCR
- 抽取
- 坐标解析
- phase detection
- evaluate
见:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/pipeline.py`
但当前还存在这些问题:
- 结果存储依赖“按 document_id 查最新 run”这种简化逻辑
- rescue 尚未形成完整闭环
- 任务上下文仍残留 `source_port` 过渡参数
- 当前 `pipeline.py` 是平台侧自编排器,而不是调用 `leaudit` 原生
`AuditService.audit(ctx)` 的适配包装器
因此还不能认为“执行链已经完全生产可用”。
### 最新架构修正建议
基于 `leaudit` 源码核对,正式建议改成:
```text
平台文档/规则/配置
→ bridge 解析输入
→ 构造 AuditServices
→ 构造 AuditConfig
→ 构造原生 AuditCtx
→ 调用 AuditService.audit(ctx)
→ 从最终 ctx 提取产物落库
```
也就是说:
- bridge 继续保留
- 但 bridge 不再负责自己重写 7 阶段编排
- bridge 负责“适配”和“持久化”
- `leaudit` 原生 `AuditService.audit(ctx)` 负责“执行”
---
## 3.7 结果落库与查询链
跑通全流程不只是引擎执行成功,还包括结果能写进去、查出来。
### 需要准备的能力
- OCR 产物写入 `leaudit_artifacts`
- 字段抽取结果写入 `leaudit_field_results`
- 规则评查结果写入 `leaudit_rule_results`
- 运行指标写入 `leaudit_run_metrics`
- 错误信息写入 `leaudit_run_errors`
- 补救结果写入 `leaudit_rescue_outcomes`
- 更新 `leaudit_audit_runs` 汇总字段
- 前端可查询:
- run 状态
- 规则级结果
- 抽取字段
- 汇总统计
### 当前项目缺口
当前 `StorageAdapter` 已有部分写入逻辑,但还有明显工程缺口:
- 多处依赖“按 document_id 找最新 run”
- `GetResult()` 仍未从 `leaudit_rule_results` 真正查规则级结果
见:
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py`
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
这说明“结果查询闭环”还未打通。
---
## 3.8 异步任务、缓存、幂等与审计
如果只在本地同步跑 Demo,可以先简化;但如果要真的作为平台运行,就必须补齐基础工程能力。
### 需要准备的能力
#### 任务调度
- Celery / Redis 异步任务
- 任务超时
- 失败重试
- 队列优先级
#### 幂等与并发
- 同一个文档重复点击“评查”如何处理
- 同一 `run_id` 重试还是新建 run
- 避免结果串写到错误 run
#### 缓存失效
- 新规则发布后,旧缓存如何失效
- 多 worker 下规则缓存如何同步更新
#### 审计
- 谁上传了规则
- 谁发布了规则
- 谁触发了评查
- 该评查具体用了哪版规则
### 当前项目缺口
- Celery 仍未真正接入业务主链
- 发布后的规则缓存失效机制未明确实现
- 审计日志表和日志落库链未形成闭环
---
## 4. 从“规则编辑”到“全流程可跑”的完整依赖链
如果要把功能讲清楚,可以把整个系统拆成下面这条依赖链:
```text
【A】上传文档
→ 写 leaudit_documents / leaudit_document_files
→ 文件进 OSS
【B】编辑规则
→ YAML 文本保存
→ 语法/语义校验
→ 上传 rules.yaml 到 OSS
→ 写 leaudit_rule_versions
→ 发布切换 current_version_id
【C】触发评查
→ 创建 leaudit_audit_runs
→ 锁定 document_file_id + rule_version_id
→ 分发任务
【D】bridge 执行
→ 下载文档到本地临时文件
→ 下载规则到本地临时 YAML
→ OCR
→ Extract
→ Evaluate
→ Rescue(如启用)
【E】结果写回
→ artifacts / field_results / rule_results / metrics / errors
→ 更新 audit_runs 汇总
【F】前端查询
→ 查 run 状态
→ 查规则结果
→ 查字段结果
→ 展示最终评查报告
```
只有 A~F 都闭环,才能说“跑通整个流程”。
---
## 5. 建议的实施优先级
## P0:先跑通最小闭环
目标:先让“上传文档 -> 触发评查 -> OCR/抽取/评查 -> 结果查询”最小可用。
### P0 需要完成
- 上传文件能落真源
- `AuditServiceImpl.Run()` 真正可触发
- 创建 `leaudit_audit_runs`
- `pipeline.run()` 真正执行
- `StorageAdapter` 明确按 `run_id` 写结果
- `GetRunStatus()` / `GetResult()` 能查到真实数据
> 注意:这一阶段甚至可以暂时继续兼容本地 `rules/`,重点先是把业务主链打通。
---
## P1:切换规则真相源到 OSS + DB
目标:让规则不再依赖本地目录作为正式来源。
### P1 需要完成
- 规则版本上传到 OSS
- `leaudit_rule_versions` 完整入库
- `leaudit_rule_type_bindings` 真正生效
- `tasks.py` / `rules_loader.py``DB -> OSS -> 本地临时 YAML`
- `_TYPE_ID_RULES_MAP` 降级为 fallback
---
## P2:开放 YAML 在线编辑能力
目标:让规则成为后台可管理资产。
### P2 需要完成
- 规则列表 / 版本历史 / YAML 内容查看
- 编辑保存
- YAML 语法校验
- DSL 语义校验
- 发布 / 回滚
- 权限与审计
---
## P3:补齐平台级工程能力
目标:让系统从“能跑”升级到“稳定可运营”。
### P3 需要完成
- Celery 多队列
- Redis 缓存与缓存失效
- 幂等控制
- 失败重试
- 规则缓存刷新
- 跨区域权限 / 审计
- run_metrics / run_errors / rescue_outcomes 全量落库
---
## 6. 一句话结论
如果目标是“跑通整个流程:上传、OCR、抽取、评查”,那么除了“把规则 YAML 放 OSS、路径放数据库”之外,还必须同时补齐:
- 上传文件真源链
- 评查 run 主线
- 规则控制面
- 规则文件上传/下载/校验链
- 正式执行链
- 结果落库与结果查询链
- 任务、缓存、幂等、审计等基础设施能力
所以这不是一个单点功能,而是一条完整平台链路的闭环建设。
---
## 7. 当前项目的核心推进建议
按实际落地顺序,建议当前项目这样推进:
1. 先打通“上传 -> 触发评查 -> run -> 结果查询”最小链路
2. 再把规则解析从本地目录切到 `OSS + DB`
3. 然后再做 YAML 在线编辑、发布、回滚
4. 最后补缓存、审计、并发、重试等平台级能力
这样做的好处是:
- 可以尽快验证主业务链是否真实可用
- 不会在规则后台还没落地时就把复杂度全部堆上来
- 能明确区分“能跑通”和“能运营”的阶段目标