feat(phase3): 收口父子单与全链路验收

This commit is contained in:
2026-08-10 12:23:43 +08:00
parent b294695169
commit 75d5fd4e26
55 changed files with 1110 additions and 115 deletions
@@ -1,10 +1,30 @@
import { registerPendingContract } from './_phase3-pending-contract.mjs'
const MODULE = 'phase3-waiting-for-loading'
const OPTIONS = { scenario: 'waiting-for-loading-status', deploymentBlocker: true }
const BASE = '/api/platform/v1/first-leg/outbound-dispatches'
export async function run(context) {
registerPendingContract(context, {
module: 'phase3-waiting-for-loading', scenario: 'waiting-for-loading-status', name: 'WAITING_FOR_LOADING 统一终态',
reason: 'WAITING_FOR_LOADING、查询和状态时间线已实现并推送,待目标提交部署且 confirm/reverse 真实 HTTP 通过后删除此项', category: 'deployment-validation-pending',
fixtures: ['phase3Loading', 'phase3ContainerLoading'], contractSource: 'OutboundDispatchStatus / phase3-outbound-dispatch-v1.yaml',
assertions: ['本轮出仓完成后进入 WAITING_FOR_LOADING', '列表与详情状态一致', '历史记录来源状态、操作者和时间完整'],
})
const fixture = context.createdResources?.phase3OutboundDispatch
if (!fixture?.inboundId || !fixture?.containerBookingId || fixture.marker !== context.marker) {
context.addCoverageGap(MODULE, OPTIONS.scenario, 'WAITING_FOR_LOADING 状态与历史',
'本轮未取得 phase3-outbound-dispatch 的 marker 隔离聚合,未使用历史资源', 'fixture')
return
}
const selector = `inboundId=${encodeURIComponent(fixture.inboundId)}&containerBookingId=${encodeURIComponent(fixture.containerBookingId)}`
const response = await context.request('GET', `${BASE}/detail?${selector}`)
const detail = context.apiSuccess(MODULE, '回查 WAITING_FOR_LOADING 状态历史', response, selector, OPTIONS)
const history = Array.isArray(detail?.timeline)
? detail.timeline.filter((item) => item.module === 'OUTBOUND_DISPATCH') : []
const confirmed = history.find((item) => item.action === 'CONFIRM_DISPATCH')
const reversed = history.find((item) => item.action === 'REVERSE_DISPATCH')
context.assert(MODULE, '确认出仓真实进入 WAITING_FOR_LOADING', response,
fixture.confirmedStatus === 'WAITING_FOR_LOADING'
&& fixture.confirmedInboundStatus === 'LOADED'
&& confirmed?.fromStatus === 'READY_FOR_DISPATCH' && confirmed?.toStatus === 'WAITING_FOR_LOADING'
&& Boolean(confirmed?.operatorId) && Boolean(confirmed?.operatorName) && Boolean(confirmed?.occurredAt),
`confirmed=${confirmed?.fromStatus || 'missing'}->${confirmed?.toStatus || 'missing'}, version=${fixture.confirmedVersion ?? 'missing'}`, OPTIONS)
context.assert(MODULE, '撤销后状态恢复且 WAITING 历史不可变', response,
detail?.aggregate?.dispatchStatus === 'READY_FOR_DISPATCH' && detail?.aggregate?.inboundStatus === 'LOADED'
&& reversed?.fromStatus === 'WAITING_FOR_LOADING' && reversed?.toStatus === 'READY_FOR_DISPATCH'
&& Boolean(reversed?.operatorId) && Boolean(reversed?.occurredAt),
`current=${detail?.aggregate?.dispatchStatus || 'missing'}, reversed=${reversed?.fromStatus || 'missing'}->${reversed?.toStatus || 'missing'}`, OPTIONS)
}