spec.md 15 KB

数据表逻辑删除分批改造

status: applied-with-warning created: 2026-07-07 complexity: 🔴复杂

1. 背景与目标

当前项目中部分用户可见的主数据、配置数据和设计态元数据仍通过 MyBatis-Plus deleteById/deleteBatchIds/removeById/remove 或 Mapper XML DELETE FROM 做物理删除。目标是在不影响框架运行表、日志清理和授权关系重建语义的前提下,分批将可恢复、可审计的数据改为逻辑删除。

可验证结果:

  • 已有删除字段但未生效的表,删除调用改为 UPDATE ... SET del_flag/deleted = 1
  • 需要软删的项目内部主表新增 del_flag 或补齐实体 @TableLogic
  • 自定义 Mapper XML 查询显式过滤逻辑删除记录。
  • 定时任务框架自带表和 Flowable 引擎自带表不进入改造范围。

2. 代码现状(Research Findings)

2.1 相关入口与链路

  • MyBatis-Plus 全局配置未配置全局逻辑删除字段,仅设置 idType,见 forge-server/forge-admin-server/src/main/resources/application.ymlmybatis-plus.global-config.dbConfig
  • 低代码动态 CRUD 删除已按运行时表是否存在 del_flag 自动选择软删或物理删,见 forge-server/forge-framework/forge-plugin-parent/forge-plugin-generator/src/main/java/com/mdframe/forge/plugin/generator/service/DynamicCrudService.java deleteById(String configKey, Object id)DynamicCrudRepository.deleteById(...)
  • Flyway 当前 V1.0.0__baseline.sql 是历史基线占位,新增结构变更必须新增版本脚本,见 forge-server/db/migration/V1.0.0__baseline.sql

2.2 现有实现

  • ai_agent 表已有 del_flag,但 AiAgent 实体无 @TableLogic,删除入口在 forge-server/forge-framework/forge-plugin-parent/forge-plugin-ai/src/main/java/com/mdframe/forge/plugin/ai/agent/controller/AiAgentController.java delete(Long id)
  • ai_provider 表已有 del_flag,但 AiProvider 实体无 @TableLogic,删除入口在 forge-server/forge-framework/forge-plugin-parent/forge-plugin-ai/src/main/java/com/mdframe/forge/plugin/ai/provider/service/AiProviderService.java delete(Long id)
  • ai_report_project 表已有 del_flag,但 ReportProject 实体无 @TableLogic,删除入口在 forge-server/forge-report-server/src/main/java/com/mdframe/forge/report/project/controller/ReportProjectController.java delete(Long id)ReportProjectMapper.xml 自定义查询未过滤 del_flag
  • ai_report_template 表已有 del_flagReportTemplateMapper.xml 查询已经过滤 t.del_flag = '0',但实体无 @TableLogic,删除入口在 forge-server/forge-report-server/src/main/java/com/mdframe/forge/report/project/template/service/ReportTemplateService.java deleteTemplate(Long id, Long userId)
  • sys_employee 表已有 del_flagEmployee 实体只有普通 delFlag 字段,删除入口在 forge-server/forge-admin-server/src/main/java/com/mdframe/forge/employee/service/impl/EmployeeServiceImpl.java deleteById(Long id)deleteBatch(Long[] ids)
  • sys_flow_node_config 表已有 del_flag,但 FlowNodeConfig 实体无逻辑删除字段;删除入口在 forge-server/forge-framework/forge-plugin-parent/forge-plugin-flow/src/main/java/com/mdframe/forge/starter/flow/service/impl/FlowNodeConfigServiceImpl.java deleteConfig(String id)deleteByModelId(String modelId)
  • sys_flow_approval_level 实体已有 @TableLogic private Integer deleted,但全量初始化 SQL 中该表缺 deleted 字段,入口在 FlowNodeConfigServiceImpl 删除节点配置时清理层级配置。
  • sys_file_metadata 使用 status=0 作为自定义软删除,见 forge-server/forge-framework/forge-plugin-parent/forge-plugin-system/src/main/java/com/mdframe/forge/plugin/system/service/impl/SystemFileMetadataPersistence.java delete(String fileId),不强制迁移为 del_flag

