8.2 KiB
8.2 KiB
资产创建跳转与路由回归收尾
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
- 真实 API 创建资产成功后,页面直接进入
/assets/:assetId,不出现“放弃未保存的修改?”对话框(真实assets-flow通过)。 - 成功跳转使用
replace并保留安全列表来源;浏览器返回不会回到已提交的/assets/new(真实资产链路后退/前进通过)。 - 创建成功的导航不等待列表/详情缓存失效完成;缓存刷新异常不会阻止 canonical 跳转(代码顺序与后台 catch 复核通过)。
- 创建失败仍保留表单、dirty protection 与自然中文错误,不发生 post-save bypass(聚焦 mock 400 回归通过)。
- 资产未保存取消/放弃回归继续通过,证明共享 guard 的普通保护未被削弱(聚焦 mock 回归通过)。
assets-flow.spec.ts真实主链路通过,覆盖创建跳转、返回/前进与后续资产流转(1 passed / 0 failed / 0 skipped)。procurement-flow.spec.ts不再断言Employee,而是验证“申请人”与 fixture 中文姓名;完整主链路通过(1 passed / 0 failed / 0 skipped)。- 两个归档任务均有 append-only post-archive delta,明确 1 条产品回归与 9 条测试侧问题的不同归属及本任务引用。
- 现有前端 spec 明确成功持久化导航的 bypass 契约、失败边界和回归要求。
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
- 静态与构建:
cd client && npm run typecheckcd client && npm run build
- 共享 guard 与路由聚焦回归:
cd client && npx playwright test tests/e2e/business-detail-routing.spec.ts --workers=1 --reporter=listcd client && npx playwright test tests/e2e/r103-cross-page-ui-consistency.spec.ts --grep "资产长表单切回记录列表" --workers=1 --reporter=list
- 当前回环本地服务上补跑真实主链路:
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
- 记录真实 passed/failed/skipped 数量;若出现范围外新失败,只分类和留证,不顺手扩大修复。
- 流程门禁:
python3 ./.trellis/scripts/task.py validate 08-07-business-routing-regression-repairnode scripts/qa/check-trellis-governance.mjs --jsongit diff --check