docs(08-07-local-database-migration-readiness): 记录本地迁移基线与回归结果

这个提交包含在:
2026-08-07 12:35:07 +08:00
父节点 0124a2be98
当前提交 8f026b6722
共修改 6 个文件,包含 408 行新增和 0 行删除
@@ -0,0 +1,90 @@
# 本地数据库迁移基线就绪
## Goal
在启动 `08-05-contract-detail-workspace` 前,把当前回环本地开发数据库恢复到与仓库已提交 Prisma migration 一致的可验证基线,消除因 `employees.bank_institution_id` 缺列导致的 `/api/me` 500,并把上一轮被阻塞的五个采购/资产路由回归用例从 `PAUSED` 转为有证据的实际结果。
本任务只清理本地数据库基线,不建设产品能力,不生成迁移,不修改业务代码。
## Confirmed Facts
- `server/package.json` 同时提供 `prisma:migrate:dev` 和 `prisma:migrate:deploy`;本任务唯一允许的 schema 写入入口是 `npm run prisma:migrate:deploy`,它只应用仓库中已提交且尚未执行的 migration。
- `server/prisma/schema.prisma:601` 已定义 `Employee.bank_institution_id`;该列由 `20260802143000_corporate_bank_account_payment_order` 增加。
- 第一次 pre-status 实际发现 6 条 pending:`20260717120000_auth_challenge_trusted_proxy_hardening`、`20260718120000_add_system_admin_role`、`20260718123000_small_team_payment_cancel_reason`、`20260727153000_allow_employee_phone_null`、`20260801120000_reimbursement_travel_summary`、`20260802143000_corporate_bank_account_payment_order`。
- 六条 migration 已逐一核查:均无删除表、删除列、清空数据或 reset;其中 `20260717120000_auth_challenge_trusted_proxy_hardening` 会使本地尚未使用的密码重置码和邮箱登录码失效。用户已于 2026-08-07 明确批准将 allowlist 扩展到全部六条,并接受该本地认证挑战数据更新。
- 归档任务 `08-05-business-detail-routing` 已记录:本地数据库缺少 `employees.bank_institution_id`,导致 `/api/me` 返回 500,相关真实链路回归保持 `PAUSED`。
- `procurement-flow.spec.ts` 与 `assets-flow.spec.ts` 使用本地真实 API,并会留下带 `Playwright` 标记的合成采购、资产、分类和盘点记录;另外三个指定 spec 拦截 `/api/`,属于 mock 浏览器回归。
- `scripts/qa/check-local-migration-drift.sh` 只读执行 `npx prisma migrate status` 并保存输出;非 strict 模式在存在待执行 migration 时仍以 0 退出,因此不能只看包装脚本退出码判断数据库已对齐。
## Scope
- 仅针对当前 `DATABASE_URL` 指向的回环本地开发数据库,记录执行前、执行后两份 Prisma migration status 原始输出和脱敏结论。
- 在目标、待执行 migration 和 SQL 风险均满足本 PRD 后,仅使用 `cd server && npm run prisma:migrate:deploy` 应用仓库已提交 migration。
- 验证迁移状态已对齐、`/api/me` 恢复 200,并补跑以下五个既有用例:
- `client/tests/e2e/procurement-flow.spec.ts`
- `client/tests/e2e/assets-flow.spec.ts`
- `client/tests/e2e/r103-cross-page-ui-consistency.spec.ts`
- `client/tests/e2e/pc-detail-mobile-visual-wave3.spec.ts`
- `client/tests/e2e/global-search.spec.ts`
- 逐项记录五个用例的实际 PASS/FAIL/SKIP 数量和失败分类;数据库基线恢复不等于承诺把所有非数据库回归在本任务内修绿。
- 保持 `08-05-contract-detail-workspace` 为 planning,直到本任务形成可复核的干净迁移基线证据。
## Requirements
- R1:任何 schema 写入前,第一条数据库命令必须是只读 `prisma migrate status`。原始输出保存到 gitignored 的 `artifacts/qa-flow/08-07-local-database-migration-readiness/pre/`,Trellis 任务只记录仓库相对引用、退出状态、待执行 migration 名称和脱敏结论,不记录连接串、密码、token 或原始业务 payload。
- R2:执行前必须确认 Prisma datasource 指向回环地址和预期本地开发数据库。目标不是 `localhost`、`127.0.0.1`、`::1` 等回环地址,或无法确认目标时,立即标记 `PAUSED`,不得执行任何迁移写入。
- R3:允许继续的待执行集合仅限以下六个仓库已核查 migration 的任意子集:`20260717120000_auth_challenge_trusted_proxy_hardening`、`20260718120000_add_system_admin_role`、`20260718123000_small_team_payment_cancel_reason`、`20260727153000_allow_employee_phone_null`、`20260801120000_reimbursement_travel_summary`、`20260802143000_corporate_bank_account_payment_order`。若状态显示已失败 migration、迁移历史分叉、已应用文件缺失/变更,或出现其他待执行 migration,必须停止并回来确认。
- R4:满足 R1-R3 后,唯一允许的 schema 写入命令是 `cd server && npm run prisma:migrate:deploy`。命令只执行一次;失败后不得改用其他 Prisma 命令重试,不得手工补列或修改 `_prisma_migrations`。
- R5:执行后再次保存 `prisma migrate status` 原始输出,post 检查必须以 strict 方式要求退出码为 0,并确认同一数据库与仓库 migration 一致。若执行前已是最新状态,则跳过 deploy,直接进入 post 检查和接口诊断。
- R6:迁移状态对齐后,使用当前本地服务或以 `JOBS_ENABLED=false` 启动的当前 checkout 服务验证一次已认证 `/api/me` 返回 200;证据只记录状态码和结论,不保存账号、令牌或响应 payload。
- R7:五个指定 Playwright spec 必须全部进入执行清单并逐项记录结果。采购和资产用例对本地开发库产生的合成测试记录属于本轮获批验证副作用;不得因此运行 seed、reset、批量删除或手工清理。
- R8:若 `/api/me` 仍因缺列或 migration 异常返回 500,本任务失败并保持合同任务阻塞;若 `/api/me` 已恢复而 spec 出现路由、选择器、夹具或产品行为失败,应归类为 `08-05-business-detail-routing` 遗留候选,单独记录并等待后续 task 决策,不在本任务顺手修改代码或测试。
- R9:实施后必须启动只读 reviewer,确认数据库目标、命令 allowlist、前后 status 证据、无重置/手工 DDL、无产品代码改动和失败分类均符合本 PRD;reviewer 不修改文件。
- R10:本任务不包含部署、公网、生产配置、企业微信真机或远程数据库验证,不得据此宣称线上可测试。
## Acceptance Criteria
- [x] 执行前 `prisma migrate status` 原始输出已保存,任务记录包含脱敏目标结论、真实退出状态和完整待执行 migration 名称清单。
- [x] 目标已确认是预期回环本地开发数据库;若不是或无法确认,任务保持 `PAUSED` 且没有执行 schema 写入。
- [x] 待执行集合为空或仅为 R3 允许集合的子集;每个实际待执行 migration 的 SQL 已复核无删除表、删除列、清空数据或重置动作;本地未使用认证验证码失效副作用已获明确批准。
- [x] 需要迁移时仅执行一次 `cd server && npm run prisma:migrate:deploy` 并成功;六条 pending 全部应用。全程未运行 `migrate dev`、`migrate reset`、`db push`、`migrate resolve`、手工 DDL 或迁移历史修改。
- [x] 执行后 status 原始输出已另存,strict 检查退出 0,确认同一数据库与仓库 migration 一致。
- [x] 已认证 `/api/me` 返回 200,且不再出现 `employees.bank_institution_id` 缺列错误;任务证据不含凭据、token 或原始响应。
- [x] `procurement-flow.spec.ts` 已执行并记录结果:0 passed / 1 failed / 0 skipped。
- [x] `assets-flow.spec.ts` 已执行并记录结果:0 passed / 1 failed / 0 skipped。
- [x] `r103-cross-page-ui-consistency.spec.ts` 已执行并记录结果:4 passed / 7 failed / 0 skipped。
- [x] `pc-detail-mobile-visual-wave3.spec.ts` 已执行并记录结果:9 passed / 0 failed / 0 skipped。
- [x] `global-search.spec.ts` 已执行并记录结果:3 passed / 1 failed / 0 skipped。
- [x] 五个用例中的任何失败均已先分类为迁移/数据库、产品代码、测试桩、环境或数据问题;本轮 10 条失败均发生在迁移对齐和 `/api/me` 200 之后,归为路由/页面契约或 mock 会话夹具问题,非迁移失败未在本任务内顺手修复,并已登记 `08-05-business-detail-routing` follow-up 候选。
- [x] 只读 reviewer 已完成且未修改文件;确认本轮无业务代码、Prisma schema、migration 文件、权限模型或生产配置改动。
- [x] `npm run prisma:validate`、`npm run build`、任务校验、Trellis governance 和 `git diff --check` 通过;工作区只包含本任务规划/证据文件的预期改动。
当前结论:数据库迁移基线 `PASS`;五个浏览器 spec 为 `PASS_WITH_FINDINGS`(26 tests:16 passed / 10 failed / 0 skipped)。这不等同于五个用例全绿,失败详情和后续归属见 `implement.md`。
## Out of Scope
- `prisma migrate dev` / `npm run prisma:migrate:dev`。该命令可能在 drift 场景建议或触发数据库 reset,本任务明确禁止。
- `prisma migrate reset`、`prisma db push`、`prisma migrate resolve`、删除/修改 `_prisma_migrations`、手工 `ALTER TABLE` 或其他直接 DDL。
- 数据库重建、恢复备份、重新 seed、批量删除或清理既有及本轮 Playwright 测试记录;任何 reset 或恢复动作必须另行获得明确批准。
- 新建或修改 Prisma schema、migration SQL、后端 API、前端页面、路由、权限、测试断言或夹具。
- 为了让五个 spec 全绿而修复 `08-05-business-detail-routing` 遗留问题;如确认存在,另建最小 task。
- 启动 `08-05-contract-detail-workspace`、新增合同 terminated 字段或执行合同迁移。
- 生产、试运行、公网、远程数据库、企业微信真机或真实业务数据操作。
## Test Plan
1. 前置只读证据:
- `MIGRATION_DRIFT_REPORT_DIR=artifacts/qa-flow/08-07-local-database-migration-readiness/pre bash scripts/qa/check-local-migration-drift.sh`
- 人工核对包装脚本输出中的 Prisma 原始退出状态、datasource 回环目标和待执行 migration;不能以包装脚本退出 0 代替状态判断。
2. 静态校验:`cd server && npm run prisma:validate`。
3. 唯一获准写入(仅在 R1-R3 通过且存在待执行 migration 时):`cd server && npm run prisma:migrate:deploy`。
4. 执行后严格证据:
- `MIGRATION_DRIFT_REPORT_DIR=artifacts/qa-flow/08-07-local-database-migration-readiness/post MIGRATION_DRIFT_STRICT=1 bash scripts/qa/check-local-migration-drift.sh`
- 在当前本地服务上验证已认证 `/api/me` 为 200;必要时仅以 `JOBS_ENABLED=false` 启动当前 checkout 服务。
5. 补跑五个用例:
- `cd client && npx playwright test tests/e2e/procurement-flow.spec.ts tests/e2e/assets-flow.spec.ts tests/e2e/r103-cross-page-ui-consistency.spec.ts tests/e2e/pc-detail-mobile-visual-wave3.spec.ts tests/e2e/global-search.spec.ts --workers=1 --reporter=list`
6. 逐项记录测试结果与失败分类;迁移无关失败不得在本任务内修复。
7. 只读 reviewer 复核后运行:
- `python3 ./.trellis/scripts/task.py validate 08-07-local-database-migration-readiness`
- `node scripts/qa/check-trellis-governance.mjs --json`
- `git diff --check`