fix(fleet): verify dispatch cargo and retain checked costs on continuation

This commit is contained in:
2026-10-03 20:24:56 +08:00
parent f56c68d952
commit f2e25ec34b
5 changed files with 109 additions and 34 deletions
@@ -12,8 +12,9 @@ function fixture(fault = '') {
const trip = { tripNo: proof.tripNo, vehicleId: '11', driverId: '21', warehouseId: '92', ...originalTransport, status: 'IN_TRANSIT',
recordVersion: '7', departedAt: now, expectedDriverEndAt: new Date(Date.now() + 86400000).toISOString(), maxPalletSpaces: 30, maxLoadKg: 18000, maxVolumeCbm: 90 }
const dispatchDetails = ['A', 'B'].map(customer => ({ dispatchNo: `PC-${customer}`, customerId: customer, overseasWarehouseId: '92',
status: 'READY_TO_DEPART', packageCount: 10, pickedPackageCount: 10, shippedPackageCount: 0, ...originalTransport, items: [{ inboundCode: `IN-${customer}`, packageCount: 10 }] }))
const liveDispatches = dispatchDetails.map(row => ({ ...row, status: 'DEPARTED', shippedPackageCount: 10 }))
status: 'READY_TO_DEPART', packageCount: 10, pickedPackageCount: 10, shippedPackageCount: 0, ...originalTransport,
items: [{ id: `ITEM-${customer}`, warehousePalletId: 'PALLET-INTERNAL', inboundCode: `IN-${customer}`, packageCount: 10 }] }))
const liveDispatches = dispatchDetails.map(({ customerId, ...row }) => ({ ...row, status: 'DEPARTED', shippedPackageCount: 10 }))
const cargo = ['A', 'B'].map(customer => ({ customerId: customer, dispatchNo: `PC-${customer}`, dispatchItemId: `ITEM-${customer}`, warehousePalletId: 'PALLET-INTERNAL', palletNo: 'PAL-REAL', packages: 10, destinationKey: 'FBA:ONE' }))
const originalHistory = { action: 'DEPART', recordVersion: '7', snapshot: { trip: copy(trip), confirmedLoad: { cargo,
pallets: [{ warehousePalletId: 'PALLET-INTERNAL', palletSpaces: 1, weightKg: 100, volumeCbm: 1 }] } } }
@@ -24,6 +25,8 @@ function fixture(fault = '') {
const conflict = message => ({ http: 200, body: { code: 'A0409', message }, requestId: 'request', traceId: 'trace' })
const bump = () => { trip.recordVersion = String(BigInt(trip.recordVersion) + 1n) }
const bindings = dispatchDetails.map(row => ({ dispatchNo: row.dispatchNo, customerId: row.customerId }))
if (fault === 'binding-customer') bindings[0].customerId = 'OTHER'
if (fault === 'dispatch-cargo') liveDispatches[0].items = [{ ...liveDispatches[0].items[0], id: 'OTHER-ITEM' }]
const context = {
context: { async checkpointFleetHandover() {} },
marker, createdResources: { fleetTrips: [proof], fleetAcceptance: { marker, tripNo: proof.tripNo,
@@ -207,7 +210,7 @@ test('every HTTP call observes a completed pre-send checkpoint; post-response di
assert.equal(saved.at(-1).requests.at(-1).status, 'SENDING')
})
for (const [fault, message] of Object.entries({ 'wrong-customer': '预览精确包含', 'double-count-pallet': '共享实托只计一次', 'stale-accepted': '陈旧版本交接必须拒绝', 'unrelated-conflict': '陈旧版本交接必须拒绝',
for (const [fault, message] of Object.entries({ 'binding-customer': '每张排车已发车', 'dispatch-cargo': '每张排车已发车', 'wrong-customer': '预览精确包含', 'double-count-pallet': '共享实托只计一次', 'stale-accepted': '陈旧版本交接必须拒绝', 'unrelated-conflict': '陈旧版本交接必须拒绝',
'pda-keeps-original': 'PDA保持原发车资源', 'rewritten-pda-departure': 'PDA保持原发车资源', 'fee-changed': '交接不新增或改写派送费用',
'rewritten-departure': '只新增一次交接且原DEPART内容保持不变', 'replay-releases-next': '旧请求重放不能释放下一计划车辆' })) {
test(`business counterexample ${fault} cannot be reported as successful handover`, async () => {