151 行
8.2 KiB
Markdown
151 行
8.2 KiB
Markdown
# 设计说明
|
||
|
||
## 1. 设计目标
|
||
|
||
本任务建立一个最小、可审计的本地数据库基线恢复流程:先证明目标和迁移状态,再用唯一允许的 forward-only 命令应用仓库 migration,最后独立验证数据库、接口和上一轮被阻塞的回归证据。
|
||
|
||
任务不改变任何产品契约。它解决的是“本地数据库 schema 落后于当前 checkout”这一环境/数据基线问题。
|
||
|
||
## 2. 安全不变量
|
||
|
||
1. 目标必须是预期回环本地开发数据库;目标不明或非回环时零写入。
|
||
2. 第一条数据库命令和最后一条数据库检查均为 `prisma migrate status`。
|
||
3. schema 写入命令只有 `npm run prisma:migrate:deploy`;不存在自动 fallback。
|
||
4. 允许集合之外的 pending migration、failed migration、history divergence 或 applied migration 异常全部进入 `PAUSED`。
|
||
5. 不运行 reset、dev、db push、resolve、手工 DDL、seed 或数据清理。
|
||
6. 原始 status 输出只保存在 gitignored 本地 artifacts;Trellis 只记录脱敏摘要和仓库相对引用。
|
||
7. 数据库基线恢复和产品回归通过是两层结论,不能互相冒充。
|
||
|
||
## 3. 状态流
|
||
|
||
```text
|
||
PLANNING
|
||
-> PRE_STATUS(只读)
|
||
-> 非回环/目标不明 ----------------------> PAUSED
|
||
-> failed/diverged/未知 pending ----------> PAUSED
|
||
-> 已是最新 ------------------------------> POST_STATUS
|
||
-> 仅 allowlist pending + SQL 安全 --------> DEPLOY_ONCE
|
||
-> deploy 失败 ----------------------> READ_ONLY_RECHECK -> PAUSED
|
||
-> deploy 成功 ----------------------> POST_STATUS
|
||
-> POST_STATUS strict PASS
|
||
-> /api/me 仍是 migration/缺列 500 --------> BLOCKED
|
||
-> /api/me 200 ----------------------------> FIVE_SPEC_RUN
|
||
-> FIVE_SPEC_RUN
|
||
-> migration/数据库失败 ------------------> BLOCKED
|
||
-> 产品/夹具/环境/数据失败 ----------------> FOLLOW_UP_REQUIRED
|
||
-> 全部通过 ------------------------------> BASELINE_READY
|
||
```
|
||
|
||
`FOLLOW_UP_REQUIRED` 表示本地 migration 基线已经恢复,但上一轮路由化仍有独立红灯;本任务只记录,不修改代码。合同任务是否继续由后续复核决定,不能把该失败吞成 PASS。
|
||
|
||
## 4. 目标与迁移前置
|
||
|
||
### 4.1 目标确认
|
||
|
||
- 从 Prisma status 的 datasource 信息确认使用预期本地开发数据库和回环主机。
|
||
- 任务记录只写“loopback=true/false、目标已人工匹配=true/false”,不复制连接 URL、用户名或密码。
|
||
- 若 shell 环境或 Prisma 自动加载的配置无法证明目标,停止,不尝试通过连接或写入来猜测。
|
||
|
||
### 4.2 Pending allowlist
|
||
|
||
| Migration | 仓库 SQL 摘要 | 本轮判断 |
|
||
| --- | --- | --- |
|
||
| `20260717120000_auth_challenge_trusted_proxy_hardening` | 增加认证挑战计数/锁定字段和索引,并失效本地未使用密码重置码、邮箱登录码 | 增量 schema + 已批准本地挑战数据更新 |
|
||
| `20260718120000_add_system_admin_role` | `RoleCode` 增加 `system_admin` | 非删除型 enum 扩展 |
|
||
| `20260718123000_small_team_payment_cancel_reason` | `payment_batches` 增加可空取消原因 | 纯增量 |
|
||
| `20260727153000_allow_employee_phone_null` | `employees.phone` 放宽为可空 | 非删除型 |
|
||
| `20260801120000_reimbursement_travel_summary` | 报销表增加四个可空差旅摘要字段 | 纯增量 |
|
||
| `20260802143000_corporate_bank_account_payment_order` | 新增银行机构/付款账户表,并增加员工及付款批次相关可空字段、索引和外键 | 增量;包含本轮缺失列 |
|
||
|
||
`migrate deploy` 会一次应用全部 pending migration,不能选择单个 ID。因此执行前 status 返回值必须是上述六条集合的子集,并逐个复读实际 SQL。任何额外 ID 都改变获批写入范围,必须暂停。用户已明确接受第一条 migration 对本地未使用认证验证码的失效处理。
|
||
|
||
### 4.3 命令 allowlist / denylist
|
||
|
||
允许:
|
||
|
||
- `npx prisma migrate status`(只读,允许由现有 drift wrapper 调用)。
|
||
- `npm run prisma:validate`(只读 schema 校验)。
|
||
- `npm run prisma:migrate:deploy`(唯一 schema 写入,前置通过后一次)。
|
||
|
||
禁止:
|
||
|
||
- `prisma migrate dev`
|
||
- `prisma migrate reset`
|
||
- `prisma db push`
|
||
- `prisma migrate resolve`
|
||
- 手工 SQL、迁移表修改、migration 文件改写
|
||
|
||
## 5. 证据设计
|
||
|
||
### 5.1 原始证据
|
||
|
||
- Pre:`artifacts/qa-flow/08-07-local-database-migration-readiness/pre/prisma-migrate-status.txt`
|
||
- Post:`artifacts/qa-flow/08-07-local-database-migration-readiness/post/prisma-migrate-status.txt`
|
||
|
||
两份文件由现有 `check-local-migration-drift.sh` 生成并保持 gitignored。它们用于本地只读复核,不提交。
|
||
|
||
### 5.2 Trellis 脱敏记录
|
||
|
||
`implement.md` 的执行记录只写:
|
||
|
||
- 执行时间与 HEAD;
|
||
- pre/post Prisma 实际退出状态;
|
||
- pending migration ID;
|
||
- `loopback=true/false`、目标匹配结论;
|
||
- deploy 是否执行及退出状态;
|
||
- `/api/me` 状态码;
|
||
- 五个 spec 的 passed/failed/skipped 和失败分类;
|
||
- reviewer 结论。
|
||
|
||
不记录 datasource URL、数据库账号、测试账号、密码、token、完整 API payload 或完整本地路径。
|
||
|
||
## 6. 服务与接口验证
|
||
|
||
- 优先复用已经运行且确认属于当前 checkout、当前本地数据库的服务。
|
||
- 如需启动服务,先确认当前构建对应 HEAD,再以回环 host、`JOBS_ENABLED=false` 和当前本地数据库启动,避免后台任务引入无关写入。
|
||
- `/api/me` 必须通过现有测试登录链路观察到 200;不另建凭据文件,不把认证材料写入任务证据。
|
||
- 若 status 已对齐但 `/api/me` 仍报缺列,说明不是普通 pending migration,停止并保留现场。
|
||
|
||
## 7. 五个用例与数据副作用
|
||
|
||
| Spec | API 类型 | 数据副作用 |
|
||
| --- | --- | --- |
|
||
| `procurement-flow.spec.ts` | 当前本地真实 API | 创建并推进合成采购记录,保存归档字段 |
|
||
| `assets-flow.spec.ts` | 当前本地真实 API | 创建合成资产分类、资产和盘点/流转记录 |
|
||
| `r103-cross-page-ui-consistency.spec.ts` | mock API | 无本地业务数据写入 |
|
||
| `pc-detail-mobile-visual-wave3.spec.ts` | mock API | 无本地业务数据写入 |
|
||
| `global-search.spec.ts` | mock API | 无本地业务数据写入 |
|
||
|
||
两个真实流 spec 使用时间戳或 `Playwright` 标记,便于识别,但当前测试没有自动清理。本任务不增加清理逻辑,不运行 reset 或批量删除;如后续需要治理测试数据,另建 task。
|
||
|
||
## 8. 失败分类
|
||
|
||
| 现象 | 分类 | 本任务处置 |
|
||
| --- | --- | --- |
|
||
| deploy 前目标非回环/不明 | 安全前置失败 | `PAUSED`,零写入 |
|
||
| status 出现 allowlist 外 ID、failed 或 divergence | migration 范围变化 | `PAUSED`,回来确认 |
|
||
| deploy 失败 | 数据库/migration | 保存输出,只读重查 status,停止 |
|
||
| post status 非 0 | 数据库基线未恢复 | `BLOCKED` |
|
||
| `/api/me` 仍因缺列 500 | migration 未解决 | `BLOCKED` |
|
||
| `/api/me` 200,但页面/选择器/断言失败 | 产品或测试桩 | 记录 `08-05-business-detail-routing` follow-up 候选 |
|
||
| 真实流缺业务前置数据 | 数据问题 | 记录缺口,不 seed、不重置 |
|
||
| 服务或端口不可用 | 环境问题 | 仅修复本地启动条件;不改产品代码 |
|
||
|
||
## 9. 回滚与失败恢复
|
||
|
||
- Prisma committed migration 是 forward-only。本任务不提供“drop 回去”的自动回滚,也不把已成功 migration 标记为未应用。
|
||
- deploy 失败后只允许保存输出并再次执行只读 status;不得用 `migrate dev/reset/resolve`、手工 DDL 或改 migration 历史继续推进。
|
||
- deploy 成功后若必须撤销,只能通过另行批准的备份恢复或新的纠正 migration;两者均不在本任务范围。
|
||
- Playwright 产生的合成记录不在本任务删除。测试数据清理由独立 task 评估,避免误删本地真实开发数据。
|
||
|
||
## 10. Review Gate
|
||
|
||
实施完成后只读 reviewer 专门核查:
|
||
|
||
1. pre/post 原始 status 证据存在且属于同一回环目标;
|
||
2. 实际 pending 集合未超出 allowlist;
|
||
3. 只执行了允许命令,未使用任何 reset/dev/db push/resolve/手工 DDL;
|
||
4. 没有修改 schema、migration、server/client 业务代码或测试;
|
||
5. `/api/me` 和五个 spec 结论没有把迁移通过与产品通过混为一谈;
|
||
6. 合同 task 未在基线结论形成前启动。
|