test: align phase3 and overseas business acceptance

This commit is contained in:
2026-08-25 13:06:09 +08:00
parent d686b05966
commit 995c1833f8
8 changed files with 269 additions and 84 deletions
@@ -127,52 +127,40 @@ export async function run(context) {
const reverseResponse = await request(context, 'POST', `${BASE}/reverse-dispatch`, {
inboundId, containerBookingId, expectedVersion: Number(confirmed.aggregate.version), remark: context.marker,
}, { 'Idempotency-Key': reverseKey })
const reversed = context.apiSuccess(MODULE, '撤销国内出仓恢复装柜完成', reverseResponse, '', OPTIONS)
context.assert(MODULE, 'reverse-dispatch 恢复 READY_FOR_DISPATCH 与 LOADED', reverseResponse,
reversed?.aggregate?.dispatchStatus === 'READY_FOR_DISPATCH' && reversed?.aggregate?.inboundStatus === 'LOADED'
&& reversed?.timeline?.some?.((item) => item.module === 'OUTBOUND_DISPATCH' && item.action === 'REVERSE_DISPATCH'),
`dispatch=${reversed?.aggregate?.dispatchStatus || 'missing'}, inbound=${reversed?.aggregate?.inboundStatus || 'missing'}`, OPTIONS)
context.addStep(MODULE, '实际DEPARTED_WAREHOUSE节点产生后撤销精确返回A0409', reverseResponse,
reverseResponse.http === 200 && codeOf(reverseResponse) === 'A0409'
&& String(reverseResponse.body?.message || '').includes('DEPARTED_WAREHOUSE')
&& String(reverseResponse.body?.message || '').includes('禁止撤销'),
`HTTP=${reverseResponse.http}, code=${codeOf(reverseResponse)}, message=${reverseResponse.body?.message || 'missing'}`, OPTIONS)
const reverseReplayResponse = await request(context, 'POST', `${BASE}/reverse-dispatch`, {
inboundId, containerBookingId, expectedVersion: Number(confirmed.aggregate.version), remark: context.marker,
}, { 'Idempotency-Key': reverseKey })
const reverseReplay = context.apiSuccess(MODULE, 'reverse-dispatch 幂等重放', reverseReplayResponse, '', OPTIONS)
context.assert(MODULE, '撤销重放保持 READY_FOR_DISPATCH 与同一版本', reverseReplayResponse,
reverseReplay?.aggregate?.dispatchStatus === 'READY_FOR_DISPATCH'
&& Number(reverseReplay?.aggregate?.version) === Number(reversed?.aggregate?.version),
`dispatch=${reverseReplay?.aggregate?.dispatchStatus || 'missing'}, version=${reverseReplay?.aggregate?.version ?? 'missing'}`, OPTIONS)
const reverseHashConflict = await request(context, 'POST', `${BASE}/reverse-dispatch`, {
inboundId, containerBookingId, expectedVersion: Number(confirmed.aggregate.version), remark: 'forged',
}, { 'Idempotency-Key': reverseKey })
context.addStep(MODULE, 'reverse-dispatch 同键异参返回 A0409', reverseHashConflict,
reverseHashConflict.http === 200 && codeOf(reverseHashConflict) === 'A0409',
`HTTP=${reverseHashConflict.http}, code=${codeOf(reverseHashConflict)}`, OPTIONS)
const staleConfirmResponse = await request(context, 'POST', `${BASE}/confirm-dispatch`, actionBody,
{ 'Idempotency-Key': `${context.marker}-outbound-confirm-stale`.slice(0, 128) })
context.addStep(MODULE, '撤销后旧版本再次确认返回 A0409', staleConfirmResponse,
staleConfirmResponse.http === 200 && codeOf(staleConfirmResponse) === 'A0409',
`HTTP=${staleConfirmResponse.http}, code=${codeOf(staleConfirmResponse)}`, OPTIONS)
context.addStep(MODULE, '禁止撤销边界重复请求仍精确返回A0409', reverseReplayResponse,
reverseReplayResponse.http === 200 && codeOf(reverseReplayResponse) === 'A0409'
&& String(reverseReplayResponse.body?.message || '').includes('DEPARTED_WAREHOUSE'),
`HTTP=${reverseReplayResponse.http}, code=${codeOf(reverseReplayResponse)}`, OPTIONS)
const finalDetailResponse = await request(context, 'GET', `${BASE}/detail?${selector}`)
const finalDetail = context.apiSuccess(MODULE, '负向与幂等验证后回查出仓聚合', finalDetailResponse, '', OPTIONS)
context.assert(MODULE, '出仓聚合保持 READY_FOR_DISPATCH、LOADED 和确认撤销历史', finalDetailResponse,
finalDetail?.aggregate?.dispatchStatus === 'READY_FOR_DISPATCH'
context.assert(MODULE, '出仓聚合保持 WAITING_FOR_LOADING、LOADED 且无成功撤销历史', finalDetailResponse,
finalDetail?.aggregate?.dispatchStatus === 'WAITING_FOR_LOADING'
&& finalDetail?.aggregate?.inboundStatus === 'LOADED'
&& Number(finalDetail?.aggregate?.version) === Number(reversed?.aggregate?.version)
&& finalDetail?.timeline?.some?.((item) => item.module === 'OUTBOUND_DISPATCH' && item.action === 'CONFIRM_DISPATCH')
&& finalDetail?.timeline?.some?.((item) => item.module === 'OUTBOUND_DISPATCH' && item.action === 'REVERSE_DISPATCH'),
&& Number(finalDetail?.aggregate?.version) === Number(confirmed?.aggregate?.version)
&& finalDetail?.timeline?.filter?.((item) => item.module === 'OUTBOUND_DISPATCH'
&& item.action === 'CONFIRM_DISPATCH').length === 1
&& !finalDetail?.timeline?.some?.((item) => item.module === 'OUTBOUND_DISPATCH'
&& item.action === 'REVERSE_DISPATCH'),
`dispatch=${finalDetail?.aggregate?.dispatchStatus || 'missing'}, inbound=${finalDetail?.aggregate?.inboundStatus || 'missing'}, version=${finalDetail?.aggregate?.version ?? 'missing'}`, OPTIONS)
if (reversed?.aggregate) {
if (confirmed?.aggregate) {
context.createdResources.phase3OutboundDispatch = {
marker: context.marker, inboundId, containerBookingId,
orderId: id(reversed.aggregate.orderId), tenantId: id(reversed.aggregate.tenantId),
confirmedStatus: confirmed?.aggregate?.dispatchStatus || null,
confirmedInboundStatus: confirmed?.aggregate?.inboundStatus || null,
confirmedVersion: Number(confirmed?.aggregate?.version),
finalStatus: reversed.aggregate.dispatchStatus,
finalInboundStatus: reversed.aggregate.inboundStatus,
finalVersion: Number(reversed.aggregate.version),
orderId: id(confirmed.aggregate.orderId), tenantId: id(confirmed.aggregate.tenantId),
confirmedStatus: confirmed.aggregate.dispatchStatus,
confirmedInboundStatus: confirmed.aggregate.inboundStatus,
confirmedVersion: Number(confirmed.aggregate.version),
finalStatus: confirmed.aggregate.dispatchStatus,
finalInboundStatus: confirmed.aggregate.inboundStatus,
finalVersion: Number(confirmed.aggregate.version),
}
}
}