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)
This commit is contained in:
pmc 2026-05-08 12:29:49 +08:00
parent 7065d73666
commit 28bc2a7251
4 changed files with 158 additions and 18 deletions

View File

@ -150,3 +150,4 @@
*2026-05-08 更新Plan 01-02 落地(修改记录追加 + 双重验证 commit c1743a3Phase 1 全部交付2/2 plan等待 /gsd-plan-phase 2 启动 Phase 2* *2026-05-08 更新Plan 01-02 落地(修改记录追加 + 双重验证 commit c1743a3Phase 1 全部交付2/2 plan等待 /gsd-plan-phase 2 启动 Phase 2*
*2026-05-08 更新Plan 02-01 落地commits d60dd89 + 0bcaa39CRED-FE-02 + CRED-FE-03 状态切到 ✅ DonePhase 2 进度 1/2等待 Plan 02-02 收尾* *2026-05-08 更新Plan 02-01 落地commits d60dd89 + 0bcaa39CRED-FE-02 + CRED-FE-03 状态切到 ✅ DonePhase 2 进度 1/2等待 Plan 02-02 收尾*
*2026-05-08 更新Plan 02-02 落地commit 2be1f1d 修改记录追加 + plan 级双重验证Phase 2 全部交付2/2 planMilestone 进度 2/3 phase67%),等待 /gsd-plan-phase 3 启动 Phase 3* *2026-05-08 更新Plan 02-02 落地commit 2be1f1d 修改记录追加 + plan 级双重验证Phase 2 全部交付2/2 planMilestone 进度 2/3 phase67%),等待 /gsd-plan-phase 3 启动 Phase 3*
*2026-05-08 更新Plan 03-01 落地commit 7065d73 — RootLayout 挂载 Sonner Toaster修复仓库 9 处 toast pre-existing dead codeCRED-FE-05 反馈通道前置打通CRED-FE-05 完整闭环仍依赖 03-02 接入Phase 3 进度 1/3*

View File

