import assert from 'node:assert/strict' import test from 'node:test' import { readFileSync } from 'node:fs' import { fulfillmentHistorySnapshot, validTwoFragmentTree, validSignatureGate, completionCounts, exactCompletionOutboxProof, rootCompletionTimeMatches, resolveF40MerchantCredentials, f40CreateDispatchBody, resolveF40LoadingMeasurements, sendFragment, f40LocalDateTime, validFragmentCabinetIdentity, validUnloadedRemainder, validRemainderCancellationGate, exactCancelledRemainderOutboxProof, cancelUnloadedRemainder, verifyRootProjections, verifyRemainderTaxIdentity, validFreshReceiptSave, preserveReceivingEvidence, resolveF40ReceivingWarehouse, run } from './phase5-root-fulfillment.mjs' import { loadOneFragment } from './phase3-order-splitting.mjs' import { verifyPalletLabels } from './phase3-loading-finalize.mjs' import { awaitProducerConsumption, convertReceivingContainers, runReceiving, resolveSharedWarehouse } from './phase4-overseas-pda.mjs' const source = readFileSync(new URL('./phase5-root-fulfillment.mjs', import.meta.url),'utf8') test('根完成UTC时刻与上海本地签收最大值一致,拒绝时区偏移、较早来源和缺失证据', () => { const times = ['2026-10-05T21:55:00.000', '2026-10-05T21:56:07.922'] assert.equal(rootCompletionTimeMatches('2026-10-05T13:56:07.922', times), true) assert.equal(rootCompletionTimeMatches('2026-10-05T13:56:07.922Z', [...times].reverse()), true) assert.equal(rootCompletionTimeMatches('2026-10-05T13:56:07.922Z', ['2026-10-05T21:56:07.922+08:00']), true) for (const value of ['2026-10-05T21:56:07.922', '2026-10-05T13:55:00', null]) { assert.equal(rootCompletionTimeMatches(value, times), false) } assert.equal(rootCompletionTimeMatches('2026-10-05T13:56:07.922', []), false) assert.equal(rootCompletionTimeMatches('2026-10-05T13:56:07.922', ['invalid']), false) }) const history = (...actions) => actions.map((action,index) => ({id:String(index+1),action})) const tree = () => ({parentOrderId:'100',originalPackageCount:2,cumulativeLoadedPackageCount:2, currentRemainderPackageCount:0,children:[ {orderId:'100',sourceOrderId:'100',splitRole:'LOADED',packageCount:1}, {orderId:'101',sourceOrderId:'100',splitRole:'REMAINDER',packageCount:1}, {orderId:'101',sourceOrderId:'101',splitRole:'LOADED',packageCount:1}, ]}) const signed = () => ({root:{status:'COMPLETED',histories:history('OVERSEAS_DELIVERED','FULFILLMENT_COMPLETED')}, child:{status:'COMPLETED',histories:history('OVERSEAS_DELIVERED')}, rootInbound:{processStatus:'DELIVERED',orderStatusSnapshot:'COMPLETED'}}) const outbox = () => ({readOnly:true,customerId:'90',rootOrderId:'100',orders:['100','101'].map(orderId => ({ orderId,customerId:'90',rootOrderId:'100',eventType:'FIRST_LEG_ORDER_FULFILLMENT_COMPLETED', count:1,publishedCount:1,pendingCount:0,failedCount:0, }))}) const fixture = () => ({steps:[],token:'offline',marker:'offline-only',createdResources:{}, addStep(_module,_label,_response,passed){this.steps.push({passed})}, assert(_module,_label,_response,passed){this.steps.push({passed})}, addCoverageGap(){},apiSuccess(_module,_label,response){return response?.body?.data}, }) function remainderTaxFixture(taxMode) { const context=fixture(),calls=[] const evidence={taxMode,customerId:'90',rootOrderId:'100',childOrderId:'101',rootOrderNo:'ORDER-ROOT', rawChild:{id:'101',tenantId:'90',taxMode},rootInbound:{orderId:'100',taxMode}, childInbound:{orderId:'101',tenantId:'90',taxMode}} const rows=[{orderId:'100',tenantId:'90',taxMode,relation:{role:'PARENT',rootOrderId:'100'}}, {orderId:'101',tenantId:'90',taxMode,relation:{role:'CHILD',rootOrderId:'100',parentOrderId:'100'}}] context.request=async(method,path,body,token)=>{ calls.push({method,path,body,token}) const filter=new URL(path,'https://offline.invalid').searchParams.get('taxMode') const records=filter&&filter!==taxMode?[]:structuredClone(rows) return {http:200,body:{code:'200',data:{records,total:records.length}}} } return {context,evidence,calls,rows} } test('raw remainder and actual inbound summary taxMode agree for BUY and TAX and customer filters retain exact parent/child',async()=>{ for(const mode of ['BUY_DECLARATION','TAX_REFUND']){ const f=remainderTaxFixture(mode) await verifyRemainderTaxIdentity(f.context,f.evidence,'own-customer') assert.equal(f.calls.length,3) assert.ok(f.calls.every(c=>c.method==='GET'&&c.token==='own-customer'&&!c.path.includes('/customs'))) assert.deepEqual(f.evidence.matchingTax.records.map(r=>r.orderId),['100','101']) assert.equal(f.evidence.otherTax.total,0) assert.match(f.calls[1].path,new RegExp('taxMode='+mode)) } }) test('missing or wrong raw remainder taxMode is rejected before customer/customs calls despite valid inbound projection',async()=>{ for(const mode of ['BUY_DECLARATION','TAX_REFUND'])for(const actual of [null,undefined,mode==='BUY_DECLARATION'?'TAX_REFUND':'BUY_DECLARATION']){ const f=remainderTaxFixture(mode);f.evidence.rawChild.taxMode=actual await assert.rejects(verifyRemainderTaxIdentity(f.context,f.evidence,'own-customer'),/原始余量子订单继承/) assert.equal(f.calls.length,0) } }) test('wrong inbound tax, missing filtered child, foreign customer or wrong parent identity cannot pass',async()=>{ for(const mutate of [f=>f.evidence.childInbound.taxMode=null,f=>f.rows.pop(),f=>f.rows[1].tenantId='91', f=>f.rows[1].relation.parentOrderId='999',f=>f.rows[1].taxMode='BUY_DECLARATION']) { const f=remainderTaxFixture('TAX_REFUND');mutate(f) await assert.rejects(verifyRemainderTaxIdentity(f.context,f.evidence,'own-customer')) } const f=remainderTaxFixture('TAX_REFUND'),original=f.context.request f.context.request=async(...args)=>{const r=await original(...args);if(args[1].includes('taxMode=BUY_DECLARATION'))r.body.data={records:[f.rows[1]],total:1};return r} await assert.rejects(verifyRemainderTaxIdentity(f.context,f.evidence,'own-customer'),/otherTax/) }) test('F40 unified projections require exact root and customer session with final COMPLETED or unfinished DELIVERED',async()=>{ for (const completed of [true,false]) { const context=fixture(),calls=[],snapshot={root:{status:completed?'COMPLETED':'TRANSPORTING',histories:history('OVERSEAS_DELIVERED')}} context.request=async(method,path,body,token)=>{ calls.push({method,path,token}) return {http:200,body:{code:'200',data:{summary:{orderId:'100',mainStatus:completed?'COMPLETED':'DELIVERED'}}}} } const result=await verifyRootProjections(context,'90','100','customer-session',snapshot) assert.deepEqual(result.platform,result.customer) assert.equal(calls[0].path,'/api/platform/v1/orders/100?tenantId=90') assert.equal(calls[1].path,'/api/merchant/v1/orders/100') assert.equal(calls[1].token,'customer-session') assert.equal(context.steps.every(step=>step.passed),true) } }) test('F40 customer mismatched root or prematurely completed projection fails closed',async()=>{ for (const summary of [{orderId:'101',mainStatus:'COMPLETED'},{orderId:'100',mainStatus:'DELIVERED'}]) { const context=fixture() context.request=async(_method,path)=>({http:200,body:{code:'200',data:{summary: path.startsWith('/api/platform')?{orderId:'100',mainStatus:'COMPLETED'}:summary}}}) await assert.rejects(verifyRootProjections(context,'90','100','customer-session',{root:{status:'COMPLETED',histories:[]}}), /平台客户统一状态/) } }) test('F40 README documents all three independent modes and fail-closed receiving/zero child event evidence',()=>{ const readme=readFileSync(new URL('./README.md',import.meta.url),'utf8') for(const value of ['CHILD_FIRST','ROOT_SIGNED_REMAINDER_CANCELLED','orderStopAtApproved=true', 'PROCESSING','WAIT_SPLIT','A0409','phase4ReceivingEvidenceReader','零事件子行'])assert.ok(readme.includes(value),value) assert.match(source,/proof\.beforeReceiptReplayOutbox = await waitState/) assert.match(source,/outboxCounts\(proof.beforeReceiptReplayOutbox\) === outboxCounts\(proof.outboxProof\)/) assert.match(source,/validFreshReceiptSave\(beforeFresh,afterFresh\)/) assert.match(source,/JSON.stringify\(afterFresh\) === JSON.stringify\(receiptProof.afterSameKey\)/) }) test('fresh receipt save allows exactly one document version/revision/audit while business completion stays unchanged',()=>{ const documents={version:'2',uploadedCategoryCount:1,categories:[{category:'RECEIPT',files:[{fileId:'1'}]}],replayed:false} const before={documents,delivery:{order:{version:'2',status:'DELIVERED',signedAt:'2026-09-30T16:00:00'}, operations:[{id:'1',operationNode:'RECEIPT_AUTO_COMPLETE'}],skus:[{packageCount:1}],fees:[]},revisions:[{version:'2'}]} const after=structuredClone(before);after.documents.version='3';after.delivery.order.version='3' after.delivery.operations.push({id:'2',operationNode:'SAVE_DOCUMENTS',result:'保存派送资料:1/3类', operatedAt:'2026-09-30T16:01:00',operatorName:'platform'}) after.revisions.push({version:'3',savedAt:'2026-09-30T16:01:00',operatorId:'platform',snapshot:after.documents}) assert.equal(validFreshReceiptSave(before,after),true) for(const mutate of [ value=>value.documents.version='4',value=>value.delivery.order.version='2', value=>value.delivery.order.signedAt='2026-09-30T16:01:00',value=>value.delivery.order.status='RETURNED', value=>value.documents.categories[0].files[0].fileId='2',value=>value.delivery.skus[0].packageCount=2, value=>value.delivery.fees.push({amount:1}),value=>value.delivery.operations[0].id='999', value=>value.delivery.operations[1].operationNode='RECEIPT_AUTO_COMPLETE', value=>value.delivery.operations.push({...value.delivery.operations[1],id:'3'}), value=>value.revisions.pop(),value=>value.revisions[0].version='1', ]){const bad=structuredClone(after);mutate(bad);assert.equal(validFreshReceiptSave(before,bad),false)} }) test('F40 retains partial and failed receiving raw snapshots without exporting identity credentials',()=>{ const proof={},scope={createdResources:{phase4OverseasPda:{receivingCompletionEvidence:{}}},token:'secret'} preserveReceivingEvidence(proof,scope) scope.createdResources.phase4OverseasPda.receivingCompletionEvidence['20']={status:'UNPROVEN',stages:{ BEFORE_COMPLETE:{captured:true,evidence:{balances:[]}},AFTER_COMPLETE:{captured:false,evidence:{balances:[{id:'1'}]}}}} assert.deepEqual(proof.receivingCompletionEvidence,scope.createdResources.phase4OverseasPda.receivingCompletionEvidence) assert.equal(JSON.stringify(proof).includes('secret'),false) assert.match(source,/finally \{ preserveReceivingEvidence\(proof,scope\);/) assert.match(source,/proof.receiptReplayProofs \|\|= \[\]/) }) function nativeF40Candidate() { const sourceVersion = 'a'.repeat(64) return { sourceKey: 'PLAN:9007199254740993', sourceVersion, customerId: '90', warehouseId: '80', inboundCode: 'IN-F40', availablePackages: '1', destination: { key: 'FBA:ONT8', type: 'FBA', warehouseCode: 'ONT8' }, selection: { sourceType: 'INBOUND_PLAN', planPalletId: '9007199254740993', warehousePalletId: '9007199254740994', returnReceiptId: null, relabelNo: null, sourceVersion }, blockReasons: [], appointmentBatches: [{ batchKey: 'FBA_APPOINTMENT:9007199254740995', customerId: '90', recordVersion: '9007199254740996', sources: [{ sourceKey: 'ORDER:9007199254740997', destinationKey: 'FBA:ONT8', packageCount: 1 }] }] } } test('F40 native Create uses frozen candidate source and exact FBA batch version including zero, without legacy vehicle/Transfer fields', () => { const candidate = nativeF40Candidate() const body = f40CreateDispatchBody('offline', '80', '90', [candidate]) assert.equal(body.warehouseId, '80') assert.equal(body.cargo[0].planPalletId, '9007199254740993') assert.equal(body.cargo[0].warehousePalletId, '9007199254740994') assert.equal(body.cargo[0].sourceVersion, candidate.sourceVersion) assert.deepEqual(body.batchAllocations, [{ planPalletId: '9007199254740993', batchKey: 'FBA_APPOINTMENT:9007199254740995', customerId: '90', sourceKey: 'ORDER:9007199254740997', destinationKey: 'FBA:ONT8', packageCount: 1, recordVersion: '9007199254740996' }]) candidate.appointmentBatches[0].recordVersion = '0' assert.equal(f40CreateDispatchBody('offline', '80', '90', [candidate]).batchAllocations[0].recordVersion, '0') assert.equal(body.vehicle, null); assert.equal(body.driver, null) assert.equal('vehiclePlate' in body, false); assert.equal('plannedDeliveryAt' in body, false) assert.equal(f40LocalDateTime(new Date('2026-09-30T01:02:03.456Z')), '2026-09-30T01:02:03') const dto = readFileSync(new URL('../../lastleg-service/src/main/java/com/baiyue/lastleg/dispatch/port/DispatchCommands.java', import.meta.url), 'utf8') assert.match(dto, /record Create/) for (const field of ['warehouseId', 'cargo', 'batchAllocations', 'sourceVersion']) assert.ok(dto.includes(field), field) }) test('F40 native Create rejects foreign/ambiguous sources and incomplete batch allocation instead of guessing source or version', () => { for (const mutate of [value => { value.customerId = '91' }, value => { value.warehouseId = '81' }, value => { value.sourceVersion = 'stale' }, value => { value.selection.sourceVersion = 'stale' }, value => { value.selection.planPalletId = 9007199254740992 }, value => { value.availablePackages = '9007199254740993' }, value => { value.blockReasons = ['NOT_RECEIVED'] }, value => { value.appointmentBatches[0].recordVersion = null }, value => { value.appointmentBatches[0].recordVersion = 9007199254740992 }, value => { value.appointmentBatches[0].customerId = '91' }, value => { value.appointmentBatches[0].sources[0].packageCount = 2 }, value => { value.appointmentBatches[0].sources[0].destinationKey = 'FBA:OTHER' }, value => { value.appointmentBatches.push(structuredClone(value.appointmentBatches[0])) }]) { const candidate = nativeF40Candidate(); mutate(candidate) assert.throws(() => f40CreateDispatchBody('offline', '80', '90', [candidate])) } const candidate = nativeF40Candidate() assert.throws(() => f40CreateDispatchBody('offline', '80', '90', [candidate, candidate])) }) test('F40 credentials prefer a complete current fixture pair and never combine fixture with configured customer',() => { const options={username:'offline-admin',password:'offline-admin-secret',merchantUsername:'configured-customer',merchantPassword:'configured-secret'} const current={username:'fixture-customer',password:'fixture-secret',tenantId:'90'} assert.deepEqual(resolveF40MerchantCredentials({options,context:{merchantQualificationFixture:current}}), {username:'fixture-customer',password:'fixture-secret',customerId:'90'}) assert.deepEqual(resolveF40MerchantCredentials({options,context:{}}), {username:'configured-customer',password:'configured-secret',customerId:null}) for(const incomplete of [{username:'fixture-only',tenantId:'90'},{password:'fixture-only',tenantId:'90'}, {username:'fixture-customer',password:'fixture-secret'}]) assert.equal(resolveF40MerchantCredentials({options,context:{merchantQualificationFixture:incomplete}}),null) assert.equal(resolveF40MerchantCredentials({options:{merchantUsername:'incomplete'},context:{}}),null) assert.ok(source.indexOf("'F40 正式订单创建客户与本轮登录客户一致'") < source.indexOf("await stage(scope, 'inbound-measurement')")) }) test('F40 reads formal nested domestic cabinet workbench and compares booking/plan/task identity instead of inventing GET containers/id',() => { const controller=readFileSync(new URL('../../firstleg/src/main/java/com/baiyue/firstleg/controller/PlatformContainerController.java',import.meta.url),'utf8') const dto=readFileSync(new URL('../../firstleg/src/main/java/com/baiyue/firstleg/terminaldrayage/dto/ContainerWorkbenchDtos.java',import.meta.url),'utf8') assert.match(controller,/@GetMapping\("\/domestic\/\{id\}"\)/) assert.doesNotMatch(controller,/@GetMapping\("\/\{id\}"\)/) assert.match(dto,/record WorkbenchItem\(ContainerBookingEntity container, String workbenchStage/) assert.match(source,/`\/api\/platform\/v1\/containers\/domestic\/\$\{result.containerId\}`/) assert.doesNotMatch(source,/`\/api\/platform\/v1\/containers\/\$\{result.containerId\}`/) const fragment={containerId:'20',planId:'30',taskId:'40',oceanBookingId:'50'},task={id:'40',containerBookingId:'20',loadingPlanId:'30'} const workbench={container:{id:'20',cabinetNo:'D0001',containerNo:'OFFLINE',oceanBookingId:'50'}} assert.equal(validFragmentCabinetIdentity(workbench,fragment,task),true) assert.equal(validFragmentCabinetIdentity(workbench,{...fragment,containerId:'21'},task),false) assert.equal(validFragmentCabinetIdentity(workbench,fragment,{...task,containerBookingId:'21'}),false) assert.equal(validFragmentCabinetIdentity(workbench,fragment,{...task,loadingPlanId:'31'}),false) assert.equal(validFragmentCabinetIdentity(workbench,fragment,{...task,id:'41'}),false) assert.equal(validFragmentCabinetIdentity(workbench,{...fragment,oceanBookingId:'51'},task),false) assert.equal(validFragmentCabinetIdentity(workbench.container,fragment,task),false) }) test('formal tree requires one root physical source plus its exact real remainder child and conserves two boxes',() => { assert.equal(validTwoFragmentTree(tree(),'100','101'),true) for (const change of [ value => value.parentOrderId='999', value => value.currentRemainderPackageCount=1, value => value.children[2].sourceOrderId='999', value => value.children[1].sourceOrderId='999', value => value.children[2].packageCount=2, value => value.children.push({splitRole:'UNKNOWN',orderId:'999'}), ]) {const value=tree();change(value);assert.equal(validTwoFragmentTree(value,'100','101'),false)} }) test('F40 separates immutable physical task cartons from current actual FBA receiving prefix scans',() => { assert.match(source,/cartonMarks: stableLoadedCartonMarks\(task.items\)/) assert.match(source,/receivingCartonMarks:\[`\$\{current.summary.inboundCode\}#PDA-CONTRACT-1`\]/) assert.doesNotMatch(source,/cartonMarks:\s*\[`\$\{current.summary.inboundCode\}#PDA-CONTRACT/) }) test('raw Order and original status history remain in evidence including operator, reason and timestamp',() => { const detail={order:{id:'100',orderRole:'MASTER',version:3,status:'TRANSPORTING'},statusHistory:[ {id:'11',orderId:'100',action:'OVERSEAS_DELIVERED',operatorName:'OVERSEAS_DELIVERY_EVENT', reason:'signed actual delivery',occurredAt:'2026-09-30T01:00:00',fromStatus:'TRANSPORTING',toStatus:'TRANSPORTING'}, ]} const snapshot=fulfillmentHistorySnapshot(detail) assert.deepEqual(snapshot.rawOrder,detail.order) assert.deepEqual(snapshot.histories,detail.statusHistory) assert.deepEqual(completionCounts(snapshot),{own:1,final:0}) }) test('root shipment signed first preserves unfinished root while effective child remains pending',() => { const snapshot=signed();snapshot.root.status='TRANSPORTING' snapshot.root.histories=history('OVERSEAS_DELIVERED');snapshot.child={status:'TRANSPORTING',histories:[]} snapshot.rootInbound.orderStatusSnapshot='TRANSPORTING' assert.equal(validSignatureGate(snapshot,'MASTER'),true) snapshot.root.status='COMPLETED' assert.equal(validSignatureGate(snapshot,'MASTER'),false) }) test('child signed before root remains an independent completed child and cannot finish unsigned root',() => { const snapshot=signed();snapshot.root={status:'TRANSPORTING',histories:[]} snapshot.rootInbound={processStatus:'IN_TRANSIT',orderStatusSnapshot:'TRANSPORTING'} assert.equal(validSignatureGate(snapshot,'CHILD'),true) assert.equal(validSignatureGate(snapshot,'MASTER'),false) snapshot.root.histories=history('OVERSEAS_DELIVERED') assert.equal(validSignatureGate(snapshot,'CHILD'),false) }) test('all signed requires root own fact, exactly one aggregate final history and real Firstleg delivered completion',() => { assert.equal(validSignatureGate(signed(),'MASTER',true),true) for(const change of [ value => value.root.histories=history('FULFILLMENT_COMPLETED'), value => value.root.histories.push({action:'FULFILLMENT_COMPLETED'}), value => value.child.histories.push({action:'OVERSEAS_DELIVERED'}), value => value.child.status='CANCELLED', value => value.rootInbound.orderStatusSnapshot='TRANSPORTING', value => value.rootInbound.processStatus='RECEIVED', ]) {const value=signed();change(value);assert.equal(validSignatureGate(value,'MASTER',true),false)} }) test('Outbox requires exact customer/root/source aggregate membership, unique completion and PUBLISHED',() => { assert.equal(exactCompletionOutboxProof(outbox(),'90','100',['101','100']),true) for(const change of [ value => value.readOnly=false, value => value.customerId='91', value => value.rootOrderId='999', value => value.orders[0].rootOrderId='999', value => value.orders[0].customerId='91', value => value.orders[1].orderId='100', value => value.orders[0].count=2, value => value.orders[1].publishedCount=0, value => value.orders[1].pendingCount=1, value => value.orders[0].failedCount=1, value => value.orders[0].eventType='OVERSEAS_DELIVERED', value => value.orders.pop(), ]) {const value=outbox();change(value);assert.equal(exactCompletionOutboxProof(value,'90','100',['100','101']),false)} }) test('exported fragment producer preserves fail closed supplier precondition and never writes without actual source master',async() => { const context=fixture(),calls=[] context.request=async(method,path) => {calls.push([method,path]);return {http:200,body:{code:200,data:{records:[]}}}} assert.equal(await loadOneFragment(context,{sourceOrderNo:'offline-only'}),null) assert.equal(calls.length,1) assert.equal(calls[0][0],'GET') assert.match(calls[0][1],/category=BOOKING&status=ACTIVE/) }) test('exported pallet label helper preserves FBA eligibility without introducing writes for other destinations',async() => { const context=fixture();context.request=async() => {throw new Error('unexpected HTTP')} assert.equal(await verifyPalletLabels(context,{destinationType:'OVERSEAS'},'1'),null) assert.equal(await verifyPalletLabels(context,{destinationType:'FBA',fulfillmentType:'ONE_CLICK_DROPSHIP'},'1'),null) }) test('exported consumer polling and conversion fail closed when real producer consumption is absent',async() => { const context=fixture(),calls=[] context.request=async(method,path) => {calls.push([method,path]);return {http:200,body:{code:200,data:{records:[]}}}} assert.equal(await awaitProducerConsumption(context,[]),true) assert.equal(await convertReceivingContainers(context,[{containerNo:'OFFLINE'}]),false) assert.equal(calls.every(([method]) => method==='GET'),true) assert.equal(context.steps.at(-1).passed,false) }) test('exported receiving rejects unmatched current producer instead of borrowing any history container',async() => { const context=fixture();context.request=async(_method,path) => ({http:200,body:{code:200,data: path.endsWith('/candidates')?[{containerNo:'ANOTHER',sourceContainerBookingId:'999',totalPackages:1}]:null}}) await runReceiving(context,'offline-pda',null,null,{containerNo:'EXPECTED',containerBookingId:'100'},false,{attempts:1}) assert.equal(context.steps.some(step => step.passed === false),true) }) test('exported receiving warehouse resolver continues to choose only configured active official warehouse',async() => { const context=fixture();context.request=async() => ({http:200,body:{code:200,data:{records:[ {id:'193000000000200003',warehouseType:'OVERSEAS',status:'ACTIVE',warehouseName:'offline'}, ]}}}) assert.deepEqual(await resolveSharedWarehouse(context),{id:'193000000000200003',name:'offline'}) }) function warehouseSelectionFixture() { const producers = [1, 2].map(n => ({ tenantId: '90', containerNo: `CONTAINER-${n}`, containerBookingId: `BOOKING-${n}`, sourceInboundId: `INBOUND-${n}`, inboundCode: `CODE-${n}` })) const orders = producers.map((p, n) => ({ id: `LASTLEG-${n}`, customerId: p.tenantId, sourceContainerBookingId: p.containerBookingId, sourceInboundId: p.sourceInboundId, inboundCode: p.inboundCode, containerNo: p.containerNo, overseasWarehouseId: 'actual-warehouse', overseasWarehouseCode: 'ACTUAL' })) const warehouses = [{ id: 'other-warehouse', warehouseName: 'other', warehouseCode: 'OTHER', warehouseType: 'OVERSEAS', status: 'ACTIVE' }, { id: 'actual-warehouse', warehouseName: 'actual', warehouseCode: 'ACTUAL', warehouseType: 'OVERSEAS', status: 'ACTIVE' }] const calls = [], context = fixture() context.request = async (method, path) => { calls.push({ method, path }) const rows = path.includes('/warehouse-admin?') ? warehouses : orders.filter(row => row.containerNo === new URL(path, 'https://offline.invalid').searchParams.get('containerNo')) return { http: 200, body: { code: 200, data: { records: rows, total: rows.length } } } } return { producers, orders, warehouses, calls, context } } test('F40 selects actual source warehouse irrespective of authority list order and only performs GET', async () => { for (const reverse of [false, true]) { const f = warehouseSelectionFixture() if (reverse) { f.warehouses.reverse(); f.orders.reverse(); f.producers.reverse() } const warehouse = await resolveF40ReceivingWarehouse(f.context, f.producers) assert.equal(warehouse.id, 'actual-warehouse') assert.equal(warehouse.code, 'ACTUAL') assert.equal(warehouse.sourceOrders.length, 2) assert.ok(f.calls.every(row => row.method === 'GET')) } assert.ok(source.indexOf('await awaitProducerConsumption(scope,producers)') < source.indexOf('await resolveF40ReceivingWarehouse(scope,producers)')) assert.ok(source.indexOf('await resolveF40ReceivingWarehouse(scope,producers)') < source.indexOf('await createPicker(scope, 7')) assert.doesNotMatch(source, /resolveSharedWarehouse|19300000000020000[34]/) }) test('F40 warehouse resolution rejects wrong customer, booking, inbound identity, duplicates and missing assignment', async () => { for (const mutate of [ f => { f.orders[0].customerId = 'foreign' }, f => { f.orders[0].sourceContainerBookingId = 'foreign' }, f => { f.orders[0].sourceInboundId = 'foreign' }, f => { f.orders[0].inboundCode = 'foreign' }, f => { f.orders[0].containerNo = 'foreign' }, f => { f.orders[0].overseasWarehouseId = '' }, f => { f.orders.push({ ...f.orders[0] }) }, ]) { const f = warehouseSelectionFixture(); mutate(f) await assert.rejects(resolveF40ReceivingWarehouse(f.context, f.producers), /来源柜客户入仓身份/) assert.ok(f.calls.every(row => !row.path.includes('/warehouse-admin?'))) } }) test('F40 warehouse resolution blocks different receiving warehouses and invalid or ambiguous official master data', async () => { const mixed = warehouseSelectionFixture(); mixed.orders[1].overseasWarehouseId = 'other-warehouse' await assert.rejects(resolveF40ReceivingWarehouse(mixed.context, mixed.producers), /同一实际接柜仓/) for (const mutate of [ f => { f.warehouses.pop() }, f => { f.warehouses[1].status = 'DISABLED' }, f => { f.warehouses[1].warehouseType = 'DOMESTIC' }, f => { f.warehouses[1].warehouseCode = 'WRONG' }, f => { f.warehouses.push({ ...f.warehouses[1] }) }, ]) { const f = warehouseSelectionFixture(); mutate(f) await assert.rejects(resolveF40ReceivingWarehouse(f.context, f.producers), /唯一启用海外收货仓/) assert.ok(f.calls.every(row => row.method === 'GET')) } }) test('F40 warehouse resolution rejects empty or duplicate producers before HTTP', async () => { for (const select of [() => [], f => [f.producers[0], f.producers[0]], f => [{ ...f.producers[0], sourceInboundId: '' }]]) { const f = warehouseSelectionFixture() await assert.rejects(resolveF40ReceivingWarehouse(f.context, select(f)), /唯.*本轮实装来源/) assert.equal(f.calls.length, 0) } }) test('complete orchestrator calls actual source chain and blocks missing Outbox evidence; no fake callback or SQL',() => { assert.equal(typeof run,'function') for(const name of ['orders','inbound-measurement','phase3-customs','phase3-outbound-dispatch', 'phase3-carrier-schedule-queries'])assert.ok(source.includes(`'${name}'`)) for(const name of ['loadOneFragment','verifyPalletLabels','awaitProducerConsumption', 'convertReceivingContainers','prepareTerminalDrayage','runReceiving','pickAll','withDeliveryEventRecovery']) assert.match(source,new RegExp(`await ${name}\\(`)) assert.match(source,/\(\) => saveReceiptAndComplete\(context, deliveries\[0\], customerId, index\)/) assert.match(source,/rootOrderId,\s*sourceOrderIds:\[rootOrderId,childOrderId\]/) assert.match(source,/HTTP_VERIFIED_OUTBOX_PENDING/) assert.match(source,/finally \{ preserveReceivingEvidence\(proof,scope\); proof.currentStage = 'PDA_IDENTITY_CLEANUP'; await disablePicker/) assert.doesNotMatch(source,/['"`]\/internal\/|UPDATE\s+ord_|INSERT\s+INTO|\/complete-delivery/) }) const oneLoadedTree = () => ({...tree(),cumulativeLoadedPackageCount:1,currentRemainderPackageCount:1, children:tree().children.slice(0,2).map(row=>({...row,loadingPlanId:'30',containerBookingId:'20'}))}) const approvedChild = () => fulfillmentHistorySnapshot({order:{id:'101',tenantId:'90',orderRole:'CHILD', rootOrderId:'100',parentOrderId:'100',status:'APPROVED',version:1,orderNo:'R-1',inboundCode:'I-1',completedAt:null},statusHistory:[]}) const unshippedInbound = () => ({id:'301',tenantId:'90',orderId:'101',orderNo:'R-1',inboundCode:'I-1', processStatus:'WAIT_SPLIT',orderStatusSnapshot:'APPROVED',totalPackageCount:1,containerNo:null,cabinetNo:null}) const cancelled = () => ({root:{status:'COMPLETED',histories:history('OVERSEAS_DELIVERED','FULFILLMENT_COMPLETED')}, child:{status:'CANCELLED',rawOrder:{completedAt:null},histories:history('CANCELLED')}, rootInbound:{processStatus:'DELIVERED',orderStatusSnapshot:'COMPLETED'}}) const cancellationOutbox = () => {const value=outbox();value.orders[1].count=0;value.orders[1].publishedCount=0;return value} test('unloaded remainder requires real raw APPROVED child, exact customer/root/source and one remaining physical box',() => { const child=approvedChild(),inbound=unshippedInbound(),tree=oneLoadedTree() assert.equal(validUnloadedRemainder(tree,child,inbound,'90','100','101'),true) for(const mutate of [ value => value.child.status='PROCESSING',value => value.child.status='ACCEPTED', value => value.child.rootOrderId='999',value => value.child.parentOrderId='999', value => value.child.rawOrder.tenantId='91',value => value.child.orderId='102', value => value.child.histories=history('OVERSEAS_DELIVERED'), value => value.inbound.orderId='102',value => value.inbound.tenantId='91', value => value.inbound.inboundCode='ANOTHER',value => value.inbound.orderNo='ANOTHER', value => value.inbound.processStatus='LOADED',value => value.inbound.totalPackageCount=2, value => value.inbound.orderStatusSnapshot='PROCESSING',value => value.inbound.containerNo='ACTUAL-CABINET', value => value.inbound.cabinetNo='ACTUAL-CABINET',value => value.tree.children.push(tree.children[0]), value => value.tree.children[0].sourceOrderId='101',value => value.tree.children[1].loadingPlanId='31', value => value.tree.children[1].containerBookingId='21',value => value.tree.currentRemainderPackageCount=0, ]) { const value={tree:oneLoadedTree(),child:approvedChild(),inbound:unshippedInbound()};mutate(value) assert.equal(validUnloadedRemainder(value.tree,value.child,value.inbound,'90','100','101'),false) } }) test('cancelled remainder cannot substitute for child signature in either full-signature mode',() => { assert.equal(validRemainderCancellationGate(cancelled()),true) assert.equal(validSignatureGate(cancelled(),'MASTER',true),false) assert.equal(validSignatureGate(cancelled(),'CHILD',true),false) for(const mutate of [ value=>value.root.histories=history('FULFILLMENT_COMPLETED'), value=>value.root.histories.push({action:'FULFILLMENT_COMPLETED'}), value=>value.child.status='COMPLETED',value=>value.child.histories.push({action:'OVERSEAS_DELIVERED'}), value=>value.child.histories.push({action:'CANCELLED'}),value=>value.child.rawOrder.completedAt='2026-09-30T01:00:00', value=>value.rootInbound.orderStatusSnapshot='APPROVED',value=>value.rootInbound.processStatus='RECEIVED', ]){const value=cancelled();mutate(value);assert.equal(validRemainderCancellationGate(value),false)} }) test('cancellation Outbox requires exactly one published root completion and explicit zero child completion counts',() => { assert.equal(exactCancelledRemainderOutboxProof(cancellationOutbox(),'90','100','101'),true) assert.equal(exactCompletionOutboxProof(cancellationOutbox(),'90','100',['100','101']),false) for(const mutate of [ value=>value.orders.pop(),value=>value.orders[1].count=1,value=>value.orders[1].publishedCount=1, value=>value.orders[1].pendingCount=1,value=>value.orders[1].failedCount=1, value=>value.orders[1].count=null,value=>delete value.orders[1].failedCount, value=>value.orders[1].rootOrderId='999',value=>value.orders[1].customerId='91', value=>value.orders[1].orderId='100',value=>value.orders[1].eventType='ORDER_CANCELLED', value=>value.orders[0].count=2,value=>value.orders[0].publishedCount=0,value=>value.readOnly=false, ]){const value=cancellationOutbox();mutate(value);assert.equal(exactCancelledRemainderOutboxProof(value,'90','100','101'),false)} }) function cancellationFixture(change=null) { const context=fixture(),calls=[],proof={snapshots:[]} const rootDetail={order:{id:'100',tenantId:'90',orderRole:'MASTER',rootOrderId:'100',status:'APPROVED', version:1,orderNo:'R',inboundCode:'I',completedAt:null},statusHistory:history('OVERSEAS_DELIVERED')} const childDetail={order:approvedChild().rawOrder,statusHistory:[]} const rootInbound={summary:{processStatus:'DELIVERED',orderStatusSnapshot:'APPROVED'}} const childInbound={summary:unshippedInbound()},tree=oneLoadedTree() let count=0 context.context={f40BaseMarker:'offline-only',f40ReadOnlyOutboxEvidence:async args=>{ assert.deepEqual(args,{customerId:'90',rootOrderId:'100',sourceOrderIds:['100','101'], eventType:'FIRST_LEG_ORDER_FULFILLMENT_COMPLETED'}) return cancellationOutbox() }} if(change)change({rootDetail,childDetail,childInbound,tree}) let frozenCancel context.request=async(method,path,body,token,headers)=>{ calls.push({method,path,body,headers}) if(method==='POST'){ assert.equal(path,'/api/platform/v1/orders/first-leg/101/cancel?tenantId=90') assert.ok(body.reason.includes('offline-only')) assert.ok(headers?.['Idempotency-Key']) if(count++)return {http:200,body:{code:headers['Idempotency-Key']===frozenCancel.key && JSON.stringify(body)===frozenCancel.payload ? '200' : 'A0409'}} assert.equal(body.expectedVersion,childDetail.order.version) frozenCancel={key:headers['Idempotency-Key'],payload:JSON.stringify(body)} childDetail.order.status='CANCELLED';childDetail.order.version++ childDetail.statusHistory=history('CANCELLED') rootDetail.order.status='COMPLETED';rootDetail.order.version++ rootDetail.order.completedAt='2026-09-30T01:00:00' rootDetail.statusHistory=history('OVERSEAS_DELIVERED','FULFILLMENT_COMPLETED') rootInbound.summary.orderStatusSnapshot='COMPLETED' return {http:200,body:{code:'200',data:null}} } let data if(path.includes('/fulfillment-tree?'))data=tree else if(path.includes('/orders/first-leg/100?'))data=rootDetail else if(path.includes('/orders/first-leg/101?'))data=childDetail else if(path.includes('/inbounds/300?'))data=rootInbound else if(path.includes('/inbounds/301?'))data=childInbound else throw new Error(`unexpected offline request ${path}`) return {http:200,body:{code:'200',data:structuredClone(data)}} } return {context,proof,calls} } test('formal cancellation helper rereads physical eligibility, uses public cancel and accepts replay rejection only with unchanged facts and Outbox',async()=>{ const {context,proof,calls}=cancellationFixture() const result=await cancelUnloadedRemainder(context,proof,'90','100','101','300','301') assert.equal(validRemainderCancellationGate(result),true) const writes=calls.filter(row=>row.method==='POST') assert.equal(writes.length,4) assert.deepEqual(writes[1].body,writes[0].body) assert.deepEqual(writes[1].headers,writes[0].headers) assert.equal(writes[2].headers['Idempotency-Key'],writes[0].headers['Idempotency-Key']) assert.notEqual(writes[3].headers['Idempotency-Key'],writes[0].headers['Idempotency-Key']) assert.ok(writes[3].body.expectedVersion>writes[0].body.expectedVersion) assert.equal(proof.snapshots.length,3) assert.deepEqual(proof.cancelReplayOutbox.before,proof.cancelReplayOutbox.after) assert.equal(context.steps.every(step=>step.passed),true) }) test('formal cancellation helper stops before any mutation for PROCESSING, unsigned root or already loaded child',async()=>{ for(const change of [value=>value.childDetail.order.status='PROCESSING', value=>value.rootDetail.order.status='PROCESSING',value=>value.rootDetail.statusHistory=[], value=>value.childInbound.summary.processStatus='LOADED',value=>value.tree.children.push(tree().children[2])]) { const {context,proof,calls}=cancellationFixture(change) await assert.rejects(cancelUnloadedRemainder(context,proof,'90','100','101','300','301'),/仅取消真实签收根下未装 APPROVED/) assert.equal(calls.some(row=>row.method!=='GET'),false) } }) test('cancel scenario uses new approved-only order and exactly root shipment; both existing full-signature modes remain independent',()=>{ assert.match(source,/const cancelRemainder = signatureOrder === 'ROOT_SIGNED_REMAINDER_CANCELLED'/) assert.match(source,/orderStopAtApproved:cancelRemainder/) assert.match(source,/approvedRoot.status === 'APPROVED'/) assert.match(source,/if \(cancelRemainder\) \{[\s\S]*?proof.unloadedRemainder[\s\S]*?\} else \{[\s\S]*?second = await fragment/) assert.match(source,/const producers = cancelRemainder \? \[first\] : \[first,second\]/) assert.match(source,/signatureOrder === 'CHILD_FIRST' \? \[second,first\] : producers/) assert.match(source,/if \(cancelRemainder\) await cancelUnloadedRemainder/) const orderSource=readFileSync(new URL('./orders.mjs',import.meta.url),'utf8') assert.match(orderSource,/context.context\?\.orderStopAtApproved === true/) }) test('early F40 failures become FAILED with only a safe stage and preserve the original exception',async() => { const context=fixture();context.context={};context.options={} await assert.rejects(run(context),/F40 本轮客户完整凭据有效/) assert.equal(context.createdResources.phase5RootFulfillment.finalStatus,'FAILED') assert.equal(context.createdResources.phase5RootFulfillment.failedStage,'CUSTOMER_IDENTITY') assert.equal('error' in context.createdResources.phase5RootFulfillment,false) const secretError=new Error('offline-secret-body-not-recorded') const withLogin=fixture();withLogin.context={};withLogin.options={merchantUsername:'offline',merchantPassword:'offline'} withLogin.request=async()=>{throw secretError} await assert.rejects(run(withLogin),error=>error === secretError) assert.equal(withLogin.createdResources.phase5RootFulfillment.finalStatus,'FAILED') assert.equal(JSON.stringify(withLogin.createdResources.phase5RootFulfillment).includes(secretError.message),false) }) function nativeFragmentFixture() { const context = fixture(), events = [], calls = [] const producer = { tenantId: '90', inboundCode: 'IN-F40', sourceInboundId: '901', sourceOrderId: '100', rootOrderId: '100', containerBookingId: '902' } const rootProof = { fragments: [producer], currentStage: 'DISPATCH_AND_SIGNATURE_1' } context.context = { f40BaseMarker: 'offline-F40', f40RootFulfillmentProof: rootProof } const measurement = { environment: 'TEST', marker: 'offline-F40-SEND-0', dispatchNo: 'DS-F40', pallets: [] } context.context.f40LoadingMeasurements = { 'DS-F40': measurement } context.checkpoint = async () => { events.push('checkpoint') } const delivery = { customerId: '90', deliveryNo: 'DL-F40', outboundNo: 'OB-F40', packageCount: '1', destination: { key: 'FBA:ONT8', warehouseCode: 'ONT8' } } let created, departed, signed = false context.request = async (method, path, body, token) => { calls.push({ method, path, body: structuredClone(body), token }) let data if (method === 'GET' && path.includes('/candidates?')) { assert.equal(new URL(path, 'https://offline.invalid').searchParams.get('warehouseId'), '80') assert.equal(new URL(path, 'https://offline.invalid').searchParams.has('sourceStage'), false) data = { complete: true, candidates: [nativeF40Candidate()] } } else if (method === 'POST' && path.endsWith('/dispatches')) { events.push('create') if (created) data = { ...created, replayed: true } else data = created = { dispatchNo: 'DS-F40', status: 'ACTIVE', stage: 'BEFORE_LOADING', recordVersion: '0', result: { dispatchNo: 'DS-F40', changedItemIds: ['9007199254740998'] } } } else if (method === 'POST' && path.endsWith('/depart')) { events.push('depart') assert.equal(token, 'pda-memory') assert.equal(body.recordVersion, '9007199254740999') if (departed) { assert.deepEqual(body, calls.find(call => call.path.endsWith('/depart')).body) data = { ...departed, replayed: true } } else data = departed = { dispatchNo: 'DS-F40', status: 'ACTIVE', stage: 'DELIVERING', recordVersion: '9007199254741000', result: { shippedPackages: '1', deliveries: [delivery], outbounds: [{ customerId: '90', outboundNo: 'OB-F40' }] } } } else if (method === 'GET' && path.includes('/delivery-orders/')) { data = { order: { id: '9007199254741001', customerId: '90', outboundNo: 'OB-F40', deliveryNo: 'DL-F40', version: '9007199254741002', status: departed ? 'DELIVERING' : 'WAIT_DELIVERY' }, skus: [{ inboundCode: 'IN-F40', packageCount: 1 }] } } else if (method === 'GET' && path.endsWith('/outbound-orders/OB-F40')) { data = { outbound: { customerId: '90', outboundNo: 'OB-F40', status: 'OUTBOUNDED' }, pallets: [{ inboundCode: 'IN-F40' }] } } else if (method === 'GET' && path.endsWith('/dispatches/DS-F40')) { assert.equal(signed, true); events.push('normal-completed') data = { dispatchNo: 'DS-F40', status: 'ACTIVE', stage: 'DELIVERED', recordVersion: '9007199254741004' } } else throw new Error(`Unexpected offline wire ${method} ${path}`) return { http: 200, body: { code: '200', data } } } const deps = { async fulfillmentEvidenceContext(current) { events.push('evidence'); return current }, async prepareFleetTrip(current, module, dispatchNo, warehouseId) { events.push('prepare-review'); assert.equal(dispatchNo, 'DS-F40'); assert.equal(warehouseId, '80') return { dispatchNo, warehouseId, tripNo: 'TR-F40', recordVersion: '1' } }, async pickAll(current, token, dispatchNo) { events.push('pick'); assert.equal(token, 'pda-memory'); assert.equal(dispatchNo, 'DS-F40'); return true }, async confirmFleetLoading(current, module, proof, token, actual) { events.push('loading-complete'); assert.equal(token, 'pda-memory'); assert.equal(actual, measurement) if (!actual) throw new Error('实际测量缺少有效palletSpaces') departed = true; proof.loadingCommand = { replay: { replayed: true } }; return '9007199254740998' }, async readAutomaticDispatchDelivery() { events.push('arrange'); return { deliveries: [delivery], outbounds: [{ customerId: '90', outboundNo: 'OB-F40', packageCount: '1' }], data: { documents: { deliveries: [delivery] } } } }, async verifyAutomaticDeparture() { events.push('read-current-depart-version'); return { data: { recordVersion: '9007199254740999', stage: 'DELIVERING', counts: { shippedPackageCount: 1 } } } }, async saveReceiptAndComplete(current, actual, customerId, index) { events.push('receipt'); assert.equal(actual, delivery); assert.equal(customerId, '90'); assert.equal(index, 0) signed = true return { order: { customerId: '90', deliveryNo: 'DL-F40', status: 'DELIVERED', version: '9007199254741003', signedAt: '2026-10-19T01:00:00' } } }, async finishFleetTrip() { events.push('finish'); return { status: 'VERIFIED' } }, } return { context, producer, rootProof, deps, events, calls, measurement } } test('F40 fragment uses native creation, reviews, real PDA scan, explicit loading/token/evidence, arrangement, refreshed departure version and normal signature', async () => { const f = nativeFragmentFixture() const result = await sendFragment(f.context, f.producer, { warehouseId: '80', token: 'pda-memory' }, 'merchant-memory', 0, f.deps) assert.equal(result.outboundNo, 'OB-F40'); assert.equal(result.receiptVersion, '9007199254741003') assert.equal(result.signedAt, '2026-10-19T01:00:00') assert.deepEqual(f.events.filter(event => event !== 'checkpoint'), ['evidence', 'create', 'create', 'prepare-review', 'pick', 'loading-complete', 'arrange', 'read-current-depart-version', 'receipt', 'normal-completed', 'finish']) assert.equal(f.calls.some(call => /pre-arrange|\/status|\/api\/merchant\//.test(call.path)), false) assert.equal(f.calls.some(call => call.method === 'PUT'), false) assert.equal(f.rootProof.dispatches[0].stage, 'DELIVERED') assert.equal(f.rootProof.dispatches[0].loadingReplay.replayed, true) assert.equal(f.context.steps.every(step => step.passed), true) }) test('F40 missing real measurement evidence stops before arranging, departing or signing while keeping the failed source proof', async () => { const f = nativeFragmentFixture() delete f.context.context.f40LoadingMeasurements f.deps.confirmFleetLoading = async (_context, _module, _proof, token, actual) => { assert.equal(token, 'pda-memory'); assert.equal(actual, undefined) throw new Error('实际测量缺少有效palletSpaces') } await assert.rejects(sendFragment(f.context, f.producer, { warehouseId: '80', token: 'pda-memory' }, 'merchant-memory', 0, f.deps), /实际测量缺少/) assert.equal(f.events.includes('arrange'), false) assert.equal(f.calls.some(call => call.path.endsWith('/depart')), false) assert.equal(f.events.includes('receipt'), false) assert.equal(f.rootProof.dispatches[0].dispatchNo, 'DS-F40') assert.equal(f.rootProof.dispatches[0].stage, 'FAILED') assert.equal(f.rootProof.dispatches[0].failedAction, 'LOADING_COMPLETE') assert.equal(f.events.at(-1), 'checkpoint') }) test('F40 measurement reader receives the exact current TEST source scope and preserves its returned evidence without inferred values', async () => { const f = nativeFragmentFixture(), response = { arbitrary: 'opaque-original-proof' } f.context.marker = 'offline-F40-SEND-0' f.context.context.f40LoadingMeasurements = async scope => { assert.deepEqual(scope, { environment: 'TEST', marker: 'offline-F40-SEND-0', dispatchNo: 'DS-F40', warehouseId: '80', sourceInboundId: '901', inboundCode: 'IN-F40' }) return response } assert.equal(await resolveF40LoadingMeasurements(f.context, 'DS-F40', f.producer, '80'), response) }) test('F40 fresh receipt revision evidence preserves string versions above safe integer precision', () => { const oldVersion = '9007199254740993', newVersion = '9007199254740994' const documents = { version: oldVersion, uploadedCategoryCount: 1, categories: [{ category: 'RECEIPT', files: [{ fileId: '9007199254740995' }] }], replayed: false } const before = { documents, delivery: { order: { version: oldVersion, status: 'DELIVERED', signedAt: '2026-10-19T01:00:00' }, operations: [{ id: '9007199254740996', operationNode: 'RECEIPT_AUTO_COMPLETE' }] }, revisions: [{ version: oldVersion }] } const after = structuredClone(before) after.documents.version = newVersion; after.delivery.order.version = newVersion after.delivery.operations.push({ id: '9007199254740997', operationNode: 'SAVE_DOCUMENTS', result: '保存派送资料:1/3类', operatedAt: '2026-10-19T01:01:00', operatorName: 'TEST' }) after.revisions.push({ version: newVersion, savedAt: '2026-10-19T01:01:00', operatorId: 'platform', snapshot: after.documents }) assert.equal(validFreshReceiptSave(before, after), true) after.documents.version = '9007199254740995' assert.equal(validFreshReceiptSave(before, after), false) })