feat: close preload confirmation and loading flow

This commit is contained in:
2026-08-15 17:04:00 +08:00
parent 5b8e7d6989
commit a35794e918
34 changed files with 1194 additions and 512 deletions
+60 -17
View File
@@ -3,6 +3,7 @@ import { existsSync, readFileSync } from 'node:fs'
import { dirname, resolve } from 'node:path'
import test from 'node:test'
import { fileURLToPath } from 'node:url'
import { normalizeModuleOrder } from './admin-test-env-acceptance.mjs'
const scriptsDir = dirname(fileURLToPath(import.meta.url))
const backendScript = readFileSync(resolve(scriptsDir, 'backend-full-regression.ps1'), 'utf8')
@@ -62,33 +63,75 @@ test('test-environment full acceptance keeps assigned and unassigned customer bo
assert.match(bookingModule, /phase3Loading[\s\S]*phase3ContainerLoading/)
})
test('test-environment loading chains bind the latest container version before opening PDA', () => {
test('test-environment loading chains push without a number and open PDA only after all prerequisites', () => {
const containerLoading = readFileSync(
resolve(scriptsDir, 'admin-test-env-modules', 'phase3-container-loading.mjs'), 'utf8')
const bridgeLoading = readFileSync(
resolve(scriptsDir, 'admin-test-env-modules', 'phase3-loading.mjs'), 'utf8')
assert.match(containerLoading, /version: Number\(linkedContainer\.version\), reason: context\.marker/)
assert.match(containerLoading, /expectedVersion: Number\(pushed\.version\), operationReason: context\.marker/)
const bridgeIndex = bridgeLoading.indexOf('原子关联入库预装与柜次装柜计划')
const rejectedPushIndex = bridgeLoading.indexOf('无真实柜号拒绝推送柜次计划')
const transportIndex = bridgeLoading.indexOf('绑定真实柜号后开放三期 PDA 推送门禁')
const pushIndex = bridgeLoading.indexOf('无真实柜号推送预装成功并冻结柜次明细')
const absentIndex = bridgeLoading.indexOf('无号 push 成功后 PDA 查询明确 A0404')
const transportIndex = bridgeLoading.indexOf('预装 EDITING 清单绑定真实柜号')
const linkIndex = bridgeLoading.indexOf('预装补号后关联三期 CONFIRMED 订舱')
const releaseIndex = bridgeLoading.indexOf('三期订舱携带已冻结运输快照并放舱')
const successfulPushIndex = bridgeLoading.indexOf('真实柜号与 RELEASED 订舱就绪后推送并生成 PDA 任务')
const confirmIndex = bridgeLoading.indexOf('计划级原子确认整份预装并触发唯一 PDA 任务')
const pdaIndex = bridgeLoading.indexOf('读取柜次级 PDA 唯一事实任务')
assert.ok(bridgeIndex >= 0 && rejectedPushIndex > bridgeIndex && transportIndex > rejectedPushIndex
&& releaseIndex > transportIndex && successfulPushIndex > releaseIndex && pdaIndex > successfulPushIndex)
assert.match(bridgeLoading, /const missingContainerPushRejected = failure\(missingContainerPushResponse\)[\s\S]*if \(!missingContainerPushRejected\) return/)
assert.match(bridgeLoading, /const missingContainerTaskAbsent =[\s\S]*if \(!missingContainerTaskAbsent\) return/)
assert.match(bridgeLoading, /version: transportVersion/)
assert.ok(pushIndex >= 0 && absentIndex > pushIndex && transportIndex > absentIndex
&& linkIndex > transportIndex && releaseIndex > linkIndex && confirmIndex > releaseIndex && pdaIndex > confirmIndex)
assert.match(bridgeLoading, /codeOf\(missingContainerTaskResponse\) === 'A0404'/)
assert.match(bridgeLoading, /push exact replay 对计划版本历史关联和任务零漂移/)
assert.match(bridgeLoading, /bookingReleased\?\.oceanBooking\?\.status === 'RELEASED'/)
assert.match(bridgeLoading, /loading-plans\/\$\{loadingPlanId\}\/confirm/)
assert.match(bridgeLoading, /readiness\?\.readyForPda === true/)
assert.match(bridgeLoading, /计划级确认同 key 异参返回冲突[\s\S]*已确认计划使用新 key 重复确认返回冲突/)
assert.doesNotMatch(bridgeLoading, /\/preload\/confirming|\/preload\/confirm\?tenantId=/)
const containerRejectedPushIndex = containerLoading.indexOf('无真实柜号拒绝推送预装计划')
const containerTransportIndex = containerLoading.indexOf('在放舱前绑定本轮真实箱号')
const containerPushIndex = containerLoading.indexOf('无真实柜号推送预装计划成功')
const containerTransportIndex = containerLoading.indexOf('预装 EDITING 清单绑定本轮真实柜号')
const containerLinkIndex = containerLoading.indexOf('首次关联真实已确认订舱柜')
const containerReleaseIndex = containerLoading.indexOf('订舱携带已冻结运输快照放舱并满足 PDA 门禁')
const containerSuccessfulPushIndex = containerLoading.indexOf('柜号与 RELEASED 订舱就绪后推送预装计划')
const containerConfirmIndex = containerLoading.indexOf('计划级原子确认整份预装并触发唯一 PDA 任务')
const containerPdaIndex = containerLoading.indexOf('查询本轮柜次 PDA 拣货任务')
assert.ok(containerRejectedPushIndex >= 0 && containerTransportIndex > containerRejectedPushIndex
&& containerReleaseIndex > containerTransportIndex && containerSuccessfulPushIndex > containerReleaseIndex
&& containerPdaIndex > containerSuccessfulPushIndex)
assert.ok(containerPushIndex >= 0 && containerTransportIndex > containerPushIndex
&& containerLinkIndex > containerTransportIndex && containerReleaseIndex > containerLinkIndex
&& containerConfirmIndex > containerReleaseIndex
&& containerPdaIndex > containerConfirmIndex)
assert.match(containerLoading, /loading-plans\/\$\{planId\}\/confirm/)
assert.match(containerLoading, /readiness\?\.readyForPda === true/)
assert.match(containerLoading, /计划级确认同 key 异参返回冲突[\s\S]*已确认计划使用新 key 重复确认返回冲突/)
assert.doesNotMatch(containerLoading, /\/preload\/confirming|\/preload\/confirm\?tenantId=/)
})
test('default Admin HTTP entry carries one marker-isolated loading chain through evidence and LOADED', () => {
const focused = normalizeModuleOrder([
'merchant-qualification-fixture', 'orders', 'inbound-measurement',
'phase3-container-loading', 'phase3-loading', 'phase3-container-overview',
'phase3-pda-convergence', 'phase3-evidence-gate', 'phase3-customs',
'phase3-loading-finalize',
])
assert.deepEqual(focused, [
'merchant-qualification-fixture', 'orders', 'inbound-measurement',
'phase3-container-loading', 'phase3-loading', 'phase3-container-overview',
'phase3-pda-convergence', 'phase3-evidence-gate', 'phase3-customs',
'phase3-loading-finalize',
])
const loading = readFileSync(resolve(scriptsDir, 'admin-test-env-modules', 'phase3-loading.mjs'), 'utf8')
const evidenceGate = readFileSync(resolve(scriptsDir, 'admin-test-env-modules', 'phase3-evidence-gate.mjs'), 'utf8')
const customs = readFileSync(resolve(scriptsDir, 'admin-test-env-modules', 'phase3-customs.mjs'), 'utf8')
const finalize = readFileSync(resolve(scriptsDir, 'admin-test-env-modules', 'phase3-loading-finalize.mjs'), 'utf8')
assert.match(loading, /context\.createdResources\.phase3Loading = \{[\s\S]*marker: context\.marker/)
for (const field of ['inboundId', 'loadingPlanId', 'containerBookingId', 'canonicalPdaTaskId']) {
assert.match(loading, new RegExp(`context\\.createdResources\\.phase3Loading = \\{[\\s\\S]*${field}`))
}
assert.match(loading, /const evidenceTypes = \['PHOTO_STEP_1', 'PHOTO_STEP_2', 'PHOTO_STEP_3', 'PHOTO_STEP_4', 'SEAL'\]/)
assert.match(evidenceGate, /fixture\??\.marker !== context\.marker/)
assert.match(evidenceGate, /taskId[\s\S]*inboundId[\s\S]*loadingPlanId[\s\S]*containerBookingId/)
assert.match(customs, /createdResources\?\.phase3Loading[\s\S]*container\?\.finalStatus/)
assert.match(finalize, /fixture\?\.marker !== context\.marker/)
assert.match(finalize, /统一硬门禁通过后推进 LOADED 且五类有效证据仍完整/)
assert.match(finalize, /统一订单详情投影同一订单为 LOADED[\s\S]*统一订单列表投影同一订单为 LOADED/)
})