2.3 发现与风险

  • 若只给实体加 @TableLogic,但表缺字段,会导致删除 SQL 访问不存在列而失败。
  • 若只给表加字段,不改 XML 查询,自定义列表仍会查出已删除数据。
  • 授权关系表如果改为软删,可能产生脏授权或唯一索引冲突,必须单独评审。
  • 日志、会话、清理任务和框架运行表保留物理删除更合理。
  • 远程当前库 information_schema 查询在 /apply 阶段已尝试,沙箱内连接失败,提权审批服务返回 503,无法完成远程实库盘点;本批使用仓库全量初始化 SQL + 幂等 Flyway 脚本兜底。

3. 功能点

  • 功能 1:对已有删除字段但仍物理删除的表补齐实体 @TableLogic 和 XML 查询过滤。
  • 功能 2:对项目内部主数据/配置表分批新增 del_flag 并接入逻辑删除。(Batch 2.1/2.2 已完成,Batch 2.3a 组织/岗位已完成,Batch 2.3b-1 租户已完成,Batch 2.3b-2 角色已完成,Batch 2.3b-3 菜单资源已完成,Batch 2.3b-4 用户已完成)
  • 功能 3:对低代码、数据资产、报表、应用中心设计态元数据分批新增 del_flag 并接入逻辑删除。(Batch 3.1 低代码/应用中心主设计态表已完成,Batch 3.2 数据资产/报表目录已完成,Batch 3.3 采购样例业务表已完成)
  • 功能 4:对 Mapper XML DELETE FROM 逐项分类,保留框架/日志/关系重建类物理删除,转换用户可见数据的物理删除。
  • 功能 5:记录所有明确排除的表和原因。

4. 业务规则

  • 定时任务框架自带表排除:qrtz_*、SnailJob/Quartz 内部表。
  • Flowable 引擎自带表排除:act_*flw_*、Flowable/Liquibase changelog 表。
  • sys_job_configsys_job_log 属于 Forge 内部表,不按定时任务框架自带表排除,纳入盘点和改造评审。
  • Forge 自研流程配置表不属于 Flowable 引擎表,例如 sys_flow_modelsys_flow_templatesys_flow_node_configsys_flow_formsys_flow_entry,按平台配置数据处理。
  • 关系表默认保持物理删除,除非明确需要恢复子配置。
  • 低代码运行表删除逻辑已存在,优先确保运行表包含 del_flag
  • 新增内置字段迁移必须通过 forge-server/db/migration/ Flyway 脚本,脚本必须防重复。

5. 数据变更

