Files
leaudit-platform-backend/docs/内部公文模块/迁移前后业务语义对照分析.md

898 lines
23 KiB
Markdown

# 迁移前后业务语义对照分析
## 1. 文档目的
本文档只做一件事:
- 把迁移前项目 `/home/wren-dev/Porject/govdoc-audit` 的**真实业务语义**与当前 `leaudit-platform``govdoc` 模块的**平台化实现语义**对齐清楚
本文档的目标不是要求“旧项目代码逐行照搬”,而是明确以下边界:
- **业务逻辑不改**
- **代码实现方式可以按当前项目规范重构**
- **平台化接入可以改承载层,但不能改业务语义**
换句话说:
- 可以从旧项目的 `audit_id` 单体模型迁移为当前平台的 `document + run` 模型
- 可以从本地文件持久化迁移为 `DB + OSS + worker`
- 可以从独立 FastAPI 项目迁移为 `leaudit-platform` 的模块化结构
但不能把“公文格式审查业务”改造成另一套语义。
---
## 2. 结论先行
本次迁移应遵守的总原则是:
> **保持业务语义一致,允许技术实现重构。**
具体解释如下:
- **不要求旧项目的目录结构、表结构、路由写法、同步/异步实现方式一字不改**
- **要求用户视角的业务流程、结果语义、报告语义、规则语义、页面交互语义保持一致**
- **要求新增实现遵守当前 `leaudit-platform` 的代码规范、分层方式、权限体系、存储方式、路由组织方式**
因此,后续所有补齐和修复都必须先回答一个问题:
> 这是“实现方式变化”,还是“业务语义变化”?
只有前者允许直接重构;后者必须先明确是否获得业务确认。
---
## 2.1 必须继承什么,不继承什么
为了避免把“参考旧项目”误解成“照搬旧代码”,这里把边界明确写死。
### 必须继承的是业务语义
必须继承的,是旧项目已经成立并已对外生效的业务语义,包括:
- 审查对象是什么
- 审查链路顺序是什么
- 规则怎么定义、怎么解释
- 结果对象由哪些部分构成
- `pass / fail / skipped` 三分态语义
- 报告产物有哪些
- 详情页交付什么能力
- 规则版本如何追溯
也就是说,必须继承的是:
- **业务口径**
- **结果口径**
- **规则口径**
- **交付口径**
### 不必须继承的是旧实现
不必须继承的,是旧项目为了落地这些业务语义所采用的具体技术实现,包括:
- 旧目录结构
- 旧项目模块拆分
- 旧接口路径
- 旧表结构
- 旧本地文件存储方式
- 旧同步执行方式
- 旧前端工程组织方式
- 旧缓存或本地路径约定
也就是说,不需要继承的是:
- **代码写法**
- **工程结构**
- **部署方式**
- **存储承载方式**
### 正确理解
因此,“以旧项目为基线”这句话,准确含义应是:
> **以旧项目作为业务语义基线,而不是作为代码实现模板。**
后续所有实施动作,都应按下面这个标准判断:
- 如果是在恢复旧业务语义,可以推进
- 如果是在复制旧实现细节,不应作为目标
这也是后续为什么应说:
- **按旧业务语义补齐**
而不应简单说:
- **补齐到旧项目**
---
## 3. 迁移前项目的业务基准
## 3.1 业务定位
迁移前项目 `govdoc-audit` 的本质不是普通文档管理,也不是审批流系统,而是:
- **内部公文格式审查系统**
其目标是:
- 上传一份公文文件
- 对公文格式、结构、文种、实体、规则进行审查
- 产出一份完整审查结果和对应报告产物
因此它的核心不是“保存文件”,而是:
- **完成一次完整审查并交付审查结果**
---
## 3.2 核心业务对象
旧项目的核心业务对象是:
- `AuditResult`
它聚合了以下业务结果:
- `document`
- `summary`
- `findings`
- `checked_rules`
- `entities`
- `structure`
- `outline`
这说明旧项目的业务中心是:
- **一次完整审查结果**
而不是:
- 单纯的文档主档
- 单纯的异步任务记录
- 单纯的某次规则执行流水
当前平台即使改为 `document + run` 模型,也必须保证对外仍能还原这一语义。
---
## 3.3 旧项目固定主链路
旧项目的审查链路顺序是明确且稳定的:
1. 上传文件
2. 统一转换为 `canonical.docx`
3. 解析文档结构 `parse_docx`
4. 角色标注 `role_tag`
5. 加载规则 `load_rules`
6. 先做结构化实体构建 `build_entities`
7. 对缺失实体做差量 LLM 抽取
8. 执行规则评估 `evaluate_rules`
9. 生成完整 `AuditResult`
10. 生成报告产物
11. 持久化结果
这条链路可以按当前项目规范拆层,但业务顺序不能被破坏。
---
## 3.4 旧项目的结果语义
旧项目对结果有几条明确语义:
- `summary` 是结果总览,不是从前端临时拼装出来的派生值
- `findings` 是问题清单,是详情页审查视图的主数据
- `checked_rules` 是规则级结果清单,且必须保留 `pass / fail / skipped`
- `entities` 不只是调试数据,而是前端“实体”标签页正式展示内容
- `structure``outline` 是正式交付数据,不是可有可无的附加信息
这意味着迁移后不能只保证“能查到一部分结果”,而必须保证:
- **前端详情页所依赖的一整组业务结果是完整成立的**
---
## 3.5 旧项目的规则语义
旧项目规则体系虽然技术上只是单个 YAML 文件,但业务语义是完整的:
- 有一个当前生效规则集
- 规则集有明确元数据:`type_id / version / source / description`
- 每次审查结果都知道自己使用的是哪一版规则
- 前端可以查看当前规则列表和单条规则详情
因此迁移到平台后:
- 可以不再沿用旧项目“本地单 YAML + 本地缓存”的实现方式
- 但必须保留“当前生效规则集 + 规则版本可追溯 + 规则详情可查看”的业务语义
---
## 3.6 旧项目的报告语义
旧项目一次审查完成后,正式产物包括:
- 原始文件 `original`
- 标准化文档 `canonical.docx`
- 审查结果 `result.json`
- 批注文档 `annotated.docx`
- 报告页面 `report.html`
- 段落视图 `paragraphs.html`
这里最关键的是:
- **报告产物不是附属功能,而是审查业务结果的一部分**
旧项目里,详情页默认就可以使用:
- 原始文件下载
- 批注 DOCX 下载
- 报告 HTML 打开
- 段落视图联动预览
因此迁移到平台后,不能接受以下状态长期存在:
- run 已完成,但报告产物为空
- 前端按钮可点,但实际上无真实产物
- 详情页只展示结构化 JSON 结果,不恢复正式报告闭环
---
## 3.7 旧项目的页面交互语义
旧项目前端已形成稳定交互语义:
- 列表页是主入口
- 上传成功后直接进入详情页
- 详情页是完整审查结果页
- `报告 HTML / 批注 DOCX / 原始文件 / 段落预览` 是四种不同能力
- 问题列表与段落视图双向联动
- `问题 / 已通过 / 已跳过` 是三分态展示,不可压扁为两态
- 详情页 `review / structure / outline / entities` 是正式功能页签
迁移时页面风格、代码写法、路由框架可以变化,但交互语义不能被弱化。
---
## 4. 当前平台允许变化的实现层
以下变化属于**承载层重构**,原则上允许:
## 4.1 对象模型变化
旧项目:
- `audit_id` 是单一业务主键
当前平台可改为:
- `document` 作为文档主档
- `run` 作为执行记录
但要求:
- 对外仍然要能还原“某份文档当前/某次完整审查结果”
- 前端详情页不能被迫暴露底层拆分复杂性
---
## 4.2 存储方式变化
旧项目:
- 本地目录存文件
- SQLite/本地 DB 存列表摘要
当前平台可改为:
- OSS 存原文和报告产物
- PostgreSQL 存文档、run、规则结果、产物索引
但要求:
- 存储迁移不能导致产物语义丢失
- 列表和详情所需的结果字段必须仍然可稳定读取
---
## 4.3 执行方式变化
旧项目:
- 上传后同步或准同步返回完整结果
当前平台可改为:
- 上传后创建 `run`
- 通过 Celery/worker 异步执行
但要求:
- 最终完成后必须补齐旧项目那套完整审查结果语义
- 不能因为改成异步,就把“正式报告产物”降级成以后再说的可选项
---
## 4.4 代码组织变化
旧项目:
- 独立项目,接口、存储、规则、前端相对直连
当前平台可改为:
- `controller / service / bridge / engine / model / frontend api adapter`
但要求:
- 新实现必须遵守当前项目开发规范
- 不能为了“像旧项目”而破坏当前平台已有规范
换句话说:
- **保业务,不保旧代码写法**
---
## 4.5 路由变化
旧项目:
- `/audit`
- `/audits`
- `/rules`
当前平台可改为:
- `/govdoc/documents`
- `/govdoc/runs`
- `/govdoc/rules`
但要求:
- API 适配层必须把旧前端依赖的业务语义重新拼装出来
- 不能让前端为了适应后端重构而失去旧业务能力
---
## 5. 当前平台必须保持不变的业务语义
以下内容视为迁移边界,后续不得随意更改。
## 5.1 审查本质不变
`govdoc` 仍然是:
- **内部公文格式审查模块**
不是:
- 流程审批模块
- 纯文档归档模块
- 单纯的规则管理模块
---
## 5.2 结果对象语义不变
即便底层是 `document + run`,对外仍必须稳定提供:
- `summary`
- `findings`
- `checked_rules`
- `entities`
- `structure`
- `outline`
这些必须被视为同一份审查结果的正式组成部分。
---
## 5.3 内置实体语义不变
以下 8 个内置实体语义必须保留:
- `title`
- `doc_number`
- `recipient`
- `date`
- `signature`
- `attachments`
- `wenzhong`
- `issuer`
迁移后可以调整存储位置和实现方式,但不能弱化为“可有可无”。
---
## 5.4 评分语义不变
评分规则保持:
- `error` 每条扣 10
- `warning` 每条扣 3
- 最低 0
列表状态分段保持:
- `pass >= 90`
- `warning 70-89`
- `fail < 70`
这既影响后端汇总,也影响前端筛选和颜色语义。
---
## 5.5 规则状态语义不变
`checked_rules` 必须保留:
- `pass`
- `fail`
- `skipped`
不能做以下简化:
-`skipped` 并入 `fail`
- 只保留问题规则,不保留通过/跳过规则
---
## 5.6 报告产物语义不变
迁移后必须恢复并保持以下正式能力:
- 原始文件下载
- 批注 DOCX 下载
- 报告 HTML 打开
- 段落视图联动预览
如果某项能力在页面上出现按钮或入口,就必须对应真实可用的后端产物。
---
## 5.7 规则版本追溯语义不变
每次审查必须知道:
- 使用了哪套规则
- 使用了哪一版规则
旧项目是 `ruleset_id / ruleset_version`,新平台可以改成平台自己的规则版本对象,但业务追溯语义不能丢。
---
## 5.8 页面交互语义不变
必须保留:
- 上传成功后直接进入详情
- 列表作为主入口
- 列表可查看、导出、删除
- 详情页具备完整结果展示
- 问题与段落视图双向联动
- 详情页保留 `review / structure / outline / entities`
页面样式可以按当前项目统一,但交互语义不能被削弱。
---
## 6. 当前平台与旧项目的主要差异判断
这里不讨论代码优劣,只判断“是否偏离业务语义”。
## 6.1 已经属于等价平台化改造的部分
以下变化本身没有问题:
-`leaudit_documents` 复用文档主档
- 新增 `govdoc_runs` 记录执行历史
- 使用 worker 异步执行
- 使用 `govdoc_rule_results` 存储规则结果
- 前端通过适配层把 `document + run` 再组装成详情页结果
这些属于合理平台化改造。
---
## 6.2 已偏离旧项目业务语义的部分
以下问题不是单纯代码 bug,而是业务语义没有完全迁回来:
### 6.2.1 报告产物闭环未恢复
当前若 `run completed``annotated.docx / report.html` 没有真实产物,则已偏离旧项目“完成一次审查即交付正式报告”的业务语义。
### 6.2.2 规则版本参数未真正生效
如果接口出现了 `ruleVersionId`,但执行时仍然只走固定 YAML 路径,则不满足旧项目“当前规则集明确、结果可追溯”的业务语义,也不满足平台化后的规则治理预期。
### 6.2.3 文件能力被收缩但未做业务确认
旧项目支持 `.docx / .doc / .wps`,当前平台若只支持 `.docx`,这不一定绝对错误,但它已经是业务能力收缩,必须明确确认,不能默认当作正常迁移。
### 6.2.4 详情页结果仍依赖多接口拼接且存在缺口
旧项目详情页本质上拿到的是一份完整审查结果。当前平台如果只是“部分接口可用、部分产物缺失、部分状态不一致”,则尚未恢复旧项目业务完整性。
---
## 6.3 属于当前平台规范问题但不构成业务变更的部分
以下属于实现层改良点,不构成业务逻辑变化:
- 按当前项目规范补 service 分层
- 按当前项目规范补 schema / model / DDL
- 按当前项目规范补权限、菜单、entryModule
- 使用 OSS 而不是本地目录
- 使用 worker 而不是同步执行
- 把旧项目前端接口改成新平台 API adapter
这些都应当做,而且应该做得更规范。
---
## 7. 后续实施的硬边界
后续所有开发和修复,必须同时满足两条:
1. **业务语义对齐旧项目**
2. **代码实现遵守当前平台规范**
任何方案如果只满足其中一条,都不能视为合格迁移。
### 7.1 不能接受的方案
- 只求接口返回 200,不管结果是否构成完整审查语义
- 只把页面先点亮,不补正式报告产物
- 只保留 JSON 结果,不恢复批注 DOCX 和 HTML 报告
- 为了适配平台,擅自删除 `skipped`、实体页、结构页、大纲页等旧业务能力
- 用硬编码规则路径长期替代规则版本治理
### 7.2 可以接受的方案
- 底层对象从 `audit` 拆成 `document + run`
- 用异步 `run` 承载旧项目同步审查流程
- 用平台规则版本体系承载旧项目 `ruleset_id / ruleset_version`
- 用 OSS 索引表承载旧项目本地报告文件
- 用平台前端适配层恢复旧项目页面语义
---
## 8. 面向后续实施的判定标准
后续补齐时,建议每一项改动都按下面三个问题判断:
### 8.1 这项改动是在补实现,还是在改业务?
如果是补实现,可以继续推进。
如果是改业务,必须先业务确认。
### 8.2 这项改动是否恢复了旧项目正式能力?
例如:
- 是否恢复正式报告产物
- 是否恢复规则版本追溯
- 是否恢复详情页完整结果
### 8.3 这项改动是否符合当前项目规范?
例如:
- 是否走当前项目的 service / controller / bridge 分层
- 是否复用平台已有文档主档、权限、存储、规则治理能力
- 是否避免写出一套脱离平台的新“旧系统兼容层”
---
## 9. 结论
本次内部公文模块迁移,不应理解为:
- 旧项目代码照搬
也不应理解为:
- 只要能在当前平台里跑起来就算完成
正确理解应是:
> **旧项目负责定义业务语义,当前平台负责承载实现。**
因此后续实施必须坚持:
- **业务逻辑保持一致**
- **代码实现按当前项目规范重构**
- **平台化不等于业务降级**
在这个前提下,后续才有资格进入正式的补齐修复计划和实施排期。
---
## 10. YAML 迁移现状补充结论
这一节专门回答一个更具体的问题:
- 旧项目内部公文的 `rules.yaml` 有没有迁到当前平台
- 迁过来之后,是否符合当前平台的格式
### 10.1 先说结论
结论分三层:
1. **DSL 格式层面:已经迁过来,而且当前平台可以直接解析执行**
2. **规则内容层面:不是完整迁移,只迁了一个最小可运行规则集**
3. **规则标识层面:`type_id` 命名发生了变化,这属于语义边界,需要后续明确是否回归旧命名**
也就是说:
- 不能说“内部公文 YAML 没迁”
- 但也不能说“旧项目规则已经完整迁完”
更准确的表述是:
> **当前平台已经有一份按 `govdoc` DSL 编写、可被当前引擎真实加载执行的内部公文规则 YAML,但它只是旧项目完整规则语义的缩减版。**
---
### 10.2 当前平台与旧项目用的是同一套 govdoc DSL
旧项目规则文件:
- `/home/wren-dev/Porject/govdoc-audit/rules/govdoc_general/rules.yaml`
当前平台规则文件:
- `/home/wren-dev/Porject/leaudit-platform/rules/govdoc/govdoc_general/rules.yaml`
两边都采用同样的三段结构:
- `metadata`
- `extract`
- `rules`
并且两边 DSL schema 是同源的:
- 旧项目:`/home/wren-dev/Porject/govdoc-audit/src/govdoc_audit/dsl/schema.py`
- 当前平台:`/home/wren-dev/Porject/leaudit-platform/fastapi_modules/fastapi_leaudit/govdoc_engine/dsl/schema.py`
我已直接核对:
- `CheckType` 集合一致
- `Rule / RuleGroup / RuleSet` 结构一致
- `load_rules()` 加载方式一致
因此这里的事实不是:
- 旧项目一套 YAML
- 当前平台另一套 YAML
而是:
- **旧项目和当前平台本来就在使用同一套 `govdoc DSL`**
所以“按照我们的平台格式”这句话,正确理解应该是:
- **是否符合当前平台 `govdoc_engine` 的 DSL 格式**
而不是:
- 是否长得像合同规则那套 `leaudit DSL`
---
### 10.3 当前平台这份 YAML 已经被真实接入,不是摆设
当前平台 `govdoc` 服务里,规则文件解析路径已经明确指向:
- `rules/govdoc/govdoc_general/rules.yaml`
代码位置:
- [govdocServiceImpl.py](/home/wren-dev/Porject/leaudit-platform/fastapi_modules/fastapi_leaudit/services/impl/govdocServiceImpl.py:963)
并且我已用当前平台 loader 直接解析成功:
- `metadata.type_id = govdoc_general`
- `metadata.name = 内部公文通用规则`
- `2` 个规则组
- `6` 条规则
这说明:
- **当前平台里的内部公文 YAML 不是未接入状态**
- **它已经是当前 `govdoc` 引擎实际使用的规则源**
---
### 10.4 但规则内容不是旧项目全量迁移
旧项目规则文件统计结果:
- `8` 个规则组
- `31` 条规则
当前平台规则文件统计结果:
- `2` 个规则组
- `6` 条规则
而且两边 `rule_id` 没有重叠,说明当前平台这份 YAML 不是“把旧规则原样搬过来后删了几条”,而是:
- **重新写了一个最小规则集**
当前平台保留的 6 条规则是:
- `govdoc_title_required`
- `govdoc_doc_number_required`
- `govdoc_signature_required`
- `govdoc_date_required`
- `govdoc_wenzhong_whitelist`
- `govdoc_attachment_marker_style`
这 6 条规则只覆盖了:
- 标题是否识别
- 发文字号是否识别
- 署名是否识别
- 日期是否识别
- 文种是否合法
- 附件标记样式
它更像:
- **内部公文链路先跑通时的最小可运行审查集**
而不是:
- **旧项目完整业务规则集**
---
### 10.5 旧项目已存在、但当前平台尚未完整迁入的规则语义
旧项目那份规则 YAML 中,明确存在以下业务语义,而当前平台现有 YAML 尚未完整覆盖:
#### 10.5.1 标题类规则
- 标题文种合规性 AI 判断
- `"请求"+"请示"` 重复表述
- `"上报"+"报告"` 重复表述
- `"关于"+"对"` 介词连用
- 标题回行破词检查
- 标题字体字号检查
#### 10.5.2 发文字号规则
- 年份必须用六角括号 `〔〕`
- 顺序号前不加 `第`
- 顺序号不编虚位
#### 10.5.3 格式规则
- 主标题字体
- 一级标题字体
- 二级标题字体
- 正文字体
- 三级标题字体
- 四级标题字体
- 附件后不加冒号
- 不使用“此页无正文”
- 附件项末尾不加标点
- 附件标记字体样式
#### 10.5.4 层级序号规则
- 层级序号格式
- 二级标题换行不带句号
#### 10.5.5 标点规则
- 并列书名号/引号之间不加顿号
- 句内括号末尾不加标点
- 引号嵌套规范
#### 10.5.6 文字表述与提法规则
- 易混淆词
- 简称使用规范
- 成文日期必须用阿拉伯数字
- 成文日期不编虚位
#### 10.5.7 发文机关规则
- 发文机关署名不能用简称
- 发文机关与党务/行政文稿性质一致性检查
这些规则并不是“旧项目里某些未来能力”,而是旧项目已经写进当前正式规则集、并通过 DSL 表达出来的既有业务语义。
因此从迁移判断上讲,当前状态应定义为:
- **格式已迁**
- **规则内容仅部分迁移**
不能定义为:
- 完整迁移
---
### 10.6 当前平台 DSL 能力足够承接旧规则,不存在“格式不兼容”问题
我核对了旧项目规则里实际使用到的检查类型,包括:
- `ai`
- `attachment_marker_style`
- `confused_pair`
- `cross_role`
- `font`
- `forbid_chars`
- `forbid_phrase`
- `hierarchy`
- `punctuation`
- `regex_forbid`
- `wenzhong_whitelist`
这些检查类型都已经存在于当前平台 `govdoc_engine` 的 schema 与执行器中。
这意味着:
- 当前没完整迁入旧规则,**主要不是因为平台 DSL 不支持**
- 而是因为当前仓库只先落了一份缩减规则集
这点很重要,因为它直接限定了后续实施边界:
- 后续补齐旧规则时,原则上应优先补 YAML 内容
- 不应先假设必须重写一套新的业务逻辑
---
### 10.7 需要特别注意的边界:`type_id` 命名已变化
旧项目规则元数据:
- `metadata.type_id: govdoc.general`
当前平台规则元数据:
- `metadata.type_id: govdoc_general`
这不是格式错误,但它是一个需要明确的语义边界,因为旧项目里与规则集相关的设计、文档、测试、存储语义,大量使用的是:
- `govdoc.general`
当前平台现在改成了:
- `govdoc_general`
因此这里至少要明确一件事:
- 这是当前平台有意做的命名收敛
- 还是迁移过程中临时改写后的遗留差异
在没有进一步统一之前,当前更稳妥的结论是:
- **当前平台规则 YAML 在 DSL 格式上是合法的**
- **但其 `type_id` 与旧项目规则集标识并不完全一致**
这个差异不一定马上要改,但必须在后续实施时被明确记录,避免后面在规则版本治理、回溯、接口契约、前端展示上继续漂移。
---
### 10.8 最终判断
针对“内部公文 YAML 有没有迁移过来,是否按我们平台格式”这个问题,最终判断如下:
- **有迁过来**
- **格式上符合当前平台 `govdoc` 引擎 DSL**
- **并且已经被当前平台真实加载使用**
- **但只迁了最小可运行规则集,不等于旧项目完整规则语义已经迁完**
- **另外 `metadata.type_id``govdoc.general` 变成了 `govdoc_general`,这是一个应显式管理的命名差异**
所以后续如果要继续推进,不应再讨论“要不要重新发明一套内部公文规则格式”,而应直接进入更准确的问题:
> **在保持当前平台 `govdoc DSL` 不变的前提下,如何把旧项目内部公文 31 条规则语义按当前平台规范补齐回来。**