const MODULE = 'phase3-container-overview' const OPTIONS = { scenario: 'phase3-container-overview-read-only', deploymentBlocker: true } const CONTAINERS = '/api/platform/v1/containers' function id(value) { return value == null ? '' : String(value) } export async function run(context) { const fixture = context.createdResources?.phase3ContainerLoading const containerId = id(fixture?.containerBookingId) const planId = id(fixture?.loadingPlanId) const warehouseId = id(fixture?.warehouseId) if (!containerId || !planId || !warehouseId || fixture?.marker !== context.marker) { context.addStep(MODULE, '复用智能装柜产生的货柜 overview fixture', null, false, `containerBookingId=${containerId || 'missing'}, loadingPlanId=${planId || 'missing'}, warehouseId=${warehouseId || 'missing'}`, OPTIONS) return } const overviewResponse = await context.request('GET', `${CONTAINERS}/${encodeURIComponent(containerId)}/overview`) const overview = context.apiSuccess(MODULE, '查询货柜 overview 聚合详情', overviewResponse, `containerBookingId=${containerId}`, OPTIONS) context.assert(MODULE, 'overview 返回货柜身份、版本和时间线', overviewResponse, id(overview?.container?.id) === containerId && Number.isFinite(Number(overview?.container?.version)) && Array.isArray(overview?.documents) && Array.isArray(overview?.exceptionHistory) && Array.isArray(overview?.timeline), `documents=${overview?.documents?.length ?? 'missing'}, timeline=${overview?.timeline?.length ?? 'missing'}`, OPTIONS) const timeline = Array.isArray(overview?.timeline) ? overview.timeline : [] context.assert(MODULE, 'overview timeline 按 occurredAt 升序返回', overviewResponse, timeline.every((item, index) => index === 0 || new Date(timeline[index - 1]?.occurredAt) <= new Date(item?.occurredAt)), `events=${timeline.length}`, OPTIONS) if (overview?.pda) { context.assert(MODULE, 'overview PDA 摘要字段完整', overviewResponse, ['taskId', 'taskStatus', 'taskVersion', 'itemCount', 'completedItemCount', 'unresolvedItemCount'] .every((field) => overview.pda[field] !== undefined) && Array.isArray(overview.pda.photoCounts) && Array.isArray(overview.pda.photos) && Array.isArray(overview.pda.exceptionReasons), `taskId=${id(overview.pda.taskId)}, photos=${overview.pda.photos.length}`, OPTIONS) for (const [index, photo] of overview.pda.photos.entries()) { context.assert(MODULE, `overview PDA 照片摘要 ${index + 1} 字段完整`, overviewResponse, ['evidenceId', 'fileId', 'status', 'downloadPath'].every((field) => photo[field] !== undefined), `fileId=${id(photo.fileId)}`, OPTIONS) } } for (const documentType of ['DELIVERY_ORDER', 'PICKUP_ORDER']) { const response = await context.request('GET', `${CONTAINERS}/${encodeURIComponent(containerId)}/documents/${documentType}`) const data = context.apiSuccess(MODULE, `查询 ${documentType} 单证`, response, `documentType=${documentType}`, OPTIONS) context.assert(MODULE, `${documentType} 单证归属货柜`, response, data == null || id(data.containerId || containerId) === containerId, `containerBookingId=${containerId}`, OPTIONS) } const clearance = await context.request('GET', `${CONTAINERS}/${encodeURIComponent(containerId)}/clearance`) context.apiSuccess(MODULE, '查询目的港清关资料', clearance, `containerBookingId=${containerId}`, OPTIONS) const customs = await context.request('GET', `/api/platform/v1/first-leg/loading-lists/${encodeURIComponent(planId)}/customs?warehouseId=${encodeURIComponent(warehouseId)}`) context.apiSuccess(MODULE, '查询出口报关资料', customs, `loadingPlanId=${planId}, warehouseId=${warehouseId}`, OPTIONS) context.addStep(MODULE, '异常标记/取消、单证上传和完成锁定保持写入阻断', null, true, '默认全量脚本只读;写场景需显式独立授权和一次性测试柜次', OPTIONS) }