- 新增 .planning/phases/02-rbac-ai/02-01-SUMMARY.md(含 frontmatter / 任务详情 / 验证结果 / Self-Check PASSED)
- STATE.md:进度 50% → 75%,已完成 plan 2 → 3,Phase 2 状态切到 In progress(1/2 plan)
- ROADMAP.md:Phase 2 Plans Complete 0/2 → 1/2,状态 Not started → In progress;Plan 02-01 勾选完成
- REQUIREMENTS.md:CRED-FE-02 + CRED-FE-03 状态切到 ✅ Done,Active 段两条 unchecked → checked
7.8 KiB
7.8 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, decisions, metrics
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | decisions | metrics | |||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 02-rbac-ai | 01 | rbac + ai-model-page |
|
|
|
|
|
|
|
|
Phase 2 Plan 01:扩展 RBAC 矩阵 + /ai-model 页面凭据槽位入口 Summary
一句话
把 'credential-slot' 模块加入 PermissionModule union 与「超级管理员/AI模型管理员」角色矩阵,同时把 /ai-model 页面转为 Client Component 并加上受 mounted && hasPermission('credential-slot') 收敛的「凭据槽位」入口 Button + 占位 Dialog(DialogTitle「通用凭据槽位」+ DialogDescription「对话框真实内容由 Phase 3 落地」)。
完成的需求
- ✅ CRED-FE-02 RBAC 模块声明:PermissionModule 14 项 union + 6 角色矩阵(其中超级管理员、AI模型管理员含 credential-slot);其他 4 角色逐字未动
- ✅ CRED-FE-03 /ai-model 页面入口:Button + 占位 Dialog 已落地,未授权角色 DOM 中完全不存在;点击触发占位 Dialog 打开
执行的任务
Task 1:扩展 lib/permissions.ts RBAC(commit d60dd89)
改动 4 处(与 PLAN 一致):
- PermissionModule union 末尾追加
| "credential-slot";(第 14 项) - 「超级管理员」数组末尾追加
"credential-slot" - 「AI模型管理员」数组末尾追加
"credential-slot" - 文件顶部权限矩阵注释表新增「凭据槽位」行(与代码同步)
未动:
- 内容管理员 / 卡牌管理员 / 查看者 / 管理员 4 个角色数组逐字不变
getModuleFromPath函数体(pathMap 不含credential-slot)getUserRole/getAllowedModules/hasPermission/hasPathPermission函数体
验证:
grep -nE "['\"]credential-slot['\"]" lib/permissions.ts命中 3 行(union literal + 2 角色数组)grep -n "credential-slot" lib/permissions.ts命中 4 行(含注释)npx tsc --noEmit整体 67 条存量错误,无新错误指向 lib/permissions.ts
Task 2:app/ai-model/page.tsx 加入口 Button + 占位 Dialog(commit 0bcaa39)
改动 5 处(与 PLAN 一致):
- line 1 加
"use client"指令(文件转为 Client Component) - 新增 imports:
useState, useEffect(react)、Dialog 子组件 5 个 (@/components/ui/dialog)、KeyRound(lucide-react)、hasPermission(@/lib/permissions) - 函数体顶部加
mounted+isCredentialDialogOpen两个useState(false)+ 一个useEffect(() => setMounted(true), [])(复用 sidebar.tsx 的 mounted 守卫模式) - DashboardHeader children 改为
<div className="flex items-center gap-2">包裹,含原「添加新模型」Button + 新增{mounted && hasPermission("credential-slot") && <Button variant="outline" onClick={() => setIsCredentialDialogOpen(true)}><KeyRound .../>凭据槽位</Button>} </Tabs>之后、</DashboardShell>之前插入 controlled mode 占位 Dialog(DialogTitle「通用凭据槽位」+ DialogDescription「对话框真实内容由 Phase 3 落地」)
未动:
- Tabs / TabsContent / Card 等所有原有内容(line 18-441,对应改动后 line 60-470)逐字未动
- 不新建
components/ai-model/CredentialSlotDialog.tsx - 不引入 sonner / useToast /
getCredentialSlot/updateCredentialSlot - package.json / yarn.lock / package-lock.json / pnpm-lock.yaml 全部未动
验证:
head -n 1 app/ai-model/page.tsx输出"use client"grep命中 KeyRound×2 + 凭据槽位×2 + 通用凭据槽位×1 + hasPermission("credential-slot")×1 + setIsCredentialDialogOpen×3 + 对话框真实内容由 Phase 3 落地×1npx tsc --noEmit无新错误指向 app/ai-model/page.tsx
Plan 级整体验证
| # | 校验项 | 结果 |
|---|---|---|
| 1 | npx tsc --noEmit 不引入指向 lib/permissions.ts / app/ai-model/page.tsx 的新错误 |
✅ 0 条 |
| 2 | grep -nE "['\"]credential-slot['\"]" lib/permissions.ts 命中 3 行 |
✅ |
| 3 | 4 个不应含 credential-slot 的角色数组逐字未变 | ✅ |
| 4 | getModuleFromPath pathMap 中无新增 credential-slot 路径映射 |
✅ |
| 5 | head -n 1 app/ai-model/page.tsx = "use client" |
✅ |
| 6 | KeyRound / 凭据槽位 / 通用凭据槽位 / hasPermission(credential-slot) / setIsCredentialDialogOpen / 对话框真实内容由 Phase 3 落地 全部命中 | ✅(综合 ≥10 条) |
| 7 | git diff --stat package.json yarn.lock package-lock.json pnpm-lock.yaml 0 行输出(不引入新依赖) |
✅ |
偏离 PLAN 之处
无 — Plan 02-01 完全按照 02-01-PLAN.md 的 5 处改动逐字执行;mounted 守卫模式严格复刻 components/sidebar.tsx:83-104。
已知遗留 / 移交事项
- 修改记录:本 plan 未触动
docs/修改记录.md,由 Plan 02-02 在收尾任务中统一为 Phase 2 写一条条目 - 占位 Dialog:仅含 DialogTitle + DialogDescription,无 Footer / 表单 / 提交按钮;表单与提交逻辑由 Phase 3 / CRED-FE-04 落地
- 后端联调:Phase 3 才会真正调用
getCredentialSlot()/updateCredentialSlot();本 plan 不涉及任何后端调用
提交历史
| Task | Commit | 描述 |
|---|---|---|
| 1 | d60dd89 |
feat(02-01): 扩展 RBAC 矩阵增加 credential-slot 模块 |
| 2 | 0bcaa39 |
feat(02-01): /ai-model 页面新增凭据槽位入口 Button + 占位 Dialog |
Self-Check
文件存在性:
lib/permissions.ts:FOUND(126 行;123 → 126,+3 行 = union +1 / 超管 +1 / AI模型管理员 +1,注释表 +1 与原 -1 净 0;实际 4 处改动结果总 +3 行而非 +4 是因为最早 union 末项"settings";替换为"settings"+ 新增一行| "credential-slot";,注释表本身只增 1 行,三个数组各 +1 但其中一个原行被改为多行)app/ai-model/page.tsx:FOUND(488 行;446 → 488,+42 行 = imports +13 / state +5 / DashboardHeader 重构 +7 / Dialog +14 - 其他微调)
Commit 存在性:
- d60dd89:FOUND(git log)
- 0bcaa39:FOUND(git log)