feat(sprint-2): V10 选项 B 完整切换 + G1 闸门通过

框架切换:Next.js 16 → Vite 5 + React 19 + React Router 7
状态管理:7 手写 hook → 4 Zustand slice
数据获取:直接 fetch → TanStack Query 5 (15 hooks)
表单:3-step 状态机 → RHF 7 + Zod
测试:0 → 25 单测 + 20 e2e (4 浏览器)
Bundle:192 KB gzip (目标 < 300 KB)
Lint:49 warning → 0 warning
Type:33 any → 0 any

S2-T-01 切 Vite 5 + React 19 框架
S2-T-02 Zustand 4 slice 替代 7 手写 hook
S2-T-03 TanStack Query 5 + 15 hooks
S2-T-04 Vitest + RTL + MSW + Chromatic 配置
S2-T-05 OpenAPI Codegen + Zod schema 复用
S2-T-06 RHF 7 + Zod 重写 FormCard
S2-T-07 Playwright 视觉基线 4 浏览器 5 spec
S2-T-08 Vite build + bundle < 300KB gzip

G1 闸门 (全部通过):
- typecheck: 0 error
- lint: 0 error 0 warning
- test (Vitest): 25/25 passed
- test:e2e (Playwright): 20/20 passed
- build (Vite): 326 modules 4.14s
- codegen:check: OpenAPI types 非占位

Sprint 2 收口报告:SPRINT_2_CLOSEOUT_2026-07-03.md
This commit is contained in:
Frontend Developer
2026-07-03 15:51:03 +08:00
parent 7892625ed2
commit e8b8ad079e
107 changed files with 13903 additions and 6652 deletions

View File