@ -62,7 +62,7 @@
4. 提交失败路径:后端返回非成功响应或网络异常时,错误经由 `lib/api/error-handler.ts` 统一映射为可读中文消息后通过 toast 提示;对话框保持打开、表单字段保留用户输入、不丢失编辑态 4. 提交失败路径:后端返回非成功响应或网络异常时,错误经由 `lib/api/error-handler.ts` 统一映射为可读中文消息后通过 toast 提示;对话框保持打开、表单字段保留用户输入、不丢失编辑态
5. 端到端串联(依赖 qy_lty 后端 Phase 2 落地):以"超级管理员"账户登录 → 进入 `/ai-model` → 点击凭据槽位入口 → 输入一组真实 APP ID + Access Token → 提交 → 看到成功 toast → 关闭后重新打开对话框,`access_token` 仅显示新值末 4 位、`updated_at` 已刷新 5. 端到端串联(依赖 qy_lty 后端 Phase 2 落地):以"超级管理员"账户登录 → 进入 `/ai-model` → 点击凭据槽位入口 → 输入一组真实 APP ID + Access Token → 提交 → 看到成功 toast → 关闭后重新打开对话框,`access_token` 仅显示新值末 4 位、`updated_at` 已刷新
**Plans**: 3 plans **Plans**: 3 plans
- [ ] 03-01-PLAN.md — 在 app/layout.tsx 挂载 Sonner Toaster修复仓库 pre-existing dead code解锁 toast 反馈) - [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-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 - [ ] 03-03-PLAN.md — docs/修改记录.md 顶部追加 Phase 3 条目(含 access_token 强制输入权衡说明 + 候选下一周期 milestone 锚点)+ plan 级双重验证tsc 反向断言 + 13 条 grep specifics + lockfile diff
**UI hint**: yes **UI hint**: yes
@ -76,10 +76,11 @@ Phase 按数值顺序执行1 → 2 → 3如出现紧急插入记为 1.1
|-------|----------------|--------|-----------| |-------|----------------|--------|-----------|
| 1. 凭据槽位 API 客户端 | 2/2 | ✅ Complete | 2026-05-08 | | 1. 凭据槽位 API 客户端 | 2/2 | ✅ Complete | 2026-05-08 |
| 2. RBAC 收敛 + AI 模型页入口 | 2/2 | ✅ Complete | 2026-05-08 | | 2. RBAC 收敛 + AI 模型页入口 | 2/2 | ✅ Complete | 2026-05-08 |
| 3. 编辑对话框 + 提交反馈 | 0/3 | Planning complete | - | | 3. 编辑对话框 + 提交反馈 | 1/3 | In Progress | - |
--- ---
*生成时间2026-05-07Milestone v1.0「通用凭据槽位前端集成」启动;与 qy_lty 后端 v1.0 并行,端到端验收依赖后端 Phase 2 落地* *生成时间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 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 更新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 启动*

View File

@ -3,19 +3,19 @@ gsd_state_version: 1.0
milestone: v1.0 milestone: v1.0
milestone_name: 通用凭据槽位前端集成 milestone_name: 通用凭据槽位前端集成
status: completed status: completed
last_updated: "2026-05-08T04:24:42.043Z" last_updated: "2026-05-08T04:26:30Z"
last_activity: 2026-05-08 last_activity: 2026-05-08
progress: progress:
total_phases: 3 total_phases: 3
completed_phases: 2 completed_phases: 2
total_plans: 7 total_plans: 7
completed_plans: 4 completed_plans: 5
percent: 57 percent: 71
--- ---
# Project State — 洛天依应用管理后台qy-lty-admin # Project State — 洛天依应用管理后台qy-lty-admin
**最后更新**: 2026-05-08Phase 2 全部交付Plan 02-01 主体功能 + Plan 02-02 修改记录追加 + plan 级双重验证CRED-FE-02 + CRED-FE-03 已闭环;等待 /gsd-plan-phase 3 启动 Phase 3「编辑对话框 + 提交反馈」 **最后更新**: 2026-05-08Phase 3 启动Plan 03-01 落地 — RootLayout 挂载 Sonner Toaster修复仓库 9 处 toast pre-existing dead codecommit 7065d73Phase 3 进度 1/3等待 Plan 03-02 启动
## 项目引用 ## 项目引用
@ -29,14 +29,14 @@ progress:
``` ```
Milestone: v1.0 通用凭据槽位前端集成 Milestone: v1.0 通用凭据槽位前端集成
Phase: Phase 2「RBAC 收敛 + AI 模型页入口」✅ 已交付 Phase: Phase 3「编辑对话框 + 提交反馈」🚧 进行中
Plan: 02-01 完成 ✅ / 02-02 完成 ✅ Plan: 03-01 完成 ✅ / 03-02 待启动 / 03-03 待启动
Status: Phase 2 fully delivered (2/2 plans done);待 /gsd-plan-phase 3 Status: Phase 3 in progress (1/3 plans done);待 Plan 03-02 启动
Progress: [██████████] 100%Phase 2 内部 2/2 plan 完成milestone 整体 67% Progress: [███▓░░░░░░] 33%Phase 3 内部 1/3 plan 完成milestone 整体 71%
Last activity: 2026-05-08 Last activity: 2026-05-08
``` ```
**下一步行动**:运行 `/gsd-plan-phase 3` 规划 Phase 3「编辑对话框 + 提交反馈」CRED-FE-04 + CRED-FE-05。占位 Dialog 已在 `app/ai-model/page.tsx` line 473-485 就位Phase 3 抽到 `components/ai-model/CredentialSlotDialog.tsx` 并接入 RHF + Zod + Sonner **下一步行动**:运行 Plan 03-02新建 `components/ai-model/credential-slot-dialog.tsx` + RHF/Zod/Sonner + handleApiError`app/ai-model/page.tsx` 删占位 Dialog 接入新组件。Sonner Toaster 已在 RootLayout 挂载commit 7065d73全局 toast 反馈通道已通
## Phase 概览 ## Phase 概览
@ -44,7 +44,7 @@ Last activity: 2026-05-08
|-------|------|------|---------|------| |-------|------|------|---------|------|
| 1 | 凭据槽位 API 客户端 | CRED-FE-01 ✅ | — | ✅ 已交付2/2 plan2026-05-08| | 1 | 凭据槽位 API 客户端 | CRED-FE-01 ✅ | — | ✅ 已交付2/2 plan2026-05-08|
| 2 | RBAC 收敛 + AI 模型页入口 | CRED-FE-02 ✅, CRED-FE-03 ✅ | yes | ✅ 已交付2/2 plan2026-05-08| | 2 | RBAC 收敛 + AI 模型页入口 | CRED-FE-02 ✅, CRED-FE-03 ✅ | yes | ✅ 已交付2/2 plan2026-05-08|
| 3 | 编辑对话框 + 提交反馈 | CRED-FE-04, CRED-FE-05 | yes | 未开始 | | 3 | 编辑对话框 + 提交反馈 | CRED-FE-04, CRED-FE-05(部分 — Toaster 前置已就绪)| yes | 🚧 进行中1/3 plan2026-05-08|
## 联动 milestone ## 联动 milestone
@ -58,10 +58,10 @@ Last activity: 2026-05-08
| 指标 | 数值 | | 指标 | 数值 |
|------|------| |------|------|
| 已完成 phase | 2 / 3 | | 已完成 phase | 2 / 3 |
| 已完成 plan | 5 / 5Phase 1 全部交付 + Phase 2 全部交付| | 已完成 plan | 5 / 7Phase 1 全部交付 + Phase 2 全部交付 + Phase 3 进行中 1/3|
| Milestone 进度 | ~67%2/3 phase 完成)| | Milestone 进度 | ~71%2/3 phase 完成 + Phase 3 内部 33%|
| 启动日期 | 2026-05-07 | | 启动日期 | 2026-05-07 |
| 最近活动 | 2026-05-08 Plan 02-02 落地commit 2be1f1d修改记录追加 + 双重验证| | 最近活动 | 2026-05-08 Plan 03-01 落地commit 7065d73RootLayout 挂载 Sonner Toaster|
### Plan 执行记录 ### Plan 执行记录
@ -71,6 +71,7 @@ Last activity: 2026-05-08
| 01-02 | 2 | 1 | ~360s | 2026-05-08 | | 01-02 | 2 | 1 | ~360s | 2026-05-08 |
| 02-01 | 2 | 2 | ~6min | 2026-05-08 | | 02-01 | 2 | 2 | ~6min | 2026-05-08 |
| 02-02 | 2 | 1 | ~3min | 2026-05-08 | | 02-02 | 2 | 1 | ~3min | 2026-05-08 |
| 03-01 | 1 | 1 | ~1min | 2026-05-08 |
## 累积上下文 ## 累积上下文
@ -83,6 +84,7 @@ Last activity: 2026-05-08
- **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 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 d60dd89app/ai-model/page.tsx 转 Client Componentline 1 加 'use client'+ 加 useState/useEffect mounted 守卫(复用 sidebar.tsx 同模式)+ DashboardHeader 内追加凭据槽位 Buttonvariant=outline / KeyRound 图标 / 受 mounted && hasPermission('credential-slot') 收敛)+ </Tabs> 后插入 controlled mode 占位 DialogDialogTitle「通用凭据槽位」+ 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 收尾修改记录追加。 - **2026-05-08 Plan 02-01 落地**lib/permissions.ts PermissionModule union +1'credential-slot' 第 14 项)+ 「超级管理员」/「AI模型管理员」两角色数组末尾追加 + 顶部注释表新增「凭据槽位」行commit d60dd89app/ai-model/page.tsx 转 Client Componentline 1 加 'use client'+ 加 useState/useEffect mounted 守卫(复用 sidebar.tsx 同模式)+ DashboardHeader 内追加凭据槽位 Buttonvariant=outline / KeyRound 图标 / 受 mounted && hasPermission('credential-slot') 收敛)+ </Tabs> 后插入 controlled mode 占位 DialogDialogTitle「通用凭据槽位」+ 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 收尾修改记录追加。
- **2026-05-08 Plan 02-02 落地**docs/修改记录.md 顶部追加 [2026-05-08] Phase 2 条目commit 2be1f1d纯追加 +32 行 / -0 行;含 7 字段结构 + CONTEXT.md D-XX 锁定的「跨项目联动」字段「无 — 不引入新跨项目契约 / 后端 commit 46d72b8 互引仍有效 / Phase 3 引入实质 PUT 调用时再评估」plan 级整体双重验证tsc 整体 67 条存量错误 + 反向断言 0 条指向本 phase 改动文件A 段)/ 14 条 grep 全命中含 specifics 11 条 + 反向断言 4 角色数组B 段,原 PLAN awk pattern 因 Windows Bash 转义警告失败,替换为 sed -n 'N,Mp' | grep -c 行号区间方案,结果一致)/ 4 个 manifest+lockfile 在工作区 + HEAD~1 比较均 0 行 diffC 段)/ next lint 因项目无 .eslintrc* 跳过沿用 Phase 1 判定D 段。CLAUDE.md 修改记录强制规则闭环Phase 2 全部 5 条 success criteria 全部确认通过Phase 2 已交付2/2 plan - **2026-05-08 Plan 02-02 落地**docs/修改记录.md 顶部追加 [2026-05-08] Phase 2 条目commit 2be1f1d纯追加 +32 行 / -0 行;含 7 字段结构 + CONTEXT.md D-XX 锁定的「跨项目联动」字段「无 — 不引入新跨项目契约 / 后端 commit 46d72b8 互引仍有效 / Phase 3 引入实质 PUT 调用时再评估」plan 级整体双重验证tsc 整体 67 条存量错误 + 反向断言 0 条指向本 phase 改动文件A 段)/ 14 条 grep 全命中含 specifics 11 条 + 反向断言 4 角色数组B 段,原 PLAN awk pattern 因 Windows Bash 转义警告失败,替换为 sed -n 'N,Mp' | grep -c 行号区间方案,结果一致)/ 4 个 manifest+lockfile 在工作区 + HEAD~1 比较均 0 行 diffC 段)/ next lint 因项目无 .eslintrc* 跳过沿用 Phase 1 判定D 段。CLAUDE.md 修改记录强制规则闭环Phase 2 全部 5 条 success criteria 全部确认通过Phase 2 已交付2/2 plan
- **2026-05-08 Plan 03-01 落地**app/layout.tsx 第 3 行新增 `import { Toaster } from '@/components/ui/sonner'`;第 17-21 行 `<body>` 块由单行改为多行结构、`{children}` 之后追加 `<Toaster />`(共 +5 / -1 行commit 7065d73。修复仓库 9 处 `toast(...)` 调用因 portal 未挂载而全部静默失败的 pre-existing dead code 问题Phase 3 业务功能 toast 反馈通道前置打通。tsc 反向断言 0 条指向 app/layout.tsx4 个 lockfile 工作区 0 行 diff不引入新依赖sonner@^1.7.1 已在 deps。决策点挂在 `<body>``{children}` 之后(不是 `<head>`、不是 children 之前);不挂第二个 Radix Toast ToasterCONTEXT D-Toast 锁单一 Sonner 通道);不给 RootLayout 加 `"use client"`components/ui/sonner.tsx 已 'use client'RSC layout 直接渲染 client child 即可);不新增 ThemeProvidersonner.tsx:9 useTheme 已有 'system' fallback。Phase 3 进度 1/3等待 Plan 03-02 启动。
### 待办事项 ### 待办事项
@ -105,14 +107,14 @@ Last activity: 2026-05-08
| PROJECT.md | ✅ 已加入 Milestone v1.0 段 + Active 5 项 | | PROJECT.md | ✅ 已加入 Milestone v1.0 段 + Active 5 项 |
| REQUIREMENTS.md | ✅ Active 段已落地Traceability 已回填 5/5CRED-FE-01 + CRED-FE-02 + CRED-FE-03 已勾选完成 | | REQUIREMENTS.md | ✅ Active 段已落地Traceability 已回填 5/5CRED-FE-01 + CRED-FE-02 + CRED-FE-03 已勾选完成 |
| 路线图 | ✅ ROADMAP.md 落地3 phasecoarsePhase 1 + Phase 2 已完成、Phase 3 待启动 | | 路线图 | ✅ ROADMAP.md 落地3 phasecoarsePhase 1 + Phase 2 已完成、Phase 3 待启动 |
| 当前 phase | Phase 2 ✅ 已交付02-01 + 02-02 全部完成);待 /gsd-plan-phase 3 | | 当前 phase | Phase 3 🚧 进行中03-01 完成03-02 / 03-03 待启动) |
| 当前 milestone | v1.0 通用凭据槽位前端集成 | | 当前 milestone | v1.0 通用凭据槽位前端集成 |
## 会话连续性 ## 会话连续性
**最近会话**2026-05-08 **最近会话**2026-05-08
**最近动作**:执行 Plan 02-02docs/修改记录.md 顶部追加 [2026-05-08] Phase 2 条目 + plan 级双重验证tsc 反向断言 0 条 / 14 条 grep 全命中 / 4 个 lockfile 未动 / lint 跳过沿用 Phase 1commit 2be1f1dPhase 2 全部交付5/5 success criteria 通过) **最近动作**:执行 Plan 03-01app/layout.tsx 挂载 Sonner Toaster + tsc 反向断言 0 条 + lockfile 0 diff + SUMMARY 落地commit 7065d73Phase 3 进度 1/3CRED-FE-05 反馈通道前置打通
**下一会话起点**:运行 `/gsd-plan-phase 3` 规划 Phase 3「编辑对话框 + 提交反馈」CRED-FE-04 + CRED-FE-05抽离 components/ai-model/CredentialSlotDialog.tsx + RHF/Zod + Sonner 反馈 **下一会话起点**:运行 Plan 03-02新建 components/ai-model/credential-slot-dialog.tsx — RHF + Zod + Sonner toast + handleApiError改 app/ai-model/page.tsx 删 Phase 2 占位 Dialog 接入新组件)
## 工作流配置 ## 工作流配置
@ -149,3 +151,4 @@ CLAUDE.md 中两条强制规则,做任何 phase 时必须遵守:
*2026-05-08 Plan 01-02 完成(修改记录追加 + 双重验证Phase 1 全部交付2/2 plan等待 /gsd-plan-phase 2 启动 Phase 2* *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 + 占位 DialogCRED-FE-02 + CRED-FE-03 已交付Phase 2 进度 1/2等待 Plan 02-02 收尾* *2026-05-08 Plan 02-01 完成RBAC 扩展 + /ai-model 页面入口 Button + 占位 DialogCRED-FE-02 + CRED-FE-03 已交付Phase 2 进度 1/2等待 Plan 02-02 收尾*
*2026-05-08 Plan 02-02 完成(修改记录追加 + 双重验证Phase 2 全部交付2/2 planmilestone 进度 67%2/3 phase等待 /gsd-plan-phase 3 启动 Phase 3* *2026-05-08 Plan 02-02 完成(修改记录追加 + 双重验证Phase 2 全部交付2/2 planmilestone 进度 67%2/3 phase等待 /gsd-plan-phase 3 启动 Phase 3*
*2026-05-08 Plan 03-01 完成RootLayout 挂载 Sonner Toaster — commit 7065d73修复 9 处 toast pre-existing dead codePhase 3 进度 1/333%milestone 进度 71%5/7 plan等待 Plan 03-02 启动*

View File

@ -0,0 +1,135 @@
---
phase: 03-dialog-feedback
plan: 01
subsystem: ui
tags: [next.js, react, sonner, toast, root-layout]
# Dependency graph
requires:
- phase: 02-rbac-entry
provides: app/ai-model/page.tsx 占位 Dialogtoast 反馈接入点上游)
provides:
- RootLayout 顶层挂载 Sonner Toaster portal全局 toast.success/error 调用从 dead code 转为可见反馈
- 修复仓库 9 处 toast 调用静默失败的 pre-existing 问题
affects:
- 03-02-dialog-feedback凭据槽位 Dialog 抽离 + RHF/Zod + Sonner toast 反馈)
- 后续任何依赖 toast 反馈的 phase / plan
# Tech tracking
tech-stack:
added: [] # Sonner 已在 deps^1.7.1),未引入新依赖
patterns:
- "RootLayout 全局 portal 挂载点:第三方 client component 直接渲染在 RSC layout 的 <body> 内(无需 layout.tsx 自身 'use client'"
key-files:
created: []
modified:
- "app/layout.tsx+5 / -1 行;第 3 行 import + 第 18-21 行 <body> 块)"
key-decisions:
- "挂载位置选 <body> 内 {children} 之后:保证所有路由 children 渲染完成后 Toaster portal 仍位于 body 顶层"
- "不给 RootLayout 加 'use client'components/ui/sonner.tsx 已 'use client'RSC layout 直接渲染 client child 即可"
- "不挂 Radix Toast Toastercomponents/ui/toaster本 phase 锁定 Sonner 单一通道CONTEXT D-Toast 决策)"
- "不新增 ThemeProvidersonner.tsx:9 useTheme() 已有 fallback 'system',无 ThemeProvider 也能跑"
patterns-established:
- "全局 portal 挂载样板:在 RootLayout <body> 内、{children} 之后追加 portal 元素Toaster / Modals / 全局 overlay 等通用此结构)"
requirements-completed: [CRED-FE-05] # 部分进度 — 本 plan 仅修复 Toaster 挂载前置CRED-FE-05 完整闭环依赖 03-02 提交反馈接入
# Metrics
duration: ~1min
completed: 2026-05-08
---
# Phase 3 Plan 01RootLayout 挂载 Sonner Toaster Summary
**在 `app/layout.tsx` `<body>` 末尾挂载 Sonner `<Toaster />`,修复仓库 9 处 `toast(...)` 调用因 portal 未挂载而全部静默失败的 pre-existing dead code 问题**
## Performance
- **Duration:** ~1 分钟
- **Started:** 2026-05-08T04:25:14Z
- **Completed:** 2026-05-08T04:26:12Z
- **Tasks:** 1 / 1
- **Files modified:** 1
## Accomplishments
- RootLayout 顶层注入 `<Toaster />`,全局 `toast.success(...)` / `toast.error(...)` 命令式调用从 dead code 转为屏幕可见反馈
- 修复 Phase 1+2 累计 9 处现存 `toast(...)` 调用静默失败的 pre-existing bug
- Phase 3 业务功能(提交反馈 toast的硬前置打通为 03-02 的 Dialog 抽离 + RHF/Zod + Sonner 接入扫清 portal 障碍
- 不引入新依赖sonner@^1.7.1 已在 package.json4 个 lockfile 全部 0 行 diff
## Task Commits
每个 task 原子提交:
1. **Task 1在 RootLayout 挂载 Sonner Toaster** - `7065d73` (feat)
## Files Created/Modified
- `app/layout.tsx` - 第 3 行新增 `import { Toaster } from '@/components/ui/sonner'`;第 17-21 行 `<body>` 块由单行 `<body>{children}</body>` 改为多行结构,`{children}` 之后追加 `<Toaster />`(共 +5 / -1 行)
## 具体行号映射
| 改动点 | 原内容 | 新内容 | 行号 |
|--------|--------|--------|------|
| import 块新增 | (无) | `import { Toaster } from '@/components/ui/sonner'` | 第 3 行 |
| `<body>` 块 | `<body>{children}</body>` | `<body>\n {children}\n <Toaster />\n</body>` | 第 17-21 行 |
## Decisions Made
- **挂载位置 `<body>` 内 `{children}` 之后**Toaster 是顶层 portal需在所有 children 之后挂载以确保 z-index / DOM 顺序正确;放在 `<body>` 内而不是 `<html>` 顶层,遵循 Sonner 官方推荐
- **保留单引号风格**:现有 `import './globals.css'` 用单引号,新增 import 沿用单引号保持文件内一致;与 plan body 描述一致plan 的 `<verify>` grep pattern 使用双引号是 verify 脚本风格不一致,与实际写入内容无关)
- **不给 RootLayout 加 `"use client"`**components/ui/sonner.tsx 顶部已 `"use client"`RSC layout 直接渲染 client child 即可,无需整个 RootLayout 客户端化
- **不挂第二个 Radix Toast Toaster**:本 phase 锁定 Sonner 单一通道CONTEXT.md D-Toast 决策),避免双 Toaster 系统并存
## Deviations from Plan
None — plan executed exactly as written。所有「严格约束」全部遵守
- 未挂 Radix Toast `<Toaster />`
- 未新增 ThemeProvider / next-themes 包装
- 未改 metadata / html lang / globals.css import 顺序
- 未给 RootLayout 加 `"use client"`
- 本 plan 唯一改动 `app/layout.tsx` 的 task未挂任何其他 provider
## Issues Encountered
无。Plan 描述精确(仅 1 个 task2 处精确改动verify 段除 grep 引号风格与 write 内容不一致这一非阻塞风格差异外,全部命中。
## 验证结果
| 验证项 | 期望 | 实际 | 结论 |
|--------|------|------|------|
| A 段 tsc 反向断言 | `npx tsc --noEmit` 输出过滤后 0 条指向 `app/layout.tsx` | 0 条命中 | ✅ 通过 |
| B 段 import grep | 命中 1 行 `from '@/components/ui/sonner'` | 第 3 行命中 | ✅ 通过 |
| B 段 `<Toaster />` grep | 命中 1 行 `<Toaster />` | 第 20 行命中 | ✅ 通过 |
| C 段 lockfile diff | `git diff --stat HEAD -- package.json *.lock` 输出 0 行 | 0 行 | ✅ 通过 |
| D 段 lint | 项目无 `.eslintrc*`,沿用 Phase 1+2 判定(不阻塞) | 跳过 | ✅ 沿用判定 |
`npx tsc --noEmit` 整体存量错误 67 条与本 plan 改动文件零相关(沿用 Phase 1+2 判定),未引入指向 `app/layout.tsx` 的新错误。
## User Setup Required
无 — 本 plan 不引入新依赖、不需要环境变量、不需要外部服务配置。
## Next Phase Readiness
- ✅ Sonner Toaster portal 已在全局挂载Phase 3 Plan 02 可以放心调 `toast.success(...)` / `toast.error(...)`
- ✅ 4 个 lockfile 未动,下游 plan 不需重装依赖
- ⏭️ 下一步:执行 Plan 03-02CredentialSlotDialog 组件抽离 + RHF/Zod 表单 + Sonner 提交反馈,落地 CRED-FE-04 + 闭环 CRED-FE-05
- ⚠️ 本 plan 单独无法跑通端到端 toast 反馈(需 Plan 03-02 联动验证),属于硬前置类 plan 的预期形态
## Self-Check: PASSED
- ✅ `app/layout.tsx` 存在且包含改动(第 3 行 import + 第 17-21 行 `<body>` 块)
- ✅ commit `7065d73` 存在于 git log`git log --oneline -1` 命中)
- ✅ tsc 反向断言通过0 条新错误指向 app/layout.tsx
- ✅ lockfile 0 diff不引入新依赖
---
*Phase: 03-dialog-feedback*
*Plan: 01*
*Completed: 2026-05-08*