Files
gaokao-volunteer-system/SPRINT_3_S3_NEW_MODULES.md
Frontend Developer e8b8ad079e 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
2026-07-03 15:51:03 +08:00

11 KiB
Raw Blame History

Sprint 3 任务拆解W4-5 · 12 人天 · 62 子任务)— V10 选项 B

技术栈Vite 5 + React 19 + Zustand 4 + TanStack Query 5 + RHF 7 + Zod 目标5 大 V2 新模块Share / Query / Review / LLM / Poster+ Share Link 统计 + Portal 集成 闸门G2LLM fallback 4 模实测可切换 + 5 模块端到端跑通) V10 变化:从 22d 缩到 12d节省 10d = 8 hook 真实化用 TanStack Query 替代 + 5 模块统一模式) PM 决策2026-07-03整体重写为新实现Playwright 视觉回归 + Chromatic 验收


⚠️ V10 关键变化(与 V2 对比)

维度 V2 V10 选项 B
useChat 拆 6 子 hook 1.5d 0.5dV10 已用 Zustand 替代S3 只需补 mock
真实 sendMessage 1.0d 0.5dTanStack Query mutation + Zod
useAudit + LLM 增强 1.5d 0.75dZustand + mutation hook
5 大新模块 14d 8d(统一 TanStack Query 模式)
视觉回归 0d +1dV10 Chromatic 验证)
总估时 22d 12d

0. Sprint 3 概览

任务 主任务 估时 子任务数
T-B-12 useChatOrchestratorV10 重写) 0.5d 3
T-B-13 真实 sendMessage + typing 0.5d 3
T-B-14 真实 getHistory + 滚动恢复 0.5d 3
T-B-15 usePlan/useConsultation 真实化 0.75d 4
T-B-16 useProfile Zustand 版 0.5d 3
T-B-17 useAudit + LLM 增强4 模 fallback 0.75d 4
T-B-22 Share Link API4 端点) 0.75d 4
T-B-23 Data Query API3 端点) 0.75d 4
T-B-24 Review Flow API3 端点) 0.75d 4
T-B-25 Portal API2 端点) 0.5d 3
T-B-26 LLM Audit Enhance API 0.75d 4
T-B-27 Poster Generate API 0.5d 3
T-B-28 Share Link 统计 + 分享 UI 1.0d 5
T-B-29 Chromatic 视觉回归S3 增量) 0.5d 3
T-B-30 ESLint 0 warning 守门V10 重写) 0.5d 3
合计 15 任务 9.5d + 缓冲 2.5d = 12d 56 + 6 整合 = 62

T-B-12 · useChatOrchestratorV10 重写 · 0.5d · 3 子任务)⚠️ V10 简化

V10 收益Sprint 2 已建立 Zustand store + TanStack QueryS3 只需组装编排层

ST-S3-B-12.1 写 chat-fixtures0.25d

  • 产出apps/web/__mocks__/chat-fixtures.ts
  • 3 套 mock:广东物理 620 / 广东历史 580 / 河北物理 600

ST-S3-B-12.2 写 useChatOrchestrator0.125d

  • 产出apps/web/src/hooks/useChatOrchestrator.ts
  • 职责Zustand messages + TanStack Query mutation + Typing 状态机
  • V10 收益:从 1.5dV2 拆 6 子 hook→ 0.125d

ST-S3-B-12.3 接入 8 个 UI 组件0.125d

  • 覆盖MessageList / InputBar / TypingIndicator / PlanCard / ModeIndicator / 等

T-B-13 · 真实 sendMessage + typing0.5d · 3 子任务)

ST-S3-B-13.1 写 useChatSendMutation0.25d

  • 封装POST /api/chat/send + SSE 流式响应
  • 类型z.infer<typeof ChatSendSchema>

ST-S3-B-13.2 写 useTypingState Zustand selector0.125d

  • 三态thinking旋转/ paused静止/ stopped隐藏

ST-S3-B-13.3 接入 InputBar 真实点击发送0.125d

  • 验收
    • 点击发送 → 流式输出 → typing 状态切换正确
    • any 数量 0

T-B-14 · 真实 getHistory + 滚动恢复0.5d · 3 子任务)

ST-S3-B-14.1 写 useChatHistoryQuery0.125d

  • 封装GET /api/chat/history?sessionId=xxx
  • 缓存策略staleTime: 5min + gcTime: 30min

ST-S3-B-14.2 写滚动恢复 hook0.25d

  • 产出useScrollRecovery(ref, [messages.length])
  • 行为sessionId 变化时滚到底部;用户上滑时不打断
  • V10 不变量UI 1:1 复现V2 Plan §3.1 L1

