Skip to content

2.5 PR Review 与交付 ​

AI 返回代码不是交付事件。提交者要亲自读 diff、运行测试、操作 H5,并对进入 commit 的每一行负责。

本节按一条阶段 2 分支走完 Review。所有命令从教学仓 repository root 执行。

1. 回到需求,不先看 AI 解释 ​

先用用户行为重读这条分支:

  • 切换阶段、收藏和浏览历史在 refresh 后恢复;
  • 首页支持 loading、empty、error 和 retry;
  • 详情只记录存在的固定推荐 ID;
  • “我的记录”按收藏与历史 ID 取回当前内容;
  • page 经 provider 使用 client,component 不读 store,page/component 不碰 storage;
  • Enter、Space 和点击走同一 action,紧凑操作至少 44 × 44。

AI 的说明只能作为索引。需求是否满足,要从文件、断言和页面行为判断。

2. 要一份文件清单,再和 Git 对账 ​

要求 AI 返回它修改、创建、删除的路径与每个文件的责任,不要接收“已完成 persistence 和 UI”这类概括。

随后运行:

bash
git status --short
git diff --name-status checkpoint/week-01..HEAD
git diff --stat checkpoint/week-01..HEAD
git diff --check checkpoint/week-01..HEAD

git status 负责发现未提交文件;range diff 负责展示整条分支。两份清单都要和 AI 的回答对上。出现 package、lockfile、生成物或无法解释的路径时,先停在 diff,不测试、不暂存。

3. 读整条分支 diff ​

先按责任边界分组:

bash
git diff checkpoint/week-01 -- apps/web/src/domain apps/web/src/persistence
git diff checkpoint/week-01 -- apps/web/src/stores
git diff checkpoint/week-01 -- apps/web/src/api apps/web/src/composables
git diff checkpoint/week-01 -- apps/web/src/components apps/web/src/pages apps/web/src/pages.json
git diff checkpoint/week-01 -- apps/web/src/utils docs README.md

这些命令同时读取已提交和 tracked 未提交的 hunk。git status --short 找到的 untracked 新文件不会自动出现在 diff 里;逐个读取,不能跳过:

bash
git diff --no-index /dev/null apps/web/src/persistence/recommendation-state.ts

内容不同会让 git diff --no-index 返回 exit 1,这是预期结果。也可以先精确暂存单个新文件,再运行 git diff --cached -- <path>。后面的 cached gate 仍要覆盖整批待提交文件。

逐组检查:

  • domain 是否仍是四个 StageId 与五个 RecommendationId;
  • decoder 是否过滤、去重、限制 history 并返回冻结副本;
  • store 是否区分 invalid、未来版本与 read error 的写入策略;
  • client parser 是否拒绝 blank/unknown/duplicate ID、继承字段、getter、Proxy 与 sparse array;
  • 三个 page 是否只经 provider 调用 list、get、listByIds;
  • 共享 controller 是否同时丢弃 stale success 和 stale error;
  • test 中原有数量、固定文案和边界 assertion 是否被删除或放宽。

看到不懂的代码就停在对应 hunk。不要用测试绿灯跳过 diff。

4. 跑定向测试 ​

先把失败限制在最近修改的边界:

bash
npm run test:web -- \
  recommendation-state.test.ts \
  recommendation-store.test.ts

npm run test:web -- \
  recommendation-client.test.ts \
  recommendation-client-provider.test.ts \
  recommendation-request.test.ts

npm run test:web -- \
  stages.test.ts \
  recommendations.test.ts \
  keyboard-activation.test.ts \
  interaction-contract.test.ts

最终分布应为 persistence 38、store 18、client 45、provider 2、controller 9、stages 4、recommendations 20、keyboard 6、CSS guard 1。

定向失败时修第一处业务 assertion。删测试、把固定数量改成“大于 0”、把固定 ID 改成任意 string,都不算修复。

5. 跑完整 gate ​

bash
npm run check

批准所需输出:

text
Test Files  9 passed (9)
Tests       143 passed (143)
vue-tsc --noEmit: exit 0
H5 production build: exit 0

Vitest 的 Vite CJS deprecation 和 uni-app 版本提示是已知 warning。判断 build 要看 command exit code 与 DONE Build complete.。

6. 在浏览器走用户路径 ​

bash
npm --workspace apps/web run dev:h5 -- --host 127.0.0.1 --port 4173

在 http://127.0.0.1:4173/ 逐条操作:

  1. 选择 1–3 岁 后 refresh,选中态和 1 条结果保持。
  2. slow 请求完成后切到孕期,重新出现 loading,再显示 1 条。
  3. 用 Space 收藏“日常主题图画书”,URL 留在首页;refresh 后收藏态保持。
  4. 连续两次打开同一详情,最近浏览仍为 1 条。
  5. scenario=slow 先 loading 后成功。
  6. scenario=empty 显示 0 条与 empty 文案。
  7. scenario=retry 首次失败,Space 激活 retry 后成功。