操作 表名 字段/索引 说明
新增字段 sys_flow_approval_level deleted tinyint NOT NULL DEFAULT 0 修复实体已有 @TableLogic 但表缺字段
可能新增字段 sys_flow_node_config del_flag tinyint NOT NULL DEFAULT 0 若当前库缺字段则补齐
新增生成列/索引 ai_agent, sys_employee, sys_flow_node_config logic_delete_active + active 唯一索引 避免逻辑删除后原唯一键阻塞重建同编码/同节点的有效数据
新增字段 Batch 2.1 平台内部表 del_flag ai_context_configai_modelai_page_templateai_crud_configsys_message_templatesys_message_biz_typesys_job_configsys_job_log
新增生成列/索引 Batch 2.1 有业务唯一键表 logic_delete_active + active 唯一索引 避免逻辑删除后原唯一键阻塞重建同编码/同配置的有效数据
保留物理清理 sys_job_log cleanLog(days) 专用 XML DELETE 行级删除改为逻辑删除;日志留存清理仍按策略物理释放历史数据
新增字段 Batch 2.2 系统配置表 del_flag sys_configsys_dict_typesys_dict_datasys_noticesys_api_configsys_data_scope_configsys_file_storage_config
新增生成列/索引 Batch 2.2 有业务唯一键表 logic_delete_active + active 唯一索引 配置键、字典类型/字典值、API路径方法、数据权限 Mapper 方法只约束未删除记录唯一
新增字段 Batch 2.3a 组织/岗位表 del_flag sys_orgsys_post
新增生成列/索引 Batch 2.3a 组织/岗位唯一键 logic_delete_active + active 唯一索引 组织名称、岗位编码、组织内岗位名称只约束未删除记录唯一
新增字段 Batch 2.3b-1 租户表 del_flag sys_tenant
新增生成列/索引 Batch 2.3b-1 租户唯一键 logic_delete_active + active 唯一索引 租户名称只约束未删除记录唯一
新增字段 Batch 2.3b-2 角色表 del_flag sys_role
新增生成列/索引 Batch 2.3b-2 角色唯一键 logic_delete_active + active 唯一索引 租户内角色名称、角色标识只约束未删除记录唯一
新增字段 Batch 2.3b-3 菜单/权限资源表 del_flag sys_resource
新增生成列/索引 Batch 2.3b-3 资源唯一键 logic_delete_active + active 唯一索引 租户内资源权限标识只约束未删除记录唯一
新增字段 Batch 2.3b-4 用户表 del_flag sys_user
新增生成列/索引 Batch 2.3b-4 用户唯一键 logic_delete_active + active 唯一索引 默认租户内用户名只约束未删除记录唯一
新增字段 Batch 3.1 低代码/应用中心主设计态表 del_flag ai_business_suiteai_business_appai_business_objectai_business_triggerai_code_ruleai_lowcode_domainai_lowcode_model
新增生成列/索引 Batch 3.1 有业务唯一键表 logic_delete_active + active 唯一索引 套件、应用、业务对象、编码规则、低代码领域、低代码模型只约束未删除记录唯一
新增字段 Batch 3.2 数据资产/报表目录元数据表 del_flag ai_report_data_connectionai_report_data_datasetai_report_data_dataset_categoryai_report_data_business_definitionai_report_data_dimensionai_report_directory
新增生成列/索引 Batch 3.2 数据资产有业务唯一键表 logic_delete_active + active 唯一索引 数据连接、数据集、数据集分类、业务定义、维度编码只约束未删除记录唯一
新增字段 Batch 3.3 采购样例业务表 del_flag sample_purchase_order
新增生成列/索引 Batch 3.3 采购样例业务唯一键 logic_delete_active + active 唯一索引 采购单号、流程业务 Key 只约束未删除记录唯一
新增字段 Task 4 用户配置主表 del_flag ai_prompt_templateai_custom_query_scheme
新增生成列/索引 Task 4 提示词模板唯一键 logic_delete_active + active 唯一索引 提示词模板编码只约束未删除记录唯一
不变更 qrtz_*, act_*, flw_* 框架自带表排除

6. 接口变更

操作 接口 方法 变更内容
不变更 现有删除接口 POST/DELETE 接口协议不变,底层由物理删除变为逻辑删除
不变更 现有列表/详情接口 GET/POST 返回结果过滤已逻辑删除记录

7. 影响范围

  • 后端实体:forge-plugin-systemforge-plugin-aiforge-plugin-generatorforge-plugin-dataforge-plugin-flowforge-report-serverforge-business-core
  • Mapper XML:系统、AI、数据资产、低代码、报表、流程配置相关 XML。
  • SQL 迁移:forge-server/db/migration/ 新增 Flyway 脚本。
  • 前端:接口协议不变,正常不需要改。

