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

126 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 一键生成引用闭环修复设计
## 背景
项目 104 在一键生成源码阶段创建 ProjectSpec 版本失败:后台菜单
`librarian_profile` 引用了不存在的后台页面 `librarian_profile_page`
实际蓝图只保留 `admin``reader` 两个角色,但数据库和后台菜单仍包含独立的
`librarian` 账户模型。后台页面初始化先把 `librarian` 表分配给管理列表页,随后个人中心
无法再从“未匹配表”集合中取得该表并被静默跳过,最终形成悬空页面引用。
## 目标
- 只有角色编码严格等于 `admin` 时才视为系统管理员。
- 保留 `librarian` 等业务后台角色,并为其生成独立账户表、权限和个人中心。
- 后台个人中心可以与后台管理列表复用同一账户表。
- 一键生成在页面初始化结束后、ProjectSpec 快照之前完成引用闭包校验。
- 唯一可确定的历史数据问题自动修复;存在歧义时在页面初始化阶段给出精确错误。
- 保持旧蓝图兼容,不要求已有项目立即补齐新字段。
## 非目标
- 不引入新的 `adminPages` 顶层蓝图集合。
- 不重构整个 AI 生成服务或模板系统。
- 不把任意名称包含“管理员”的角色自动提升为系统管理员。
- 不通过清空 `pageRef``visibleRoles` 等方式掩盖引用错误。
## 方案选择
采用兼容式闭环修复。相比删除悬空菜单,它保留业务后台角色;相比引入完整
`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_page``librarian_profile_page` 可以同时绑定 `librarian`
页面类型优先使用 `menu.pageType`;字段为空时,个人中心默认为 `form`,其他后台页面
默认为 `list`。无法解析表的页面型后台菜单不再 `continue` 静默跳过,而是抛出包含菜单、
页面编码和候选表信息的 `ServiceException`
## 历史项目自动修复
页面初始化读取历史蓝图时,若发现满足以下全部条件的菜单,则恢复业务后台角色:
- `dataScope=CURRENT_USER`
- 菜单或页面编码以 `_profile` / `_profile_page` 结尾;
- 编码前缀能唯一匹配项目账户表;
- 该前缀不是 `admin`
修复会补充角色、将菜单 `visibleRoles` 设置为该角色、补齐 `tableName``pageType=form`
并持久化蓝图。项目 104 因此恢复 `librarian`,同时生成
`librarian_profile_page`。无法唯一推导时不猜测,转为明确错误。
## 引用闭包预检
扩展 `FrontProjectConsistencyValidator`,在页面初始化之后验证:
- 每个前台菜单的 `pageCode` 存在于前台蓝图页面或前台页面设计。
- 每个后台菜单的 `pageCode` 存在于后台页面设计。
- 每个前台页面的 `parentPageCode` 存在于前台页面集合。
- 每个菜单的 `visibleRoles` 都存在于角色集合。
- 每个页面绑定的数据表都存在。
校验在 `SourcePreviewStageHandler` 创建 ProjectSpec 版本之前执行。ProjectSpecValidator 保留为
最终防线,但同类问题应在“初始化页面”阶段失败,而不是进入“生成源码”后才失败。
## 错误处理
- 自动修复必须要求唯一匹配;多候选或无候选均不自动选择。
- 错误消息包含蓝图路径、菜单或页面编码、缺失引用及可用候选。
- 不通过删除菜单、清空角色或清空页面引用来让校验通过。
- 历史页面设计迁移继续保留原 `designId`,避免重复页面记录。
## 测试设计
按 TDD 增加以下回归场景:
1. `librarian/图书管理员` 不再被合并为 `admin`
2. 个人中心未知角色可从唯一账户表恢复,普通未知角色被拒绝。
3. 普通管理页和个人中心页可复用 `librarian` 表,分别生成 `list``form` 页面。
4. 显式 `tableName/pageType` 优先于语义匹配,旧蓝图仍能生成。
5. 无法匹配表的后台菜单在页面初始化阶段失败。
6. 前台菜单未知页面、后台菜单未知页面、未知父页面和未知角色均被预检拦截。
7. 项目 104 形态的失败任务重试后不再产生 `UNKNOWN_PAGE_REF`
8. 更新 AI 数据库生成测试,使管理员账户表自动补充后的表和字段断言与当前契约一致。
验证范围包括角色/蓝图生成、页面初始化、一致性修复、ProjectSpec 装配与校验、一键生成
编排,以及 `ruoyi-generator` 模块的相关回归测试。
## 兼容性与迁移
新增菜单字段均为可选字段,旧 JSON 可直接反序列化。新逻辑只改变错误的角色合并、静默
丢弃权限和静默跳过页面行为。现有 `admin`、普通后台列表页和已保存页面设计继续沿用原有
编码;历史失败项目在重试页面初始化时自动完成可确定的修复。