fix(firstleg): atomically finalize PDA completion
This commit is contained in:
@@ -107,19 +107,19 @@ test('downstream finalizer uses the frozen truck-coupled complete contract', ()
|
||||
assert.doesNotMatch(finalize, /\/loading\/complete\?tenantId=/)
|
||||
})
|
||||
|
||||
test('PDA complete OpenAPI freezes optional truck coupling and atomic rollback', () => {
|
||||
test('PDA complete OpenAPI freezes reliable async acceptance and checkpoint recovery', () => {
|
||||
assert.match(pdaOpenApi, /\/api\/platform\/v1\/first-leg\/pda-loading\/tasks\/\{taskId\}\/complete:/)
|
||||
assert.match(pdaOpenApi, /拖车状态不是前置门禁/)
|
||||
assert.match(pdaOpenApi, /没有有效拖车则直接继续/)
|
||||
assert.match(pdaOpenApi, /恰有一条有效拖车时由服务端加锁推进为COMPLETED并写历史/)
|
||||
assert.match(pdaOpenApi, /多条有效拖车或并发修改返回A0409且全部Firstleg本地状态回滚/)
|
||||
assert.match(pdaOpenApi, /同operationId重放返回冻结结果,不重复推进拖车或写历史/)
|
||||
assert.match(pdaOpenApi, /持久化可靠完成命令并将任务置为COMPLETING后立即返回PROCESSING事实/)
|
||||
assert.match(pdaOpenApi, /后台worker按稳定入库单顺序以checkpoint恢复/)
|
||||
assert.match(pdaOpenApi, /请求事务内不调用任何远程服务/)
|
||||
assert.match(pdaOpenApi, /同operationId重放立即返回相同PROCESSING或最终结果/)
|
||||
assert.match(pdaOpenApi, /不同operationId在处理期间返回A0409/)
|
||||
})
|
||||
|
||||
test('PDA final completion refreshes post-settlement versions for full and partial split', () => {
|
||||
ordered(loadingPickService, [
|
||||
'settlementService.settle(taskId, operatorId, operatorName)',
|
||||
'loadingDeliveryService.completeAfterPdaSettlement',
|
||||
'settlementService.settleOwner(',
|
||||
'loadingDeliveryService.completeAfterPdaSettlement(',
|
||||
])
|
||||
assert.doesNotMatch(loadingPickService,
|
||||
/new LoadingRequests\.CompleteLoadingRequest\(entry\.getValue\(\)\.version\(\), remark\)/)
|
||||
@@ -133,7 +133,8 @@ test('PDA final completion refreshes post-settlement versions for full and parti
|
||||
'pdaFinalizeLocksAndUsesLoadedSliceVersionAfterPartialSettlement',
|
||||
'pdaFinalizeKeepsOptimisticConflictForRealConcurrentChange',
|
||||
]) assert.match(loadingDeliveryServiceTest, new RegExp(regression))
|
||||
assert.match(loadingDeliveryServiceTest, /verify\(repository, never\(\)\)\.completeLoadedChild\(10, 20, 7, 6\)/)
|
||||
assert.match(loadingDeliveryServiceTest, /verify\(repository\)\.findInboundForUpdate\(10L, 21L\)/)
|
||||
assert.match(loadingDeliveryServiceTest, /verify\(repository\)\.completeLoadedChild\(10L, 20L, 9L, 9\)/)
|
||||
assert.match(loadingDeliveryServiceTest, /verify\(histories, never\(\)\)\.insert/)
|
||||
})
|
||||
|
||||
@@ -159,7 +160,8 @@ test('HTTP finalizer races distinct completion keys and persists exactly one ter
|
||||
'读取结算前 PDA 操作历史基线',
|
||||
'const completeAttempts = [1, 2].map',
|
||||
'const concurrentCompleteResponses = await Promise.all',
|
||||
'并发完成后回查 PDA 操作审计',
|
||||
'异步完成命令收敛到终态',
|
||||
'const operationsAfterConcurrent = completion.operations',
|
||||
'两个不同幂等键并发 complete 仅一成功且只写一条完成审计',
|
||||
'订舱与五类证据等保留门禁齐备后完成装柜',
|
||||
'LOADED 完成请求 Idempotency-Key 重放保持终态',
|
||||
@@ -176,3 +178,17 @@ test('HTTP finalizer races distinct completion keys and persists exactly one ter
|
||||
assert.match(finalize, /concurrentCompleteOperations\.length === 1/)
|
||||
assert.match(finalize, /concurrentCompleteOperations\[0\]\?\.operationId === completeBody\.operationId/)
|
||||
})
|
||||
|
||||
test('worker final Firstleg convergence is one short transaction after remote owner settlement', () => {
|
||||
ordered(loadingPickService, [
|
||||
'settlementService.settleOwner(',
|
||||
'loadingDeliveryService.completeAfterPdaSettlement(',
|
||||
'completionTransaction.executeWithoutResult',
|
||||
'completeTruckAfterCommit(',
|
||||
])
|
||||
const finalizer = loadingPickService.slice(loadingPickService.indexOf('private void finalizeCompletion'),
|
||||
loadingPickService.indexOf('private void requireColoadConservation'))
|
||||
for (const token of ['COMPLETE_LOADING', 'finishFromPda', 'syncInboundProjections',
|
||||
'publishCompletedEvent', 'completeAccepted', 'completionCommands.complete']) assert.match(finalizer, new RegExp(token))
|
||||
assert.doesNotMatch(finalizer, /settlementService|completeTruckAfterCommit/)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user