Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- Create docs/brainstorming/ with 5 discussion records (Mar 16 - Apr 7) - Archive ~30 outdated audit reports (V5-V11) to docs/archive/old-audits/ - Archive superseded analysis docs to docs/archive/old-analysis/ - Archive completed session plans to docs/archive/old-plans/ - Archive old test reports/validations to respective archive folders - Remove empty directories left after moves - Keep current docs: TRUTH.md, feature docs, deployment, knowledge-base, superpowers
196 lines
4.5 KiB
Markdown
196 lines
4.5 KiB
Markdown
# P0 问题修复报告
|
||
|
||
> **日期**: 2026-03-16
|
||
> **状态**: 已完成
|
||
|
||
---
|
||
|
||
## 一、问题概述
|
||
|
||
在系统上线前验证过程中发现以下 P0 级别问题:
|
||
|
||
| 问题 ID | 描述 | 严重程度 |
|
||
|---------|------|----------|
|
||
| P0-1 | Agent 对话回复内容重复 | P0 阻塞 |
|
||
| P0-2 | Tab 切换后对话内容消失 | P0 阻塞 |
|
||
| P0-3 | 团队等 Tab 操作后内容消失 | P0 阻塞 |
|
||
|
||
---
|
||
|
||
## 二、根因分析
|
||
|
||
### P0-1: 消息内容重复
|
||
|
||
**根本原因**:
|
||
- 双重流式回调 - `sendMessage` 的 `onDelta` 和 `initStreamListener` 都在更新同一条消息
|
||
- 两个回调同时追加 delta,导致内容重复
|
||
|
||
**涉及文件**:
|
||
- `desktop/src/store/chatStore.ts`
|
||
- `desktop/src/components/ChatArea.tsx`
|
||
|
||
### P0-2: Tab 切换后内容消失
|
||
|
||
**根本原因**:
|
||
- `chatStore.messages` 未持久化 - 只持久化了 `conversations` 和 `currentModel`
|
||
- Tab 切换时 `messages` 状态被重置为空数组
|
||
|
||
**涉及文件**:
|
||
- `desktop/src/store/chatStore.ts`
|
||
|
||
### P0-3: 团队状态丢失
|
||
|
||
**根本原因**:
|
||
- `teamStore` 使用普通 Zustand,没有 persist 中间件
|
||
- `activeTeam` 状态未被持久化
|
||
|
||
**涉及文件**:
|
||
- `desktop/src/store/teamStore.ts`
|
||
|
||
---
|
||
|
||
## 三、修复方案
|
||
|
||
### 3.1 P0-1 修复: 消息重复
|
||
|
||
**修改文件**: `desktop/src/store/chatStore.ts`
|
||
|
||
**修改内容**:
|
||
```typescript
|
||
// 移除 sendMessage 中的 onDelta 回调,让 initStreamListener 统一处理
|
||
// 修改前
|
||
onDelta: (delta: string) => {
|
||
set((state) => ({
|
||
messages: state.messages.map((m) =>
|
||
m.id === assistantId
|
||
? { ...m, content: m.content + delta }
|
||
: m
|
||
),
|
||
}));
|
||
},
|
||
|
||
// 修改后
|
||
onDelta: () => { /* Handled by initStreamListener to prevent duplication */ },
|
||
```
|
||
|
||
### 3.2 P0-2 修复: 消息持久化
|
||
|
||
**修改文件**: `desktop/src/store/chatStore.ts`
|
||
|
||
**修改内容**:
|
||
```typescript
|
||
// 修改前
|
||
partialize: (state) => ({
|
||
conversations: state.conversations,
|
||
currentModel: state.currentModel,
|
||
}),
|
||
|
||
// 修改后
|
||
partialize: (state) => ({
|
||
conversations: state.conversations,
|
||
currentModel: state.currentModel,
|
||
messages: state.messages, // 新增
|
||
currentConversationId: state.currentConversationId, // 新增
|
||
}),
|
||
```
|
||
|
||
### 3.3 P0-3 修复: 团队状态持久化
|
||
|
||
**修改文件**: `desktop/src/store/teamStore.ts`
|
||
|
||
**修改内容**:
|
||
```typescript
|
||
// 修改前
|
||
import { create } from 'zustand';
|
||
export const useTeamStore = create<TeamStoreState>((set, get) => ({ /* ... */ }));
|
||
|
||
// 修改后
|
||
import { create } from 'zustand';
|
||
import { persist } from 'zustand/middleware';
|
||
export const useTeamStore = create<TeamStoreState>()(
|
||
persist(
|
||
(set, get) => ({ /* ... */ }),
|
||
{
|
||
name: 'zclaw-teams',
|
||
partialize: (state) => ({
|
||
teams: state.teams,
|
||
activeTeam: state.activeTeam,
|
||
}),
|
||
}
|
||
)
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## 四、验证步骤
|
||
|
||
### 4.1 手动验证清单
|
||
|
||
- [ ] 启动应用,- [ ] 发送消息,- [ ] 验证消息内容不重复
|
||
- [ ] 切换到团队 Tab
|
||
- [ ] 切换回聊天 Tab
|
||
- [ ] 验证消息仍然存在
|
||
- [ ] 刷新页面 (F5)
|
||
- [ ] 验证消息历史恢复
|
||
- [ ] 创建团队
|
||
- [ ] 切换到其他 Tab
|
||
- [ ] 验证团队仍然选中
|
||
|
||
### 4.2 自动化测试建议
|
||
|
||
```typescript
|
||
// tests/desktop/state-persistence.test.ts
|
||
|
||
describe('State Persistence', () => {
|
||
it('should persist messages across tab switches', async () => {
|
||
// 1. 发送消息
|
||
// 2. 切换 tab
|
||
// 3. 切换回来
|
||
// 4. 验证消息存在
|
||
});
|
||
|
||
it('should not duplicate message content', async () => {
|
||
// 1. 发送消息
|
||
// 2. 等待流式响应完成
|
||
// 3. 验证内容不重复
|
||
});
|
||
|
||
it('should persist activeTeam across tab switches', async () => {
|
||
// 1. 选择团队
|
||
// 2. 切换 tab
|
||
// 3. 切换回来
|
||
// 4. 验证团队仍然选中
|
||
});
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## 五、后续工作
|
||
|
||
1. **执行用户旅程验证** - 按计划的 10 个用户旅程进行端到端测试
|
||
2. **编写回归测试** - 为状态持久化添加自动化测试
|
||
3. **问题追踪** - 发现新问题时记录到问题池
|
||
4. **回归验证** - 修复后重新验证相关功能
|
||
|
||
---
|
||
|
||
## 六、风险评估
|
||
|
||
| 风险 | 影响 | 缓解措施 |
|
||
|------|------|----------|
|
||
| localStorage 容量 | 消息过多可能超出限制 | 限制消息历史长度 |
|
||
| 性能影响 | 持久化增加 IO | 使用 debounce 优化 |
|
||
| 数据一致性 | 多 Tab 数据同步 | 添加 storage 事件监听 |
|
||
|
||
---
|
||
|
||
## 七、结论
|
||
|
||
P0 问题已修复,系统可以进行用户旅程验证。建议:
|
||
|
||
1. 立即进行 J1-J3 核心聊天功能验证
|
||
2. 修复发现的新问题
|
||
3. 完成全部 10 个用户旅程验证后生成最终报告
|