# Sprint 2 任务拆解(W2-3 · 9 人天 · 56 子任务)— V10 选项 B
> **技术栈**:Vite 5 + React 19 + TypeScript 5 + Tailwind 4 + **Zustand 4** + **TanStack Query 5** + **React Hook Form 7** + Vitest 2 + Playwright 1.55
> **目标**:整体重写 7 个手写 hook + 引入现代状态管理 + 后端 5 端点对接
> **闸门**:G1(OpenAPI 类型生成无 `any` + ESLint 0 warning)
> **V10 变化**:从 18d 缩到 9d(节省 9d = 删 33 any 修复 + 7 hook 重构 + 6 文件重写)
> **PM 决策(2026-07-03)**:整体重写为新实现;Playwright 视觉回归 + Chromatic 验收
---
## ⚠️ V10 关键变化(与 V2 对比)
| 维度 | V2 | V10 选项 B |
|---|---|---|
| 框架 | Next.js 16(保留) | **Vite 5 + React 19**(重写) |
| 状态管理 | 自定义 7 个手写 hook | **Zustand 4**(4 个 slice) |
| 数据获取 | 自写 useChat + fetch | **TanStack Query 5** |
| 表单 | 受控 + 3-step 状态机 | **React Hook Form 7** + Zod |
| 测试 | Vitest + Playwright(保留) | 同 |
| 视觉回归 | 无 | **+ Chromatic**(V10 新增) |
| 总子任务 | 58 | 56(少 2:合并到 Zustand store) |
| 总估时 | 18d | **9d** |
---
## 0. Sprint 2 概览
| 任务 | 主任务 | 估时 | 子任务数 |
|---|---|---|---|
| T-A-14 | Vitest + RTL + MSW + Chromatic 配置 | 0.5d | 4 |
| T-A-15 | 示范单测:ModeIndicator | 0.25d | 3 |
| T-A-16 | 示范单测:SafeMarkdown | 0.25d | 3 |
| T-A-17 | 示范单测:FormCard(RHF 版) | 0.5d | 4 |
| T-A-18 | Playwright + Chromatic 配置 | 0.5d | 3 |
| T-A-19 | 示范 e2e:theme.spec | 0.5d | 3 |
| T-A-20 | 示范 e2e:navigation.spec | 0.5d | 3 |
| T-A-21 | OpenAPI Codegen + Zod schema 复用 | 1.0d | 5 |
| T-A-22 | 示范调用:MSW mock server | 0.5d | 4 |
| T-B-01 | **Zustand store** + 5 query hooks(chat) | 1.0d | 5 |
| T-B-02 | TanStack Query 3 个 consultations 端点 | 0.5d | 3 |
| T-B-03 | TanStack Query 4 个 plans 端点 | 0.5d | 3 |
| T-B-04 | RHF 重写 FormCard + assessment | 1.0d | 5 |
| T-B-05 | audit/upload 端点(V10 重写) | 1.0d | 4 |
| T-B-06 | **Chromatic 视觉基线**(V10 新增) | 0.5d | 3 |
| T-B-07 | **Vite build + bundle 体积验证** | 0.5d | 4 |
| **合计** | **16 任务** | **9.5d** | **56** |
---
## T-A-14 · Vitest + RTL + MSW + Chromatic 配置(0.5d · 4 子任务)
### ST-S2-A-14.1 写 `vitest.config.ts`(0.125d)
- **产出**:`apps/web/vitest.config.ts`(jsdom env + setup 文件 + alias)
- **V10 变化**:保留 jsdom;alias 指向 `packages/ui` 和 `packages/lib`
### ST-S2-A-14.2 写 `setup.ts`(0.125d)
- **产出**:`@testing-library/jest-dom/vitest` + MSW server 启动/关闭 + Zustand store reset helper
### ST-S2-A-14.3 写 `renderWithProviders.tsx`(0.125d)
- **产出**:`packages/test-utils/renderWithProviders.tsx`
- QueryClient(测试用,禁用 retry)
- ThemeProvider
- Router(MemoryRouter)
- Zustand 注入 reset 函数
- **验收**:
- [ ] `pnpm --filter web test` 跑通
### ST-S2-A-14.4 占位测试验证(0.125d)
- **产出**:`Math.test.ts`(1+1=2)
- **验收**:
- [ ] 占位测试 1 绿
---
## T-A-15 · 示范单测:ModeIndicator(0.25d · 3 子任务)
### ST-S2-A-15.1 写 4 mode 渲染测试(0.125d)
- **覆盖**:explore / generating / auditing / adjusting
- **验收**:
- [ ] 4 模式 label 正确
### ST-S2-A-15.2 写 `deriveMode` 决策树测试(0.0625d → 0d)
- **覆盖**:
- isAuditActive → auditing
- currentPlan + no audit → adjusting
- province + score → generating
- 其他 → explore
- **验收**:
- [ ] 100% branch coverage
### ST-S2-A-15.3 验证 100% 覆盖(0.0625d → 0d)
- **命令**:`pnpm test --coverage`
- **验收**:
- [ ] `ModeIndicator.tsx` line + branch 各 100%
---
## T-A-16 · 示范单测:SafeMarkdown(0.25d · 3 子任务)
### ST-S2-A-16.1 写 XSS 注入测试(0.125d)
- **覆盖**:
- `` → 渲染为文本
- `javascript:alert(1)` → 链接被剥离
- `
` → onerror 剥离
- `