ST-S3-B-14.3 接入 ChatPanel 组件0.125d


T-B-15 · usePlan/useConsultation 真实化0.75d · 4 子任务)

ST-S3-B-15.1 写 usePlanQuery0.125d

ST-S3-B-15.2 写 usePlanCreateMutation0.25d

ST-S3-B-15.3 写 useConsultationQuery + useConsultationMutation0.25d

ST-S3-B-15.4 接入 PlanCard 真实数据0.125d

  • V10 不变量 C1PlanCard 3-Tab 切换不重渲染父组件

T-B-16 · useProfile Zustand 版0.5d · 3 子任务)⚠️ V10 简化

ST-S3-B-16.1 写 useUserStore Zustand0.25d

  • V10 收益:从 1.0dV2 真实 useProfile→ 0.25d

ST-S3-B-16.2 接入 Header 头像/菜单0.125d

ST-S3-B-16.3 接入 Settings 页面0.125d


T-B-17 · useAudit + LLM 增强4 模 fallback · 0.75d · 4 子任务)

G2 闸门核心LLM 4 模claude / gpt / gemini / deepseek实测可切换

ST-S3-B-17.1 写 LLM provider 适配器0.25d

  • 产出apps/web/src/lib/llm/provider.ts
  • 4 provider 类型ClaudeProvider / GPTProvider / GeminiProvider / DeepseekProvider
  • 接口enhance(input: AuditInput): Promise<AuditEnhancement>

ST-S3-B-17.2 写 useAuditEnhanceMutation0.25d

  • 封装POST /api/llm/audit-enhance + provider 选择
  • 降级链claude → gpt → gemini → deepseek

ST-S3-B-17.3 写 useLLMConfig Zustand store0.125d

  • 状态currentProvider / fallbackOrder / availableProviders

ST-S3-B-17.4 4 模实测切换0.125d

  • 验收G2
    • claude 失败 → 自动降级 gpt
    • gpt 失败 → 自动降级 gemini
    • 全部失败 → 走 deepseek
    • Playwright e2e 覆盖

ST-S3-B-22.1 写 useShareLinkCreate0.25d

  • 封装POST /api/share-link
  • Schema{ planId, expiresIn: 7|30|forever }

ST-S3-B-22.2 写 useShareLinkDelete0.125d

  • 封装DELETE /api/share-link/{id}

ST-S3-B-22.3 写 useShareLinkLatestQuery0.125d

  • 封装GET /api/portal/share-link/latest

ST-S3-B-22.4 写 useShareLinkStatsQuery0.25d

  • 封装GET /api/share-link/{code}/stats
  • 响应{ views, uniqueVisitors, lastAccessedAt }

T-B-23 · Data Query API3 端点 · 0.75d · 4 子任务)

ST-S3-B-23.1 写 useScoreLineQuery0.25d

  • 封装GET /api/data-query/score-line
  • 参数{ province, year, scoreType }

ST-S3-B-23.2 写 useRankEstimatorQuery0.25d

  • 封装GET /api/data-query/rank-estimator
  • V10 变化TanStack Query select 直接转换位次→等效分数

ST-S3-B-23.3 写 useMajorsQuery + useSchoolsQuery0.25d

  • 封装GET /api/data-query/majors + GET /api/data-query/schools

T-B-24 · Review Flow API3 端点 · 0.75d · 4 子任务)

ST-S3-B-24.1 写 useReviewStartMutation0.25d

  • 封装POST /api/review/start

ST-S3-B-24.2 写 useReviewStatusQuery0.125d

  • 封装GET /api/review/{id}/status
  • 轮询refetchInterval: 3000(审核中)

ST-S3-B-24.3 写 useReviewActionMutation0.25d

  • 封装POST /api/review/actionapprove / reject / request_changes
  • V10 变化Zod discriminated union 处理 3 种 action

ST-S3-B-24.4 接入 ReviewPanel UI0.125d


T-B-25 · Portal API2 端点 · 0.5d · 3 子任务)

ST-S3-B-25.1 写 usePortalCWBQuery0.25d

  • 封装GET /api/portal/{token}/cwb(位次查询)

ST-S3-B-25.2 写 usePortalFullPlanQuery0.125d

  • 封装GET /api/portal/{token}/full-plan

ST-S3-B-25.3 写 Portal 入口页面0.125d

  • UI/交互 1:1:与原型招生门户入口一致

