Files
yidaima/RuoYi-Vue/docs/superpowers/specs/2026-07-12-one-click-reference-closure-repair-design.md

6.3 KiB
Raw Blame History

一键生成引用闭环修复设计

背景

项目 104 在一键生成源码阶段创建 ProjectSpec 版本失败:后台菜单 librarian_profile 引用了不存在的后台页面 librarian_profile_page。 实际蓝图只保留 adminreader 两个角色,但数据库和后台菜单仍包含独立的 librarian 账户模型。后台页面初始化先把 librarian 表分配给管理列表页,随后个人中心 无法再从“未匹配表”集合中取得该表并被静默跳过,最终形成悬空页面引用。

目标

  • 只有角色编码严格等于 admin 时才视为系统管理员。
  • 保留 librarian 等业务后台角色,并为其生成独立账户表、权限和个人中心。
  • 后台个人中心可以与后台管理列表复用同一账户表。
  • 一键生成在页面初始化结束后、ProjectSpec 快照之前完成引用闭包校验。
  • 唯一可确定的历史数据问题自动修复;存在歧义时在页面初始化阶段给出精确错误。
  • 保持旧蓝图兼容,不要求已有项目立即补齐新字段。

非目标

  • 不引入新的 adminPages 顶层蓝图集合。
  • 不重构整个 AI 生成服务或模板系统。
  • 不把任意名称包含“管理员”的角色自动提升为系统管理员。
  • 不通过清空 pageRefvisibleRoles 等方式掩盖引用错误。

方案选择

采用兼容式闭环修复。相比删除悬空菜单,它保留业务后台角色;相比引入完整 adminPages 模型,它能以较小改动修复现有项目并维持模板兼容。

数据模型

AppMenuDesign 增加两个可选字段:

  • tableName:菜单页面明确绑定的数据表。
  • pageType:页面类型,后台个人中心使用 form,普通后台管理使用 list

AI 应为后台菜单输出这两个字段。历史蓝图字段为空时继续使用名称、编码和路径的语义 匹配;个人中心还允许从 <role>_profile<role>_profile_page 推导角色及账户表。

角色规范化

角色编码先规范化为小写蛇形命名。只有规范化编码恰好为 admin 的角色才是系统管理员。 名称不参与系统管理员判定,因此 librarian/图书管理员content_admin/内容管理员 都保留为独立角色。

如果蓝图缺少 admin,仍自动补充系统管理员。角色编码重复时保留第一项并报告规范化 结果,不把其他业务角色合并到 admin

菜单中的 visibleRoles 不再静默删除未知角色:

  • 对个人中心菜单,若编码前缀能唯一匹配账户表,则恢复对应角色并把该角色写回 visibleRoles
  • 其他未知角色无法唯一恢复时,一致性校验失败并指出菜单编码和角色编码。

后台页面初始化

后台菜单按以下优先级解析数据表:

  1. menu.tableName 精确匹配。
  2. 个人中心菜单从角色编码推导同名账户表,并允许复用已分配表。
  3. 旧蓝图继续使用 adminMenuName、菜单名称、编码和路径进行唯一语义匹配。

普通管理菜单仍只消费一次未匹配表。个人中心不从未匹配集合中移除账户表,因此 librarian_admin_pagelibrarian_profile_page 可以同时绑定 librarian

页面类型优先使用 menu.pageType;字段为空时,个人中心默认为 form,其他后台页面 默认为 list。无法解析表的页面型后台菜单不再 continue 静默跳过,而是抛出包含菜单、 页面编码和候选表信息的 ServiceException

历史项目自动修复

页面初始化读取历史蓝图时,若发现满足以下全部条件的菜单,则恢复业务后台角色:

  • dataScope=CURRENT_USER
  • 菜单或页面编码以 _profile / _profile_page 结尾;
  • 编码前缀能唯一匹配项目账户表;
  • 该前缀不是 admin

修复会补充角色、将菜单 visibleRoles 设置为该角色、补齐 tableNamepageType=form 并持久化蓝图。项目 104 因此恢复 librarian,同时生成 librarian_profile_page。无法唯一推导时不猜测,转为明确错误。

引用闭包预检

扩展 FrontProjectConsistencyValidator,在页面初始化之后验证:

  • 每个前台菜单的 pageCode 存在于前台蓝图页面或前台页面设计。
  • 每个后台菜单的 pageCode 存在于后台页面设计。
  • 每个前台页面的 parentPageCode 存在于前台页面集合。
  • 每个菜单的 visibleRoles 都存在于角色集合。
  • 每个页面绑定的数据表都存在。

校验在 SourcePreviewStageHandler 创建 ProjectSpec 版本之前执行。ProjectSpecValidator 保留为 最终防线,但同类问题应在“初始化页面”阶段失败,而不是进入“生成源码”后才失败。

错误处理

  • 自动修复必须要求唯一匹配;多候选或无候选均不自动选择。
  • 错误消息包含蓝图路径、菜单或页面编码、缺失引用及可用候选。
  • 不通过删除菜单、清空角色或清空页面引用来让校验通过。
  • 历史页面设计迁移继续保留原 designId,避免重复页面记录。

测试设计

按 TDD 增加以下回归场景:

  1. librarian/图书管理员 不再被合并为 admin
  2. 个人中心未知角色可从唯一账户表恢复,普通未知角色被拒绝。
  3. 普通管理页和个人中心页可复用 librarian 表,分别生成 listform 页面。
  4. 显式 tableName/pageType 优先于语义匹配,旧蓝图仍能生成。
  5. 无法匹配表的后台菜单在页面初始化阶段失败。
  6. 前台菜单未知页面、后台菜单未知页面、未知父页面和未知角色均被预检拦截。
  7. 项目 104 形态的失败任务重试后不再产生 UNKNOWN_PAGE_REF
  8. 更新 AI 数据库生成测试,使管理员账户表自动补充后的表和字段断言与当前契约一致。

验证范围包括角色/蓝图生成、页面初始化、一致性修复、ProjectSpec 装配与校验、一键生成 编排,以及 ruoyi-generator 模块的相关回归测试。

兼容性与迁移

新增菜单字段均为可选字段,旧 JSON 可直接反序列化。新逻辑只改变错误的角色合并、静默 丢弃权限和静默跳过页面行为。现有 admin、普通后台列表页和已保存页面设计继续沿用原有 编码;历史失败项目在重试页面初始化时自动完成可确定的修复。