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

23 KiB

迁移前后业务语义对照分析

1. 文档目的

本文档只做一件事:

  • 把迁移前项目 /home/wren-dev/Porject/govdoc-audit真实业务语义与当前 leaudit-platformgovdoc 模块的平台化实现语义对齐清楚

本文档的目标不是要求“旧项目代码逐行照搬”,而是明确以下边界:

  • 业务逻辑不改
  • 代码实现方式可以按当前项目规范重构
  • 平台化接入可以改承载层,但不能改业务语义

换句话说:

  • 可以从旧项目的 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 不只是调试数据,而是前端“实体”标签页正式展示内容
  • structureoutline 是正式交付数据,不是可有可无的附加信息

这意味着迁移后不能只保证“能查到一部分结果”,而必须保证:

  • 前端详情页所依赖的一整组业务结果是完整成立的

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 completedannotated.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

代码位置:

并且我已用当前平台 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_idgovdoc.general 变成了 govdoc_general,这是一个应显式管理的命名差异

所以后续如果要继续推进,不应再讨论“要不要重新发明一套内部公文规则格式”,而应直接进入更准确的问题:

在保持当前平台 govdoc DSL 不变的前提下,如何把旧项目内部公文 31 条规则语义按当前平台规范补齐回来。