Files
DevFlow/docs/05-代码审查/定时走查-2026-06-15-第6轮.md
T
lxy 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 进度条 + 数字 stat,GPU 友好动画,**无性能问题**
- aiShared 破环正确(ARC-06),nextMsgId 两窗口各自独立不冲突
---
## 📊 本轮摘要
| 类别 | 数 | 代表 |
|---|---|---|
| 价值闭环 | 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窗口维度)首次深查即暴露 P1(listener 泄漏)+ 状态机缺口。**再次印证 task2/3 垂直走查价值** — 横切收敛后,垂直切片是新发现来源(i18n/api/列表页/AI窗口 4 个垂直切片均挖出真问题)。
**方法论**:分离窗口 P1R1+R2)经地面核 stopListener 零调用坐实(避免第5轮代理 A 假阳性教训),走查发现须地面验证。
todo 映射:CR-260615-24P1 分离窗口 listener/ CR-25P2 状态机)/ CR-26P2 列表页)/ CR-27P2 Dashboard)。