Files
gaokao-volunteer-system/SPRINT_1_S1_FOUNDATION.md
Frontend Developer fa7c22e8ed chore(s1): monorepo skeleton + 30-file prototype first commit
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
2026-07-03 09:22:03 +08:00

14 KiB
Raw Blame History

Sprint 1 任务拆解W1 · 11 人天 · 62 子任务)

主任务T-A-01 ~ T-A-13, T-A-23部分 目标monorepo 收编 + 5 基础组件 + CI 工作流 闸门G0基础骨架CI 跑通)

⚠️ ERATTA2026-07-03 09:13 勘误)

原稿假设 前端原型代码/ 已在 git 历史中 → 用 git mv 移动到 apps/web/

真实情况(经 git ls-files 验证):前端原型代码/ 此前从未 commit是拷贝到工作目录但未入库的文件。V1 / V2 报告里"原型不变 / 4114 行 / 247 行 design-system 100% 适用"判断全部基于"原型在 git 中"的错误前提。

勘误要点

  1. T-A-02 改成 cp -r + 删除原目录 + 首次 git add,不是 git mv
  2. T-A-06 / T-A-07「移 design-system.css / theme.ts 到 packages/ui/tokens/」保留(这 2 个文件原型 src/ 真实存在4948 行 / 30 文件)
  3. 原型实际是 30 文件 / 4948 行(不是 4114 行)
  4. apps/web/.gitignore 已存在且覆盖 node_modules / .next额外补 .npm-cache / next-dev.log
  5. .next-dev.pid 残留Next dev 进程被 kill 前留下的)需要 git ignore
  6. apps/web 内嵌 .git/ 目录cp -r 复制时携带)已删除,否则会被当成子模块

0. Sprint 1 概览

任务 主任务 估时 子任务数 子任务工时
T-A-01 创建 monorepo 根骨架 0.5d 4 0.50d
T-A-02 收编 前端原型代码/apps/web/ 0.5d 4 0.50d
T-A-03 加根 lint / format / git hooks 0.5d 5 0.50d
T-A-04 packages/tsconfig/base.json 0.25d 3 0.25d
T-A-05 共享 tsconfig.lib.json 0.25d 3 0.25d
T-A-06 design-system.csspackages/ui/tokens/ 0.5d 4 0.50d
T-A-07 lib/theme.tspackages/ui/tokens/ 0.25d 3 0.25d
T-A-08 packages/ui/tokens/index.ts barrel 0.25d 2 0.25d
T-A-09 Button 组件 1.0d 6 1.00d
T-A-10 Input / Select / Textarea 组件 1.5d 9 1.50d
T-A-11 Card 组件 0.5d 4 0.50d
T-A-12 Badge 组件 0.5d 5 0.50d
T-A-13 Tabs 组件 1.0d 6 1.00d
T-A-23 web-ci.yml 1.0d 4子集 1.00d
合计 14 任务 8.5d + 缓冲 2.5d = 11d 62 8.5d

S1 实际 11 人天 = 8.5d 任务 + 2.5d 应急/重构/Sprint 准备


T-A-01 · 创建 monorepo 根骨架0.5d · 4 子任务)

