Files
leaudit-platform-backend/docs/评查点分组/评查点分组迁移执行前检查清单.md
T

10 KiB

评查点分组迁移执行前检查清单

更新时间:2026-05-03

1. 目标

本清单用于在正式执行 scripts/创建sql/migrate_rule_groups_to_doc_type_roots.sql 之前,先把当前库里的旧数据、兼容态数据和潜在冲突点查清楚。

如果希望直接执行一份只读巡检 SQL,可使用:

  • scripts/创建sql/precheck_rule_group_migration.sql

本次迁移的目标仍然是:

  • 一级分组 = 业务大类
  • 二级分组 = 具体业务类型
  • 规则集 = 挂在二级分组下
  • 入口模块 = 绑定一级分组

2. 当前风险结论

正式迁移前,必须先确认下面 4 类风险:

  1. 是否仍存在“一级直接挂具体文档类型”的旧根数据。
  2. 是否存在同一个 document_type_id 被多个二级分组同时承接的情况。
  3. 是否存在规则集同时挂在旧一级根和旧默认子级上,导致迁移后重复。
  4. document_types.entry_module_id 是否足够可靠,能支撑“先按入口模块粗分到一级业务大类”。

如果这 4 类风险没有检查清楚,不应直接跑迁移脚本。

2.1 当前已知巡检结论(2026-05-03)

基于本次实际巡检结果:

  • leaudit_document_types 共 20 条,入口归属完整
    • 合同管理:10 条
    • 案卷智能评查:10 条
  • 当前仍有 20 个旧一级根
    • 即:一级 = 具体文档类型
  • 当前已经存在 2 个新一级业务大类根
    • root.contract -> 合同
    • root.casefile -> 行政卷宗
  • 当前有 20 个默认二级分组
    • 即:二级 = 通用 / *.default
  • 当前没有发现明显冲突:
    • 没有“同一文档类型被多个二级分组重复承接”
    • 没有“同一规则集同时挂在旧一级根和默认子级”
    • 没有“二级分组未绑定规则集”

结论:

  • 当前库已经具备正式迁移的基础条件
  • 但还没有完成最后的结构补齐
  • 正式迁移前仍要先补 entry_module_id,再重跑巡检

3. 必查项

3.1 一级旧根检查

确认当前是否还有“一级 = 具体文档类型”的历史根:

SELECT
    id,
    code,
    name,
    document_type_id,
    entry_module_id,
    sort_order,
    is_enabled
FROM leaudit_evaluation_point_groups
WHERE deleted_at IS NULL
  AND COALESCE(pid, 0) = 0
  AND document_type_id IS NOT NULL
ORDER BY id;

判定原则:

  • 查出来的这些记录,都属于兼容态旧根。
  • 正式迁移后,它们不应再继续作为最终一级分组存在。

3.2 一级业务大类根检查

确认当前是否已经存在真正的业务大类根:

SELECT
    id,
    code,
    name,
    entry_module_id,
    sort_order,
    is_enabled
FROM leaudit_evaluation_point_groups
WHERE deleted_at IS NULL
  AND COALESCE(pid, 0) = 0
  AND document_type_id IS NULL
ORDER BY sort_order, id;

判定原则:

  • 正常目标结构下,这里应该看到如 合同卷宗 这类一级业务大类。
  • 如果这里为空,说明当前库还没有真正切到目标结构。

3.3 二级分组唯一性检查

确认同一个文档类型是否被多个二级分组重复承接:

SELECT
    document_type_id,
    COUNT(*) AS child_count,
    STRING_AGG(name, ' / ' ORDER BY id) AS child_names
FROM leaudit_evaluation_point_groups
WHERE deleted_at IS NULL
  AND COALESCE(pid, 0) <> 0
  AND document_type_id IS NOT NULL
GROUP BY document_type_id
HAVING COUNT(*) > 1
ORDER BY document_type_id;

判定原则:

  • 如果结果为空,说明每个文档类型目前最多只挂到一个二级分组,迁移最安全。
  • 如果结果不为空,要逐条判断:
    • 是合理的“一个文档类型拆成多个业务子类型”
    • 还是历史脏数据

3.4 旧默认子级检查

确认当前是否存在旧默认子级:

SELECT
    child.id,
    child.pid,
    parent.name AS parent_name,
    child.name,
    child.code,
    child.document_type_id
FROM leaudit_evaluation_point_groups child
JOIN leaudit_evaluation_point_groups parent
  ON parent.id = child.pid
 AND parent.deleted_at IS NULL
WHERE child.deleted_at IS NULL
  AND COALESCE(child.pid, 0) <> 0
  AND (
      child.name = '通用'
      OR child.code LIKE '%.default'
  )
ORDER BY child.id;

判定原则:

  • 这些记录多数是旧链路下的“默认子类型”兼容数据。
  • 迁移时如果它们已经被真实二级业务类型替代,应考虑把规则集迁走后再停用或清理。

3.5 规则集重复挂载检查

确认同一个文档类型下,旧一级根和默认子级是否同时挂了相同规则集:

WITH target_groups AS (
    SELECT
        g.id,
        g.document_type_id,
        g.name,
        g.code,
        CASE
            WHEN COALESCE(g.pid, 0) = 0 THEN 'old_root'
            WHEN g.name = '通用' OR g.code LIKE '%.default' THEN 'default_child'
            ELSE 'other_child'
        END AS group_kind
    FROM leaudit_evaluation_point_groups g
    WHERE g.deleted_at IS NULL
      AND g.document_type_id IS NOT NULL
)
SELECT
    tg.document_type_id,
    rgb.rule_set_id,
    COUNT(*) AS binding_count,
    STRING_AGG(tg.group_kind || ':' || tg.name, ' / ' ORDER BY tg.id) AS group_sources
