80 行
8.2 KiB
Markdown
80 行
8.2 KiB
Markdown
# 资产创建跳转与路由回归收尾
|
|
|
|
## Goal
|
|
|
|
在合同详情迁移开始前,关闭 `08-05-business-detail-routing` 中已被真实 API 回归证伪的资产创建验收项:资产创建成功后必须直接进入 canonical 详情路由,且不能被“未保存修改”保护误拦截。同时修正采购主链路中已过时的英文姓名断言,并以追加 delta 的方式纠正两个归档任务对失败性质的记录。
|
|
|
|
本任务只处理 1 条确认的产品回归和 1 条确认的测试断言漂移;其余 8 条 mock 会话/登录态失败保持独立候选,不在本轮扩张。
|
|
|
|
## Confirmed Facts
|
|
|
|
- 归档任务 `.trellis/tasks/archive/2026-08/08-05-business-detail-routing/prd.md:46` 将“资产创建成功后 URL 变为 `/assets/:assetId`,返回不会回到已提交表单”保留为 `PAUSED`,原因仅是当时本地数据库缺列,未完成真实创建验证。
|
|
- 迁移基线恢复后,`assets-flow.spec.ts` 的真实 POST `/api/assets` 已成功返回实体 ID,但页面 30 秒后仍停留 `/assets/new`;归档迁移任务已在 `implement.md:57` 记录该结果。
|
|
- 当前本地 Playwright 失败 DOM 快照明确出现“放弃未保存的修改?”对话框;这证明直接阻塞跳转的是共享未保存保护,而不是 API 响应形状。
|
|
- 后端 `server/src/routes/assets.js:1329` 返回 `{ asset }`,前端 `client/src/api/assets.ts:307-311` 同样声明 `{ asset: AssetItem }`;`data.asset.id` 可用,响应形状不是根因。
|
|
- `client/src/pages/AssetRegistryPage.tsx:577-590` 在成功回调中先更新 saved signature,再于同一回调内 `navigate(...)`。React 状态尚未完成提交时,共享 guard 仍持有 dirty=true,因此程序化成功跳转被当作离开未保存表单而拦截。
|
|
- `client/src/components/common/UnsavedChangesGuard.tsx:31-50` 已有同步 `allowNextNavigationRef`,但目前只在用户确认“放弃并离开”时使用,没有“服务端已保存成功后安全跳转”的受控入口。
|
|
- `client/tests/e2e/procurement-flow.spec.ts:91-93` 已先验证“申请人”,随后仍断言英文 `Employee`;真实页面展示中文申请人姓名,符合 `docs/产品设计规则.md:23,118` 的自然中文规则。
|
|
- `r103-cross-page-ui-consistency.spec.ts` 的 7 条失败与 `global-search.spec.ts` 的 1 条失败均伴随登录态回落,属于另一个会话/mock 夹具问题集合。
|
|
|
|
## Scope
|
|
|
|
- 修复资产创建成功后的程序化跳转,使其绕过仅针对未保存数据的离开确认,并继续使用 `replace` 与安全 `state.from`。
|
|
- 让创建成功后的 canonical 跳转成为用户可见关键路径;缓存失效不得先于或阻塞该跳转。
|
|
- 保持普通脏表单的链接、返回、刷新、记录切换和显式返回保护行为不变。
|
|
- 将采购主链路的英文 `Employee` 断言改为 fixture 中的自然中文申请人姓名。
|
|
- 为 `08-05-business-detail-routing` 与 `08-07-local-database-migration-readiness` 的归档材料追加 post-archive delta:资产失败是确认的产品回归,其余 9 条为测试断言或 mock 会话候选;不覆盖原始历史记录。
|
|
- 在现有前端 spec 中补充“成功持久化后的程序化导航不得依赖异步 dirty state 清理”的共享约束。
|
|
|
|
## Requirements
|
|
|
|
- R1:资产创建 mutation 只有在 POST 成功并取得实体 ID 后,才可使用共享的 post-save 导航入口绕过未保存拦截;失败、超时或返回无 ID 时不得绕过。
|
|
- R2:创建成功必须 `replace` 到 `buildAssetDetailPath(data.asset.id)`,保留经校验的 `backSource`;浏览器返回不得重新打开已提交的 `/assets/new`。
|
|
- R3:创建成功后的 URL 跳转先于等待列表/详情缓存失效。缓存刷新可在后台继续,但失败不能撤销已成功创建的业务结果,也不能把用户留在创建表单。
|
|
- R4:共享 guard 的新入口必须语义收窄为“成功保存后导航”,复用现有同步 allow-next 机制;不得提供无条件全局关闭 guard 的开关。
|
|
- R5:正常脏表单行为保持不变:未保存时离开仍显示一次确认;继续编辑保留 URL 与输入;放弃后只执行一次目标动作;刷新仍触发浏览器保护。
|
|
- R6:创建请求失败时仍停留 `/assets/new`,保留输入并展示自然中文错误;不得误清 dirty state 或跳到详情。
|
|
- R7:采购主链路断言使用 `EMPLOYEE.name` 等 fixture 事实,不硬编码英文角色词,也不降低对“申请人”字段存在和正确对象姓名的验证强度。
|
|
- R8:真实 `assets-flow.spec.ts` 与 `procurement-flow.spec.ts` 必须补跑并形成明确结果;真实流产生的 Playwright 合成数据不在本任务清理、seed 或 reset。
|
|
- R9:归档证据只追加复核 delta,保留原 `PAUSED` 与发现时间线;不得把当时未验证的 AC 倒写成历史已通过。
|
|
- R10:其余 8 条登录态/mock 会话失败对应的用例不做修复,不改登录实现、不顺手增加 service-worker 或会话 fixture 修复;本轮仅扩充资产未保存保护的独立聚焦回归,另行评估那 8 条失败。
|
|
- R11:不修改后端 API、Prisma schema/migration、权限模型、路由 guard、资产数据范围、合同 task 或生产配置。
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [x] 真实 API 创建资产成功后,页面直接进入 `/assets/:assetId`,不出现“放弃未保存的修改?”对话框(真实 `assets-flow` 通过)。
|
|
- [x] 成功跳转使用 `replace` 并保留安全列表来源;浏览器返回不会回到已提交的 `/assets/new`(真实资产链路后退/前进通过)。
|
|
- [x] 创建成功的导航不等待列表/详情缓存失效完成;缓存刷新异常不会阻止 canonical 跳转(代码顺序与后台 catch 复核通过)。
|
|
- [x] 创建失败仍保留表单、dirty protection 与自然中文错误,不发生 post-save bypass(聚焦 mock 400 回归通过)。
|
|
- [x] 资产未保存取消/放弃回归继续通过,证明共享 guard 的普通保护未被削弱(聚焦 mock 回归通过)。
|
|
- [x] `assets-flow.spec.ts` 真实主链路通过,覆盖创建跳转、返回/前进与后续资产流转(1 passed / 0 failed / 0 skipped)。
|
|
- [x] `procurement-flow.spec.ts` 不再断言 `Employee`,而是验证“申请人”与 fixture 中文姓名;完整主链路通过(1 passed / 0 failed / 0 skipped)。
|
|
- [x] 两个归档任务均有 append-only post-archive delta,明确 1 条产品回归与 9 条测试侧问题的不同归属及本任务引用。
|
|
- [x] 现有前端 spec 明确成功持久化导航的 bypass 契约、失败边界和回归要求。
|
|
- [x] `cd client && npm run typecheck && npm run build`、聚焦 Playwright、任务校验、Trellis governance 与 `git diff --check` 通过。
|
|
|
|
## Out of Scope
|
|
|
|
- 修复 `r103-cross-page-ui-consistency.spec.ts` 的其余 7 条登录态失败或 `global-search.spec.ts` 的 1 条登录态失败。
|
|
- 重构全部 React Query mutation、统一全站缓存策略或调整所有成功 toast 时序。
|
|
- 修改采购或资产 API payload、后端业务逻辑、数据库、权限、导航 schema、移动端路由或生产配置。
|
|
- 启动 `08-05-contract-detail-workspace` 或执行任何合同 migration。
|
|
- seed、reset、批量删除或手工清理本地 Playwright 合成数据。
|
|
- 部署、公网检查、企业微信真机或线上可测试声明。
|
|
|
|
## Test Plan
|
|
|
|
1. 静态与构建:
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
2. 共享 guard 与路由聚焦回归:
|
|
- `cd client && npx playwright test tests/e2e/business-detail-routing.spec.ts --workers=1 --reporter=list`
|
|
- `cd client && npx playwright test tests/e2e/r103-cross-page-ui-consistency.spec.ts --grep "资产长表单切回记录列表" --workers=1 --reporter=list`
|
|
3. 当前回环本地服务上补跑真实主链路:
|
|
- `cd client && E2E_MODE=local E2E_BASE_URL=http://127.0.0.1:3000 npx playwright test tests/e2e/assets-flow.spec.ts tests/e2e/procurement-flow.spec.ts --workers=1 --reporter=list`
|
|
4. 记录真实 passed/failed/skipped 数量;若出现范围外新失败,只分类和留证,不顺手扩大修复。
|
|
5. 流程门禁:
|
|
- `python3 ./.trellis/scripts/task.py validate 08-07-business-routing-regression-repair`
|
|
- `node scripts/qa/check-trellis-governance.mjs --json`
|
|
- `git diff --check`
|