@@ -1,179 +1,245 @@
# Sprint 8 任务拆解W14-16 · 8 人天 · 48 子任务)
# Sprint 8 任务拆解W14-16 · 10 人天 · 50 子任务)— V10 选项 B
> **主任务**T-E-10 ~ T-E-24
> **目标**内部页 React 化收口Share 管理 / Data Query / Review / Policy / 通知 / 公共门户)
> **闸门**:生产可发版**G7 最终**
> **技术栈**Vite 5 + React 19 + Zustand 4 + TanStack Query 5 + RHF 7 + Zod
> **目标**后台管理页面收口Share/Query/Review/Policy/通知/系统)+ 公共门户 React 化
> **闸门**G7 最终(生产可发版)
> **V10 变化**:从 8d 增到 10d+2d = 12 个后台页面,单页平均 0.5d 合理化)
> **PM 决策2026-07-03**整体重写为新实现Playwright 视觉回归 + Chromatic 验收
---
## ⚠️ V10 关键变化(与 V2 对比)
| 维度 | V2 | V10 选项 B |
|---|---|---|
| 单页估时 | 0.5-1.0d(紧凑) | **0.5-1.0d**合理化V2 有压缩) |
| 表单组件 | 手写 | **RHF + Zod**(统一模式) |
| 总估时 | 8d | **10d**+2d 合理化) |
---
## 0. Sprint 8 概览
| 任务 | 主任务 | 估时 | 子任务数 |
|---|---|---|---|
| T-E-10 | Share Link 列表 | 1.0d | 4 |
| T-E-11 | Share Link 详情 /stats | 1.0d | 4 |
| T-E-12 | Poster 管理 | 1.0d | 4 |
| T-E-13 | 分数线查询 | 1.0d | 4 |
| T-E-14 | 位次估算 | 0.75d | 3 |
| T-E-10 | Share Link 列表 | 0.75d | 3 |
| T-E-11 | Share Link 详情 /stats | 0.75d | 3 |
| T-E-12 | Poster 管理 | 0.75d | 3 |
| T-E-13 | 分数线查询 | 0.75d | 3 |
| T-E-14 | 位次估算 | 0.5d | 2 |
| T-E-15 | 专业库 | 1.0d | 4 |
| T-E-16 | 院校库 | 1.25d | 4 |
| T-E-17 | 复核 Dashboard | 1.25d | 5 |
| T-E-18 | LLM 审计日志 | 0.75d | 3 |
| T-E-19 | Policy 中心 | 1.0d | 4 |
| T-E-20 | 通知列表 | 1.0d | 3 |
| T-E-21 | 通知模板编辑 | 1.5d | 4 |
| T-E-22 | 系统设置 | 1.5d | 4 |
| T-E-23 | 用户管理 | 1.0d | 4 |
| T-E-24 | 公共门户 React 化10 页) | 1.0d | 5 |
| **合计** | **15 任务** | **15d 实际 8d + 缓冲 7d = 15d** | **48** |
> 警告S8 任务密度最大15 任务 / 8d每个 0.5d 紧凑;缓冲 7d 用于延期 / 整改
| T-E-16 | 院校库 | 1.0d | 4 |
| T-E-17 | 复核 Dashboard | 1.0d | 4 |
| T-E-18 | LLM 审计日志 | 0.5d | 3 |
| T-E-19 | Policy 中心 | 0.75d | 3 |
| T-E-20 | 通知列表 | 0.5d | 2 |
| T-E-21 | 通知模板编辑RHF | 0.75d | 3 |
| T-E-22 | 系统设置 | 0.5d | 2 |
| T-E-23 | 用户管理 | 0.5d | 2 |
| T-E-24 | 公共门户 React 化10 页) | 1.0d | 4 |
| T-E-25 | Chromatic 收口S8 最终) | 0.5d | 2 |
| T-E-26 | ESLint 0 warning 守门 | 0.25d | 2 |
| T-E-27 | G7 最终验收 | 0.25d | 1 |
| **合计** | **18 任务** | **10d** | **50** |
---
## E.3 Share Link 管理3 任务 · 12 子任务 · 3d
## T-E-10 · Share Link 列表0.75d · 3 子任务)
### T-E-10 · Share Link 列表 `/admin/share-links`1.0d · 4 子任务
- ST-S8-E-10.1 表格 + 分页0.25d
- ST-S8-E-10.2 调 `GET /api/share-link`待后端补全0.25d
- ST-S8-E-10.3 撤销按钮 + 过期筛选0.25d
- ST-S8-E-10.4 写 e2e0.25d
### T-E-11 · Share Link 详情 `/admin/share-links/{code}/stats`1.0d · 4 子任务)
- ST-S8-E-11.1 点击量 / 转化率 / 设备分布0.25d
- ST-S8-E-11.2 时序图echarts0.25d
- ST-S8-E-11.3 调 `GET /api/share-link/{code}/stats`0.25d
- ST-S8-E-11.4 写 e2e0.25d
### T-E-12 · Poster 管理 `/admin/posters`1.0d · 4 子任务)
- ST-S8-E-12.1 复用 T-B-43 usePoster0.25d
- ST-S8-E-12.2 复用 T-D-20 PosterPreview0.25d
- ST-S8-E-12.3 模板选择0.25d
- ST-S8-E-12.4 写 e2e0.25d
### ST-S8-E-10.1 写 `useShareLinksQuery`0.125d
### ST-S8-E-10.2 写 ShareLinksTable0.5d
- **V10 集成**S5-D-01 DataTable + 列筛选 + 删除按钮
### ST-S8-E-10.3 写 story + e2e0.125d
---
## E.4 Data Query 内部页4 任务 · 15 子任务 · 4d
## T-E-11 · Share Link 详情 /stats0.75d · 3 子任务)
### T-E-13 · 分数线查询 `/admin/data-query/score-line`1.0d · 4 子任务
- ST-S8-E-13.1 复用 T-D-16 ScoreLineQueryForm0.25d
- ST-S8-E-13.2 复用 T-D-17 ScoreLineResult0.25d
- ST-S8-E-13.3 导出 CSV0.25d
- ST-S8-E-13.4 写 e2e0.25d
### T-E-14 · 位次估算 `/admin/data-query/rank-estimator`0.75d · 3 子任务)
- ST-S8-E-14.1 复用 T-D-16 RankEstimatorForm0.25d
- ST-S8-E-14.2 复用 T-D-17 RankEstimatorResult0.25d
- ST-S8-E-14.3 写 e2e0.25d
### T-E-15 · 专业库 `/admin/data-query/majors`1.0d · 4 子任务)
- ST-S8-E-15.1 复用 T-D-16 MajorsQueryForm0.25d
- ST-S8-E-15.2 复用 T-D-17 MajorsResult0.25d
- ST-S8-E-15.3 分类树0.25d
- ST-S8-E-15.4 写 e2e0.25d
### T-E-16 · 院校库 `/admin/data-query/schools`1.25d · 4 子任务)
- ST-S8-E-16.1 复用 T-D-16 SchoolsQueryForm0.25d
- ST-S8-E-16.2 复用 T-D-17 SchoolsResult0.25d
- ST-S8-E-16.3 985/211 筛选0.5d
- ST-S8-E-16.4 写 e2e0.25d
### ST-S8-E-11.1 写 ShareLinkDetail0.5d
- **V10 集成**Tabs基础信息/访问统计/操作日志
### ST-S8-E-11.2 写 StatsChart0.125d
- **V10 集成**recharts LineChart
### ST-S8-E-11.3 写 story + e2e0.125d
---
## E.5 Review 内部页2 任务 · 8 子任务 · 2d
## T-E-12 · Poster 管理0.75d · 3 子任务)
### T-E-17 · 复核 Dashboard `/admin/review`1.25d · 5 子任务
- ST-S8-E-17.1 待复核列表0.25d
- ST-S8-E-17.2 LLM 增强结果0.25d
- ST-S8-E-17.3 action 按钮approve / reject / revise0.25d
- ST-S8-E-17.4 复用 T-D-18 ReviewFlow0.25d
- ST-S8-E-17.5 写 e2e0.25d
### T-E-18 · LLM 审计日志 `/admin/review/llm-logs`0.75d · 3 子任务)
- ST-S8-E-18.1 模型使用统计0.25d
- ST-S8-E-18.2 token 消耗 + fallback 触发次数0.25d
- ST-S8-E-18.3 写 e2e0.25d
### ST-S8-E-12.1 写 `usePostersQuery`0.125d
### ST-S8-E-12.2 写 PostersGrid0.5d
- **V10 集成**:缩略图 + 状态徽章
### ST-S8-E-12.3 写 story + e2e0.125d
---
## E.6 Policy 内部页1 任务 · 4 子任务 · 1d
## T-E-13 · 分数线查询0.75d · 3 子任务)
### T-E-19 · Policy 中心 `/admin/policies`1.0d · 4 子任务
- ST-S8-E-19.1 5 个政策页 editorprivacy / service-terms / policy-center / same-score / deletion-policy0.25d
- ST-S8-E-19.2 草稿/发布两态0.25d
- ST-S8-E-19.3 Markdown 编辑器0.25d
- ST-S8-E-19.4 写 e2e0.25d
- **依据**commit `c5b0c3d` `818bfa4` 5 个政策页面已实现后端
### ST-S8-E-13.1 写 ScoreLineQueryForm0.5d
- **V10 集成**S6-D-16 DataQueryForm scoreLine 变体
### ST-S8-E-13.2 写 ScoreLineResultTable0.125d
### ST-S8-E-13.3 写 story + e2e0.125d
---
## E.7 通知 + 设置4 任务 · 15 子任务 · 4d
## T-E-14 · 位次估算0.5d · 2 子任务)
### T-E-20 · 通知列表 `/admin/notifications`1.0d · 3 子任务
- ST-S8-E-20.1 列表 + 筛选0.25d
- ST-S8-E-20.2 `GET /api/admin/notifications`0.25d
- ST-S8-E-20.3 写 e2e0.5d
### T-E-21 · 通知模板编辑1.5d · 4 子任务)
- ST-S8-E-21.1 列表0.25d
- ST-S8-E-21.2 编辑器 + 变量插值0.5d
- ST-S8-E-21.3 预览0.5d
- ST-S8-E-21.4 写 e2e0.25d
### T-E-22 · 系统设置 `/admin/settings`1.5d · 4 子任务)
- ST-S8-E-22.1 分组(基础/支付/AI/通知0.5d
- ST-S8-E-22.2 表单 + 校验0.5d
- ST-S8-E-22.3 调 `PATCH /api/admin/settings`0.25d
- ST-S8-E-22.4 写 e2e0.25d
### T-E-23 · 用户管理 `/admin/users`1.0d · 4 子任务)
- ST-S8-E-23.1 列表 + 角色筛选0.25d
- ST-S8-E-23.2 创建 / 编辑 / 禁用0.5d
- ST-S8-E-23.3 调 `GET/POST/PATCH /api/admin/users`0.125d
- ST-S8-E-23.4 写 e2e0.125d
### ST-S8-E-14.1 写 RankEstimatorForm + Result0.375d
- **V10 集成**S6-D-16 DataQueryForm rankEstimator 变体
### ST-S8-E-14.2 写 story + e2e0.125d
---
## E.8 公共门户 React 化1 任务 · 5 子任务 · 1d
## T-E-15 · 专业库1.0d · 4 子任务)
### T-E-24 · 公共门户 React 化10 页 / 1d · 5 子任务
- ST-S8-E-24.1 `/pricing` 定价页0.125d
- ST-S8-E-24.2 `/portal/{token}/info` 资料向导0.125d
- ST-S8-E-24.3 `/portal/{token}/status` 状态页0.125d
- ST-S8-E-24.4 `/portal/{token}/report` 报告查看0.125d
- ST-S8-E-24.5 `/portal/{token}/cwb` 冲稳保 + `/full-plan` 完整规划 + `/notifications` + `/deletion-request` + `/payment-return` + `/s/{code}` 短链接0.5d
- **复用**:所有 portal 页用 `packages/ui/` + `packages/api-client/` + `packages/hooks/`
- **验收**
- [ ]`admin/static/portal-ui.css` 视觉一致
- [ ] 全 10 个 portal 流程跑通
### ST-S8-E-15.1 写 `useMajorsQuery`0.125d
### ST-S8-E-15.2 写 MajorsTable0.5d
- **V10 集成**S5-D-01 DataTable + 虚拟滚动
### ST-S8-E-15.3 写 MajorDetailModal0.25d
- **V10 集成**S5-D-04 Modal + Tabs
### ST-S8-E-15.4 写 story + e2e0.125d
---
## Sprint 8 收口验收(**G7 生产可发版**
## T-E-16 · 院校库1.0d · 4 子任务
- [ ] 15 主任务 / 48 子任务全部完成
- [ ] **G7 通过**:生产可发版
- 21/21 功能模块
- 17/17 后端集成点
- 0 critical a11y 违规
- Lighthouse 12 页 P75 ≥ 90
- Bundle < 150KB
- 50+ Chromatic stories
- 15+ e2e spec 全绿
- [ ] 发版前 commit`<release: v1.0.0 — frontend react migration complete>`
### ST-S8-E-16.1 写 `useSchoolsQuery`0.125d
### ST-S8-E-16.2 写 SchoolsGrid0.5d
- **V10 集成**:卡片网格 + Badge 985/211
### ST-S8-E-16.3 写 SchoolDetailDrawer0.25d
- **V10 集成**S5-D-01 Tabs + Chart
### ST-S8-E-16.4 写 story + e2e0.125d
---
## 全 8 Sprint 收口
## T-E-17 · 复核 Dashboard1.0d · 4 子任务)
| 维度 | 目标 | 实际 |
|---|---|---|
| **任务数** | 136 | 136 |
| **子任务数** | ~400 | 497 |
| **人天** | 92 | 92 |
| **周数** | 16 | 16 |
| **闸门** | 6 | 7含 G7 生产可发版) |
| **风险** | 10 | 10全部 R-NEW-1..10 应对) |
| **Sprint 缓冲** | - | 14d 散落 8 Sprint |
### ST-S8-E-17.1 写 `useReviewQueueQuery`0.125d
### ST-S8-E-17.2 写 ReviewQueueTable0.5d
### ST-S8-E-17.3 写 ReviewActions0.25d
- **V10 集成**RHF + Zod 审核表单
### ST-S8-E-17.4 写 story + e2e0.125d
---
**任务拆解完成。所有 Sprint 子表文件已生成,可按 Sprint 1 → Sprint 8 顺序执行。**
## T-E-18 · LLM 审计日志0.5d · 3 子任务)
### ST-S8-E-18.1 写 `useLLMLogsQuery`0.125d
### ST-S8-E-18.2 写 LLMLogsTable0.25d
- **列**:时间 / 用户 / Provider / 输入 / 输出 / 耗时
### ST-S8-E-18.3 写 story + e2e0.125d
---
## T-E-19 · Policy 中心0.75d · 3 子任务)
### ST-S8-E-19.1 写 `usePoliciesQuery`0.125d
### ST-S8-E-19.2 写 PolicyEditor0.5d
- **V10 集成**RHF + Zod + SafeMarkdown 预览
### ST-S8-E-19.3 写 story + e2e0.125d
---
## T-E-20 · 通知列表0.5d · 2 子任务)
### ST-S8-E-20.1 写 NotificationsTable0.375d
### ST-S8-E-20.2 写 story + e2e0.125d
---
## T-E-21 · 通知模板编辑RHF · 0.75d · 3 子任务)
### ST-S8-E-21.1 写 TemplateFormRHF + Zod · 0.5d
- **字段**:模板名称 / 渠道 / 变量 / 内容
### ST-S8-E-21.2 写变量预览0.125d
### ST-S8-E-21.3 写 story + e2e0.125d
---
## T-E-22 · 系统设置0.5d · 2 子任务)
### ST-S8-E-22.1 写 SettingsForm0.375d
- **V10 集成**RHF + Zod
### ST-S8-E-22.2 写 story + e2e0.125d
---
## T-E-23 · 用户管理0.5d · 2 子任务)
### ST-S8-E-23.1 写 UsersTable0.375d
### ST-S8-E-23.2 写 story + e2e0.125d
---
## T-E-24 · 公共门户 React 化10 页 · 1.0d · 4 子任务)
### ST-S8-E-24.1 写 10 个公共门户页0.5d
- **页面**:首页 / 政策 / 数据 / 帮助 / 关于 / 服务条款 / 隐私政策 / 联系我们 / 招贤纳士 / 友情链接
- **V10 关键**:每页 < 50 行代码(用 design system 组件拼装)
### ST-S8-E-24.2 SEO meta 注入0.25d
- **V10 集成**react-helmet-async
### ST-S8-E-24.3 sitemap.xml + robots.txt0.125d
### ST-S8-E-24.4 写 e2e0.125d
---
## T-E-25 · Chromatic 收口S8 最终 · 0.5d · 2 子任务)
### ST-S8-E-25.1 截图所有后台 + 门户页面0.375d
- **后台**12 页 × 3 主题 = 36 截图
- **门户**10 页 × 2 主题(无 system 主题)= 20 截图
- **总计**56 截图
### ST-S8-E-25.2 提交基线 + 验证 0 像素 diff0.125d
---
## T-E-26 · ESLint 0 warning 守门0.25d · 2 子任务)
### ST-S8-E-26.1 清理 S8 引入的 any0.125d
### ST-S8-E-26.2 清理 S8 引入的 unused0.125d
---
## T-E-27 · G7 最终验收0.25d · 1 子任务)
### ST-S8-E-27.1 跑 G7 闸门清单0.25d
- **验收**G7 清单 100% 通过
---
## V10 验收清单Sprint 8 G7 最终闸门)
```
G7 闸门(必须全部通过):
[ ] 12 个后台页面 + 10 个公共门户页全部完成
[ ] pnpm typecheck 0 error 0 any
[ ] pnpm lint 0 error 0 warning
[ ] pnpm test:storybook 全绿
[ ] pnpm test:e2e 全绿
[ ] pnpm chromatic 0 像素 diff
[ ] Lighthouse P/A/B/S ≥ 95
[ ] axe-core 0 critical 0 serious
[ ] bundle < 350KB gzip
[ ] 真实后端 5 模块 + admin 端到端跑通
[ ] 生产可发版
```
---
## V10 风险Sprint 8 特有)
| ID | 风险 | 等级 | 缓解 |
|---|---|---|---|
| V10-S8-R1 | 后台页面工期紧张 | 中 | 已合理化到 10dV2 8d 不现实) |
| V10-S8-R2 | 公共门户 SEO | 中 | react-helmet-async 注入 meta |
| V10-S8-R3 | G7 收口发现新问题 | 低 | S8 末预留 0.25d 收口 |
---
**Sprint 8 文档状态**V10 选项 B 重写完成
**总工时**10 人天V2 是 8 人天,+2d 合理化)
**总子任务**50 个V2 是 48 个)
**下一步**Sprint 7 完成后立即启动 → G7 收口 → 生产可发版