feat(phase3): 收口父子单与全链路验收
This commit is contained in:
@@ -1,10 +1,32 @@
|
||||
import { registerPendingContract } from './_phase3-pending-contract.mjs'
|
||||
const MODULE = 'phase3-evidence-gate'
|
||||
const OPTIONS = { scenario: 'loading-evidence-gate', deploymentBlocker: true }
|
||||
|
||||
function id(value) { return value == null ? '' : String(value) }
|
||||
|
||||
export async function run(context) {
|
||||
registerPendingContract(context, {
|
||||
module: 'phase3-evidence-gate', scenario: 'loading-evidence-gate', name: '四步照片与铅封证据完整性门禁',
|
||||
reason: '五类证据、真实文件归属和柜次 PDA 复核门禁已实现并推送,待目标提交部署且 phase3-loading 真实 HTTP 通过后删除此项', category: 'deployment-validation-pending',
|
||||
fixtures: ['phase3Loading', 'phase3ContainerLoading'], contractSource: 'PlatformLoadingDeliveryController / phase3-loading-delivery-v1.yaml',
|
||||
assertions: ['四步照片和铅封均绑定本轮柜次', '缺任一证据时完成装柜被拒绝', '全部证据与 PDA 复核齐备后幂等完成'],
|
||||
})
|
||||
const fixture = context.createdResources?.phase3Loading
|
||||
if (!fixture?.tenantId || !fixture?.inboundId || fixture.marker !== context.marker) {
|
||||
context.addCoverageGap(MODULE, OPTIONS.scenario, '五类证据多图追加、作废审计和有效证据门禁',
|
||||
'本轮未取得 phase3-loading 的 marker 隔离证据 fixture,未使用历史资源', 'fixture')
|
||||
return
|
||||
}
|
||||
const path = `/api/platform/v1/inbounds/${fixture.inboundId}/loading/evidence?tenantId=${encodeURIComponent(fixture.tenantId)}`
|
||||
const response = await context.request('GET', path)
|
||||
const data = context.apiSuccess(MODULE, '复核本轮装柜证据聚合', response, `inboundId=${fixture.inboundId}`, OPTIONS)
|
||||
const evidences = Array.isArray(data?.evidences) ? data.evidences : []
|
||||
const required = ['PHOTO_STEP_1', 'PHOTO_STEP_2', 'PHOTO_STEP_3', 'PHOTO_STEP_4', 'SEAL']
|
||||
const active = evidences.filter((item) => item.status !== 'VOID')
|
||||
const voided = evidences.find((item) => id(item.id) === id(fixture.voidedEvidenceId))
|
||||
context.assert(MODULE, '五类有效证据齐全且同类型多图追加不覆盖历史', response,
|
||||
required.every((type) => active.some((item) => item.evidenceType === type))
|
||||
&& active.filter((item) => item.evidenceType === 'PHOTO_STEP_1').length >= 1
|
||||
&& active.some((item) => item.evidenceType === 'SEAL' && Boolean(String(item.sealNo || '').trim()))
|
||||
&& active.every((item) => String(item.fileName || '').includes(context.marker)
|
||||
&& String(item.remark || '').includes(context.marker)),
|
||||
`active=${active.length}, types=${[...new Set(active.map((item) => item.evidenceType))].join(',')}`, OPTIONS)
|
||||
context.assert(MODULE, '作废证据保留原因、操作者和时间且不计入有效门禁', response,
|
||||
Boolean(voided) && voided.status === 'VOID' && voided.voidReason === `${context.marker}-wrong-photo`
|
||||
&& Boolean(voided.voidedBy) && Boolean(voided.voidedAt)
|
||||
&& !active.some((item) => id(item.id) === id(fixture.voidedEvidenceId)),
|
||||
`voidedEvidenceId=${id(fixture.voidedEvidenceId) || 'missing'}, status=${voided?.status || 'missing'}`, OPTIONS)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user