再检查未知详情 ID 不写 history、Enter/Space、所有紧凑操作 44 × 44、390px 无整页横向溢出、console error 0。记录实际观察,不写“页面看起来正常”。

7. 精确暂存实际阶段 2 文件 ​

下列 28 个路径来自 checkpoint/week-01..checkpoint/week-02-greenfield 的实际 diff。不要使用 git add apps/web/src、git add -A 或目录级通配:

bash
git add -- \
  README.md \
  apps/web/src/api/mock-recommendation-client.ts \
  apps/web/src/api/recommendation-client-provider.test.ts \
  apps/web/src/api/recommendation-client-provider.ts \
  apps/web/src/api/recommendation-client.test.ts \
  apps/web/src/api/recommendation-client.ts \
  apps/web/src/components/AsyncStatePanel.vue \
  apps/web/src/components/RecommendationCard.vue \
  apps/web/src/components/StagePicker.vue \
  apps/web/src/components/interaction-contract.test.ts \
  apps/web/src/composables/recommendation-request.test.ts \
  apps/web/src/composables/recommendation-request.ts \
  apps/web/src/domain/recommendations.test.ts \
  apps/web/src/domain/recommendations.ts \
  apps/web/src/domain/stages.test.ts \
  apps/web/src/domain/stages.ts \
  apps/web/src/pages.json \
  apps/web/src/pages/detail/index.vue \
  apps/web/src/pages/index/index.vue \
  apps/web/src/pages/saved/index.vue \
  apps/web/src/persistence/recommendation-state.test.ts \
  apps/web/src/persistence/recommendation-state.ts \
  apps/web/src/stores/recommendation-store.test.ts \
  apps/web/src/stores/recommendation-store.ts \
  apps/web/src/utils/keyboard-activation.test.ts \
  apps/web/src/utils/keyboard-activation.ts \
  docs/api-contract.md \
  docs/week-02-checkpoint.md

若其中某个文件没有本次修改,Git 不会新增 cached 内容。若 git status 还有不属于阶段 2 的文件,不要顺手加入。

8. Cached diff 是提交前最后一次 Review ​

bash
git diff --cached --name-only
git diff --cached --check
git diff --cached

Name-only 清单必须是上面的阶段 2 文件子集,且不能出现未知路径。--check 无输出后,从头读 cached diff;这份内容才会进入 commit。

提交后核对历史:

bash
git commit -m "feat(web): complete stage two recommendation flow"
git log --oneline --decorate checkpoint/week-01..HEAD
git status --short

Commit subject 要描述业务改动。Log 中每条提交都应能单独解释;git status 应为空。若采用多提交 Review,每次都重复精确 add、cached name/check/diff,不把未审文件带进后一条 commit。

9. 写 Reviewer 能复跑的 PR summary ​

markdown
## Summary
- add the versioned recommendation state boundary and Pinia persistence flow
- add the three-method RecommendationClient, app provider, Mock scenarios, and stale-request controller
- connect home, detail, and saved/history pages with shared keyboard and 44 × 44 interaction contracts

## Verification
- targeted suites: 38 / 18 / 45 / 2 / 9 / 4 / 20 / 6 / 1
- npm run check: 9 files, 143 tests, typecheck and H5 build passed
- H5: refresh persistence, stage reload, favorite, history dedupe, slow, empty, retry
- 390px: no page overflow; compact controls measured at least 44 × 44; console error 0

PR summary 写可复跑的事实,不写“AI 已完成”。

Reviewer checklist ​

  • [ ] Page 不 import data、Mock adapter 或 storage;只经 provider 使用 client。
  • [ ] Component 不读取 store;props 与 events 能从浏览器操作到达 page。
  • [ ] Decoder tests 守住 canonical stage、固定 ID、过滤去重、history 10、freeze 与 read status。
  • [ ] Store tests 守住 hydrate、runtime guard、损坏 v1 恢复、未来版本/read error 写保护与 write failure。
  • [ ] Client tests 守住 blank/unknown/duplicate、own data property、getter、Proxy、sparse array 与冻结结果。
  • [ ] Controller tests 同时覆盖 stale success、stale error、retry 最近 loader 与错误文案清理。
  • [ ] 9 个 test files、143 tests fresh 通过;既有 test expectations 没有被删除或削弱。
  • [ ] vue-tsc --noEmit、H5 build 和全部浏览器路径有本次输出。
  • [ ] 所有紧凑操作实测至少 44 × 44,Enter/Space 可操作,console error 为 0。
  • [ ] Cached name/check/diff 与 commit log 已由提交者本人复核。

返回 阶段 2 总览。

晨悦 AI 实践手册