# 迁移前后业务语义对照分析 ## 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 条规则语义按当前平台规范补齐回来。**