8. 风险与关注点

  • 权限表属于高风险范围:sys_role_resourcesys_user_rolesys_user_org_role 等默认不改为软删。
  • 数据恢复需求若覆盖子配置表,需要同步处理唯一索引和恢复冲突。
  • @TableLogic 字段类型必须匹配数据库字段类型,char(1)StringtinyintInteger
  • Mapper XML 必须显式过滤逻辑删除,不能依赖 MP 自动处理。
  • Flyway 版本号必须确认当前库 forge_schema_history 后再落最终编号。
  • 逻辑删除会改变唯一键语义;Batch 1 已对 ai_agent.agent_codesys_employee.emp_nosys_flow_node_config(model_id,node_id) 增加“仅未删除记录唯一”的兼容处理。

8.5 测试策略

  • 测试范围:编译验证、迁移 SQL 幂等验证、重点删除接口/API smoke、自定义 XML 列表过滤验证。
  • 覆盖率目标:覆盖 Batch 1 全部表;Batch 2/3 每类至少一个代表表做删除后列表不可见验证。
  • 独立 Test Spec:是。

9. 待澄清

  • 定时任务框架自带表是否排除:只排除 qrtz_*、SnailJob/Quartz 内部表;sys_job_config/sys_job_log 纳入。
  • Flowable 自带表是否排除:排除 act_*flw_*;Forge 自研 sys_flow_* 配置表纳入。
  • 是否允许先执行 Batch 1 小范围修复,再继续扩大到 Batch 2/3:用户执行 /apply logic-delete-batch-refactor 后,本轮只落 Batch 1。
  • 当前库 information_schema 盘点是否允许执行只读查询:已尝试执行,只读连接被沙箱/审批服务阻断;本轮不绕过审批,使用静态盘点和幂等迁移兜底。

10. 技术决策

  • 使用 MyBatis-Plus @TableLogic 作为实体级逻辑删除机制,不引入自定义删除拦截器。
  • del_flag 作为新表/新增字段默认逻辑删除字段;历史流程表若已使用 deleted,保持现状。
  • 分批迁移,避免一次性修改所有删除链路导致权限、日志和关系表语义混乱。
  • 关系表改造不默认执行,先做分类审查。

11. 执行日志

Task 状态 实际改动文件 备注
Task 0 completed-with-warning execution-log.md 远程实库只读查询未完成,已记录阻断原因和静态盘点依据
Task 1 completed Batch 1 Java/XML/Flyway 文件 已补 @TableLogic、XML 过滤、字段迁移、唯一键兼容
Task 2 completed Batch 2.1/2.2/2.3a/2.3b-1/2.3b-2/2.3b-3/2.3b-4 Java/XML/Flyway 文件 AI/消息/任务/低代码配置表、系统配置/字典/通知/API/数据权限/文件存储配置、组织/岗位、租户、角色、菜单资源、用户已完成
Task 3 completed Batch 3.1/3.2/3.3 Java/XML/Flyway 文件 低代码/应用中心 7 张主设计态表、数据资产/报表目录 6 张主元数据表、采购样例业务表已完成
Task 4 completed Task 4 Java/XML/Flyway 文件 XML 物理删除已评审;ai_prompt_templateai_custom_query_scheme 转逻辑删除,其余日志/会话/关系/重建型子配置保留物理删除
Task 5 completed-with-warning test-spec.mdexecution-log.md admin/report/flow 编译和静态检查通过;本地 MySQL 3407 不可用,SQL 实跑和接口 smoke 跳过

12. 审查结论

/review logic-delete-batch-refactor 执行。

13. 确认记录(HARD-GATE)

  • 确认时间:2026-07-07
  • 确认人:用户
  • 确认范围:执行 /apply logic-delete-batch-refactor;已按用户“继续”推进到 Batch 3.3 采购样例业务表,核心权限关系表、低代码关系/日志表、数据资产字段/ACL/行权限/维度项/绑定表仍按默认策略保持物理删除,Flowable/Quartz/SnailJob 框架表仍排除。