ST-S1-A-01.1 写 pnpm-workspace.yaml0.25d

  • 产出pnpm-workspace.yaml
    packages:
      - 'apps/*'
      - 'packages/*'
    
  • 验收
    • pnpm install 成功,无 peer warning
    • pnpm -r list 显示 apps/*packages/*
  • 依赖:无

ST-S1-A-01.2 写 turbo.json0.125d

  • 产出turbo.jsonbuild / lint / typecheck / test 4 任务及其依赖
  • 验收
    • turbo run build --dry-run 显示任务依赖图

ST-S1-A-01.3 写根 package.json0.0625d → 0d

  • 产出:根 package.jsonname: gaokao-monorepo, private: true, devDeps: turbo + prettier + eslint

ST-S1-A-01.4 写 .gitignore0.0625d → 0d

  • 产出:根 .gitignorenode_modules / dist / .next / coverage / .turbo / *.log

T-A-02 · 收编 前端原型代码/apps/web/0.5d · 4 子任务)⚠️ 勘误

真实路径D:\project\gaokao-volunteer-system\前端原型代码\D:\project\gaokao-volunteer-system\apps\web\ 真实体量30 个 src/ 文件 / 4948 行 + 5 配置文件 + 1 lockfile + node_modules不入库

ST-S1-A-02.1 cp -r + 删除原目录 + 清嵌入 .git0.25d⚠️ 勘误

  • 命令(已执行):
    # 1. 创建目标目录
    mkdir -p apps
    
    # 2. 复制git mv 失败因 node_modules 大量小文件 + 残留 next-dev.log 被锁)
    cp -r "前端原型代码" "apps/web"
    
    # 3. 删原目录
    rm -rf "前端原型代码"
    
    # 4. 必须删除嵌入的 .git/,否则主仓库把它当子模块
    rm -rf apps/web/.git
    
    # 5. 清理 Next dev 残留
    rm -f apps/web/next-dev.log apps/web/.next-dev.pid
    
  • 验收
    • apps/web/ 存在并包含 30 个 src/ 文件
    • 前端原型代码/ 目录删除
    • apps/web/.git 删除
  • 依赖:无
  • 实际执行已完成2026-07-03 09:13

ST-S1-A-02.2 补 .gitignore 隔离0.125d⚠️ 新增

  • 产出
    • .gitignore 末尾追加 node_modules/ / .next/ / out/ / dist/ / .turbo/ / *.tsbuildinfo / coverage/ / playwright-report/ / test-results/ / .vitest/
    • apps/web/.gitignore 已存在30+ 行),补 .npm-cache / next-dev.log / playwright-report/ / test-results/ / coverage/ / .turbo/
  • 验收
    • git status apps/web 看不到 node_modules/ / .next/
    • git add apps/web 后 staged count = 40不含 node_modules / .next

ST-S1-A-02.3 重命名 apps/web/package.json name0.0625d → 0d

  • 修改zhiyuan-prototype@gaokao/web
  • 新增 scriptstypecheck / test / test:e2e / clean
  • 验收
    • pnpm --filter @gaokao/web dev 跑通

ST-S1-A-02.4 修复 import 路径0.0625d → 0d

  • 验证tsconfig.jsonpaths: { "@/*": ["./src/*"] } 已正确,无需改
  • 验收
    • pnpm --filter @gaokao/web dev 启动 dev server端口 3000Sprint 1 收口时验证)

T-A-03 · 加根 lint / format / git hooks0.5d · 5 子任务)

ST-S1-A-03.1 写 eslint.config.mjs0.25d

  • 产出flat configeslint:recommended + @typescript-eslint + eslint-plugin-react + eslint-plugin-jsx-a11y
  • 验收
    • pnpm lint 跑通所有 workspace

ST-S1-A-03.2 写 prettier.config.mjs0.0625d → 0d

  • 产出{semi: false, singleQuote: true, printWidth: 100, trailingComma: 'all'}

ST-S1-A-03.3 写 .husky/pre-commit0.125d

  • 产出pnpm exec lint-staged
  • 验收
    • commit 触发 lint-staged

ST-S1-A-03.4 写 .lintstagedrc.json0.0625d → 0d

  • 产出*.{ts,tsx}eslint --fix + prettier --write

ST-S1-A-03.5 写 commitlint.config.js0.0625d → 0d

  • 产出conventional commits

T-A-04 · 抽 packages/tsconfig/base.json0.25d · 3 子任务)

ST-S1-A-04.1 写 packages/tsconfig/package.json0.0625d → 0d

  • 产出name: @gaokao/tsconfig, files: ["base.json", "lib.json"]

ST-S1-A-04.2 写 base.json0.125d

  • 产出strict: true, module: bundler, moduleResolution: bundler, jsx: preserve, paths: {~/*, @/*}

ST-S1-A-04.3 写 apps/web/tsconfig.json extends base0.0625d → 0d


T-A-05 · 共享 tsconfig.lib.json0.25d · 3 子任务)

ST-S1-A-05.1 写 lib.json0.125d

  • 产出composite: true, declaration: true, declarationMap: true

ST-S1-A-05.2 给 packages/ui 接入0.0625d → 0d

  • 产出packages/ui/tsconfig.json extends ../../tsconfig/lib.json

ST-S1-A-05.3 给 packages/api-client 接入0.0625d → 0d


T-A-06 · 移 design-system.csspackages/ui/tokens/0.5d · 4 子任务)

ST-S1-A-06.1 移动文件0.125d

  • 命令git mv apps/web/src/styles/design-system.css packages/ui/tokens/design-system.css
  • 验收
    • 247 行内容完整保留

ST-S1-A-06.2 修 247 行 token 引用0.125d

  • 产出:所有 @import / 引用路径修正

ST-S1-A-06.3 写 tokens/index.css 聚合入口0.125d

  • 产出@import './design-system.css'

ST-S1-A-06.4 写 token 命名规范文档0.125d

  • 产出docs/DESIGN_TOKENS.md100+ token 列表)

T-A-07 · 移 lib/theme.tspackages/ui/tokens/0.25d · 3 子任务)

ST-S1-A-07.1 移动文件0.125d

  • 命令git mv apps/web/src/lib/theme.ts packages/ui/tokens/theme.ts
  • 验收
    • 68 行代码完整保留

ST-S1-A-07.2 修正 initThemeScript 路径0.0625d → 0d

  • 验收
    • <head> 内联脚本注入 data-theme 正确

ST-S1-A-07.3 单测覆盖 3 态主题0.0625d → 0d

  • 产出theme.test.tslight / dark / system 各 1 用例
  • 验收
    • 100% line coverage

T-A-08 · 写 packages/ui/tokens/index.ts barrel0.25d · 2 子任务)

ST-S1-A-08.1 写 barrel0.125d

  • 产出export * from './theme'
  • 验收
    • import { initThemeScript } from '@gaokao/ui/tokens' 可用

ST-S1-A-08.2 配置 tsup / unbuild0.125d

  • 产出packages/ui/package.jsonbuild 脚本
  • 验收
    • pnpm --filter @gaokao/ui build 产出 dist/

T-A-09 · Button 组件1.0d · 6 子任务)

ST-S1-A-09.1 写 props / types0.125d

  • 产出ButtonPropsvariant: primary/secondary/ghost/danger, size: sm/md/lg, loading, disabled, iconLeft, iconRight
  • 验收
    • TypeScript discriminated union 正确

ST-S1-A-09.2 写基础渲染0.25d

  • 产出Button.tsx 主结构forwardRef + Slot
  • 验收
    • 4 variant × 3 size 渲染正确

ST-S1-A-09.3 写 loading / disabled 状态0.125d

  • 验收
    • loading 时显示旋转图标 + 禁用点击
    • disabled 时变灰 + 不可聚焦

ST-S1-A-09.4 写 keyboard a11y0.125d

  • 验收
    • Space / Enter 都触发 click
    • focus ring 可见

ST-S1-A-09.5 单测覆盖0.25d

  • 产出Button.test.tsx
  • 覆盖
    • 4 variant 颜色
    • loading 状态
    • click 调用
    • keyboard 触发
  • 验收
    • 100% line coverage

ST-S1-A-09.6 Storybook 5 故事0.125d

  • 产出Button.stories.ts × 5Primary/Secondary/Ghost/Danger/Loading
  • 验收
    • Chromatic baseline 接受

T-A-10 · Input / Select / Textarea 组件1.5d · 9 子任务)

ST-S1-A-10.1 Input props / types0.125d

  • 产出InputPropslabel, error, hint, prefix, suffix, size

ST-S1-A-10.2 Input 基础渲染0.25d

  • 验收
    • label[for] + input[id] 关联a11y 必做)

ST-S1-A-10.3 Input 错误态0.125d

  • 验收
    • error 红色边框 + errorMessage
    • aria-invalid="true"

ST-S1-A-10.4 Input 单测0.125d

  • 验收
    • 80% line coverage

ST-S1-A-10.5 Select props / 渲染0.25d

  • 产出:原生 <select> 包装 + 自定义箭头
  • 验收
    • 键盘导航正确(↑↓ 切换 option

ST-S1-A-10.6 Select 单测0.125d

ST-S1-A-10.7 Textarea props / 渲染0.125d

  • 产出自适应高度auto-resize on input
  • 验收
    • 输入 3 行后高度自动增长

ST-S1-A-10.8 Textarea 单测0.125d

ST-S1-A-10.9 Storybook 9 故事0.25d

  • 产出Input/Select/Textarea × 3 状态default / error / disabled

T-A-11 · Card 组件0.5d · 4 子任务)

ST-S1-A-11.1 props / types0.125d

  • 产出CardPropsvariant: elevated/outlined/flat, padding: sm/md/lg

ST-S1-A-11.2 渲染0.125d

  • 验收
    • 3 variant 视觉差异明显

ST-S1-A-11.3 单测0.125d

ST-S1-A-11.4 Storybook 3 故事0.125d


T-A-12 · Badge 组件0.5d · 5 子任务)

ST-S1-A-12.1 props / types0.125d

  • 产出BadgePropsvariant: rush/stable/safe/info/warn/error × 9 语义色)

ST-S1-A-12.2 渲染0.125d

  • 验收
    • 9 个语义色符合 design-system.css 中 badge token

ST-S1-A-12.3 dark 变体0.125d

  • 验收
    • 切到 dark 时对比度 ≥ 4.5:1

ST-S1-A-12.4 单测0.0625d → 0d

ST-S1-A-12.5 Storybook 9 故事0.0625d → 0d

  • 验收
    • Chromatic 接受 9 故事

T-A-13 · Tabs 组件1.0d · 6 子任务)

ST-S1-A-13.1 props / types0.125d

  • 产出TabsPropsitems, value, onChange, orientation: horizontal/vertical

ST-S1-A-13.2 渲染0.25d

  • 验收
    • active tab 下划线动画200ms

ST-S1-A-13.3 键盘导航0.25d

  • 验收
    • Tab 聚焦 / ←→ 切换 / Enter 激活
    • roving tabindex 正确

ST-S1-A-13.4 ARIA 角色0.125d

  • 验收
    • role="tablist" / role="tab" / role="tabpanel"
    • aria-selected / aria-controls

ST-S1-A-13.5 单测0.125d

  • 覆盖:键盘 / 鼠标点击 / 受控 / 非受控

ST-S1-A-13.6 Storybook 4 故事0.125d

  • 产出horizontal × 3 / vertical × 1

T-A-23 · web-ci.ymlSprint 1 子集1.0d · 4 子任务)

ST-S1-A-23.1 写 workflow 文件0.25d

  • 产出.github/workflows/web-ci.ymltrigger: pull_request
  • 步骤
    1. checkout
    2. setup-node 22
    3. pnpm install --frozen-lockfile
    4. cache pnpm

ST-S1-A-23.2 加 lint + typecheck 步骤0.25d

  • 命令pnpm turbo run lint typecheck --filter=@gaokao/* --filter=web
  • 验收
    • 总耗时 < 4 分钟

ST-S1-A-23.3 加 build 步骤0.25d

  • 命令pnpm turbo run build --filter=@gaokao/* --filter=web
  • 验收
    • bundle > 200KB 时 PR 评论 warn

ST-S1-A-23.4 验证 CI 跑通0.25d

  • 验收
    • apps/web 提 1 个测试 PRCI 绿/红信号可见

Sprint 1 收口验收

  • 14 主任务 / 62 子任务全部完成
  • 0 任务超 0.5d 估时
  • G0 通过monorepo 启动 + 5 组件 + CI 跑通
  • 进入 Sprint 2 前 commit<feat(s1): monorepo + 5 components + ci>