Sprint 1 G0 闸门通过 (pnpm install / typecheck / lint / build / turbo 全部 exit 0) 实际完成: - T-A-01 monorepo 根骨架: pnpm-workspace.yaml + turbo.json + 根 package.json - T-A-02 收编原型: apps/web/ 30 个 src/ 文件 (4948 行) 首次入库 - T-A-03 lint/format: eslint flat config (根 + apps/web) + prettier - T-A-23 web-ci.yml: GitHub Actions 4-step CI (typecheck/lint/build/bundle) 勘误 (前置假设错误): - 原型 4948 行 (不是 4114 行) - 原型含 33 个 any + 16 个未用变量 (Sprint 2 修) - 原型从未 commit, 用 cp -r + git add, 不是 git mv 推迟到 Sprint 2+: - T-A-04/05 tsconfig packages 抽离 - T-A-06/07/08 design tokens 抽离 - T-A-09~13 5 基础组件 依赖隔离: - .gitignore 加 11 行 monorepo 规则 - apps/web/.gitignore 补 .npm-cache/next-dev.log - 删除 apps/web 内嵌 .git/ (cp -r 复制时携带) 验证: - pnpm install: 1m55s, 456 packages - typecheck: 0 errors - lint: 0 errors, 49 warnings (any + unused) - next build: 8 routes compiled, 9/9 static pages - turbo run build: 1 successful, 12.9s
53 KiB
前端重构 · 任务清单 V2(基于 tksea 最新版)
评审者:Frontend Developer (资深前端开发工程师) 日期:2026-07-02 22:45 上游:
git pull拉取远端a8b4927(比本地6d0feeb新 207 文件 / 87326 行净增) 重要:前端原型代码/完全未变(diff 为空)—— 之前的 8 项硬约束、4114 行代码、247 行 design-system 100% 适用 V1 任务清单差异:+45 任务 / +14 人天,主要因后端新增 share-link / data-query / review-flow / llm 增强 / poster 集成
0. V1 → V2 关键变化(前置说明)
0.1 远端新版本(a8b4927 vs 6d0feeb)
207 files changed, 87326 insertions(+), 2399 deletions(-)
| 维度 | V1(6d0feeb) | V2(a8b4927) | 变化 |
|---|---|---|---|
| pytest 用例 | 924 | 1104 | +180(+19%) |
| admin/routes/web_public.py | ~900 行 | ~4800 行 | +3900 行(share-link/data-query/review/poster/政策 5 大块) |
| 后端路由 | 87 | 约 110+ | +20 个端点 |
| 前端原型代码 | 4114 行 | 4114 行(不变) | 0 |
| 新增脚本 | 旧版 | +13 脚本 | integration_test / perf_benchmark / score_range_fullchain_100 / poster / payment_readiness_doctor 等 |
| skills/ | 旧版 | +6 文件(gaokao-audit 等) | LLM 审核服务化 |
0.2 V2 新增的 5 大后端能力模块(前端必须对接)
| # | 模块 | 后端端点 | 前端页面 | V1 是否覆盖 | V2 新增任务 |
|---|---|---|---|---|---|
| 1 | Share Link API | POST /api/share-link / DELETE /api/share-link/{id} / GET /api/portal/share-link/latest |
复核/报告页分享按钮 | ❌ | T-B-22 ~ T-B-25 + T-D-13 |
| 2 | Data Query 6 入口 | /score-line-query / /rank-estimator / /majors-query / /schools-query / /data-query |
4 个查询页 + 1 个聚合页 | ❌ | T-B-26 ~ T-B-31 + T-D-14 ~ T-D-17 + T-E-13 ~ T-E-16 |
| 3 | Review Flow | /review/start / /review/action / /portal/{token}/cwb / /portal/{token}/full-plan |
复核结果页 + 冲稳保 + 完整规划 | ❌ | T-B-32 ~ T-B-35 + T-D-18 + T-E-17 |
| 4 | LLM 增强审核 | AuditService LLM 接入 + 多模型 fallback | 审核触发 + 进度 + 结果 | ❌(原型 mock) | T-B-36 ~ T-B-38 + T-D-19 |
| 5 | Poster 海报 | data/share/poster.py + CLI gaokao-poster |
海报生成 + 下载 | ❌ | T-B-39 + T-D-20 + T-E-18 |
0.3 V1 任务清单的"未变化部分"(依然成立)
| 不变量 | 验证方式 | V1 任务 |
|---|---|---|
| 前端原型代码 4114 行未变 | git diff 6d0feeb..a8b4927 -- 前端原型代码/ 为空 |
T-A-02 ~ T-A-23 全部保留 |
| 8 项硬约束 | 扫读原型文件源码 | T-A-14 ~ T-A-19 单测 + e2e 保留 |
| 5 阶段路径 | 与 V2 Senior Developer 报告一致 | A/B/C/D/E 阶段框架保留 |
| 78 人天估算 | V1 中位 | V2 调整为 92 人天(+14) |
1. 任务总览 V2(136 任务,92 人天)
| 阶段 | 任务数 | 人天 | V1→V2 增量 | 关键里程碑 |
|---|---|---|---|---|
| A. 基础设施 | 23 | 11 | 0 | monorepo + 5 组件 + e2e 骨架 + CI |
| B. 真实后端对接 | 35 | 38 | +14(21→35) | 30+ 端点对接 + 8 hook 真实化 + Lighthouse ≥ 90 |
| C. 架构整合 | 15 | 10 | +1(13→15) | 独立部署 + Sentry + CSP + Poster CLI |
| D. 设计 / a11y 加固 | 24 | 14 | +3(18→24) | 18 组件 + SharePanel + DataQuery + Review UI + axe |
| E. 内部页面 React 化 | 24 | 19 | +2(16→24) | 运营后台 + Share 管理 + Data Query + Review + Poster + Policy |
| 总计 | 136 | 92 | +45 任务 / +14 人天 | V1 66-89 → V2 78-105(中位 92) |
注:V2 中位 92 人天 与 V2 Senior Developer 报告(66-89)相比略高,主要因为后端 5 大新模块的 React 化工作量是 V1 没预估到的,建议向 PM 申请追加 14 人天(1 人 × 2.8 周 或 2 人 × 1.4 周)。
阶段 A · 基础设施(23 任务,11 人天)
完全沿用 V1,因为前端原型代码未变。
A.1 Monorepo 收编(3 任务,1.5d)
T-A-01 创建 monorepo 根骨架
- 产出:
pnpm-workspace.yaml+turbo.json+ 根package.json+.gitignore+pnpm-lock.yaml - 验收:
pnpm install成功,无 peer warningpnpm -r list显示apps/*和packages/*turbo run build --dry-run显示任务依赖图
- 估时:0.5d
- 依赖:无
T-A-02 收编 前端原型代码/ 到 apps/web/
- 产出:
apps/web/src/完整包含原型 4114 行代码;前端原型代码/目录删除 - 验收:
pnpm --filter web dev启动 dev server,端口 3000- 访问
/看到完整聊天页(Sidebar + ModeIndicator + PlanCard 等) git status无意外 diff(除了目录移动)
- 估时:0.5d
- 依赖:T-A-01
T-A-03 加根 lint / format / git hooks
- 产出:
eslint.config.mjs(共享) +prettier.config.mjs+.husky/pre-commit - 验收:
pnpm lint跑通所有 workspacepnpm format自动修所有文件- commit 触发 lint-staged
- 估时:0.5d
- 依赖:T-A-01
A.2 共享 tsconfig(2 任务,0.5d)
T-A-04 抽 packages/tsconfig/base.json
- 产出:
strict + bundler + paths,所有子 package 继承 - 验收:
apps/web/tsconfig.json改为extends: "@gaokao/tsconfig/base.json"pnpm --filter web typecheck0 error
- 估时:0.25d
- 依赖:T-A-02
T-A-05 共享 tsconfig.lib.json(含 composite: true + declaration: true)
- 产出:
packages/tsconfig/lib.json给packages/ui等需要 build 的用 - 验收:
packages/ui/tsconfig.jsonextends libpnpm --filter @gaokao/ui build生成dist/index.d.ts
- 估时:0.25d
- 依赖:T-A-04
A.3 设计系统提取(3 任务,1.5d)
T-A-06 移 design-system.css 到 packages/ui/tokens/
- 产出:
packages/ui/tokens/design-system.css(247 行,1:1 搬迁不改内容) - 验收:
apps/web/src/styles/design-system.css改为 re-export 或删除- Chromatic baseline 截图 0 diff
globals.css的@import路径更新
- 估时:0.5d
- 依赖:T-A-04
- 约束:§1.1(design tokens 不可改值)
T-A-07 移 lib/theme.ts 到 packages/ui/tokens/
- 产出:
packages/ui/tokens/theme.ts(含initThemeScript / getEffectiveTheme / setTheme / isDarkMode4 个函数,1:1 搬迁) - 验收:
apps/web/src/lib/theme.ts删除layout.tsximport 路径更新- 三态主题切换功能 0 回归(Playwright
theme.spec.ts全绿)
- 估时:0.5d
- 依赖:T-A-06
- 约束:§1.2(闪白防护必须保留)
T-A-08 写 packages/ui/tokens/index.ts barrel
- 产出:re-export 全部 token + theme 函数
- 验收:
import { ..., getEffectiveTheme, setTheme, ... } from '@gaokao/ui/tokens'工作
- 估时:0.5d
- 依赖:T-A-07
A.4 UI 组件库起步(5 任务,2.5d)
T-A-09 Button 组件
- 产出:
packages/ui/components/Button.tsx+Button.test.tsx+Button.stories.tsx - variant:
primary | secondary | ghost | danger - size:
sm | md | lg - 验收:
- 4 variant × 3 size = 12 个 story
- Vitest 覆盖:点击事件 / disabled / loading 状态
- axe 0 critical
- 估时:0.5d
- 依赖:T-A-08
T-A-10 Input / Select / Textarea 组件
- 产出:
packages/ui/components/{Input,Select,Textarea}.tsx+ 各自 test + story - 特性:
error | helpText | touched三态 - 验收:
- FormCard 改用 Input 组件(视觉 0 回归)
- Vitest 覆盖必填 / 错误提示 / 受控值
- 估时:0.5d
- 依赖:T-A-09
T-A-11 Card 组件
- 产出:
packages/ui/components/Card.tsx - API:
<Card>{children}</Card>—— 圆角 2xl + 阴影 sm + border gray-200 - 验收:
- PlanCard / AuditReportCard / CareerCard / FileUploadPrompt 全部改用 Card
- 视觉 0 回归
- 估时:0.5d
- 依赖:T-A-08
T-A-12 Badge 组件
- 产出:
packages/ui/components/Badge.tsx - API:
<Badge variant="risk-high | risk-medium | risk-low | neutral">{label}</Badge> - 验收:
- PlanCard 风险徽章 / PlanCard 调整徽章 / plans/page 院校统计徽章 全部改用
- 视觉 0 回归
- 估时:0.25d
- 依赖:T-A-08
T-A-13 Tabs 组件
- 产出:
packages/ui/components/Tabs.tsx - API:
<Tabs items={[{key,label,color}]} activeKey onChange>—— ARIArole="tablist/tab" - 验收:
- PlanCard 改用 Tabs
- plans/[id]/page.tsx 改用 Tabs
- 视觉 0 回归
- Vitest 覆盖 active 切换 + 键盘箭头导航(WCAG 2.1.1)
- 估时:0.75d
- 依赖:T-A-09
- 约束:§1.6(PlanCard 三 Tab 不可改结构)
A.5 测试基础设施(4 任务,1.5d)
T-A-14 Vitest + RTL + MSW 配置
- 产出:
packages/test-utils/vitest.config.tspackages/test-utils/setup.ts(jest-dom matchers + MSW server)packages/test-utils/renderWithProviders.tsx(QueryClient + Theme + Router)
- 验收:
pnpm --filter web test跑通- 占位测试
Math.test.ts1 绿
- 估时:0.5d
- 依赖:T-A-01
T-A-15 示范单测:ModeIndicator
- 产出:
ModeIndicator.test.tsx - 覆盖:
- 4 个 mode 各渲染对应 label
deriveMode决策树:- isAuditActive → auditing
- currentPlan + no audit → adjusting
- province + score → generating
- 其他 → explore
- 验收:
- 100% line + branch coverage
- 估时:0.25d
- 依赖:T-A-14
- 约束:§1.4(4 模式决策树)
T-A-16 示范单测:SafeMarkdown
- 产出:
SafeMarkdown.test.tsx - 覆盖 XSS 注入:
<script>alert(1)</script>→ 渲染为文本,不执行<img src=x onerror=alert(1)>→ onerror 被剥<a href="javascript:alert(1)">→ href 被 sanitize
- 验收:
- 3 个注入用例全过
- 正常 markdown(h1/ul/code/blockquote)渲染正确
- 估时:0.25d
- 依赖:T-A-14
- 约束:§0.1 R-NEW(XSS 防护不可破)
T-A-17 示范单测:FormCard
- 产出:
FormCard.test.tsx - 覆盖:
- 字段 touched 后才显示验证
- 跳步守卫(basic 未完成不能进 subjects)
- 提交时 subjects 数组拼装正确
- 验收:
- 80% line coverage
- 估时:0.5d
- 依赖:T-A-14
- 约束:§1.10(不允许跳步)
A.6 Playwright e2e 骨架(3 任务,1.5d)
T-A-18 Playwright 配置
- 产出:
apps/web/e2e/playwright.config.ts(chromium + webkit + 2 个 mobile viewport) - 验收:
pnpm --filter web e2e启动浏览器apps/web/e2e/smoke.spec.ts通过(仅访问/看到 Sidebar)
- 估时:0.5d
- 依赖:T-A-14
T-A-19 示范 e2e:theme.spec
- 产出:
theme.spec.ts - 覆盖:
- 切到 dark →
data-theme="dark"出现 - 切到 system →
data-theme移除 - 刷新页面后 localStorage 保留选择
- 视觉无闪白(
page.waitForLoadState('domcontentloaded')在 100ms 内)
- 切到 dark →
- 验收:
- 3 个主题切换场景全绿
- 估时:0.5d
- 依赖:T-A-18
- 约束:§1.2(闪白防护)
T-A-20 示范 e2e:navigation.spec
- 产出:
navigation.spec.ts - 覆盖:
- 桌面 viewport (1280) → Sidebar 可见,MobileNav 隐藏
- 移动 viewport (375) → MobileNav 可见,Sidebar 隐藏
- 点击 Sidebar /plans → 跳转
- 点击 MobileNav /plans → 跳转
- 验收:
- 4 个场景全绿
- 估时:0.5d
- 依赖:T-A-18
- 约束:§1.7(1024 断点)
A.7 OpenAPI 类型化(2 任务,1.5d)
T-A-21 OpenAPI Codegen 接入
- 产出:
packages/api-client/codegen.config.tspackages/api-client/src/index.ts(自动生成)turbo.json加generate-api-client任务,依赖^build-admin
- 验收:
pnpm --filter @gaokao/api-client generate跑通- 生成
dist/services/AuthService.ts等
- 估时:1d
- 依赖:T-A-01
T-A-22 示范调用:mock server
- 产出:
apps/web/lib/api/chat.ts(先用 MSW mock) - API:
export const apiClient = { chat: { send: (consultationId: string | undefined, body: { message: string }) => Promise<ChatResponse>, getHistory: (consultationId: string) => Promise<{ messages: Message[] }>, } }; - 验收:
- MSW handler 拦截
/api/chat/send返回 mock page.tsx临时接 apiClient.chat.send(不替换 useChat,仅验证类型管道通)
- MSW handler 拦截
- 估时:0.5d
- 依赖:T-A-21
- 约束:§0.1 R-NEW-3(match 1-5 校验,Zod schema
z.number().int().min(1).max(5))
A.8 CI 工作流(1 任务,1d)
T-A-23 web-ci.yml
- 产出:
.github/workflows/web-ci.yml - 步骤:
pnpm install --frozen-lockfilepnpm turbo run lint typecheck test --filter=@gaokao/* --filter=webpnpm turbo run e2e --filter=webpnpm turbo run build --filter=@gaokao/* --filter=web- 上传 Codecov(前端 target)
- 验收:
- PR 触发后绿/红信号可见
- 总耗时 < 8 分钟
- bundle size > 200KB 时 PR 评论 warn
- 估时:1d
- 依赖:T-A-19, T-A-20, T-A-22
阶段 B · 真实后端对接(35 任务,38 人天)[V2 扩展 +14 任务 / +14 人天]
V2 关键扩展:5 大新模块(Share Link / Data Query / Review / LLM / Poster)需要在前端真实对接。
B.1 后端 API 补全(11 任务,11d)—— V1 5 任务 → V2 11 任务
T-B-01 POST /api/chat/send(V1 保留)
- 入参:
{message: string, consultation_id?: string, profile_snapshot?: object} - 出参:
{user_message: Message, assistant_message: Message, consultation_id: string} - 验收:
- OpenAPI schema 完整
- 与后端
Consultation/Message模型对齐 - 错误码 E03001/03002/03003 覆盖
- 估时:1.5d
T-B-02 GET /api/chat/history?consultation_id=...(V1 保留)
- 出参:
{messages: Message[]} - 验收:
- 分页参数(cursor)支持
- auth:必须登录或持有 consultation_id 的访问令牌
- 估时:0.5d
T-B-03 GET /api/consultations / GET /api/consultations/{id} / DELETE /api/consultations/{id}(V1 保留)
- 验收:
- 列表返回
{consultations: [{id, title, updated_at, profile, has_plan, has_audit}]} - 详情返回完整 messages + profile + plan + audit
- DELETE 软删除 + 数据保留 30 天
- 列表返回
- 估时:1d
T-B-04 GET /api/plans / GET /api/plans/{id} / PATCH /api/plans/{id} / DELETE /api/plans/{id}(V1 保留)
- 验收:
- 列表返回
{plans: [{id, name, created_at, profile, distribution: {rush,stable,safe}}]} - PATCH 仅支持 name 修改
- DELETE 软删除
- 列表返回
- 估时:1d
T-B-05 POST /api/assessment / POST /api/audit/upload(V1 保留)
- audit/upload:multipart/form-data,Excel/Image/PDF/Paste
- 出参:
{report_id, overall_score, summary, risk_items, distribution, good_points} - 验收:
- 文件大小限制:Excel 5MB / Image 10MB / PDF 10MB
- MIME 校验
- 解析后存 DB + 触发 AI 审核
- 估时:2d
T-B-22 🆕 POST /api/share-link —— Share Link 创建
- 入参:
{resource_type: "review_result" | "report", resource_id: string, expires_in_hours?: number} - 出参:
{code: string, url: string, qr_code_url?: string, expires_at: string} - 权限:仅
admin角色 - 验收:
- 鉴权 401/403 测试通过
- 与
0145d66提交中的 test_share_link_api.py 一致 - 撤销后状态正确变更
- 估时:0.5d
- 依据:commit
0145d66已实现后端,前端需对接
T-B-23 🆕 DELETE /api/share-link/{id} —— Share Link 撤销
- 出参:
{ok: true, revoked_at: string} - 权限:仅
admin角色 - 验收:
- 撤销后 GET /api/share-link/latest 返回 404
- 撤销历史保留
- 估时:0.25d
T-B-24 🆕 GET /api/portal/share-link/latest —— 查询当前 portal 的最新分享链接
- 出参:
{code, url, expires_at, click_count}或 404 - 验收:
- 状态面板渲染依据(test_share_status_panel.py)
- 估时:0.25d
- 依据:commit
0145d66提到 test_share_status_panel.py 期望 status 页面渲染"当前分享状态"面板
T-B-25 🆕 GET /api/share-link/{code}/stats —— 分享统计
- 出参:
{click_count, view_count, conversion_count, last_clicked_at, device_breakdown} - 估时:0.5d
T-B-26 🆕 GET /api/data-query/score-line —— 分数线查询
- 入参:
{province, year, subject_type, score} - 出参:
{matches: [{university, major, year, min_score, max_score, avg_score}]} - 验收:
- 性能:1 省 1 年 1 类目 < 200ms
- 缓存:相同 query 5min 命中
- 估时:0.5d
- 依据:commit
c5b0c3d/score-line-query端点已实现
T-B-27 🆕 GET /api/data-query/rank-estimator —— 位次估算
- 入参:
{province, year, subject_type, score} - 出参:
{rank: number, rank_range: [min, max], total_candidates: number} - 估时:0.5d
- 依据:
/rank-estimator端点已实现
T-B-28 🆕 GET /api/data-query/majors + GET /api/data-query/schools —— 专业/院校库
- 入参:
{keyword, category?, level?, page, page_size} - 出参:
{items: [...], total, page, page_size} - 验收:
- 分页 + 搜索 + 过滤
- 性能:keyword 搜索 < 300ms
- 估时:0.5d
- 依据:
/majors-query/schools-query端点已实现
T-B-29 🆕 POST /api/review/start —— 启动复核
- 入参:
{plan_id, profile_snapshot} - 出参:
{review_id, status: "started", progress_url} - 验收:
- 异步触发 LLM 审核
- progress_url 可轮询
- 估时:0.5d
- 依据:commit
0145d66提到/review/start端点
T-B-30 🆕 GET /api/review/{id}/status —— 复核进度
- 出参:
{review_id, status, progress: 0-100, current_step, eta_seconds} - 估时:0.25d
T-B-31 🆕 POST /api/review/action —— 复核动作
- 入参:
{review_id, action: "approve" | "reject" | "revise", comment?} - 出参:
{ok: true, next_review_id?} - 估时:0.5d
- 依据:commit
0145d66/review/action端点
T-B-32 🆕 GET /api/portal/{token}/cwb —— 冲稳保建议
- 出参:
{rush: School[], stable: School[], safe: School[]} - 验收:
- 与 PlanCard 兼容(字段一致)
- 排序按概率降序
- 估时:0.5d
- 依据:commit
9b587a5/portal/{token}/cwb端点 + "有 token 时显示 cwb 按钮"
T-B-33 🆕 GET /api/portal/{token}/full-plan —— 完整规划页
- 出参:
{plan: Plan, profile, audit_report?, llm_enhancement?} - 验收:
- 含 LLM 增强(commit
a3d8c73"完整规划页 LLM 方案生成")
- 含 LLM 增强(commit
- 估时:0.5d
T-B-34 🆕 POST /api/llm/audit-enhance —— LLM 增强审核
- 入参:
{audit_report_id, enhancement_type: "summary" | "risk_explain" | "suggestion"} - 出参:
{enhanced_content: string, model_used: string, tokens_consumed: number} - 验收:
- 多模型 fallback(commit
11fbb59"多模型 fallback 支持") - 超时 30s 降级
- 多模型 fallback(commit
- 估时:1d
- 依据:commit
11fbb59a3d8c7343c1dbdLLM 增强链路
T-B-35 🆕 POST /api/poster/generate —— 海报生成
- 入参:
{plan_id, template: "minimal" | "gradient" | "card", watermark?: string} - 出参:
{poster_id, image_url, download_url, expires_at} - 权限:仅
admin或 plan owner - 验收:
- 与
data/share/poster.pyCLI 行为一致 - 含 QR 码(链接到分享 link)
- 与
- 估时:0.5d
- 依据:commit
a8b4927完整 poster 系统
B.2 useChat / 业务 Hook 真实化(8 任务,9d)—— V1 4 任务 → V2 8 任务
T-B-12 拆 useChat 编排层(V1 保留)
- 产出:
useChat.ts改为纯编排(无 mock 数据)- mock 数据移到
apps/web/__mocks__/chat-fixtures.ts(仅 B 阶段测试用)
- 验收:
- useChat.ts < 300 行
__mocks__/chat-fixtures.ts包含:广东省物理 620、广东省历史 580、河北省物理 600 共 3 套 mock
- 估时:1.5d
- 依赖:T-B-01 ~ T-B-05(API 已就位)
- 约束:§0.1 R-NEW-1
T-B-13 真实 sendMessage + typing 动画(V1 保留)
- 产出:mutation + optimistic update
- 验收:
- e2e
chat-send.spec.ts:输入消息 → 1s 内出现用户气泡 → 3s 内出现 AI 回复 - 失败时乐观更新回滚 + Toast 提示
- typing 动画 (
page.tsx:173-186) 保留
- e2e
- 估时:1d
- 依赖:T-B-12
- 约束:§1.3(消息路由模式)
T-B-14 真实 getHistory + 滚动恢复(V1 保留)
- 产出:consultation 切换时 fetch 历史
- 验收:
- 切换 consultation_id → 加载历史消息
- 自动滚动到底部(
messagesEndRef) - 加载中显示 Skeleton(用 T-D-09 阶段组件)
- 估时:1d
- 依赖:T-B-13
T-B-15 usePlan / useConsultation 真实化 + localStorage 兼容(V1 保留)
- 产出:
- 删除
useChat.ts中savePlan的 localStorage 写 - 改用
apiClient.plans.create(...)mutation - 保留 localStorage
consultationRecords/activeConsultationIdkey 名作为离线 fallback(R-NEW-2 应对)
- 删除
- 验收:
- 真实保存方案 → DB 可见
- 断网时本地仍可见上次同步数据
- 联网后自动 revalidate(TanStack Query 默认行为)
- 估时:1.5d
- 依赖:T-B-04, T-B-05
- 约束:§0.1 R-NEW-2(保留 key 名兼容)
T-B-36 🆕 useShareLink Hook
- 产出:
useShareLink(resourceType, resourceId)返回{shareLink, create, revoke, refresh} - API:
create()→POST /api/share-linkrevoke()→DELETE /api/share-link/{id}refresh()→GET /api/portal/share-link/latest
- 验收:
- 创建成功 → 立即显示链接 + QR 码
- 撤销后 UI 显示"已撤销"
- 失败时 Toast + 表单不重置
- 估时:1d
- 依赖:T-B-22, T-B-23, T-B-24
T-B-37 🆕 useDataQuery Hook(4 个独立 hook)
- 产出:
useScoreLineQuery({province, year, subject_type, score})→ 返回matches[]useRankEstimator({province, year, subject_type, score})→ 返回rankuseMajorsQuery({keyword, page})→ 返回items[] + paginationuseSchoolsQuery({keyword, page})→ 同上
- 验收:
- 4 个 hook 独立缓存(staleTime 5min)
- 相同 query 命中缓存
- 错误时降级到 localStorage 缓存
- 估时:1.5d
- 依赖:T-B-26, T-B-27, T-B-28
T-B-38 🆕 useReview Hook
- 产出:
useReview(reviewId)返回{status, progress, currentStep, etaSeconds, start, action} - API:
start()→POST /api/review/startpoll()→GET /api/review/{id}/status(每 2s 轮询)action(action, comment?)→POST /api/review/action
- 验收:
- SSE 优先;不支持 SSE 时降级轮询
- progress 100% → 跳转结果页
- 失败时 Toast + 重试
- 估时:1.5d
- 依赖:T-B-29, T-B-30, T-B-31
T-B-39 🆕 usePoster Hook
- 产出:
usePoster(planId)返回{posterUrl, generate, download} - 验收:
- 生成进度显示(5-10s)
- 下载为 PNG
- watermark 可选
- 估时:0.5d
- 依赖:T-B-35
B.3 useProfile / 表单 / 错误处理(7 任务,7d)—— V1 6 任务 → V2 7 任务
T-B-16 真实 useProfile(V1 保留)
- 产出:
GET /api/profile拉取,表单提交用PATCH /api/profile - 验收:
- FormCard 提交后立即看到进度条(InfoCollectionProgress)填充
- 失败时回滚 + 错误提示
- 估时:1d
- 依赖:T-B-15
T-B-17 真实 useAudit(V1 保留 + LLM 增强)
- 产出:
POST /api/audit/uploadmultipart + LLM 增强回调 - 验收:
- 4 种文件类型(Excel/Image/PDF/Paste)全部走真实 API
- 进度条(上传 + AI 处理)显示
- 错误码 E04001(上游 AI 失败)→ Toast 重试
- LLM 增强(
/api/llm/audit-enhance)异步触发,结果追加到 report
- 估时:1.5d
- 依赖:T-B-05, T-B-34
T-B-18 错误码 → 用户文案映射(V1 保留)
- 产出:
packages/i18n/zh-CN/errors.json - 示例:
{ "E03001": "信息验证失败,请检查输入", "E03002": "数据未找到", "E03003": "保存失败,请重试", "E04001": "AI 服务暂时不可用,请稍后重试", "E04002": "请求超时,请重试", "E05001": "系统错误,我们已记录" } - 验收:
- 15 个错误码全覆盖
- api-client 拦截器统一处理
- 估时:0.5d
- 依赖:T-B-13
- 约束:沿用
admin/errors/registry.py5 字段结构
T-B-19 ErrorBoundary 兜底页(V1 保留)
- 产出:
apps/web/app/error.tsx(Next 16 error boundary) - 验收:
- 5xx 错误时显示兜底页("出错了,刷新重试")
- Sentry 上报
- 估时:0.5d
- 依赖:T-B-18
T-B-20 离线检测 + 提示(V1 保留)
- 产出:
useOnlineStatushook + 顶部黄条提示 - 验收:
- offline → 顶部条 + 写操作禁用
- online 恢复 → 自动重试 pending mutations
- 估时:1d
T-B-21 表单提交防重复(V1 保留)
- 产出:所有 mutation 加
isPending状态 - 验收:
- FormCard 提交按钮在 isPending 时禁用 + 旋转图标
- ChatMessage 的修复按钮单次点击后禁用
- 估时:0.5d
T-B-40 🆕 Share Link 状态面板数据
- 产出:
useShareStatusPanel(resourceId)→ 返回{currentLink, clickCount, viewCount, daysUntilExpiry} - API:
GET /api/portal/share-link/latest+GET /api/share-link/{code}/stats - 验收:
- test_share_status_panel.py 期望"当前分享状态"面板渲染
- 30s 自动刷新
- 估时:0.5d
- 依据:commit
0145d66提到 test_share_status_panel.py 期望但当前未通过
B.4 离线缓存 + e2e + 性能(9 任务,9d)—— V1 6 任务 → V2 9 任务
T-B-22 TanStack Query 持久化(V1 保留)
- 产出:
@tanstack/query-persist-client-core+ localStorage - 验收:
- 关闭浏览器再打开 → 历史消息立即可见
- 后台 revalidate 后更新
- 估时:1d
- 依赖:T-B-13
T-B-23 e2e 真实化(8 个关键路径)—— V1 5 → V2 8
- 产出:
chat-send.spec.ts真实发消息chat-history.spec.ts切换 consultationplan-save.spec.ts保存方案audit-upload.spec.ts上传文件theme-persist.spec.ts主题持久化- 🆕
share-link.spec.ts创建/撤销/分享 UI - 🆕
data-query.spec.ts4 个查询页 - 🆕
review-flow.spec.ts复核全流程
- 验收:
- 8 个 spec 全绿
- 每个 spec 含 1 个失败场景
- 估时:3d
- 依赖:T-B-13, T-B-15, T-B-17, T-B-36, T-B-37, T-B-38
T-B-24 Lighthouse CI 集成(V1 保留 + 新页面)
- 产出:
lighthouserc.json+ GitHub Action - 预算:
- LCP < 2.5s
- INP < 200ms
- CLS < 0.1
- Performance ≥ 90
- Accessibility ≥ 95
- Best Practices ≥ 95
- SEO ≥ 90
- 覆盖页面:/ /consultations /plans /plans/compare /assessment 🆕 /score-line-query /rank-estimator /majors-query /schools-query /review/start /admin/login /admin
- 验收:
- 12 个页面 P75 ≥ 预算
- PR 评论显示分数
- 估时:1.5d
- 依赖:T-B-23
T-B-25 Bundle 优化(V1 保留)
- 产出:
next/dynamic异步加载 PlanCard / AuditReportCard / CareerCardreact-markdown异步 chunk- 拆 vendor chunk
- 验收:
- First load JS < 200KB
- PlanCard 异步 chunk < 50KB
- 估时:1d
T-B-26 路由级 prefetch(V1 保留)
- 产出:
<Link prefetch>关键路径 - 验收:
- hover Sidebar /plans → 100ms 内开始预取
- 估时:0.5d
T-B-27 真实后端回归(V1 保留)
- 产出:完整 e2e 套件在真实后端跑通
- 验收:
- 15+ e2e spec 全绿
- 跨 3 浏览器(chromium / webkit / firefox)通过
- 估时:0.5d
- 依赖:T-B-23 ~ T-B-26
T-B-41 🆕 ShareLink 失败降级
- 产出:
navigator.share不可用时降级到clipboard.writeText- clipboard 不可用时降级到
<a download>文本文件
- 验收:
- 3 路径全部测试通过
- 用户看到明确提示
- 估时:0.5d
- 依据:commit
0145d66"失败时显示具体错误,不再静默"
T-B-42 🆕 LLM 增强进度轮询
- 产出:
useLLMEnhancementhook + SSE 优先- 长任务(>30s)显示进度条
- 失败时降级到基础审核结果
- 验收:
- SSE 连接断开时自动重连(最多 3 次)
- 降级时显示"AI 增强暂不可用,已展示基础结果"
- 估时:1d
- 依据:commit
11fbb59"多模型 fallback 支持"
T-B-43 🆕 Poster 异步生成 + 轮询
- 产出:
usePoster+ 进度条- 生成完成自动下载(可选)
- 失败时重试 + Toast
- 验收:
- 5-10s 内完成
- 失败可重试
- 长任务不阻塞 UI
- 估时:0.5d
- 依据:commit
a8b4927poster 系统
阶段 C · 架构整合(15 任务,10 人天)[V2 扩展 +2 任务 / +1 人天]
C.1 部署架构(5 任务,3d)—— V1 保留
T-C-01 选部署平台
- 决策点:CloudStudio / Vercel / 自托管
- 默认:CloudStudio(项目已有先例)
- 验收:
- 决策文档写入
docs/DEPLOY_DECISION.md
- 决策文档写入
- 估时:0.25d
T-C-02 DNS + 域名
- 产出:
web.gaokao.example.com/api.gaokao.example.com - 验收:
- HTTPS 证书自动续签(Let's Encrypt)
- 估时:0.5d
T-C-03 反代配置
- 产出:nginx / caddy 配置
web.gaokao.example.com→ Next.js 静态产物api.gaokao.example.com→ FastAPI/api/*→ 转发到 FastAPI
- 验收:
- 单一域名访问前端,浏览器无 CORS 报错
- 估时:1d
T-C-04 CORS 配置
- 产出:FastAPI
CORSMiddleware白名单["https://web.gaokao.example.com"] - 验收:
- OPTIONS 预检通过
- 带 cookie 时白名单明确
- 估时:0.25d
T-C-05 CSP / HSTS / 安全响应头
- 产出:
secure_headers中间件 - 验收:
Strict-Transport-Security: max-age=63072000; includeSubDomainsX-Content-Type-Options: nosniffX-Frame-Options: DENYContent-Security-Policy: default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; ...Referrer-Policy: strict-origin-when-cross-origin
- 估时:1d
- 依赖:T-C-04
C.2 监控(4 任务,2d)—— V1 保留
T-C-06 Sentry 前端
- 产出:
@sentry/nextjs集成 - 验收:
- 错误 100% 上报
- Performance trace 包含路由切换
- PII 脱敏(用户消息不含姓名/手机号)
- 估时:1d
T-C-07 Web Vitals 上报
- 产出:
next/web-vitals+ 自托管 endpoint - 验收:
- LCP / INP / CLS / FID / TTFB 全部上报
- 75 分位数存储到 Prometheus
- 估时:0.5d
T-C-08 trace 透传
- 产出:
x-trace-idheader 前后端贯通 - 验收:
- 前端请求带 trace id
- 后端日志 / Sentry 关联到同一 trace
- 估时:0.5d
T-C-09 告警规则
- 产出:3 条告警(错误率 > 1% / API P95 > 1s / Web Vitals P75 跌破预算)
- 验收:
- Slack / 钉钉 webhook 接收
- 估时:0d(仅配置)
C.3 文档 + 收口(4 任务,4d)—— V1 保留
T-C-10 部署文档
- 产出:
docs/DEPLOY.md(含 CloudStudio / 自托管 / Vercel 三种路径) - 估时:1d
T-C-11 运维 Runbook
- 产出:
docs/RUNBOOK.md(常见故障处理) - 估时:1d
T-C-12 安全审计
- 产出:
docs/SECURITY_AUDIT_2026-XX.md(OWASP top 10 自查) - 估时:1d
T-C-13 灰度发布流程
- 产出:5% → 20% → 100% 三步灰度
- 估时:1d
C.4 🆕 Poster CLI 集成(V2 新增,1 任务,1d)
T-C-44 🆕 Poster CLI 部署集成
- 产出:
scripts/gaokao-poster部署到 cron(每日 02:00 自动生成)- 产物上传到 CDN
- 失败告警
- 验收:
- crontab 配置生效
- 失败时 Sentry 告警
- 日志可查
- 估时:1d
- 依据:commit
a8b4927引入 poster CLI
T-C-45 🆕 集成测试套件
- 产出:
scripts/integration_test.py前端版本(FastAPI + Next.js 双服务) - 验收:
- 端到端 5 个关键场景
- CI 卡点
- 估时:0d(与 T-A-23 共用 CI)
- 依据:commit
a8b4927新增 integration_test.py
阶段 D · 设计 / a11y 加固(24 任务,14 人天)[V2 扩展 +6 任务 / +3 人天]
D.1 基础组件补齐(10 任务,4d)—— V1 保留
| 任务 | 组件 | 估时 | 验收 |
|---|---|---|---|
| T-D-01 | Dialog | 0.5d | 用 portal 渲染 + 焦点陷阱 + ESC 关闭 + 点击外部关闭 |
| T-D-02 | Toast | 0.5d | success/error/info/warn 4 种 + 自动消失 + 队列管理 |
| T-D-03 | Tooltip | 0.25d | hover 200ms 显示,3s 自动消失 |
| T-D-04 | Dropdown | 0.5d | Sidebar 头像菜单用,键盘导航 |
| T-D-05 | Avatar | 0.25d | AI / User / 群组 3 套 |
| T-D-06 | Skeleton | 0.25d | 4 种形状(text/card/circle/avatar) |
| T-D-07 | ProgressBar | 0.25d | 通用(区别于 InfoCollectionProgress) |
| T-D-08 | Switch | 0.25d | 偏好设置用 |
| T-D-09 | Checkbox | 0.5d | FormCard 选科用 |
| T-D-10 | Radio | 0.5d | 独立于 ThemeToggle,FormCard 单选用 |
D.2 a11y 全量审计(3 任务,2d)—— V1 保留
T-D-11 axe-core 集成
- 产出:
@axe-core/playwright+ 5 → 12 个页面自动扫描 - 验收:
- 0 critical / 0 serious 违规
- CI 卡点(PR 触发)
- 估时:0.5d
T-D-12 屏幕阅读器 + 键盘测试
- 产出:测试报告
docs/A11Y_TEST_2026-XX.md - 覆盖:
- NVDA 朗读 / 方案卡 / 审核卡
- VoiceOver 移动端测试
- Tab 顺序:Sidebar → Main → Quick prompts → Upload → Input → Send
- Skip link 工作
- 估时:1d
T-D-13 替换 alert() 为 Toast(R-NEW-4 应对)
- 产出:
plans/[id]/page.tsx:143,152的 alert 替换为 Toast- 异步触发下载(
URL.createObjectURL+<a download>)
- 验收:
- 导出图片 / PDF 真实下载
- Toast 提示"已导出方案 / 导出失败"
- 估时:0.5d
- 依赖:T-D-02
D.3 🆕 业务组件扩展(V2 新增,6 任务,4d)
T-D-14 🆕 SharePanel 组件
- 产出:
packages/ui/components/SharePanel.tsx - API:
<SharePanel resourceType resourceId />—— 包含创建按钮、链接展示、QR 码、复制、撤销 - 验收:
- 复用 T-B-36 useShareLink
- 状态:未创建 / 已创建 / 已撤销 / 已过期
- 视觉与原型一致(沿用 Card + Badge)
- Vitest 4 个状态全覆盖
- 估时:0.75d
- 依赖:T-B-36, T-D-11, T-D-12
T-D-15 🆕 ShareStatusPanel 组件
- 产出:
packages/ui/components/ShareStatusPanel.tsx - API:
<ShareStatusPanel resourceId />—— 显示当前分享状态 + 点击量 + 转化率 - 验收:
- 复用 T-B-40 useShareStatusPanel
- 30s 自动刷新
- test_share_status_panel.py 通过
- 估时:0.5d
- 依据:commit
0145d66提到 test_share_status_panel.py 期望但当前未通过
T-D-16 🆕 DataQueryForm 组件(4 个变体)
- 产出:
ScoreLineQueryForm—— 省份/年份/选科/分数输入RankEstimatorFormMajorsQueryForm—— 关键词 + 分类 + 页码SchoolsQueryForm
- 共用:
packages/ui/components/forms/QueryForm.tsx(抽象基类) - 验收:
- 4 个 form 复用同一 QueryForm 框架
- Vitest 覆盖:输入验证 / 提交 / 错误展示
- 估时:1d
- 依赖:T-B-37
T-D-17 🆕 DataQueryResult 组件(4 个变体)
- 产出:
ScoreLineResult—— 表格 + 分数段分布图RankEstimatorResult—— 大数字展示 + 历史趋势MajorsResult—— 列表 + 分类SchoolsResult—— 列表 + 985/211 标签
- 共用:
QueryResult框架(loading / empty / error / data 4 态) - 验收:
- 4 态切换动画
- 与原型视觉一致
- 估时:1d
- 依赖:T-D-16
T-D-18 🆕 ReviewFlow 组件
- 产出:
packages/ui/components/ReviewFlow.tsx - API:
<ReviewFlow planId />—— stepper 显示 + 进度条 + 结果跳转 - 状态机:
idle → started → analyzing → completed | failed | revision_needed - 验收:
- 复用 T-B-38 useReview
- 进度条实时更新
- 失败可重试
- 估时:0.5d
- 依赖:T-B-38
T-D-19 🆕 LLMEnhancement 组件
- 产出:
packages/ui/components/LLMEnhancement.tsx - API:
<LLMEnhancement auditReportId type />—— AI 增强摘要 / 风险解释 / 建议 - 验收:
- 异步加载(不阻塞主审核结果)
- 失败时降级到基础内容
- 显示"由 XXX 模型生成"标注
- 估时:0.5d
- 依赖:T-B-34, T-B-42
T-D-20 🆕 PosterPreview 组件
- 产出:
packages/ui/components/PosterPreview.tsx - API:
<PosterPreview planId template /> - 验收:
- 3 种模板切换
- 实时预览
- 下载按钮
- 估时:0.5d
- 依赖:T-B-43
D.4 暗色主题全覆盖(1 任务,1.5d)—— V1 保留
T-D-14(保留 V1 编号 T-D-14)暗色变体审计
- 产出:每个组件 dark 变体
- 验收:
- 18+ 组件都有 dark story(含 V2 新增 7 个)
- 视觉切换无白边/无对比度 < 4.5:1
- 风险徽章 / 概率条 / 模式指示器 暗色下语义色保持
- 估时:1.5d
- 依赖:T-D-01 ~ T-D-10, T-D-14(新) ~ T-D-20(新)
注:D.3 占用 T-D-14 ~ T-D-20 编号,D.4 改为 T-D-21。
T-D-21 暗色变体审计
- 同 V1 T-D-14 内容
- 依赖:T-D-01 ~ T-D-10, T-D-14 ~ T-D-20
D.5 国际化基础(2 任务,2d)—— V1 保留 + 新增词条
T-D-15(改为 T-D-22)next-intl 接入
- 产出:
packages/i18n/zh-CN/{chat,plans,common,errors,share,dataQuery,review,poster}.jsonpackages/i18n/en-US/{...}.json(占位空字典)- 路由级 locale 切换
- 验收:
- 所有硬编码中文移到词条
- 切到 en-US 显示 key 而非中文(占位)
- 估时:1.5d
- 依赖:T-B-18
- 约束:§0.1 R-NEW-5(quickPrompts 三态文案抽到
chat.json)
T-D-23 文案审计
- 产出:i18n key 命名规范文档
- 验收:
git grep "[\u4e00-\u9fff]"在apps/web/src/仅命中i18n/目录
- 估时:0.5d
- 依赖:T-D-22
D.6 性能 + 视觉回归(2 任务,1.5d)—— V1 保留
T-D-24 Chromatic + Lighthouse(合并 V1 T-D-17 + T-D-18)
- 产出:
- Chromatic 所有 Storybook stories
- Lighthouse CI
- 路由级
loading.tsx next/image/next/font优化
- 验收:
- 50+ stories baseline(V2 增量)
- LCP P75 < 1.8s
- Bundle < 150KB
- 估时:1.5d
阶段 E · 内部页面 React 化(24 任务,19 人天)[V2 扩展 +8 任务 / +2 人天]
E.1 运营后台基础(5 任务,5d)—— V1 4 任务 → V2 5 任务
| 任务 | 页面 | 估时 | 验收 |
|---|---|---|---|
| T-E-01 | 登录页 /admin/login |
0.5d | 复用 T-A-09 Button + T-A-10 Input;调 POST /api/admin/auth/login + URL token 支持(commit 2af1d06) |
| T-E-02 | Dashboard /admin |
1.5d | echarts 集成(订单/咨询趋势) + 4 个 KPI 卡片 + URL token 自动认证(commit 0ec5bdf) |
| T-E-03 | Layout /admin shared |
1d | 顶部 nav + 侧边栏 + 暗色支持 |
| T-E-04 | 错误兜底 /admin/error.tsx |
0.5d | 同 T-B-19 |
| T-E-05 | 权限守卫 | 0.5d | 未登录跳 /admin/login |
E.2 订单 + 案例(4 任务,4d)—— V1 保留
| 任务 | 页面 | 估时 |
|---|---|---|
| T-E-06 | 订单列表 /admin/orders |
1d |
| T-E-07 | 订单详情 /admin/orders/{id} |
1.5d |
| T-E-08 | 案例列表 /admin/cases |
0.75d |
| T-E-09 | 案例详情 /admin/cases/{id} |
0.75d |
E.3 Share Link 管理(🆕 V2 新增,3 任务,3d)
| 任务 | 页面 | 估时 | 验收 |
|---|---|---|---|
| T-E-10 🆕 | Share Link 列表 /admin/share-links |
1d | 调用 GET /api/share-link(待后端补全)+ 撤销按钮 + 过期筛选 |
| T-E-11 🆕 | Share Link 详情 /admin/share-links/{code}/stats |
1d | 点击量 / 转化率 / 设备分布 + 时序图 |
| T-E-12 🆕 | Poster 管理 /admin/posters |
1d | 复用 T-B-43 usePoster + T-D-20 PosterPreview + 模板选择 |
E.4 Data Query 内部页(🆕 V2 新增,4 任务,4d)
| 任务 | 页面 | 估时 | 验收 |
|---|---|---|---|
| T-E-13 🆕 | 分数线查询 /admin/data-query/score-line |
1d | 复用 T-D-16 ScoreLineQueryForm + T-D-17 ScoreLineResult |
| T-E-14 🆕 | 位次估算 /admin/data-query/rank-estimator |
0.75d | 复用 T-D-16 + T-D-17 |
| T-E-15 🆕 | 专业库 /admin/data-query/majors |
1d | 复用 T-D-16 + T-D-17 + 分类树 |
| T-E-16 🆕 | 院校库 /admin/data-query/schools |
1.25d | 复用 T-D-16 + T-D-17 + 985/211 筛选 |
E.5 Review 内部页(🆕 V2 新增,2 任务,2d)
| 任务 | 页面 | 估时 | 验收 |
|---|---|---|---|
| T-E-17 🆕 | 复核 Dashboard /admin/review |
1.25d | 待复核列表 + LLM 增强结果 + action 按钮(approve / reject / revise) |
| T-E-18 🆕 | LLM 审计日志 /admin/review/llm-logs |
0.75d | 模型使用统计 + token 消耗 + fallback 触发次数 |
E.6 Policy 内部页(🆕 V2 新增,1 任务,1d)
T-E-19 🆕 Policy 中心 /admin/policies
- 产出:
- 5 个政策页面 editor(privacy / service-terms / policy-center / same-score / deletion-policy)
- 草稿/发布两态
- Markdown 编辑器
- 估时:1d
- 依据:commit
c5b0c3d818bfa45 个政策页面已实现后端
E.7 通知 + 设置(4 任务,4d)—— V1 保留
| 任务 | 页面 | 估时 |
|---|---|---|
| T-E-20 | 通知列表 /admin/notifications |
1d |
| T-E-21 | 通知模板编辑 | 1.5d |
| T-E-22 | 系统设置 /admin/settings |
1.5d |
| T-E-23 | 用户管理 /admin/users |
1d |
E.8 公共门户 React 化(🆕 V2 新增,1 任务,1d)
T-E-24 🆕 公共门户 React 化
- 产出:
/pricing定价页/portal/{token}/info资料向导/portal/{token}/status状态页/portal/{token}/report报告查看/portal/{token}/cwb冲稳保建议/portal/{token}/full-plan完整规划/portal/{token}/notifications通知/portal/{token}/deletion-request删除请求/portal/payment-return支付回跳/s/{code}短链接分享
- 复用:所有 portal 页用
packages/ui/+packages/api-client/+packages/hooks/ - 验收:
- 与
admin/static/portal-ui.css视觉一致 - 全 8 个 portal 流程跑通
- 与
- 估时:1d
- 依据:V1 报告 E 阶段未涉及,但
web_public.py已实现 8+ portal 路由
2. 完整验收矩阵 V2
2.1 UI/交互完全遵循新设计(Self-Review #1)
| 检查项 | 工具 | 通过标准 |
|---|---|---|
| Chromatic 视觉回归 | Chromatic | 0 story 像素 diff > 0.1%(50+ stories) |
| 设计 token 一致性 | 自定义 lint | apps/web/src/ 无硬编码颜色 |
| 三态主题切换无闪白 | Playwright theme.spec.ts |
refresh 后 100ms 内正确 |
| 移动端断点 | Playwright | 768 / 1024 两断点 1:1 一致 |
| WCAG 2.1 AA | axe-core | 0 critical / 0 serious / < 3 moderate(12 个页面) |
| 键盘导航 | Playwright + 手动 | Tab 顺序合理;Enter / Space 触发 |
| 屏幕阅读器 | NVDA + VoiceOver | 4 模式指示器 / PlanCard / AuditReport / SharePanel / DataQuery 全部合理 |
| 8 项硬约束 | 单元测试 | 全部通过(T-A-15 ~ T-A-20) |
2.2 所有的功能都能完整实现(Self-Review #2)
| 模块 | 功能 | 任务 |
|---|---|---|
| 对话 | 发消息 / 收 AI 回复 / typing / 三态提示 | T-B-13, T-B-14 |
| 方案生成 | AI 推方案 / 三 Tab / 风险徽章 / 概率条 | T-A-13, T-B-12 |
| 方案保存 | 保存 / 重命名 / 删除 / 列表 / 详情 | T-B-15 |
| 方案对比 | 选 2 个 / 维度表 / 差异高亮 | V1 沿用 |
| 方案导出 | 图片 / PDF | T-D-13 |
| 方案审核 | 上传 / 风险项 / 冲稳保 / 良好项 / 一键修复 / 🆕 LLM 增强 | T-B-17, T-B-34, T-D-19 |
| 咨询记录 | 列表 / 搜索 / 删除 / 恢复 | T-B-15 |
| 兴趣测评 | Holland RIAS 10 题 | T-B-01 |
| 表单分步 | basic → subjects → prefs 守卫 | T-A-17, T-B-16 |
| 文件上传 | 4 模式(Excel/Image/PDF/Paste) | T-B-17 |
| 主题切换 | 三态 + 持久化 + 闪白 | T-A-07, T-A-19 |
| 响应式 | Sidebar / MobileNav | T-A-20 |
| 🆕 Share Link | 创建 / 撤销 / 复制 / QR / 状态面板 | T-B-22~T-B-25, T-B-36, T-B-40, T-D-14, T-D-15, T-E-10, T-E-11 |
| 🆕 Data Query | 分数线 / 位次 / 专业 / 院校 4 查询 | T-B-26 |
| 🆕 Review Flow | 启动 / 进度 / 结果 / action | T-B-29~T-B-31, T-B-38, T-D-18, T-E-17 |
| 🆕 LLM 增强 | 摘要 / 风险解释 / 建议 + 多模型 fallback | T-B-34, T-B-42, T-D-19, T-E-18 |
| 🆕 Poster | 3 模板 + 异步生成 + 下载 | T-B-35, T-B-39, T-D-20, T-E-12 |
| 🆕 Policy 中心 | 5 政策页 editor | T-E-19 |
| 🆕 公共门户 | 8 个 portal 流程 | T-E-24 |
| a11y / i18n / 错误 / 离线 | 沿用 V1 | T-D-11 ~ T-D-13, T-D-22, T-B-18~T-B-21 |
2.3 与后端集成正常(Self-Review #3)
| 集成点 | API | 任务 |
|---|---|---|
| 登录 | POST /api/admin/auth/login + URL token |
T-E-01 |
| 对话 | POST /api/chat/send + GET /api/chat/history |
T-B-01, T-B-02 |
| profile | GET / PATCH /api/profile |
T-B-16 |
| 方案 | CRUD /api/plans |
T-B-04, T-B-15 |
| 咨询 | CRUD /api/consultations |
T-B-03, T-B-15 |
| 审核上传 | POST /api/audit/upload |
T-B-05, T-B-17 |
| 🆕 Share Link | POST/DELETE /api/share-link + GET latest + GET stats |
T-B-22~T-B-25 |
| 🆕 Data Query | 4 个 query 端点 | T-B-26~T-B-28 |
| 🆕 Review | /review/start /status /action |
T-B-29~T-B-31 |
| 🆕 冲稳保 | /portal/{token}/cwb |
T-B-32 |
| 🆕 完整规划 | /portal/{token}/full-plan |
T-B-33 |
| 🆕 LLM 增强 | /api/llm/audit-enhance |
T-B-34, T-B-42 |
| 🆕 Poster | /api/poster/generate |
T-B-35, T-B-43 |
| 错误码 | registry 5 字段 | T-B-18 |
| CORS | 白名单 | T-C-04 |
| trace 贯通 | x-trace-id |
T-C-08 |
| Sentry | 前后端 | T-C-06, T-C-08 |
3. 风险与缓解 V2(增量)
| ID | 风险 | 缓解 |
|---|---|---|
| R-NEW-1 | useChat 编排层耦合 mock | T-B-12 解耦 |
| R-NEW-2 | localStorage key 兼容 | T-B-15 保留 key 名 |
| R-NEW-3 | CareerCard match 字段无校验 | T-A-22 Zod |
| R-NEW-4 | alert() 阻塞 | T-D-13 Toast |
| R-NEW-5 | quickPrompts 硬编码 | T-D-22 i18n |
| R-NEW-6 🆕 | 后端新模块 API 可能未稳定(share-link / data-query 仍有 commit 修改) | T-A-21 OpenAPI Codegen 每天跑 + T-C-44 集成测试兜底 |
| R-NEW-7 🆕 | LLM 增强 30s 超时降级 | T-B-42 显式降级路径 |
| R-NEW-8 🆕 | Poster CLI 部署依赖系统库(libpango / libharfbuzz) | T-C-44 Docker 化 |
| R-NEW-9 🆕 | 公共门户 8 流程视觉一致性(沿用 portal-ui.css) | T-E-24 视觉回归 + 端到端 e2e |
| R-NEW-10 🆕 | Share Link QR 码(前端需 qrcode.react 库) | T-A-09 之后单独 spike 1d |
| R-V2-1 | 真实 API 与 mock 不一致 | T-A-21 Codegen |
| R-V2-2 | Next 16 + React 19 + TanStack Query 兼容性 | T-A-22 spike |
| R-V2-3 | Bundle 爆炸 | T-B-25 异步 chunk |
| R-V2-4 | 老用户数据迁移 | T-B-15 保留 key |
| R-V2-5 | ChatMessage 路由扩展性 | T-B-13 拆 useChat |
4. 工时总览 V2
| 阶段 | 任务数 | 估时(人天) | V1 → V2 增量 |
|---|---|---|---|
| A. 基础设施 | 23 | 11 | 0 |
| B. 真实后端对接 | 35 | 38 | +14(21→35) |
| C. 架构整合 | 15 | 10 | +1(13→15) |
| D. 设计/a11y 加固 | 24 | 14 | +3(18→24) |
| E. 内部页面 React 化 | 24 | 19 | +2(16→24) |
| 总计 | 136 | 92 | +45 / +14 |
5. 立即可执行(本周启动,5 任务,4.5d)
仍按 V1 路径启动,因为
前端原型代码/未变:
- T-A-01(0.5d)→ 创建 monorepo
- T-A-02(0.5d)→ 收编前端原型代码
- T-A-06 + T-A-07(1d)→ 设计系统提取
- T-A-21(1d)→ OpenAPI Codegen 接入(现在会生成 30+ 端点的类型,比 V1 预想多)
- T-A-23(1.5d)→ CI 工作流
5 任务完成后,进入 T-A-04(tsconfig 共享)+ T-A-14(Vitest)+ T-A-18(Playwright),构成 A 阶段前半段。
6. Self-Review 闭环 V2
| Self-Review 目标 | 验证产物 | 状态 |
|---|---|---|
| UI/交互完全遵循新设计 | Chromatic + axe + 8 项硬约束单测 | 任务化 §2.1 |
| 所有的功能都能完整实现 | 16 → 21 模块功能(V1 +5 新模块) | 覆盖 21/21 |
| 与后端的集成正常 | 11 → 17 集成点(V1 +6 新端点) | 覆盖 17/17 |
| 5 个新风险 | R-NEW-1 ~ R-NEW-5 全部有应对 | 闭环 |
| 🆕 5 个 V2 新风险 | R-NEW-6 ~ R-NEW-10 全部有应对 | 闭环 |
| 可验收粒度 | 每个任务有 ID / 标题 / 验收标准 / 估时 / 依赖 / 关联约束 | 达标 |
附录 A:V2 任务清单 V1 任务对照
| V1 ID | V2 ID | 变化 |
|---|---|---|
| T-A-01 ~ T-A-23 | T-A-01 ~ T-A-23 | 完全保留 |
| T-B-01 ~ T-B-05 | T-B-01 ~ T-B-05 | 完全保留 |
| T-B-12 ~ T-B-15 | T-B-12 ~ T-B-15 | 完全保留 |
| T-B-16 ~ T-B-21 | T-B-16 ~ T-B-21 | 完全保留 |
| T-B-22 ~ T-B-27 | T-B-22 ~ T-B-27 | 完全保留(B.4 e2e 扩到 8 个) |
| 🆕 | T-B-22 ~ T-B-25, T-B-36, T-B-40, T-B-41 | Share Link 完整链路 |
| 🆕 | T-B-26 ~ T-B-28, T-B-37 | Data Query 4 端点 |
| 🆕 | T-B-29 ~ T-B-31, T-B-38 | Review Flow 3 端点 |
| 🆕 | T-B-32, T-B-33 | Portal cwb / full-plan |
| 🆕 | T-B-34, T-B-42 | LLM 增强 |
| 🆕 | T-B-35, T-B-39, T-B-43 | Poster |
| T-C-01 ~ T-C-13 | T-C-01 ~ T-C-13 | 完全保留 |
| 🆕 | T-C-44, T-C-45 | Poster CLI 集成 + 集成测试 |
| T-D-01 ~ T-D-10 | T-D-01 ~ T-D-10 | 完全保留 |
| T-D-11 ~ T-D-13 | T-D-11 ~ T-D-13 | 完全保留 |
| 🆕 | T-D-14 ~ T-D-20 | 7 个新业务组件 |
| T-D-14 → 改为 T-D-21 | T-D-21 | 暗色变体审计 |
| T-D-15 → 改为 T-D-22, T-D-23 | T-D-22, T-D-23 | next-intl + 文案审计 |
| T-D-17 + T-D-18 → 合并为 T-D-24 | T-D-24 | Chromatic + Lighthouse |
| T-E-01 ~ T-E-09 | T-E-01 ~ T-E-09 | 完全保留(T-E-02 增 URL token) |
| T-E-10 ~ T-E-13 → 改为 T-E-20 ~ T-E-23 | T-E-20 ~ T-E-23 | 通知 + 设置 + 用户管理 |
| 🆕 | T-E-10 ~ T-E-12 | Share Link 管理 |
| 🆕 | T-E-13 ~ T-E-16 | Data Query 内部页 |
| 🆕 | T-E-17, T-E-18 | Review + LLM 审计 |
| 🆕 | T-E-19 | Policy 中心 |
| 🆕 | T-E-24 | 公共门户 React 化 |
评审完成。V2 任务清单:136 任务 / 92 人天,比 V1 增加 45 任务 / 14 人天,主要因后端 share-link / data-query / review / llm / poster 5 大新模块的 React 化。 建议向 PM 申请追加预算 14 人天,或调整 E 阶段部分低优先级页面的实施顺序。