文件
hyb-oa/.trellis/tasks/09-26-approve-success-state-unchanged/prd.md
T
wangsli和Claude Opus 5.5 0931b1ea49 修复慢网络下审批后页面显示旧状态:SW API 缓存仅在离线时回退 [09-26-approve-success-state-unchanged]
app-api-runtime 对 /api/me、/api/workflow/tasks*、/api/workflow/approvers*、
/api/notifications* 使用 NetworkFirst + networkTimeoutSeconds: 3。网络响应
超过 3 秒时 Service Worker 返回审批前缓存的旧响应,真实响应被丢弃,页面
仍显示「待派发」。审批写入本身正确。自 2026-03(9112383d)起存在。

去掉网络超时,只在网络失败(离线)时回退缓存;退出登录清理缓存不变。
新增回归测试锁定该规则。负载复现修复前 3 轮命中 2 轮,修复后 3 轮 0 命中。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-26 18:58:45 +08:00

38 行
3.3 KiB
Markdown
原始文件 Blame 文件历史

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
# 审批通过返回成功但任务状态未变的并发异常调查
## Goal
查清完整门禁中采购主链路间歇失败的根因:经理审批接口返回 200,但随后任务详情仍为 `pending`、处理历史无 `approve`。确认它是测试隔离问题还是产品缺陷;若为产品缺陷,确认影响范围(是否波及全部审批实体)及是否在生产 `b1d25d3c` 已存在。
## Background / Evidence(2026-09-26)
- 候选 `750a184b` / `34675e1a` 共 4 轮 `verify-candidate`(2 核/8G,4 worker 固定)。`procurement-flow.spec.ts:29` 在第 2、4 轮失败,第 1 轮通过;managed `retained-local` 单跑两次均通过。第 4 轮 371/372,只剩此项。
- 失败断言 `procurement-flow.spec.ts:118`:审批后 30s 内 `main` 不含「已完成」。
- 第 4 轮服务端日志(相对采购 submit):+45.6s `POST /api/workflow/tasks/024c0c17…/approve` → 200(2917ms);+48.8s 同页 `GET /api/workflow/tasks/024c0c17…` → 200(3085ms)。审批期间无 warn/error 日志。
- 失败录像:确认框「处理中…」结束后,页面仍是同一任务、状态徽标「待派发」(= task `pending`)、可执行「通过/退回/驳回」,处理历史只有「提交」。
- 静态核对:`executeApproveWorkflowTask`(`server/src/routes/workflow.js:1395`)全部写入在同一个 `$transaction` 内;任务详情 GET 直接读库、无缓存;前端 `onSuccess` 用 `refetchTask()` 刷新(`client/src/pages/WorkflowTaskDetailPage.tsx:96`),PWA 不缓存 `/api`。采购单未匹配预算池,`confirmBudgetForEntity` 不写账。审批路径及任务详情页自 `b1d25d3c` 以来仅删除 ERP 同步。
- 第 1 轮(通过)与第 2/4 轮(失败)请求序列一致,差异只能在数据层判断;managed 环境强制 `QA_KEEP_DB=0`。
## Scope
- 非 managed 本地复现:本机 `hyb-oa-db` 临时库、`QA_KEEP_DB=1`,采购主链路与 `permission-direct-access` 并发重复运行;失败后直接查库区分「写入丢失」与「读取陈旧/错读」。
- 根因确认后给出最小修复方案(测试隔离或产品代码),修复另行确认后实施。
## Out of Scope
生产/ARM 访问、真实数据写入、push/部署、放宽断言或改用重试掩盖。
## Acceptance Criteria
- [x] 在保留库的环境复现至少一次,并记录失败单据任务/实例/历史的库内真实状态
- [x] 给出有证据支撑的根因(代码位置 + 机制),区分测试问题与产品缺陷
- [x] 若为产品缺陷:说明影响实体范围,及 `b1d25d3c` 是否同样存在(SW 规则覆盖 /api/me、workflow/tasks、approvers、notifications;自 2026-03 9112383d 起存在,生产同样受影响)
- [ ] 修复后 `verify-candidate` 完整通过(取得 PASS 回执)
## Test Plan
- 回归单测:`server/tests/unit/utils/client-pwa-api-cache.test.js` 锁定 `app-api-runtime` 不得设置网络超时(去掉修复即失败);`client-pwa-lifecycle.test.js` 保持退出登录清理运行时缓存。
- 构建产物核对:`client/dist/sw.js` 中 `app-api-runtime` 的 `NetworkFirst` 不含 `networkTimeoutSeconds`。
- 负载复现:`research/repro.sh`(采购 ×8 + permission-direct-access ×8,4 worker)修复前 3 轮命中 2 轮,修复后 3 轮 0 命中。
- 完整门禁:`verify-candidate` 取得 PASS 回执。