pmc 28bc2a7251 docs(03-01): 完成「RootLayout 挂载 Sonner Toaster」plan
- 新增 .planning/phases/03-dialog-feedback/03-01-SUMMARY.md(plan 完成总结)
- STATE.md 更新:Phase 3 进度 1/3,milestone 整体 71%(5/7 plan)
- ROADMAP.md 更新:Plan 03-01 标记完成(commit 7065d73),Phase 3 进度 1/3
- REQUIREMENTS.md 更新:CRED-FE-05 反馈通道前置打通(完整闭环依赖 03-02)

任务原子提交:feat 7065d73(app/layout.tsx)
2026-05-08 12:29:49 +08:00

87 lines
9.7 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.

# Roadmap洛天依应用管理后台qy-lty-admin
## 概览
本路线图聚焦 **Milestone v1.0「通用凭据槽位前端集成」**:在 Web 管理后台的 `/ai-model` 大模型管理页面接入后端 v1.0 暴露的 `/api/v1/admin/credential-slot/` 端点,让运营者能够录入与编辑 APP ID + Access Token且 Access Token 仅展示末 4 位脱敏掩码、留空保留旧值。粒度为 **coarse**(目标 2-4 phase按"API 客户端 → 权限收敛 + 页面入口 → 编辑对话框 + 反馈"自下而上分三个 phase 串行推进。
**跨项目依赖(重要)**:本前端 milestone 的代码层工作Phase 1-3**不阻塞** qy_lty 后端,可独立开发并以 mock / 联调环境推进;但**端到端集成测试**与上线验收**强依赖** qy_lty 后端 Milestone v1.0 的 **Phase 2「管理端读写接口」**GET/PUT `/api/v1/admin/credential-slot/`)落地后才能跑通。规划时序上,建议本仓库 Phase 1 与后端 Phase 1-2 并行,本仓库 Phase 3 与后端 Phase 2 收尾对齐,以便 milestone 完成时双方在 `docs/修改记录.md` 互相引用条目。
## Milestones
- 🚧 **v1.0 通用凭据槽位前端集成** — Phase 1-3启动 2026-05-07与 qy_lty 后端 v1.0 并行)
## Phases
**Phase 编号说明:**
- 整数 phase1、2、3当期 milestone 计划工作
- 小数 phase2.1、2.2):紧急插入工作(标记 INSERTED
小数 phase 在数值序内夹在前后整数之间执行。
- [x] **Phase 1: 凭据槽位 API 客户端** — 落地 `lib/api/credential-slot.ts`:类型定义、`mapBackendCredentialSlot` 适配器、`getCredentialSlot()` / `updateCredentialSlot()` 两个调用,并从 `lib/api/index.ts` 导出 ✅ 2026-05-08 完成
- [x] **Phase 2: RBAC 收敛 + AI 模型页入口** — 在 `lib/permissions.ts` 新增 `credential-slot` 模块 key分配给"超级管理员"与"AI模型管理员";在 `/ai-model` 页面渲染受权限收敛的"凭据槽位"入口(按钮或卡片)✅ 2026-05-08 完成
- [ ] **Phase 3: 编辑对话框 + 提交反馈** — 实现 `components/ai-model/CredentialSlotDialog.tsx`React Hook Form + Zod、脱敏掩码预填、留空保留旧值语义并通过 Sonner toast + `error-handler.ts` 完成成功/失败反馈
## Phase Details
### Phase 1: 凭据槽位 API 客户端
**Goal**: 在 `lib/api/` 层提供独立、无 UI 依赖的凭据槽位读写客户端,让后续 phase 可以直接以"调用 + 类型"方式接入,不必再次处理 axios / 适配器细节
**Depends on**: Nothing本 milestone 首个 phase
**Requirements**: CRED-FE-01
**Success Criteria**(必须为真):
1. `lib/api/credential-slot.ts` 导出 `getCredentialSlot()``updateCredentialSlot(payload)` 两个函数,分别走 `apiClient.get` / `apiClient.put` 命中 `/v1/admin/credential-slot/`,与现有 `lib/api/*.ts` 的拦截器、Bearer token 注入、`StandardResponseMiddleware` 解包行为完全一致
2. 模块导出共享类型 `CredentialSlot { appId: string; accessTokenMasked: string; updatedAt: string }` 与提交载荷类型,前端类型为 camelCase后端 snake_case 字段(`app_id` / `access_token` / `updated_at`)通过 `mapBackendCredentialSlot()` 适配器统一转换,沿用 `lib/api/adapters.ts``mapBackend*` 约定
3. `lib/api/index.ts` 导出新模块,`import { getCredentialSlot, updateCredentialSlot, type CredentialSlot } from '@/lib/api'` 在任一组件文件中均能解析通过 `tsc --noEmit`
4. 在浏览器开发态以 mock 后端或后端 Phase 2 联调环境调用 `getCredentialSlot()`,控制台可以看到一条带 `Authorization: Bearer ...` 的请求,且返回值字段名是前端 camelCase说明适配器生效未把后端原始 snake_case 直接透传)
**Plans**: 2 plans
- [x] 01-01-PLAN.md — 新建 lib/api/credential-slot.ts类型 + adapter + GET/PUT+ lib/api/index.ts 末尾追加具名 re-export
- [x] 01-02-PLAN.md — docs/修改记录.md 顶部追加 Phase 1 条目 + 跑双重验证npm run lint + npx tsc --noEmit+ 探针验证 barrel 入口
### Phase 2: RBAC 收敛 + AI 模型页入口
**Goal**: 通过 `lib/permissions.ts` 把"凭据槽位"声明为受控模块、仅向"超级管理员"与"AI模型管理员"开放;并在 `/ai-model` 页面渲染受权限校验收敛的入口控件,让授权用户能看到入口、未授权用户看不到入口
**Depends on**: Phase 1
**Requirements**: CRED-FE-02, CRED-FE-03
**Success Criteria**(必须为真):
1. `lib/permissions.ts``PermissionModule` 类型新增 `'credential-slot'` 字面量,`PERMISSION_MATRIX` 中"超级管理员"与"AI模型管理员"两个角色的模块列表均包含 `'credential-slot'`,其余角色(内容管理员、卡牌管理员、查看者)不包含;调用 `hasPermission('credential-slot')` 在两类账户下返回 `true`,其他角色返回 `false`
2. `getModuleFromPath('/ai-model')` 行为不变(凭据槽位是 `/ai-model` 内嵌子能力,不占独立路由),不引入侧边栏新菜单项
3. 以"AI模型管理员"角色登录访问 `/ai-model`,页面工具栏 / Header 区域可见明确的"凭据槽位"入口控件(按钮或卡片,文案明确);以"内容管理员"或"查看者"角色登录访问同一页面入口控件不渲染DOM 中不存在,而非仅隐藏)
4. 入口控件的可见性判断走 `hasPermission('credential-slot')`,不直接读 `localStorage.user_role` 字符串比较点击入口控件触发对话框打开行为Phase 3 落地后端到端可用,本 phase 至少打开一个空对话框占位以验证联动点存在)
**Plans**: 2 plans
- [x] 02-01-PLAN.md — 扩展 lib/permissions.ts RBACPermissionModule union +1 / 矩阵 +2 角色)+ app/ai-model/page.tsx 加 "use client"、入口 Button、占位 Dialog ✅ 2026-05-08commits d60dd89 + 0bcaa39
- [x] 02-02-PLAN.md — docs/修改记录.md 顶部追加 Phase 2 条目 + plan 级双重验证npx tsc --noEmit 反向断言 + grep 11 条 specifics + 不引入新依赖)✅ 2026-05-08commit 2be1f1d
**UI hint**: yes
### Phase 3: 编辑对话框 + 提交反馈
**Goal**: 落地 `CredentialSlotDialog` 组件让授权运营者能够查看脱敏的当前凭据、安全地提交新值,且成功 / 失败两条路径都有清晰的 toast 反馈;表单语义采用"留空保留旧值"避免回写脱敏掩码假值
**Depends on**: Phase 2
**Requirements**: CRED-FE-04, CRED-FE-05
**Success Criteria**(必须为真):
1. 打开对话框时自动调用 `getCredentialSlot()` 拉取数据:`app_id` 字段以**明文**预填、`access_token` 字段以**末 4 位掩码**显示并附"如需更新请重新输入,留空保留旧值"提示文案、`updated_at` 以只读形式呈现(运营可看到"上次更新"时间)
2. 表单使用 React Hook Form + Zod 校验:当 `app_id` 输入框被清空且与原值不同则提示"不能为空"`access_token` 字段允许留空(语义=保留旧值),但**一旦用户输入新值**则要求非空白字符;提交时**仅传递用户实际改动过的字段**给 `updateCredentialSlot()`**绝不**把脱敏掩码当真值回写
3. 提交成功路径:`updateCredentialSlot()` 返回成功后,调用 `useToast()` 弹出 Sonner 成功 toast中文文案如"凭据槽位已更新"),对话框自动关闭,再次打开时数据被重新拉取并展示新的 `updated_at`
4. 提交失败路径:后端返回非成功响应或网络异常时,错误经由 `lib/api/error-handler.ts` 统一映射为可读中文消息后通过 toast 提示;对话框保持打开、表单字段保留用户输入、不丢失编辑态
5. 端到端串联(依赖 qy_lty 后端 Phase 2 落地):以"超级管理员"账户登录 → 进入 `/ai-model` → 点击凭据槽位入口 → 输入一组真实 APP ID + Access Token → 提交 → 看到成功 toast → 关闭后重新打开对话框,`access_token` 仅显示新值末 4 位、`updated_at` 已刷新
**Plans**: 3 plans
- [x] 03-01-PLAN.md — 在 app/layout.tsx 挂载 Sonner Toaster修复仓库 pre-existing dead code解锁 toast 反馈)✅ 2026-05-08commit 7065d73
- [ ] 03-02-PLAN.md — 新建 components/ai-model/credential-slot-dialog.tsxRHF + Zod + Sonner + handleApiError+ 改 app/ai-model/page.tsx删占位 Dialog + 接入新组件)
- [ ] 03-03-PLAN.md — docs/修改记录.md 顶部追加 Phase 3 条目(含 access_token 强制输入权衡说明 + 候选下一周期 milestone 锚点)+ plan 级双重验证tsc 反向断言 + 13 条 grep specifics + lockfile diff
**UI hint**: yes
## Progress
**执行顺序:**
Phase 按数值顺序执行1 → 2 → 3如出现紧急插入记为 1.1 / 2.1 等)
| Phase | Plans Complete | Status | Completed |
|-------|----------------|--------|-----------|
| 1. 凭据槽位 API 客户端 | 2/2 | ✅ Complete | 2026-05-08 |
| 2. RBAC 收敛 + AI 模型页入口 | 2/2 | ✅ Complete | 2026-05-08 |
| 3. 编辑对话框 + 提交反馈 | 1/3 | In Progress | - |
---
*生成时间2026-05-07Milestone v1.0「通用凭据槽位前端集成」启动;与 qy_lty 后端 v1.0 并行,端到端验收依赖后端 Phase 2 落地*
*2026-05-08 更新Phase 2 全部交付Plan 02-01 + Plan 02-02 共 2/2 完成commit 2be1f1d 修改记录追加 + plan 级双重验证Milestone 进度 2/3 phase67%),等待 /gsd-plan-phase 3 启动 Phase 3*
*2026-05-08 更新Phase 3 plan 规划完成3 plan 串行03-01 挂载 Sonner Toaster → 03-02 新组件 + page 接入 → 03-03 修改记录追加 + 双重验证);等待 /gsd-execute-phase 3 启动执行*
*2026-05-08 更新Plan 03-01 落地commit 7065d73 — RootLayout 挂载 Sonner Toaster修复 9 处 toast pre-existing dead codePhase 3 进度 1/3等待 Plan 03-02 启动*