fix(delivery): expose signed quantity and publish correct signature instant

This commit is contained in:
2026-10-03 23:09:24 +08:00
parent 0c8ede3889
commit 1f7ddf7bc9
11 changed files with 162 additions and 16 deletions
@@ -65,6 +65,29 @@ function fixture(fault = '') {
}
const run = f => verifyFleetReturnRedispatch(f.context, 'test', f.trip, f.input, f.dependencies)
for (const signedPackages of [undefined, null, '5', -1, 1.5]) test(`unknown or invalid original signed quantity ${signedPackages} stops before redispatch`, async () => {
const f = fixture(), save = f.dependencies.saveReceiptAndComplete
f.dependencies.saveReceiptAndComplete = async (...args) => {
const result = await save(...args)
result.order.signedPackages = signedPackages
return result
}
f.dependencies.prepareFleetTrip = () => assert.fail('invalid signed quantity must stop before preparing redispatch')
await assert.rejects(run(f), /stored quantity/)
assert.equal(f.trip.returnRedispatch.originalSignatures.length, 0)
})
for (const signedPackages of [undefined, null, '2', 0, 3]) test(`redispatch requires actual numeric two signed boxes: ${signedPackages}`, async () => {
const f = fixture(), save = f.dependencies.saveReceiptAndComplete
f.dependencies.saveReceiptAndComplete = async (...args) => {
const result = await save(...args)
if (args[1].deliveryNo === 'DL-NEW') result.order.signedPackages = signedPackages
return result
}
f.dependencies.finishFleetTrip = () => assert.fail('invalid new signature must not release trip resources')
await assert.rejects(run(f), /two boxes actually signed/)
})
test('reviewed candidate recovery retains DELIVERING and never repeats original delivery start', async () => {
const f = fixture(); f.input.sourceSelectionRecovery = true
assert.equal((await run(f)).status, 'HTTP_CHAIN_VERIFIED_SOURCE_EVENT_EVIDENCE_REQUIRED')
@@ -154,7 +154,8 @@ export async function verifyFleetReturnRedispatch(context, module, trip, input,
for (const [index, number] of input.deliveryNos.entries()) {
const current = await delivery(number)
const signed = await deps.saveReceiptAndComplete(io, current.order, customerId, 171 + index)
check('Original remaining cargo actually signed', signed?.order?.signedAt)
check('Original remaining cargo actually signed with a stored quantity', signed?.order?.signedAt
&& Number.isSafeInteger(signed.order.signedPackages) && signed.order.signedPackages >= 0)
proof.originalSignatures.push(copy(signed.order))
}
const beforeA = await tail(a.relation), beforeB = await tail(b.relation)
@@ -201,12 +202,12 @@ export async function verifyFleetReturnRedispatch(context, module, trip, input,
Object.assign(proof.preSignatureGate, { status: 'VERIFIED', audit })
await context.checkpoint()
const newSignature = await deps.saveReceiptAndComplete(io, newDelivery.order, customerId, 271)
check('Redispatched two boxes actually signed', newSignature?.order?.signedAt && Number(newSignature.order.signedPackages) === 2)
check('Redispatched two boxes actually signed', newSignature?.order?.signedAt && newSignature.order.signedPackages === 2)
const afterA = await tail(a.relation), afterB = await tail(b.relation)
check('A completes only after redispatch; B remains complete', afterA.order.subOrderStatus?.includes('DELIVERY:DELIVERED') && afterB.order.subOrderStatus === beforeB.order.subOrderStatus)
for (const original of proof.originalSignatures) {
const current = (await delivery(original.deliveryNo)).order
check('Original signed facts stay immutable', current.signedAt === original.signedAt && Number(current.signedPackages) === Number(original.signedPackages) && Number(current.packageCount) === Number(original.packageCount))
check('Original signed facts stay immutable', current.signedAt === original.signedAt && current.signedPackages === original.signedPackages && Number(current.packageCount) === Number(original.packageCount))
}
proof.afterRedispatch = { A: afterA, B: afterB, newSignature, departed }
proof.domesticAfterRedispatch = await domesticBoundary(a, b, true)