docs: reorganize backend project documentation
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
# 规则编辑与规则链路文档导航
|
||||
|
||||
> 最后整理:2026-05-04
|
||||
> 说明:本目录关注后端规则引擎、规则存储、Bridge 接入、YAML 编辑与执行链路。
|
||||
|
||||
## 阅读顺序
|
||||
|
||||
1. `docs/leaudit/README.md`
|
||||
2. `统一OSS与规则管理实施计划.md`
|
||||
3. `原生AuditCtx接入重构方案.md`
|
||||
4. 按需查看其余专项文档
|
||||
|
||||
## 文档分组
|
||||
|
||||
| 文档 | 作用 | 当前建议 |
|
||||
|------|------|----------|
|
||||
| `统一OSS与规则管理实施计划.md` | 规则链路主实施方案,含 OSS、规则管理、执行链、验收顺序 | 主参考 |
|
||||
| `原生AuditCtx接入重构方案.md` | 新平台如何接入原生 `AuditCtx` 流程 | 主参考 |
|
||||
|
||||
## 本次归并
|
||||
|
||||
- `开发任务拆解清单.md` 的执行清单已并入 `统一OSS与规则管理实施计划.md`
|
||||
- `跑通全流程所需准备项.md` 的能力清单已并入 `统一OSS与规则管理实施计划.md`
|
||||
- `为什么仍然需要Bridge适配层.md` 的边界说明已并入 `原生AuditCtx接入重构方案.md`
|
||||
- `yaml规则在线编辑设计.md` 的真相源设计已并入 `统一OSS与规则管理实施计划.md`
|
||||
- `worker并发执行改造方案.md` 的任务编排与队列口径已并入 `统一OSS与规则管理实施计划.md`
|
||||
- 当前如果只想知道“先做什么、后做什么、验收到哪里”,优先看 `统一OSS与规则管理实施计划.md`
|
||||
|
||||
## 和 `docs/leaudit/` 的分工
|
||||
|
||||
- `docs/leaudit/`:稳定架构、表结构、处理流水线
|
||||
- `docs/规则编辑/`:规则管理、Bridge 接入、落地实施顺序
|
||||
- 当前阶段状态与真实阻塞统一回写 `docs/HANDOFF.md`
|
||||
|
||||
## 维护规则
|
||||
|
||||
- 这里的文档以“规则链路后端实现”视角为主
|
||||
- 如果内容已经变成当前正式现状,应同步回写 `docs/HANDOFF.md`
|
||||
- 临时推演稿如果已经完成使命,应合并进正式文档后删除
|
||||
@@ -1,336 +0,0 @@
|
||||
原生 LeAudit Worker 并发执行改造方案
|
||||
|
||||
这份文档不是纯方案稿,而是“已经落地到哪一步 + 当前系统为什么这么设计 + 后续接手时要看什么”的实施记录。后面如果忘了这套东西是干什么的,先看这份。
|
||||
|
||||
目标
|
||||
|
||||
- 把上传触发评查从 HTTP 同步执行切到 `Run -> dispatch -> worker`
|
||||
- 平台侧只做:
|
||||
- 上传入库
|
||||
- OSS / 规则文件解析
|
||||
- run 状态编排
|
||||
- 结果持久化
|
||||
- 原生 `/home/wren-dev/Porject/leaudit/src/leaudit` 继续负责:
|
||||
- `AuditCtx`
|
||||
- `AuditService.audit(ctx)`
|
||||
- OCR / extract / evaluate / rescue 主流程
|
||||
|
||||
为什么要改成 worker
|
||||
|
||||
- HTTP 请求里同步跑全链路会把 OCR、LLM、VLM、补救流程都塞进 Web 线程
|
||||
- 后续存在并发上传、多文档批量处理、多 worker 扩容场景
|
||||
- 同步模式下容易遇到:
|
||||
- 请求超时
|
||||
- 事件循环混用
|
||||
- 多线程/多请求互相阻塞
|
||||
- 状态不可追踪
|
||||
- 改造成 worker 后,API 只负责“受理 + 排队”,重任务交给 Celery worker 进程
|
||||
|
||||
当前已落地
|
||||
|
||||
- `fastapi_admin/celery_app.py`
|
||||
- 新增 Celery app,broker/backend 复用当前 Redis
|
||||
- `fastapi_admin/config/_settings.py`
|
||||
- 新增 worker 队列、并发、超时、OCR 视觉并发、signature probe 限时等配置
|
||||
- `fastapi_admin/config/__init__.pyi`
|
||||
- 暴露新的 LEAUDIT 配置项
|
||||
- `app.toml`
|
||||
- 正式加入 `[LEAUDIT]` worker/并发相关配置
|
||||
- 补齐 `[OCR].BASE_URL`
|
||||
- `fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py`
|
||||
- `Run()` 改为只创建 `leaudit_audit_runs` 并投递任务
|
||||
- 相同文档已有活动 run 时直接复用,避免重复创建
|
||||
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py`
|
||||
- 改为 `runId` 驱动,而不是把整份文件内容直接塞到同步调用链
|
||||
- 增加 Celery task 入口
|
||||
- 增加 run 抢占,避免重复消费
|
||||
- 增加队列路由
|
||||
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/client_factory.py`
|
||||
- OCR client 读取平台配置,避免 `base_url is required`
|
||||
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/auditServiceFactory.py`
|
||||
- 原生服务装配读取平台并发配置
|
||||
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py`
|
||||
- 修复原生 `FieldValue` 新旧结构兼容
|
||||
- 修复 JSONB 字段写库序列化
|
||||
- `scripts/start_worker.sh`
|
||||
- worker 启动脚本改为动态读取配置
|
||||
- worker nodename 改成唯一,避免 Celery `DuplicateNodenameWarning`
|
||||
- `docs/规则编辑/worker并发执行改造方案.md`
|
||||
- 记录当前这套机制,避免后续自己忘记
|
||||
|
||||
执行链路
|
||||
|
||||
1. `POST /api/upload`
|
||||
2. `DocumentServiceImpl.Upload()` 写 `leaudit_documents / leaudit_document_files`
|
||||
3. 原始文件上传 OSS
|
||||
4. `AuditServiceImpl.Run()` 创建 `leaudit_audit_runs`
|
||||
5. `dispatch_leaudit_task(run_id)` 投递 Celery
|
||||
6. worker 消费 `leaudit.process_document`
|
||||
7. worker 按 `runId` 查库,取:
|
||||
- 文档
|
||||
- 活跃文件版本
|
||||
- 当前规则版本
|
||||
- 规则 OSS 地址
|
||||
8. bridge 下载 OSS 文件 / 规则文件到本地临时文件
|
||||
9. `NativeRunner` 构建原生 `AuditCtx` 并调用原生 audit
|
||||
10. `StorageAdapter` 把结果写回 `leaudit_*`
|
||||
|
||||
当前实现涉及的关键文件
|
||||
|
||||
- 上传入口
|
||||
- `fastapi_modules/fastapi_leaudit/controllers/documentController.py`
|
||||
- `fastapi_modules/fastapi_leaudit/services/documentService.py`
|
||||
- `fastapi_modules/fastapi_leaudit/services/impl/documentServiceImpl.py`
|
||||
- bridge 层
|
||||
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/fileSourceResolver.py`
|
||||
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/ruleVersionResolver.py`
|
||||
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/auditCtxBuilder.py`
|
||||
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/auditServiceFactory.py`
|
||||
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/nativeRunner.py`
|
||||
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py`
|
||||
- `fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py`
|
||||
- worker 与配置
|
||||
- `fastapi_admin/celery_app.py`
|
||||
- `fastapi_admin/config/_settings.py`
|
||||
- `app.toml`
|
||||
- `scripts/start_worker.sh`
|
||||
|
||||
并发配置正式化
|
||||
|
||||
- `LEAUDIT_LLM_MAX_CONCURRENCY`
|
||||
- 单文档内 LLM 全局信号量上限
|
||||
- `LEAUDIT_VLM_MAX_CONCURRENCY`
|
||||
- 单文档内 VLM 主流程上限
|
||||
- `LEAUDIT_OCR_VLM_CONCURRENCY`
|
||||
- OCR 视觉增强 / 印章分类阶段的 VLM 并发上限
|
||||
- `LEAUDIT_SIGNATURE_PROBE_CONCURRENCY`
|
||||
- DOCX 签名候选区域补探测并发上限
|
||||
- `LEAUDIT_SIGNATURE_PROBE_TIMEOUT`
|
||||
- 单次签名 probe 的 VLM 超时,避免长时间卡住 OCR 尾部
|
||||
- `LEAUDIT_WORKER_CONCURRENCY`
|
||||
- 单 worker 进程可并发执行的任务数
|
||||
- `LEAUDIT_WORKER_QUEUE_URGENT`
|
||||
- 前端上传中的“紧急”队列
|
||||
- `LEAUDIT_WORKER_QUEUE_NORMAL`
|
||||
- 前端上传中的“普通”队列
|
||||
- `LEAUDIT_TASK_SOFT_TIME_LIMIT`
|
||||
- Celery 软超时
|
||||
- `LEAUDIT_TASK_TIME_LIMIT`
|
||||
- Celery 硬超时
|
||||
- `LEAUDIT_RUN_LOCK_SECONDS`
|
||||
- 为后续升级“租约锁”预留的锁超时配置
|
||||
|
||||
当前 `app.toml` 基线
|
||||
|
||||
```toml
|
||||
[OCR]
|
||||
BASE_URL = "http://i-2.gpushare.com:44112/"
|
||||
|
||||
[LEAUDIT]
|
||||
LLM_MAX_CONCURRENCY = 5
|
||||
VLM_MAX_CONCURRENCY = 3
|
||||
OCR_VLM_CONCURRENCY = 3
|
||||
SIGNATURE_PROBE_CONCURRENCY = 2
|
||||
SIGNATURE_PROBE_TIMEOUT = 20
|
||||
WORKER_QUEUE_URGENT = "leaudit.urgent"
|
||||
WORKER_QUEUE_NORMAL = "leaudit.normal"
|
||||
WORKER_CONCURRENCY = 2
|
||||
RUN_LOCK_SECONDS = 1800
|
||||
TASK_SOFT_TIME_LIMIT = 3300
|
||||
TASK_TIME_LIMIT = 3600
|
||||
```
|
||||
|
||||
当前队列路由策略
|
||||
|
||||
- 前端上传 `speed=urgent` -> `leaudit.urgent`
|
||||
- 前端上传 `speed=normal` -> `leaudit.normal`
|
||||
- `/audit/run` 也支持 `speed`
|
||||
- 未识别值默认归到 `normal`
|
||||
|
||||
接口收口
|
||||
|
||||
- 上传接口:`POST /upload`
|
||||
- 入参:
|
||||
- `file`
|
||||
- `typeId` / `typeCode`
|
||||
- `region`
|
||||
- `fileRole`
|
||||
- `createdBy`
|
||||
- `autoRun`
|
||||
- `speed=normal|urgent`
|
||||
- 已去掉旧系统 `bizDocumentId` 输入
|
||||
- 上传返回:
|
||||
- `documentId`
|
||||
- `internalDocumentNo`
|
||||
- `fileId`
|
||||
- `typeId`
|
||||
- `typeCode`
|
||||
- `region`
|
||||
- `fileName`
|
||||
- `ossUrl`
|
||||
- `speed`
|
||||
- `processingStatus`
|
||||
- `autoRunTriggered`
|
||||
- `run`
|
||||
- 手动触发:`POST /audit/run`
|
||||
- 支持 `speed=normal|urgent`
|
||||
- 状态查询:
|
||||
- `GET /audit/run/{runId}`
|
||||
- 结果查询:
|
||||
- `GET /audit/result/{runId}`
|
||||
|
||||
当前业务收敛结论
|
||||
|
||||
- 不再继续扩 `high/default/batch` 三层方案
|
||||
- 当前真实业务只有前端上传,并且只有“紧急 / 普通”两档速度需求
|
||||
- 所以 worker 体系正式收敛成两级模型:
|
||||
- `urgent`
|
||||
- `normal`
|
||||
- 这样既满足优先级需求,也避免过度设计
|
||||
|
||||
状态流转
|
||||
|
||||
- 新建 run
|
||||
- `status=queued`
|
||||
- `phase=dispatch`
|
||||
- worker 抢占成功
|
||||
- `status=running`
|
||||
- `phase=prepare`
|
||||
- 原生流程推进中
|
||||
- `phase` 会继续流转为 OCR / extraction / evaluation / rescue / persist 等阶段
|
||||
- 执行成功
|
||||
- `status=completed`
|
||||
- `result_status` 由 bridge 汇总写回
|
||||
- 执行失败
|
||||
- `status=failed`
|
||||
- `phase` 停在失败发生阶段
|
||||
- `leaudit_run_errors` 记录错误明细
|
||||
|
||||
避免重复消费
|
||||
|
||||
- API 触发 `Run()` 时:
|
||||
- 若同一文档已有 `queued/running/retrying` 的 run,且 `Force=False`
|
||||
- 直接返回当前活动 run,不重复创建
|
||||
- worker 开始执行前:
|
||||
- 先按 run 状态执行原子抢占
|
||||
- 仅允许 `status in ('queued', 'pending', 'retrying')` 的 run 进入执行
|
||||
- 抢占失败时:
|
||||
- 当前 worker 直接跳过
|
||||
- 返回 `already_claimed`
|
||||
|
||||
当前表语义
|
||||
|
||||
- `leaudit_documents`
|
||||
- 平台内部文档主表
|
||||
- 一次前端上传会创建一条新的 document
|
||||
- 不再依赖旧系统 `documents.id`
|
||||
- `biz_document_id` 仅作为内部追踪号保留,避免立刻改库
|
||||
- `leaudit_document_files`
|
||||
- 具体上传文件记录
|
||||
- 保存文件名、后缀、MIME、SHA256、OSS 地址等文件级信息
|
||||
- 当前仍保留单独文件表,为后续是否合表留余地
|
||||
|
||||
已踩过并修掉的坑
|
||||
|
||||
- 事件循环混用
|
||||
- 同步 HTTP 链路里直接执行原生异步流程,容易出现 `Future attached to a different loop`
|
||||
- 现在改成 worker 独立进程执行,HTTP 只排队
|
||||
- OCR base_url 缺失
|
||||
- 原因是平台 bridge 没把 `[OCR].BASE_URL` 正确喂给原生 client
|
||||
- 现已在 `app.toml` 和 `client_factory.py` 补齐
|
||||
- 原生 `FieldValue` 结构变化
|
||||
- 新版本 `FieldValue` 不一定有 `.position`
|
||||
- `storage_adapter.py` 已改为兼容:
|
||||
- 优先读 `position`
|
||||
- 没有时回退到 `metadata.match_position / bbox / page_num`
|
||||
- asyncpg + JSONB 序列化
|
||||
- 不能把 `list/dict` 直接按字符串列方式塞给 `CAST(:x AS JSONB)`
|
||||
- 需要先 `json.dumps(..., ensure_ascii=False)` 再入库
|
||||
- 当前已在这些路径处理:
|
||||
- `leaudit_rule_results.stages`
|
||||
- `leaudit_rule_results.extracted_fields`
|
||||
- `leaudit_rule_results.field_positions`
|
||||
- `leaudit_rule_results.remediation`
|
||||
- `leaudit_rule_results.rule_meta`
|
||||
- `leaudit_rescue_outcomes.payload`
|
||||
|
||||
当前运行现状
|
||||
|
||||
- `POST /api/upload` 已经可以快速返回 `queued`
|
||||
- worker 已能真正执行到:
|
||||
- OCR
|
||||
- extraction
|
||||
- evaluation
|
||||
- rescue
|
||||
- 已验证真实样本端到端成功:
|
||||
- `run_id=10`
|
||||
- `document_id=9`
|
||||
- `phase=executed`
|
||||
- `24 passed / 4 failed / 0 skipped`
|
||||
- 当前主要耗时瓶颈明确在 OCR 阶段
|
||||
- 一次验证中:
|
||||
- `ocr=277.79s`
|
||||
- `extraction=13.65s`
|
||||
- `evaluation=11.81s`
|
||||
- `total=303.25s`
|
||||
- 已针对 OCR 长尾补第一轮治理:
|
||||
- DOCX `signature probe` 增加单独超时
|
||||
- DOCX `signature probe` 增加并发限制
|
||||
- 避免某个候选框失败时串行拖住整个尾段
|
||||
- 如果代码刚修过但日志仍报旧错,第一怀疑项不是代码没改,而是 worker 进程还没重启,仍在跑旧代码
|
||||
- worker 日志会明确打印:
|
||||
- `run_id=xx 已投递到 worker 队列: queue=..., speed=...`
|
||||
- `run_id=xx worker开始执行: queue=..., speed=..., filename=...`
|
||||
|
||||
启动方式
|
||||
|
||||
后端 API:
|
||||
|
||||
```bash
|
||||
.venv/bin/python run.py
|
||||
```
|
||||
|
||||
worker:
|
||||
|
||||
```bash
|
||||
bash scripts/start_worker.sh
|
||||
```
|
||||
|
||||
脚本会自动读取:
|
||||
|
||||
- `LEAUDIT_WORKER_CONCURRENCY`
|
||||
- `LEAUDIT_WORKER_QUEUE_URGENT`
|
||||
- `LEAUDIT_WORKER_QUEUE_NORMAL`
|
||||
|
||||
并拼成:
|
||||
|
||||
```bash
|
||||
celery -A fastapi_admin.celery_app:celery_app worker \
|
||||
-Q leaudit.urgent,leaudit.normal \
|
||||
--concurrency=2
|
||||
```
|
||||
|
||||
同时 worker nodename 会带主机名和进程号,避免多个 worker 使用同名节点。
|
||||
|
||||
联调时的最小操作顺序
|
||||
|
||||
1. 启动 API:`.venv/bin/python run.py`
|
||||
2. 启动 worker:`bash scripts/start_worker.sh`
|
||||
3. 调用上传接口,确认返回 `processingStatus=queued`
|
||||
4. 看 worker 日志是否出现:
|
||||
- 抢占 run
|
||||
- OCR result saved
|
||||
- Extraction result saved
|
||||
- Evaluation results saved
|
||||
- finalize run
|
||||
5. 如果日志还是旧报错,先重启 worker 再测一次
|
||||
|
||||
后续明确待办
|
||||
|
||||
- 给 run 抢占补上真正的租约锁字段:
|
||||
- `worker_id`
|
||||
- `lock_expires_at`
|
||||
- `attempt_count`
|
||||
- 如果后续紧急任务量上来,再考虑把 `urgent` 单独拆成专属 worker
|
||||
- 补 `GET /run/{id}/status` 或前端轮询说明
|
||||
- 评估 OCR 阶段是否继续拆更细粒度并发,但前提是先确认外部 OCR / VLM 服务的限流上限
|
||||
@@ -1,306 +0,0 @@
|
||||
# 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 加载方式
|
||||
|
||||
又能保证:
|
||||
|
||||
- 在线编辑方便
|
||||
- 版本管理清晰
|
||||
- 发布回滚简单
|
||||
- 多实例一致
|
||||
- 运行结果可审计可追溯
|
||||
|
||||
这是当前项目向“规则可运营平台”演进时最合理的方案。
|
||||
@@ -1,296 +0,0 @@
|
||||
# 为什么仍然需要 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/`**
|
||||
|
||||
这才是当前项目最稳妥、最可维护的长期方案。
|
||||
@@ -579,14 +579,50 @@ AuditServiceImpl.Run()
|
||||
|
||||
---
|
||||
|
||||
## 10.5 为什么仍然需要 Bridge 适配层
|
||||
|
||||
即使当前方向已经明确为:
|
||||
|
||||
- 使用原生 `AuditCtx`
|
||||
- 使用原生 `AuditService.audit(ctx)`
|
||||
- 不再由平台自己手写 7 阶段主流程编排
|
||||
|
||||
也仍然必须保留 Bridge,原因是:
|
||||
|
||||
1. 平台世界和引擎世界不是同一套对象
|
||||
- 平台关心:`document_id`、`rule_set_id`、`rule_version_id`、`oss_url`、`run_id`
|
||||
- 引擎关心:`file_path`、`RulesFile`、`AuditServices`、`AuditConfig`、`AuditCtx`
|
||||
2. 平台层还要处理 OSS 下载、run 状态、结果落库、前端查询
|
||||
3. 如果 Controller / Service 直接 import `leaudit.services.*`,边界会失守,后续升级会把改动扩散到整个平台
|
||||
|
||||
因此正确结构不是:
|
||||
|
||||
```text
|
||||
平台层 -> 直接调用 leaudit AuditCtx / AuditService
|
||||
```
|
||||
|
||||
而是:
|
||||
|
||||
```text
|
||||
平台层 -> Bridge 适配层 -> leaudit AuditCtx / AuditService
|
||||
```
|
||||
|
||||
Bridge 的固定职责应保持为:
|
||||
|
||||
- 输入适配:文档真源、规则版本、OSS 下载、本地临时路径
|
||||
- 运行装配:`AuditServices`、`AuditConfig`、`AuditCtx`
|
||||
- 输出适配:把 `ctx` 结果写回 `leaudit_*` 表
|
||||
- 边界保护:只有 `leaudit_bridge/` 感知原生 `leaudit` 类型
|
||||
|
||||
所以这次重构真正要取消的,是“平台自己编排评查主流程”,不是 Bridge 本身。
|
||||
|
||||
---
|
||||
|
||||
## 11. 与现有文档的关系
|
||||
|
||||
本方案是以下文档的进一步收敛:
|
||||
|
||||
- `docs/规则编辑/yaml规则在线编辑设计.md`
|
||||
- `docs/规则编辑/跑通全流程所需准备项.md`
|
||||
- `docs/规则编辑/开发任务拆解清单.md`
|
||||
- `docs/规则编辑/为什么仍然需要Bridge适配层.md`
|
||||
- `docs/规则编辑/统一OSS与规则管理实施计划.md`
|
||||
|
||||
它的核心新增点是:
|
||||
|
||||
|
||||
@@ -1,711 +0,0 @@
|
||||
# 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-1:Celery / 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 + 校验/发布/回滚`
|
||||
|
||||
也就是说:
|
||||
|
||||
- **第一优先级是评查主链**
|
||||
- **第二优先级是规则执行链**
|
||||
- **第三优先级才是规则编辑后台**
|
||||
|
||||
这样开发成本最低,验证路径也最清晰。
|
||||
@@ -1,3 +1,10 @@
|
||||
# LeAudit 规则链路实施总方案
|
||||
|
||||
> 说明:这份文档是当前 `docs/规则编辑/` 目录的主实施文档。
|
||||
> 原 `开发任务拆解清单.md` 的任务顺序、文件清单与验收口径,后续统一以本文件为准。
|
||||
> 原 `跑通全流程所需准备项.md` 的能力清单,也统一归并到本文件维护。
|
||||
> 原 `yaml规则在线编辑设计.md` 与 `worker并发执行改造方案.md` 的核心口径,也统一归并到本文件维护。
|
||||
|
||||
## 背景
|
||||
|
||||
当前 `leaudit-platform` 已经完成第一阶段原生执行链接入:
|
||||
|
||||
@@ -1,520 +0,0 @@
|
||||
# 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 发到线上。
|
||||
|
||||
### 至少需要两层校验
|
||||
|
||||
#### 1)YAML 语法校验
|
||||
|
||||
- 缩进是否正确
|
||||
- 结构是否可解析
|
||||
- 基本字段是否存在
|
||||
|
||||
#### 2)LeAudit 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` 与 `AuditServiceImpl.GetResult()` 已明显向前推进,但还有工程缺口:
|
||||
|
||||
- 仍保留少量“按 document_id 找最新 run”的兼容路径
|
||||
- 结果查询虽已能查规则/字段/errors/rescue/metrics/artifacts,但还缺前端最终展示口径梳理
|
||||
|
||||
见:
|
||||
|
||||
- `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. 最后补缓存、审计、并发、重试等平台级能力
|
||||
|
||||
这样做的好处是:
|
||||
|
||||
- 可以尽快验证主业务链是否真实可用
|
||||
- 不会在规则后台还没落地时就把复杂度全部堆上来
|
||||
- 能明确区分“能跑通”和“能运营”的阶段目标
|
||||
Reference in New Issue
Block a user