T-B-26 · LLM Audit Enhance API0.75d · 4 子任务)

ST-S3-B-26.1 写 useAuditEnhanceMutation0.25d

  • 封装POST /api/llm/audit-enhance

ST-S3-B-26.2 写流式响应处理0.25d

  • V10 关键技术SSE + ReadableStream + Zustand 增量更新
  • 复用useChatSendMutation 的流式逻辑

ST-S3-B-26.3 写 LLM 结果展示组件0.125d

ST-S3-B-26.4 接入 AuditPanel UI0.125d


T-B-27 · Poster Generate API0.5d · 3 子任务)

ST-S3-B-27.1 写 usePosterGenerateMutation0.25d

  • 封装POST /api/poster/generate
  • 响应{ posterUrl, qrCode, expiresAt }

ST-S3-B-27.2 写海报预览组件0.125d

  • V10 视觉:海报需与原型的视觉风格一致

ST-S3-B-27.3 接入 ShareDialog UI0.125d


V10 加强5 个子任务覆盖 UI + 统计图表 + 移动端适配

ST-S3-B-28.1 写 ShareDialog 组件0.25d

  • UI/交互 1:1:与原型分享弹窗一致
  • V10 不变量:移动端 48px 触发区

ST-S3-B-28.2 写 QR Code 展示组件0.125d

  • 依赖qrcode.react

ST-S3-B-28.3 写 Stats 统计卡片0.25d

  • 3 卡片:访问数 / 独立访客 / 最近访问
  • 图标lucide-react

ST-S3-B-28.4 写访问趋势 mini chart0.25d

  • 依赖recharts
  • V10 收益Sprint 5 chart 任务的预演

ST-S3-B-28.5 写 e2eshare-link.spec0.125d


T-B-29 · Chromatic 视觉回归S3 增量 · 0.5d · 3 子任务)⚠️ V10 新增

ST-S3-B-29.1 截图新增 5 模块页面0.25d

  • 页面ShareDialog / Stats / DataQuery / ReviewPanel / Poster Preview

ST-S3-B-29.2 提交 Chromatic 增量基线0.125d

ST-S3-B-29.3 Chromatic diff 阈值告警0.125d

  • CIpnpm chromatic --exit-zero-on-changes

T-B-30 · ESLint 0 warning 守门V10 重写 · 0.5d · 3 子任务)

V10 关键S3 完成后 ESLint 必须 0 warningV2 是 49 warning 缓慢修)

ST-S3-B-30.1 清理 S3 引入的 any0.25d

  • 验收grep -r "any" apps/web/src/ 0 结果

ST-S3-B-30.2 清理 S3 引入的 unused vars0.125d

ST-S3-B-30.3 升级 Sprint 1 临时 warn 规则为 error0.125d

  • 规则@typescript-eslint/no-explicit-any / react-hooks/set-state-in-effect
  • 目的:阻止 Sprint 4-8 倒退

V10 验收清单Sprint 3 G2 闸门)

G2 闸门(必须全部通过):
  [ ] 5 大新模块端到端跑通Share / Query / Review / LLM / Poster
  [ ] LLM 4 模实测可切换 + 自动降级
  [ ] pnpm typecheck 0 error 0 any
  [ ] pnpm lint 0 error 0 warning
  [ ] pnpm test 100% 覆盖新增 56 个子任务相关组件
  [ ] pnpm test:e2e 5 spec 全绿
  [ ] pnpm build bundle < 320KB gzip+20KB for new modules
  [ ] pnpm chromatic 视觉基线 13 页全提交
  [ ] 原型 7 个手写 hook + 1 个 lib/ 全部删除
  [ ] ESLint 0 warningV2 是 49 warning 修 1 整轮)

V10 风险Sprint 3 特有)

ID 风险 等级 缓解
V10-S3-R1 LLM 4 模 provider 适配成本高 抽象统一接口;先实现 1 模,再快速复制 3 模
V10-S3-R2 SSE 流式响应与 TanStack Query 兼容 onMutate + Zustand 增量更新,绕过 React Query 的缓存机制
V10-S3-R3 5 新模块并发开发协调 串行实施T-B-22 → T-B-23 → T-B-24 → T-B-26 → T-B-27
V10-S3-R4 Chromatic 商业服务配额 Sprint 2 已用 1 次S3 再用 1 次,剩余 8 次给 S4-S8

Sprint 3 文档状态V10 选项 B 重写完成 总工时12 人天V2 是 22 人天,节省 10d 总子任务62 个V2 是 70 个) 下一步Sprint 2 完成后立即启动