生产由 b1d25d3c 更新为 70af0c6b:两个新迁移已应用(pending=none),
合同 refresh 与只读复核 13/13 通过,源码属主正确,公网免凭据检查通过。
SSH 断线后补跑包装器尾部步骤的过程已记入任务。
Co-Authored-By: Claude Opus 5.5 <[email protected]>
3.4 KiB
3.4 KiB
审批通过返回成功但任务状态未变的并发异常调查
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 轮通过;managedretained-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
- 在保留库的环境复现至少一次,并记录失败单据任务/实例/历史的库内真实状态
- 给出有证据支撑的根因(代码位置 + 机制),区分测试问题与产品缺陷
- 若为产品缺陷:说明影响实体范围,及
b1d25d3c是否同样存在(SW 规则覆盖 /api/me、workflow/tasks、approvers、notifications;自 2026-039112383d起存在,生产同样受影响) - 修复后
verify-candidate完整通过(取得 PASS 回执):70af0c6b372/372,artifacts/release-gate/20260926-202856,require离线复核通过
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 回执。