FROM leaudit_rule_group_bindings rgb
JOIN target_groups tg
  ON tg.id = rgb.group_id
WHERE rgb.deleted_at IS NULL
GROUP BY tg.document_type_id, rgb.rule_set_id
HAVING COUNT(*) > 1
ORDER BY tg.document_type_id, rgb.rule_set_id;

判定原则:

  • 如果结果不为空,迁移脚本执行前要先确认是否允许去重。
  • 否则迁移后可能出现:
    • 同一规则集被重复搬到新二级分组
    • 或者旧运行汇总结果不稳定

3.6 文档类型与入口模块映射检查

确认 document_types 是否都有稳定入口归属:

SELECT
    dt.id,
    dt.code,
    dt.name,
    dt.entry_module_id,
    em.name AS entry_module_name
FROM leaudit_document_types dt
LEFT JOIN leaudit_entry_modules em
  ON em.id = dt.entry_module_id
WHERE dt.deleted_at IS NULL
ORDER BY dt.id;

重点看:

  • 是否存在 entry_module_id IS NULL
  • 是否存在入口模块已被删除、停用或名称异常
  • 是否存在“明明是合同类型却挂在卷宗入口”这类错误归属

3.7 规则集可运行性检查

迁移前需要确认二级分组绑定过去的规则集不是空壳:

SELECT
    rs.id,
    rs.rule_name,
    rs.rule_type,
    rs.current_version_id,
    rs.fallback_version_id
FROM leaudit_rule_sets rs
WHERE rs.deleted_at IS NULL
ORDER BY rs.id;

这一步建议再配合业务接口实际看:

  • 是否有可用版本

4. 正式迁移推荐执行顺序

步骤 1:先备份

必须先备份这几张表:

  • leaudit_evaluation_point_groups
  • leaudit_rule_group_bindings
  • leaudit_rule_type_bindings
  • leaudit_document_types

步骤 2:先补字段,不迁数据

先补结构层缺口:

  1. leaudit_evaluation_point_groups 增加 entry_module_id
  2. 建索引
  3. 给已有一级业务大类根补入口绑定

建议值:

  • root.contract -> entry_module_id = 1
  • root.casefile -> entry_module_id = 2

步骤 3:重新跑巡检

字段补完后,重新执行:

  • scripts/创建sql/precheck_rule_group_migration.sql

确认:

  • 一级业务大类根能正确看到入口模块字段
  • 巡检结果仍无重复承接、重复绑定、空壳规则集等问题

步骤 4:测试库执行正式迁移

再执行:

  • scripts/创建sql/migrate_rule_groups_to_business_roots.sql

说明:

  • 旧脚本 scripts/创建sql/migrate_rule_groups_to_doc_type_roots.sql 仅保留兼容历史引用
  • 不建议继续作为正式迁移脚本使用

步骤 5:迁后验证 4 个页面

必须验证:

  1. /rule-groups
  2. /files/upload
  3. /document-types/new?id=...
  4. /documents/list

5. 迁移脚本调整口径

基于当前巡检结果,正式脚本建议继续遵守:

  1. 不要再硬编码“只有合同和卷宗”
  2. 优先复用已存在业务大类根,不重复新造
  3. 一级根编码必须统一,例如继续沿用:
    • root.contract
    • root.casefile
  • 可用规则数是否大于 0

否则迁完结构后,上传仍然会失败,只是失败原因从“结构问题”变成“规则集不可运行”。

4. 执行前必须人工确认的业务映射

SQL 只能粗分,业务归属必须人工确认:

4.1 一级业务大类清单

至少要先列清:

  • 哪些文档类型归到 合同
  • 哪些文档类型归到 卷宗
  • 是否已经存在第 3 个业务大类,如 内部公文

4.2 二级业务类型命名规范

要确认:

  • 二级显示名称是否直接用 document_types.name
  • 还是需要改成更贴近业务的名称
    • 例如:处罚-一般程序
    • 而不是数据库里原始的技术名

4.3 默认子类型保留策略

需要人工确认:

  • 哪些文档类型仍保留 默认子类型(通用)
  • 哪些必须拆成多个真实二级业务类型

5. 执行顺序建议

推荐按下面顺序推进:

  1. 跑本清单中的查询 SQL,导出当前状态。
  2. 形成一份 document_type -> 一级业务大类 -> 目标二级名称 的确认表。
  3. 在测试库执行迁移脚本。
  4. 验证以下页面:
    • /rule-groups
    • /files/upload
    • /document-types/new?id=...
    • /documents/list
  5. 验证上传链路:
    • 能否正确选择子类型
    • 上传后是否命中预期规则集
    • 合同附件追加链路是否仍正常
  6. 测试通过后,再评估正式库执行窗口。

6. 当前不建议直接执行的情况

只要出现以下任一情况,都不建议直接执行迁移脚本:

  • document_types.entry_module_id 还有大量空值
  • 同一文档类型被多个旧组重复承接,但业务还没定论
  • 规则集存在大量“可用规则数 = 0”
  • 一级业务大类并不只有 合同 / 卷宗,但映射方案还没补
  • 业务方还没确认二级命名与保留策略

7. 当前结论

截至当前,这套系统已经具备:

  • 前端按新链路展示和解释的能力
  • 后端兼容新旧结构的能力
  • 新配置回写旧运行绑定表的能力

但数据库正式迁移这一步,仍然必须先做“数据盘点 + 业务确认 + 测试库演练”三件事,不能直接在正式库硬切。