Files
DevFlow/docs/05-代码审查/定时走查-2026-06-15-第6轮.md
绝尘 f30df333b3 docs: 巡检简报+todo 回写(2026-06-15 第2轮)
巡检发现:
- 2196c77 workflow 整文件替换回退破坏(AiChat+Ideas 12项功能)
- B-260615-03 truncated 标志已落地
- AR-8-scroll scrollToBottom smooth 已补
- CR-260615-09 .ai-md 残余:4详情页各21处 scoped .ai-md
  (全局 ai-md.css 75行已建,旧副本待清理但非阻塞)
2026-06-15 17:23:57 +08:00

74 lines
5.5 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.
# 定时代码走查 — 第 6 轮2026-06-15
> 触发:定时走查 cron每 30 分钟)。范围 = **列表页 + Dashboard + AI 面板/窗口垂直切片**此前从未深查。1 新提交CR-22 修复)。
> 方法2 路代理A 列表页 / B Dashboard+AI窗口+ 主代理地面核 stopListener。
> 性质:核对记录,不改产品代码(本会话 session-role-diagnose-only。todo 见 `docs/todo.md`。
> 关联:[第1-5轮](./)。
---
## CR-22 ✅ + CR-23 撤销(价值第 5 次闭环)
- `16aeacc` CR-22 ✅types.ts 3 枚举注释对齐后端Task/Idea/Project status+ 删 AiConversationSummary.models 冗余
- CR-23 撤销(不适用):接收方核对 B-34「Tauri 不转」注释在 ARC-05 拆分时已简化workflow.ts:81/project.ts:58 仅风格对齐无错误说明)
---
## 🔴 分离窗口生命周期新功能首次深查P1 核心)
**代理 B R1-R5**。地面核 `stopListener`(useAiEvents.ts:258) **全仓零调用**grep App/AiChat/AiDetached onUnmounted/onBeforeUnmount 都不调)确认 R2。
### CR-260615-24 [P1] listener 双注册 + 永不清理R1+R2
- **R1 双窗口重复消费 ai-chat-event**:后端 `app.emit`stream_recv/agentic/commands/audit 多处)是**全局广播**发给所有 webview。主窗口AiChat.vue:790+ 分离窗口AiDetached 渲染 AiChat各注册 `listen('ai-chat-event')`,两窗口 handleEvent 都触发 → delta 各 `+=` 一次 / AiAgentRound 各 push 空气泡。当前靠 App.vue:94 `v-if="panelOpen && !detached"` detach 时卸载主窗口 AiChat 间接停,但 state 是模块级单例handleEvent 仍写主窗口 state**脆弱隐式契约**。
- **R2 stopListener 零调用**useAiEvents.ts:258 定义但全仓无调用点 → listener + watchdog 永久泄漏startListener 幂等防重复注册,但卸载不释放)。
- **边界影响**reattach 重叠窗口期多一条空 assistant 消息(非崩溃/非数据损坏)。
- **修**AiChat.vue onBeforeUnmount 补 `store.stopListener()` + detach 时主窗口显式 stopListener / reattach startListener或后端 `emit_to(label)` 定向。
### CR-260615-25 [P2] 分离窗口状态机缺口R3/R4/R5
- **R3**`win.once('tauri://destroyed')` 置 detached=false 但**不恢复 panelOpen=true**(只 reattachPanel 显式设)→ 用户直接 X 关分离窗口后面板消失,需手动 Ctrl+I
- **R4**`resumeInDetached`(useAiWindow.ts:79-95) 强行重建生成态(读 df-ai-gen 置 streaming=true + push 空气泡),与后端 `ai_is_generating` 真值可能失配 → 假气泡 / 130s 后 watchdog 假超时
- **R5**:分离窗口 onMounted `switchConversation`(useAiWindow.ts:81) + loadConversations 内自动 switch后端 **AiSession 单例** activeConversationId 被分离窗口覆盖 → 主窗口期间发消息可能落错会话B-22 同类延伸)
---
## 🟡 列表页(代理 A
### CR-260615-26 [P2] AR-11 + B-29 契约交互 + Tasks 空态R-1/Y-2
- **R-1**AR-11 监听器project.ts:38对 task 调 `loadTasks()` **无参 → 全量加载**,破坏 B-260615-29 建立的「store.tasks 反映当前筛选」契约。filteredGroups 二次过滤**兜住结果正确**,但 store.tasks 变全量createTask push 到全量数组)+ 性能
- **Y-2**Tasks.vue:39-71 **无 loading/error/empty 兜底**加载失败或无结果时空白页store.error/loading 零引用)。对比 Projects.vue:107 至少有空态
### ✅ 列表页亮点
- **Projects/Tasks i18n 100%**grep 确认中文仅注释/console— CR-08 范围内这两页**无硬编码遗漏**
- Projects.vue useConfirm composable 抽离DRY消除 4 视图重复)
- B-260615-29 筛选重载注释保留(可追溯)
---
## 🟡 Dashboard代理 B
### CR-260615-27 [P2] refresh 兜底 + stage 颜色 + 死代码M1/M3/L4
- **M1**refreshDashboard.vue:202-204Promise.all **无 try/catch**,任一接口失败 unhandledrejection + 用户无反馈onMounted 有 try/catch 但 refresh 无)
- **M3**getProjectStage(:150) status→stage 映射 **planning 归 coding stage颜色紫但 label planning**颜色语义撒谎cancelled 归 testing 同)
- **L4**:决策/批注两 panel(:103-120) 永远空态CSS(.decision-row/.anno-row :504-572) 完整但模板未用 = **死代码**
### ✅ Dashboard 亮点
- **无图表库**,纯 CSS 进度条 + 数字 statGPU 友好动画,**无性能问题**
- aiShared 破环正确ARC-06nextMsgId 两窗口各自独立不冲突
---
## 📊 本轮摘要
| 类别 | 数 | 代表 |
|---|---|---|
| 价值闭环 | 1 | CR-22 ✅ + CR-23 撤销 |
| P1 新发现 | 1 | 分离窗口 R1+R2 listener 双注册+泄漏CR-24|
| P2 新发现 | 3 | 分离窗口状态机CR-25/ 列表页契约+空态CR-26/ DashboardCR-27|
| 亮点 | 4 | 列表页 i18n 100% / Dashboard 纯 CSS 无性能问题 / aiShared 破环 / useConfirm DRY |
**本轮价值****分离窗口是新功能,前几轮横切(按提交/改动)完全没覆盖**垂直切片Dashboard+AI窗口维度首次深查即暴露 P1listener 泄漏)+ 状态机缺口。**再次印证 task2/3 垂直走查价值** — 横切收敛后垂直切片是新发现来源i18n/api/列表页/AI窗口 4 个垂直切片均挖出真问题)。
**方法论**:分离窗口 P1R1+R2经地面核 stopListener 零调用坐实避免第5轮代理 A 假阳性教训),走查发现须地面验证。
todo 映射CR-260615-24P1 分离窗口 listener/ CR-25P2 状态机)/ CR-26P2 列表页)/ CR-27P2 Dashboard