docs(02-01): 完成 Phase 2 Plan 02-01(RBAC 扩展 + /ai-model 凭据槽位入口)
- 新增 .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
This commit is contained in:
parent
0bcaa398cc
commit
15e725a32f
@ -88,8 +88,8 @@
|
||||
### 通用凭据槽位前端集成(CRED-FE)
|
||||
|
||||
- [x] **CRED-FE-01** API 客户端 `lib/api/credential-slot.ts`:导出 `getCredentialSlot()`、`updateCredentialSlot({ app_id, access_token })`;含响应适配器 `mapBackendCredentialSlot()`(snake_case → camelCase);共享类型 `CredentialSlot { appId, accessTokenMasked, updatedAt }`;从 `lib/api/index.ts` 导出
|
||||
- [ ] **CRED-FE-02** RBAC 模块声明:`lib/permissions.ts` 加入 `credential-slot` 模块 key(`PermissionModule` 类型扩充);`PERMISSION_MATRIX` 把该模块分配给"超级管理员"和"AI模型管理员"两个角色;`getModuleFromPath()` 不需要新映射(凭据槽位是内嵌于 `/ai-model` 的子能力,不占独立路由)
|
||||
- [ ] **CRED-FE-03** `/ai-model` 页面入口:在合适位置(如页头工具栏 / Header 右侧)渲染"凭据槽位"按钮或卡片;仅当 `hasPermission('credential-slot')` 为 true 时可见;点击触发对话框打开
|
||||
- [x] **CRED-FE-02** RBAC 模块声明:`lib/permissions.ts` 加入 `credential-slot` 模块 key(`PermissionModule` 类型扩充);`PERMISSION_MATRIX` 把该模块分配给"超级管理员"和"AI模型管理员"两个角色;`getModuleFromPath()` 不需要新映射(凭据槽位是内嵌于 `/ai-model` 的子能力,不占独立路由)
|
||||
- [x] **CRED-FE-03** `/ai-model` 页面入口:在合适位置(如页头工具栏 / Header 右侧)渲染"凭据槽位"按钮或卡片;仅当 `hasPermission('credential-slot')` 为 true 时可见;点击触发对话框打开
|
||||
- [ ] **CRED-FE-04** 编辑对话框组件 `components/ai-model/CredentialSlotDialog.tsx`:基于 `components/ui/dialog.tsx`;表单 React Hook Form + Zod 校验;预填态显示后端返回的 `app_id` 明文 + `access_token` 末 4 位掩码 + 不可改的 `updated_at`;表单语义为"留空保留旧值,重新输入才覆写"(避免把脱敏掩码当真值回写);提交触发 `updateCredentialSlot()`,仅提交用户实际输入的字段
|
||||
- [ ] **CRED-FE-05** 提交反馈:成功调用 `useToast()` 弹 Sonner 成功 toast 并自动关闭对话框、重新触发 GET 刷新预填;失败走 `lib/api/error-handler.ts` 统一映射后端错误并 toast 提示
|
||||
|
||||
@ -134,8 +134,8 @@
|
||||
| Requirement | Phase | UI hint | Status |
|
||||
|-------------|-------|---------|--------|
|
||||
| CRED-FE-01 API 客户端 `lib/api/credential-slot.ts`(类型 + 适配器 + GET/PUT) | Phase 1 凭据槽位 API 客户端 | — | ✅ Done (Plan 01-01 commits a0d0b9c + c072bbe;Plan 01-02 commit c1743a3 修改记录追加 + 双重验证;Phase 1 已封盘 2026-05-08) |
|
||||
| CRED-FE-02 RBAC 模块声明(`lib/permissions.ts` 加 `credential-slot` key + 矩阵分配) | Phase 2 RBAC 收敛 + AI 模型页入口 | yes | Pending |
|
||||
| CRED-FE-03 `/ai-model` 页面入口(受 `hasPermission('credential-slot')` 收敛) | Phase 2 RBAC 收敛 + AI 模型页入口 | yes | Pending |
|
||||
| CRED-FE-02 RBAC 模块声明(`lib/permissions.ts` 加 `credential-slot` key + 矩阵分配) | Phase 2 RBAC 收敛 + AI 模型页入口 | yes | ✅ Done (Plan 02-01 commit d60dd89, 2026-05-08) |
|
||||
| CRED-FE-03 `/ai-model` 页面入口(受 `hasPermission('credential-slot')` 收敛) | Phase 2 RBAC 收敛 + AI 模型页入口 | yes | ✅ Done (Plan 02-01 commit 0bcaa39, 2026-05-08) |
|
||||
| CRED-FE-04 编辑对话框 `CredentialSlotDialog.tsx`(RHF + Zod,留空保留旧值语义) | Phase 3 编辑对话框 + 提交反馈 | yes | Pending |
|
||||
| CRED-FE-05 提交反馈(Sonner toast 成功 + `error-handler.ts` 失败映射) | Phase 3 编辑对话框 + 提交反馈 | yes | Pending |
|
||||
|
||||
@ -148,3 +148,4 @@
|
||||
*Last updated: 2026-05-07 — Milestone v1.0「通用凭据槽位前端集成」ROADMAP 生成,Traceability 回填 5/5*
|
||||
*2026-05-08 更新:Plan 01-01 落地,CRED-FE-01 状态切到 ✅ Done(Active 段已自动勾选 [x])*
|
||||
*2026-05-08 更新:Plan 01-02 落地(修改记录追加 + 双重验证 commit c1743a3),Phase 1 全部交付(2/2 plan),等待 /gsd-plan-phase 2 启动 Phase 2*
|
||||
*2026-05-08 更新:Plan 02-01 落地(commits d60dd89 + 0bcaa39),CRED-FE-02 + CRED-FE-03 状态切到 ✅ Done;Phase 2 进度 1/2,等待 Plan 02-02 收尾*
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
3. 以"AI模型管理员"角色登录访问 `/ai-model`,页面工具栏 / Header 区域可见明确的"凭据槽位"入口控件(按钮或卡片,文案明确);以"内容管理员"或"查看者"角色登录访问同一页面,入口控件不渲染(DOM 中不存在,而非仅隐藏)
|
||||
4. 入口控件的可见性判断走 `hasPermission('credential-slot')`,不直接读 `localStorage.user_role` 字符串比较;点击入口控件触发对话框打开行为(Phase 3 落地后端到端可用,本 phase 至少打开一个空对话框占位以验证联动点存在)
|
||||
**Plans**: 2 plans
|
||||
- [ ] 02-01-PLAN.md — 扩展 lib/permissions.ts RBAC(PermissionModule union +1 / 矩阵 +2 角色)+ app/ai-model/page.tsx 加 "use client"、入口 Button、占位 Dialog
|
||||
- [x] 02-01-PLAN.md — 扩展 lib/permissions.ts RBAC(PermissionModule union +1 / 矩阵 +2 角色)+ app/ai-model/page.tsx 加 "use client"、入口 Button、占位 Dialog ✅ 2026-05-08(commits d60dd89 + 0bcaa39)
|
||||
- [ ] 02-02-PLAN.md — docs/修改记录.md 顶部追加 Phase 2 条目 + plan 级双重验证(npx tsc --noEmit 反向断言 + grep 11 条 specifics + 不引入新依赖)
|
||||
**UI hint**: yes
|
||||
|
||||
@ -72,7 +72,7 @@ Phase 按数值顺序执行:1 → 2 → 3(如出现紧急插入,记为 1.1
|
||||
| Phase | Plans Complete | Status | Completed |
|
||||
|-------|----------------|--------|-----------|
|
||||
| 1. 凭据槽位 API 客户端 | 2/2 | ✅ Complete | 2026-05-08 |
|
||||
| 2. RBAC 收敛 + AI 模型页入口 | 0/2 | Not started | - |
|
||||
| 2. RBAC 收敛 + AI 模型页入口 | 1/2 | 🚧 In progress | - |
|
||||
| 3. 编辑对话框 + 提交反馈 | 0/TBD | Not started | - |
|
||||
|
||||
---
|
||||
|
||||
@ -2,20 +2,20 @@
|
||||
gsd_state_version: 1.0
|
||||
milestone: v1.0
|
||||
milestone_name: 通用凭据槽位前端集成
|
||||
status: completed
|
||||
last_updated: "2026-05-08T03:41:45.303Z"
|
||||
status: in_progress
|
||||
last_updated: "2026-05-08T08:00:00.000Z"
|
||||
last_activity: 2026-05-08
|
||||
progress:
|
||||
total_phases: 3
|
||||
completed_phases: 1
|
||||
total_plans: 4
|
||||
completed_plans: 2
|
||||
percent: 50
|
||||
completed_plans: 3
|
||||
percent: 75
|
||||
---
|
||||
|
||||
# Project State — 洛天依应用管理后台(qy-lty-admin)
|
||||
|
||||
**最后更新**: 2026-05-08(Phase 1 全部交付:plan 01 代码 + plan 02 修改记录追加 + 双重验证;CRED-FE-01 已交付,等待 /gsd-plan-phase 2 启动 Phase 2)
|
||||
**最后更新**: 2026-05-08(Phase 2 Plan 02-01 完成:RBAC +credential-slot 模块 + /ai-model 页面入口 Button + 占位 Dialog;CRED-FE-02 + CRED-FE-03 已交付;等待 Plan 02-02 收尾修改记录)
|
||||
|
||||
## 项目引用
|
||||
|
||||
@ -29,21 +29,21 @@ progress:
|
||||
|
||||
```
|
||||
Milestone: v1.0 通用凭据槽位前端集成
|
||||
Phase: Phase 1「凭据槽位 API 客户端」✅ 已交付
|
||||
Plan: 01-01 完成 ✅ / 01-02 完成 ✅
|
||||
Status: Phase 1 complete (2/2 plans done);等待 Phase 2 启动
|
||||
Progress: [██████████] 100%(Phase 1 内部 2/2 plan 完成)
|
||||
Phase: Phase 2「RBAC 收敛 + AI 模型页入口」🚧 进行中
|
||||
Plan: 02-01 完成 ✅ / 02-02 待启动
|
||||
Status: Phase 2 in progress (1/2 plans done)
|
||||
Progress: [█████░░░░░] 50%(Phase 2 内部 1/2 plan 完成)
|
||||
Last activity: 2026-05-08
|
||||
```
|
||||
|
||||
**下一步行动**:运行 `/gsd-plan-phase 2` 启动 Phase 2「RBAC 收敛 + AI 模型页入口」(CRED-FE-02 + CRED-FE-03)。
|
||||
**下一步行动**:运行 `/gsd-execute-phase 2`(或对 02-02-PLAN.md 单独 execute)落地 Plan 02-02:docs/修改记录.md 顶部追加 Phase 2 条目 + plan 级双重验证。
|
||||
|
||||
## Phase 概览
|
||||
|
||||
| Phase | 标题 | 需求 | UI hint | 状态 |
|
||||
|-------|------|------|---------|------|
|
||||
| 1 | 凭据槽位 API 客户端 | CRED-FE-01 ✅ | — | ✅ 已交付(2/2 plan,2026-05-08)|
|
||||
| 2 | RBAC 收敛 + AI 模型页入口 | CRED-FE-02, CRED-FE-03 | yes | 未开始(待 /gsd-plan-phase 2)|
|
||||
| 2 | RBAC 收敛 + AI 模型页入口 | CRED-FE-02 ✅, CRED-FE-03 ✅ | yes | 🚧 进行中(1/2 plan:02-01 完成 / 02-02 待启动)|
|
||||
| 3 | 编辑对话框 + 提交反馈 | CRED-FE-04, CRED-FE-05 | yes | 未开始 |
|
||||
|
||||
## 联动 milestone
|
||||
@ -58,10 +58,10 @@ Last activity: 2026-05-08
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| 已完成 phase | 1 / 3 |
|
||||
| 已完成 plan | 2 / 2(Phase 1 全部交付)|
|
||||
| Milestone 进度 | ~33%(1/3 phase 完成)|
|
||||
| 已完成 plan | 3 / 5(Phase 1 全部交付 + Phase 2 Plan 02-01 完成)|
|
||||
| Milestone 进度 | ~50%(1/3 phase 完成 + 1 phase 进行中)|
|
||||
| 启动日期 | 2026-05-07 |
|
||||
| 最近活动 | 2026-05-08 Plan 01-02 落地(commit c1743a3)|
|
||||
| 最近活动 | 2026-05-08 Plan 02-01 落地(commits d60dd89 + 0bcaa39)|
|
||||
|
||||
### Plan 执行记录
|
||||
|
||||
@ -69,6 +69,7 @@ Last activity: 2026-05-08
|
||||
|------------|-------|---------|------|----------|
|
||||
| 01-01 | 2 | 2 | ~76s | 2026-05-08 |
|
||||
| 01-02 | 2 | 1 | ~360s | 2026-05-08 |
|
||||
| 02-01 | 2 | 2 | ~6min | 2026-05-08 |
|
||||
|
||||
## 累积上下文
|
||||
|
||||
@ -79,6 +80,7 @@ Last activity: 2026-05-08
|
||||
- **2026-05-07 表单"留空保留旧值"语义**:后端 GET 返回的是末 4 位脱敏掩码,前端**绝不**能把掩码当真值再 PUT 回去;Phase 3 success criteria #2 显式约束。
|
||||
- **2026-05-08 Plan 01-01 落地**:1:1 复刻 ai-models.ts 风格的 credential-slot.ts(adapter + GET/PUT),index.ts 末尾具名 re-export 4 个公共符号;类型层 `accessTokenMasked` vs `accessToken` 编译期屏障已建立,Phase 3 表单编写时 TS 会拦截"把脱敏字符串赋给 accessToken 字段"这条 bug 路径。
|
||||
- **2026-05-08 Plan 01-02 落地**:docs/修改记录.md 顶部追加 [2026-05-08] Phase 1 条目(含「跨项目联动」+「服务端联动」字段引用后端 commit 46d72b8);`npx tsc --noEmit` 在新增/修改文件零类型错误(67 条存量错误与本 phase 无关);临时探针验证 barrel 入口可解析后已删除。`npm run lint` 因项目未 bootstrap ESLint(无 .eslintrc* / eslint-config-next)进入交互式 prompt → 按 PLAN 自动 verify 规则判定通过(不指向新增/修改文件),ESLint 基础设施补齐留给 PERM-06 候选 #3。
|
||||
- **2026-05-08 Plan 02-01 落地**:lib/permissions.ts PermissionModule union +1('credential-slot' 第 14 项)+ 「超级管理员」/「AI模型管理员」两角色数组末尾追加 + 顶部注释表新增「凭据槽位」行(commit d60dd89);app/ai-model/page.tsx 转 Client Component(line 1 加 'use client')+ 加 useState/useEffect mounted 守卫(复用 sidebar.tsx 同模式)+ DashboardHeader 内追加凭据槽位 Button(variant=outline / KeyRound 图标 / 受 mounted && hasPermission('credential-slot') 收敛)+ </Tabs> 后插入 controlled mode 占位 Dialog(DialogTitle「通用凭据槽位」+ DialogDescription「对话框真实内容由 Phase 3 落地」)(commit 0bcaa39);`npx tsc --noEmit` 不引入指向 lib/permissions.ts / app/ai-model/page.tsx 的新错误(67 条存量错误与本 phase 无关);不引入新依赖(4 个 lockfile 全部未动)。CRED-FE-02 + CRED-FE-03 已交付,等待 Plan 02-02 收尾修改记录追加。
|
||||
|
||||
### 待办事项
|
||||
|
||||
@ -99,16 +101,16 @@ Last activity: 2026-05-08
|
||||
|------|------|
|
||||
| 代码库映射 | ✅ `.planning/codebase/` 7 文档(commit `a85b6a7`) |
|
||||
| PROJECT.md | ✅ 已加入 Milestone v1.0 段 + Active 5 项 |
|
||||
| REQUIREMENTS.md | ✅ Active 段已落地,Traceability 已回填 5/5;CRED-FE-01 已勾选完成 |
|
||||
| 路线图 | ✅ ROADMAP.md 落地(3 phase,coarse),Phase 1 已完成 |
|
||||
| 当前 phase | Phase 1 ✅ 已交付,Phase 2 待启动 |
|
||||
| REQUIREMENTS.md | ✅ Active 段已落地,Traceability 已回填 5/5;CRED-FE-01 + CRED-FE-02 + CRED-FE-03 已勾选完成 |
|
||||
| 路线图 | ✅ ROADMAP.md 落地(3 phase,coarse),Phase 1 已完成、Phase 2 进行中 |
|
||||
| 当前 phase | Phase 2 🚧 进行中(02-01 完成 / 02-02 待启动)|
|
||||
| 当前 milestone | v1.0 通用凭据槽位前端集成 |
|
||||
|
||||
## 会话连续性
|
||||
|
||||
**最近会话**:2026-05-08
|
||||
**最近动作**:执行 Plan 01-02(docs/修改记录.md 顶部追加 Phase 1 条目;commit c1743a3)+ 双重验证(tsc 0 个新文件错误 / next lint 因 ESLint 未 bootstrap 进 prompt 但不指向新文件)+ 临时探针验证 barrel 入口后删除;Phase 1 全部交付
|
||||
**下一会话起点**:运行 `/gsd-plan-phase 2` 启动 Phase 2「RBAC 收敛 + AI 模型页入口」(CRED-FE-02 + CRED-FE-03)
|
||||
**最近动作**:执行 Plan 02-01(lib/permissions.ts 扩展 RBAC + app/ai-model/page.tsx 加凭据槽位 Button + 占位 Dialog;commits d60dd89 + 0bcaa39)+ tsc 0 个新文件错误 + 不引入新依赖;CRED-FE-02 + CRED-FE-03 已交付
|
||||
**下一会话起点**:执行 Plan 02-02(docs/修改记录.md 顶部追加 [2026-05-08] Phase 2 条目 + plan 级双重验证)
|
||||
|
||||
## 工作流配置
|
||||
|
||||
@ -143,3 +145,4 @@ CLAUDE.md 中两条强制规则,做任何 phase 时必须遵守:
|
||||
*2026-05-07 由 gsd-roadmapper 切换到 Phase 1 待启动状态*
|
||||
*2026-05-08 Plan 01-01 完成(CRED-FE-01 已交付),Phase 1 进度 1/2,等待 Plan 01-02 收尾*
|
||||
*2026-05-08 Plan 01-02 完成(修改记录追加 + 双重验证),Phase 1 全部交付(2/2 plan);等待 /gsd-plan-phase 2 启动 Phase 2*
|
||||
*2026-05-08 Plan 02-01 完成(RBAC 扩展 + /ai-model 页面入口 Button + 占位 Dialog),CRED-FE-02 + CRED-FE-03 已交付;Phase 2 进度 1/2,等待 Plan 02-02 收尾*
|
||||
|
||||
139
qy-lty-admin/.planning/phases/02-rbac-ai/02-01-SUMMARY.md
Normal file
139
qy-lty-admin/.planning/phases/02-rbac-ai/02-01-SUMMARY.md
Normal file
@ -0,0 +1,139 @@
|
||||
---
|
||||
phase: 02-rbac-ai
|
||||
plan: 01
|
||||
subsystem: rbac + ai-model-page
|
||||
tags: [rbac, permissions, ai-model, dialog, client-component]
|
||||
requires:
|
||||
- lib/api/credential-slot.ts:CredentialSlot(Phase 1 已交付,本 plan 暂未直接消费,留给 Phase 3)
|
||||
- components/ui/dialog.tsx:Dialog/DialogContent/DialogHeader/DialogTitle/DialogDescription
|
||||
- components/ui/button.tsx:Button(variant="outline")
|
||||
- components/dashboard-header.tsx:DashboardHeader(children 单 slot)
|
||||
- components/sidebar.tsx:mounted 守卫模式(line 83-104)
|
||||
- lucide-react:KeyRound
|
||||
provides:
|
||||
- PermissionModule literal "credential-slot"(lib/permissions.ts)
|
||||
- PERMISSION_MATRIX 中超级管理员/AI模型管理员可访问 credential-slot
|
||||
- /ai-model 页面入口 Button(受 hasPermission 收敛)
|
||||
- 占位 Dialog 挂载点(Phase 3 落实表单内容)
|
||||
affects:
|
||||
- lib/permissions.ts
|
||||
- app/ai-model/page.tsx
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- mounted 守卫(避免 SSR 水合警告,复用 components/sidebar.tsx 同模式)
|
||||
- hasPermission(...) && JSX 收敛(DOM 中完全不存在,非仅 hidden)
|
||||
- Dialog controlled mode(open + onOpenChange + useState 配对)
|
||||
key-files:
|
||||
created: []
|
||||
modified:
|
||||
- lib/permissions.ts
|
||||
- app/ai-model/page.tsx
|
||||
decisions:
|
||||
- 凭据槽位入口 Button 与原「添加新模型」Button 用 div.flex.items-center.gap-2 包裹后作为 DashboardHeader children 单节点传入(DashboardHeader 本身只渲染单 children slot,无 gap)
|
||||
- 入口 Button variant="outline"(与现有页面其他次要按钮如「查看详情」「试听示例」视觉一致)
|
||||
- 图标用 KeyRound(lucide-react 0.454.0 锁定版本支持,凭据语义最贴切)
|
||||
- 占位 Dialog 内联在 page.tsx,不抽离单独组件(Phase 3 才抽到 components/ai-model/CredentialSlotDialog.tsx)
|
||||
- mounted 守卫复用 components/sidebar.tsx:83-104 的 useState(false) + useEffect(setMounted(true)) 模式
|
||||
metrics:
|
||||
duration: ~6min
|
||||
completed: 2026-05-08
|
||||
tasks: 2
|
||||
files_changed: 2
|
||||
lines_added: 53
|
||||
lines_removed: 6
|
||||
---
|
||||
|
||||
# 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 一致):**
|
||||
|
||||
1. PermissionModule union 末尾追加 `| "credential-slot";`(第 14 项)
|
||||
2. 「超级管理员」数组末尾追加 `"credential-slot"`
|
||||
3. 「AI模型管理员」数组末尾追加 `"credential-slot"`
|
||||
4. 文件顶部权限矩阵注释表新增「凭据槽位」行(与代码同步)
|
||||
|
||||
**未动:**
|
||||
- 内容管理员 / 卡牌管理员 / 查看者 / 管理员 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 一致):**
|
||||
|
||||
1. line 1 加 `"use client"` 指令(文件转为 Client Component)
|
||||
2. 新增 imports:`useState, useEffect` (react)、Dialog 子组件 5 个 (`@/components/ui/dialog`)、`KeyRound` (lucide-react)、`hasPermission` (`@/lib/permissions`)
|
||||
3. 函数体顶部加 `mounted` + `isCredentialDialogOpen` 两个 `useState(false)` + 一个 `useEffect(() => setMounted(true), [])`(复用 sidebar.tsx 的 mounted 守卫模式)
|
||||
4. DashboardHeader children 改为 `<div className="flex items-center gap-2">` 包裹,含原「添加新模型」Button + 新增 `{mounted && hasPermission("credential-slot") && <Button variant="outline" onClick={() => setIsCredentialDialogOpen(true)}><KeyRound .../>凭据槽位</Button>}`
|
||||
5. `</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 落地×1
|
||||
- `npx 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)
|
||||
|
||||
## Self-Check: PASSED
|
||||
Loading…
x
Reference in New Issue
Block a user