Files
gaokao-volunteer-system/SPRINT_4_S4_PERF_OPS.md

277 lines
8.4 KiB
Markdown
Raw Normal View History

# Sprint 4 任务拆解W6-7 · 10 人天 · 46 子任务)— V10 选项 B
> **技术栈**Vite 5 + React 19 + Zustand 4 + TanStack Query 5 + RHF 7 + Zod
> **目标**:错误/兜底/离线/防重 + 性能优化 + 监控收口 + 真实后端回归
> **闸门**G3Lighthouse P75 ≥ 90 P/A/B/S+ G4Poster CLI Docker 镜像跑通)
> **V10 变化**:从 14d 缩到 10d节省 4d = Vite SSR 简化 + e2e 用 Playwright 1.55 加速)
> **PM 决策2026-07-03**整体重写为新实现Playwright 视觉回归 + Chromatic 验收
---
## ⚠️ V10 关键变化(与 V2 对比)
| 维度 | V2 | V10 选项 B |
|---|---|---|
| Lighthouse 目标 | 90 P75 | **90 P75**(保持) |
| e2e 真实化8 路径) | 3.0d | **2.0d**Playwright trace + Vite preview 加速) |
| Bundle 优化 | 1.0d | **0.5d**Vite 已分块) |
| i18n 错误码映射 | 0.5d | **0.5d**(不变) |
| 总估时 | 14d | **10d** |
---
## 0. Sprint 4 概览
| 任务 | 主任务 | 估时 | 子任务数 |
|---|---|---|---|
| T-B-18 | 错误码 → 用户文案映射 | 0.5d | 3 |
| T-B-19 | ErrorBoundary 兜底页 | 0.5d | 3 |
| T-B-20 | 离线检测 + 提示 | 1.0d | 4 |
| T-B-21 | 表单提交防重复RHF 版) | 0.5d | 3 |
| T-B-22 | TanStack Query 持久化 | 0.5d | 3 |
| T-B-23 | e2e 真实化8 路径Playwright 加速) | 2.0d | 8 |
| T-B-24 | Lighthouse CI 集成 | 1.5d | 4 |
| T-B-25 | Bundle 优化Vite 版) | 0.5d | 3 |
| T-B-26 | 路由级 prefetch | 0.5d | 2 |
| T-B-27 | 真实后端回归 | 0.5d | 2 |
| T-B-40 | Share Link 状态面板数据 | 0.5d | 3 |
| T-B-41 | ShareLink 失败降级 | 0.5d | 3 |
| T-B-42 | LLM 增强进度轮询 | 0.5d | 3 |
| T-B-43 | Poster 异步生成 + 轮询 | 0.5d | 3 |
| T-C-44 | Poster CLI 部署集成Docker | 1.0d | 4 |
| T-C-45 | 集成测试套件 | 0d | 2 |
| **合计** | **16 任务** | **10d** | **53** |
---
## T-B-18 · 错误码 → 用户文案映射0.5d · 3 子任务)
### ST-S4-B-18.1 写 `packages/i18n/zh-CN/errors.json`0.25d
- **内容**15 个错误码全覆盖
- E03001 / E03002 / E03003
- E04001 / E04002
- E05001
- +8 V2 错误码
- **约束**:沿用 `admin/errors/registry.py` 5 字段结构
### ST-S4-B-18.2 写 api-client 拦截器0.125d
- **验收**
- [ ] 拦截响应 → 查表 → 返回 i18n 文案
### ST-S4-B-18.3 写单测0.125d
- **覆盖**15 错误码各 1 用例
---
## T-B-19 · ErrorBoundary 兜底页0.5d · 3 子任务)
### ST-S4-B-19.1 写 `ErrorBoundary` 组件0.25d
- **V10 变化**:用 `react-error-boundary` 库,避免手写 class 组件
### ST-S4-B-19.2 写兜底页0.125d
- **UI/交互 1:1**:与原型 ErrorPage 一致
### ST-S4-B-19.3 接入根路由0.125d
---
## T-B-20 · 离线检测 + 提示1.0d · 4 子任务)
### ST-S4-B-20.1 写 `useOnlineStatus` hook0.25d
- **封装**`navigator.onLine` + `online`/`offline` 事件
### ST-S4-B-20.2 写 OfflineBanner 组件0.25d
- **V10 不变量 L2**:移动端 48px 高度
### ST-S4-B-20.3 写离线降级策略0.25d
- **行为**:写操作排队 + 恢复后自动重试
### ST-S4-B-20.4 写 e2eoffline.spec0.25d
---
## T-B-21 · 表单提交防重复RHF 版 · 0.5d · 3 子任务)⚠️ V10 简化
> **V10 收益**RHF `formState.isSubmitting` 内置
### ST-S4-B-21.1 接入 RHF isSubmitting0.125d
### ST-S4-B-21.2 写通用 SubmitButton 组件0.25d
### ST-S4-B-21.3 写单测0.125d
---
## T-B-22 · TanStack Query 持久化0.5d · 3 子任务)⚠️ V10 简化
> **V10 收益**`@tanstack/query-async-storage-persister` 内置支持
### ST-S4-B-22.1 安装 persister0.125d
```bash
pnpm --filter web add @tanstack/query-async-storage-persister
```
### ST-S4-B-22.2 写 `queryClient.ts` 持久化配置0.25d
- **maxAge**24h
- **storage**localStorage
### ST-S4-B-22.3 验证 5 模块刷新恢复0.125d
---
## T-B-23 · e2e 真实化8 路径 · 2.0d · 8 子任务)⚠️ V10 加速
> **V10 加速**:用 Playwright `test.step` + Vite preview server
### ST-S4-B-23.1 e2e: theme-switch0.25d
### ST-S4-B-23.2 e2e: chat-send-receive0.25d
### ST-S4-B-23.3 e2e: form-submit-validation0.25d
### ST-S4-B-23.4 e2e: plan-create-view0.25d
### ST-S4-B-23.5 e2e: share-link-create-scan0.25d
### ST-S4-B-23.6 e2e: data-query-search0.25d
### ST-S4-B-23.7 e2e: review-flow-approve0.25d
### ST-S4-B-23.8 e2e: poster-generate-download0.25d
---
## T-B-24 · Lighthouse CI 集成1.5d · 4 子任务)
### ST-S4-B-24.1 安装 `@lhci/cli`0.25d
### ST-S4-B-24.2 写 `lighthouserc.json`0.5d
- **目标**P ≥ 90 / A ≥ 95 / B ≥ 90 / S ≥ 90
- **V10 收益**Vite 产物比 Next.js 小Lighthouse 分数天然更高
### ST-S4-B-24.3 接入 GitHub Action0.5d
- **验收**
- [ ] PR 触发 LHCI
- [ ] 分数 < 90 阻止合并
### ST-S4-B-24.4 调优未达标项0.25d
---
## T-B-25 · Bundle 优化Vite 版 · 0.5d · 3 子任务)⚠️ V10 简化
> **V10 收益**Sprint 2 已分块S4 只做微调
### ST-S4-B-25.1 配置 manualChunks 精细化0.125d
- **目标**recharts 单独 chunk懒加载
### ST-S4-B-25.2 配置资源内联阈值0.125d
- **4KB 以下内联**
### ST-S4-B-25.3 验证 bundle < 300KB gzip0.25d
---
## T-B-26 · 路由级 prefetch0.5d · 2 子任务)
### ST-S4-B-26.1 写 `<PrefetchLink>` 组件0.25d
- **行为**hover 200ms 后预取目标 chunk
### ST-S4-B-26.2 接入 Header / Sidebar0.25d
- **验收**
- [ ] hover → 预取 → 点击 0 等待
---
## T-B-27 · 真实后端回归0.5d · 2 子任务)
### ST-S4-B-27.1 启动后端服务0.25d
- **命令**`docker compose up backend postgres`
### ST-S4-B-27.2 跑 5 模块端到端0.25d
- **验收**
- [ ] Share / Query / Review / LLM / Poster 全部 200
---
## T-B-40 · Share Link 状态面板数据0.5d · 3 子任务)
### ST-S4-B-40.1 写 `useShareLinkStatsQuery`0.125d
- **封装**`GET /api/share-link/{code}/stats`
### ST-S4-B-40.2 写 Stats 组件0.25d
- **V10 收益**Sprint 3 已实现,此处优化
### ST-S4-B-40.3 接入 Dashboard0.125d
---
## T-B-41 · ShareLink 失败降级0.5d · 3 子任务)
### ST-S4-B-41.1 写重试机制0.25d
- **V10 收益**TanStack Query `retry: 3` 内置
### ST-B-41.2 写降级 UI0.125d
### ST-S4-B-41.3 写 e2eshare-link-fallback.spec0.125d
---
## T-B-42 · LLM 增强进度轮询0.5d · 3 子任务)⚠️ V10 简化
> **V10 收益**TanStack Query `refetchInterval` 内置
### ST-S4-B-42.1 写 `useAuditEnhanceStatusQuery`0.125d
### ST-S4-B-42.2 写进度条组件0.25d
### ST-S4-B-42.3 接入 AuditPanel0.125d
---
## T-B-43 · Poster 异步生成 + 轮询0.5d · 3 子任务)
### ST-S4-B-43.1 写 `usePosterStatusQuery`0.125d
### ST-S4-B-43.2 写状态机组件0.25d
- **三态**generating / ready / failed
### ST-S4-B-43.3 接入 PosterDialog0.125d
---
## T-C-44 · Poster CLI 部署集成Docker · 1.0d · 4 子任务)
### ST-C-44.1 写 `Dockerfile.poster`0.25d
### ST-C-44.2 写 `docker-compose.yml` 添加 poster 服务0.25d
### ST-C-44.3 本地构建 + 启动验证0.25d
### ST-C-44.4 CI 集成0.25d
---
## T-C-45 · 集成测试套件0d · 2 子任务)
### ST-C-45.1 写 `tests/integration/` 骨架0d
### ST-C-45.2 跑通 3 个集成测试0d
---
## V10 验收清单Sprint 4 G3 + G4 闸门)
```
G3 闸门(必须全部通过):
[ ] Lighthouse P75 ≥ 90P/A/B/S 四项)
[ ] pnpm build bundle < 300KB gzip
[ ] 8 e2e spec 全绿
[ ] 真实后端 5 模块 200
G4 闸门:
[ ] Poster CLI Docker 镜像本地构建 < 60s
[ ] docker compose up 启动成功
[ ] Poster 异步生成端到端跑通
```
---
## V10 风险Sprint 4 特有)
| ID | 风险 | 等级 | 缓解 |
|---|---|---|---|
| V10-S4-R1 | Lighthouse 分数不达标 | 中 | Vite 产物天然高分;重点优化 LCP 图 |
| V10-S4-R2 | 真实后端回归失败 | 中 | 用 docker compose 隔离环境;失败可回退 mock |
| V10-S4-R3 | Poster CLI Docker 镜像构建慢 | 低 | 多阶段构建 + 缓存 |
---
**Sprint 4 文档状态**V10 选项 B 重写完成
**总工时**10 人天V2 是 14 人天,节省 4d
**总子任务**53 个V2 是 50 个)
**下一步**Sprint 3 完成后立即启动