This commit is contained in:
2026-08-18 16:39:39 +08:00
parent 7fe5b4e31f
commit a9061eca54
43 changed files with 821 additions and 1217 deletions
@@ -4,25 +4,21 @@ import test from 'node:test'
const source = readFileSync(new URL('./phase3-order-splitting.mjs', import.meta.url), 'utf8')
test('each remainder uses a simulation linked to a confirmed then released booking', () => {
test('each remainder uses a simulation linked to a released booking requirement', () => {
assert.match(source, /POST', CONTAINERS/)
assert.match(source, /POST', '\/api\/platform\/v1\/ocean-bookings'/)
assert.match(source, /一次登记直接返回 CONFIRMED/)
assert.match(source, /订舱为 RELEASED 且不预生成真实柜/)
assert.doesNotMatch(source, /ocean-bookings\/\$\{oceanBookingId\}\/(?:submit|confirm)/)
const createPayload = source.slice(source.indexOf('function bookingPayload'), source.indexOf('async function loadOneFragment'))
assert.match(createPayload, /oceanBookingDraft\(\{ marker \}/)
assert.match(createPayload, /customerId: source\.tenantId/)
assert.match(createPayload, /channelCode: source\.channelCode/)
assert.match(source, /ocean-booking-link/)
assert.match(source, /realContainerBookingId: id\(requirement\.containerBookingId\)/)
assert.match(source, /bookingDetail\.oceanBooking\.status === 'CONFIRMED'/)
assert.match(source, /`\$\{bookingPath\}\/release`/)
assert.match(source, /oceanBookingId, requirementId: id\(requirement\.id\), containerNo: realContainerNo/)
assert.match(source, /ocean-bookings\/\$\{oceanBookingId\}\/release/)
const releaseStart = source.indexOf('const releaseResponse')
const releaseBlock = source.slice(releaseStart, source.indexOf('bookingDetailResponse = await', releaseStart))
for (const field of ['billOfLadingNo', 'vesselName', 'voyageNo', 'estimatedSailingAt',
'estimatedArrivalAt']) assert.match(releaseBlock, new RegExp(`${field}: persistedTransport\\.${field}`))
assert.match(releaseBlock, /expectedVersion: Number\(bookingDetail\.oceanBooking\.version\)/)
assert.doesNotMatch(releaseBlock, /BL-\$\{|SPLIT-VESSEL|SV-\$\{|2026-/)
assert.match(releaseBlock, /expectedVersion: Number\(bookingCreated\?\.oceanBooking\?\.version\)/)
assert.match(releaseBlock, /'Idempotency-Key': `\$\{operationBase\}-booking-release`\.slice\(0, 128\)/)
assert.match(source, /oceanBooking\?\.status === 'RELEASED' && releasedAllocationMatches/)
assert.match(source, /id\(item\?\.containerBookingId\) === containerId/)
@@ -31,25 +27,25 @@ test('each remainder uses a simulation linked to a confirmed then released booki
assert.doesNotMatch(source, /candidates\?warehouseId=/)
})
test('release stops unless creation response and detail expose the same complete transport snapshot', () => {
test('release freezes and detail replays the same complete transport snapshot', () => {
assert.match(source, /const BOOKING_TRANSPORT_FIELDS = \[/)
assert.match(source, /const createdTransport = bookingTransportSnapshot\(bookingCreated\?\.oceanBooking\)/)
assert.match(source, /const createdTransport = bookingTransportSnapshot\(bookingConfirmed\?\.oceanBooking\)/)
assert.match(source, /const persistedTransport = bookingTransportSnapshot\(bookingDetail\?\.oceanBooking\)/)
assert.match(source, /completeBookingTransport\(createdTransport\)/)
assert.match(source, /sameBookingTransport\(createdTransport, persistedTransport\)/)
assert.match(source, /if \(!transportFrozen\) return null/)
})
test('PDA opens only after merging a registered real container and uses stable plan identity', () => {
test('PDA opens only after linking a released requirement and uses stable plan identity', () => {
const pushIndex = source.indexOf("`${SMART}/plans/${planId}/push-preload`")
const linkIndex = source.indexOf("`${CONTAINERS}/${containerId}/ocean-booking-link`")
const releaseIndex = source.indexOf("`${bookingPath}/release`")
const releaseIndex = source.indexOf("`/api/platform/v1/ocean-bookings/${oceanBookingId}/release`")
const confirmIndex = source.indexOf("`/api/platform/v1/first-leg/loading-plans/${encodeURIComponent(planId)}/confirm`")
const taskIndex = source.indexOf("`${PDA}/tasks?loadingPlanId=${encodeURIComponent(planId)}&warehouseId=${encodeURIComponent(warehouseId)}`")
const canonicalTaskIndex = source.indexOf("`${PDA}/tasks?loadingPlanId=${encodeURIComponent(planId)}&warehouseId=${encodeURIComponent(warehouseId)}`", taskIndex + 1)
assert.ok(linkIndex >= 0 && releaseIndex > linkIndex && pushIndex > releaseIndex
assert.ok(releaseIndex >= 0 && linkIndex > releaseIndex && pushIndex > linkIndex
&& taskIndex > pushIndex && confirmIndex > taskIndex && canonicalTaskIndex > confirmIndex)
assert.match(source, /const realContainerNo = requirement\?\.containerNo/)
assert.match(source, /const realContainerNo = `SPLIT-/)
assert.match(source, /const transportStable = linked\?\.containerNo === realContainerNo/)
assert.match(source, /linked\?\.cabinetNo === simulation\.cabinetNo/)
assert.match(source, /if \(!transportStable\) return null/)