fix phase3 loading acceptance sequence
This commit is contained in:
@@ -67,13 +67,14 @@ test('HTTP chain refreshes after stale inventory and keeps one stable PDA identi
|
||||
'已拣项减量低于 minPackageCount 返回 A0409',
|
||||
'已拣项删除返回 A0409',
|
||||
'已拣项删除和减量失败后 plan/task/items 零写入',
|
||||
'订舱或五类证据等保留门禁未齐备时 LOADED 拒绝',
|
||||
'报关与最终完成前保持 LOADING 且不提前写 COMPLETE_LOADING',
|
||||
])
|
||||
assert.match(loading, /String\(staleIncrementBatch\.body\?\.message \|\| ''\)\.includes\('库存已变化,请刷新后重试'\)/)
|
||||
assert.match(loading, /id\(incrementedTask\?\.loadingPlanId\) === loadingPlanId/)
|
||||
assert.match(loading, /id\(incrementedTask\?\.containerBookingId\) === containerBookingId/)
|
||||
assert.match(loading, /const taskDetailPath = `\$\{pdaBase\}\/tasks\/\$\{canonicalTaskId\}\?warehouseId=/)
|
||||
assert.match(loading, /loadingPlanStatus: 'LOADING', finalStatus: 'AWAITING_REVIEW'/)
|
||||
assert.doesNotMatch(loading, /complete-before-downstream/)
|
||||
assert.doesNotMatch(loading, /\/loading\/complete\?tenantId=/)
|
||||
})
|
||||
|
||||
|
||||
@@ -1142,38 +1142,20 @@ export async function run(context) {
|
||||
}
|
||||
}
|
||||
|
||||
const beforeHardGateResponse = await context.request('GET', detailPath)
|
||||
const beforeHardGate = context.apiSuccess(MODULE, '读取 LOADED 硬门禁调用前即时版本', beforeHardGateResponse, '', OPTIONS)
|
||||
const beforeHardGateVersion = Number(beforeHardGate?.summary?.version)
|
||||
context.assert(MODULE, 'LOADED 硬门禁即时基线状态和版本有效', beforeHardGateResponse,
|
||||
beforeHardGate?.summary?.processStatus === 'LOADING' && Number.isInteger(beforeHardGateVersion),
|
||||
`status=${beforeHardGate?.summary?.processStatus || 'missing'}, version=${beforeHardGate?.summary?.version ?? 'missing'}`, OPTIONS)
|
||||
if (!Number.isInteger(beforeHardGateVersion)) return
|
||||
const beforeBlockedTaskResponse = await context.request('GET', taskDetailPath)
|
||||
const beforeBlockedTask = context.apiSuccess(MODULE, '读取下游门禁拒绝前 PDA 任务快照', beforeBlockedTaskResponse, '', OPTIONS)
|
||||
const beforeBlockedPlanResponse = await context.request('GET', `${smartLoadingBase}/plans/${loadingPlanId}`)
|
||||
const beforeBlockedPlan = context.apiSuccess(MODULE, '读取下游门禁拒绝前计划快照', beforeBlockedPlanResponse, '', OPTIONS)
|
||||
const blockedBeforeDownstream = await request(context, 'POST', `${pdaBase}/tasks/${canonicalTaskId}/complete`,
|
||||
{ expectedTaskVersion: Number(beforeBlockedTask?.version),
|
||||
operationId: `${context.marker}-complete-before-downstream`.slice(0, 128), remark: `${context.marker}-before-downstream` },
|
||||
{ 'Idempotency-Key': `${context.marker}-p3-complete-before-downstream`.slice(0, 128) })
|
||||
context.addStep(MODULE, '订舱或五类证据等保留门禁未齐备时 LOADED 拒绝', blockedBeforeDownstream,
|
||||
blockedBeforeDownstream.http === 200 && codeOf(blockedBeforeDownstream) === 'A0409',
|
||||
responseEvidence(blockedBeforeDownstream), OPTIONS)
|
||||
const blockedDetailResponse = await context.request('GET', detailPath)
|
||||
const blockedDetail = context.apiSuccess(MODULE, '回查 LOADED 硬门禁拒绝后的入库状态', blockedDetailResponse, '', OPTIONS)
|
||||
const blockedTaskResponse = await context.request('GET', taskDetailPath)
|
||||
const blockedTask = context.apiSuccess(MODULE, '回查 LOADED 硬门禁拒绝后的 PDA 任务', blockedTaskResponse, '', OPTIONS)
|
||||
const blockedPlanResponse = await context.request('GET', `${smartLoadingBase}/plans/${loadingPlanId}`)
|
||||
const blockedPlan = context.apiSuccess(MODULE, '回查 LOADED 硬门禁拒绝后的计划', blockedPlanResponse, '', OPTIONS)
|
||||
context.assert(MODULE, 'LOADED 硬门禁拒绝后 task/plan/inbound 零写入', blockedDetailResponse,
|
||||
blockedDetail?.summary?.processStatus === 'LOADING'
|
||||
&& Number(blockedDetail?.summary?.version) === beforeHardGateVersion
|
||||
&& Number(blockedTask?.version) === Number(beforeBlockedTask?.version)
|
||||
&& taskItemsSignature(blockedTask) === taskItemsSignature(beforeBlockedTask)
|
||||
&& Number(blockedPlan?.version) === Number(beforeBlockedPlan?.version)
|
||||
&& blockedPlan?.status === beforeBlockedPlan?.status,
|
||||
`inboundStatus=${blockedDetail?.summary?.processStatus || 'missing'}, inboundVersion=${blockedDetail?.summary?.version ?? 'missing'}, taskVersion=${blockedTask?.version ?? 'missing'}, planVersion=${blockedPlan?.version ?? 'missing'}`, OPTIONS)
|
||||
// 报关协同在本模块之后执行,最终 COMPLETE_LOADING 只由 phase3-loading-finalize 发起。
|
||||
// 当前服务端明确不以拖车作为前置门禁,因此这里不得用一次预期失败的写请求维持 LOADING。
|
||||
const stagedDetailResponse = await context.request('GET', detailPath)
|
||||
const stagedDetail = context.apiSuccess(MODULE, '下游协同前读取装柜中入库状态', stagedDetailResponse, '', OPTIONS)
|
||||
const stagedTaskResponse = await context.request('GET', taskDetailPath)
|
||||
const stagedTask = context.apiSuccess(MODULE, '下游协同前读取待最终完成 PDA 任务', stagedTaskResponse, '', OPTIONS)
|
||||
const stagedPlanResponse = await context.request('GET', `${smartLoadingBase}/plans/${loadingPlanId}`)
|
||||
const stagedPlan = context.apiSuccess(MODULE, '下游协同前读取装柜中计划', stagedPlanResponse, '', OPTIONS)
|
||||
context.assert(MODULE, '报关与最终完成前保持 LOADING 且不提前写 COMPLETE_LOADING', stagedDetailResponse,
|
||||
stagedDetail?.summary?.processStatus === 'LOADING'
|
||||
&& stagedTask?.taskStatus === 'LOADING'
|
||||
&& stagedTask?.workflowStatus === 'AWAITING_REVIEW'
|
||||
&& stagedPlan?.status === 'LOADING',
|
||||
`inboundStatus=${stagedDetail?.summary?.processStatus || 'missing'}, taskStatus=${stagedTask?.taskStatus || 'missing'}, workflow=${stagedTask?.workflowStatus || 'missing'}, planStatus=${stagedPlan?.status || 'missing'}`, OPTIONS)
|
||||
|
||||
context.createdResources.phase3Loading = {
|
||||
tenantId, orderId: id(source?.orderId), inboundId, preloadPlanId: planId,
|
||||
@@ -1189,7 +1171,7 @@ export async function run(context) {
|
||||
inventorySnapshotVerified: inventorySnapshotVerified && atomicBatchReplayVerified,
|
||||
inventoryMutationVerified, inventoryMutationCleanup,
|
||||
dynamicIncrementVerified, incrementalInboundId,
|
||||
pdaTaskVersion: Number(blockedTask?.version),
|
||||
pdaTaskVersion: Number(stagedTask?.version),
|
||||
marker: context.marker, inboundStatus: 'LOADING', loadingPlanStatus: 'LOADING', finalStatus: 'AWAITING_REVIEW',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,9 +445,9 @@ test('phase3 loading proves stale inventory zero-write and defers final completi
|
||||
'PDA 原子批次同参同键重放保持待人工确认',
|
||||
'回查下游门禁前原子 Batch 审计',
|
||||
'最终确认前仅保留 CLAIM/BATCH 且无 COMPLETE_LOADING',
|
||||
'订舱或五类证据等保留门禁未齐备时 LOADED 拒绝',
|
||||
'LOADED 硬门禁拒绝后 task/plan/inbound 零写入',
|
||||
'报关与最终完成前保持 LOADING 且不提前写 COMPLETE_LOADING',
|
||||
])
|
||||
assert.doesNotMatch(loading, /complete-before-downstream/)
|
||||
})
|
||||
|
||||
test('phase3 loading fixture forces A0 through reversible public location status APIs', () => {
|
||||
|
||||
Reference in New Issue
Block a user