fix(phase4): enforce customer and pallet versions

This commit is contained in:
2026-08-24 15:14:18 +08:00
parent e773816c98
commit 95b72afdcc
12 changed files with 82 additions and 31 deletions
@@ -37,8 +37,9 @@ async function overseasGet(context, name, path) {
}
async function overseasMutation(context, method, name, path, body) {
const response = await context.requestOverseas(method, path, body)
assertEnvelope(context, name, response)
return { response, data: context.apiSuccess(MODULE, name, response, trace(response), OPTIONS) }
const passed = response?.http === 200 && String(response?.body?.code) === '200'
context.addStep(MODULE, name, response, passed, trace(response), OPTIONS)
return { response, data: passed ? response.body?.data : null }
}
async function overseasCsv(context, name, path) {
const response = await context.requestOverseasBinary('GET', path)
@@ -230,7 +231,7 @@ async function verifyPalletLifecycle(context, warehouseId) {
const updated = await overseasMutation(context, 'PUT', '编辑本轮公共托盘', detailPath, {
palletCode, palletType: '木托盘', capacityCbm: 2.5, unitPrice: 1, status: 'IDLE',
locationId: id(detail.data?.locationId) || undefined, remark: `${context.marker}-edited`,
locationId: id(detail.data?.locationId) || undefined, remark: `${context.marker}-edited`, version: Number(detail.data?.version),
})
context.assert(MODULE, '公共托盘编辑成功', updated.response, updated.data === null,
`palletId=${palletId}; ${trace(updated.response)}`, OPTIONS)
@@ -239,14 +240,20 @@ async function verifyPalletLifecycle(context, warehouseId) {
id(after.data?.id) === palletId && Number(after.data?.capacityCbm) === 2.5
&& Number(after.data?.unitPrice) === 1 && after.data?.remark === `${context.marker}-edited`,
`capacity=${after.data?.capacityCbm ?? 'missing'}, unitPrice=${after.data?.unitPrice ?? 'missing'}, remark=${after.data?.remark || 'missing'}; ${trace(after.response)}`, OPTIONS)
coverageGap(context, '公共托盘旧版本并发冲突',
'当前 Pallet SaveRequest/PUT 未提供 version 或 expectedVersion,无法构造稳定旧版本冲突且禁止伪造冲突请求', 'missing-version-contract')
const stale = await context.requestOverseas('PUT', detailPath, {
palletCode, palletType: '木托盘', capacityCbm: 9, unitPrice: 9, status: 'IDLE',
remark: 'STALE-DO-NOT-APPLY', version: Number(detail.data?.version),
})
context.addStep(MODULE, '公共托盘旧版本编辑返回冲突', stale,
stale?.http === 409 || (stale?.http === 200 && String(stale?.body?.code).endsWith('409')), trace(stale), OPTIONS)
} finally {
if (palletId) {
const retired = await overseasMutation(context, 'PUT', '报废本轮公共托盘',
`/api/platform/v1/warehouse-admin/${encodeURIComponent(warehouseId)}/pallets/${encodeURIComponent(palletId)}`, {
palletCode, palletType: '木托盘', capacityCbm: 2.5, unitPrice: 1, status: 'SCRAPPED',
remark: `${context.marker}-acceptance-retired`,
remark: `${context.marker}-acceptance-retired`, version: Number((await overseasGet(context,
'读取公共托盘报废前最新版本',
`/api/platform/v1/warehouse-admin/${encodeURIComponent(warehouseId)}/pallets/${encodeURIComponent(palletId)}`)).data?.version),
})
context.createdResources.phase4OverseasWarehouse.terminalStatus = retired.data === null ? 'SCRAPPED' : null
context.assert(MODULE, '本轮公共托盘已报废收口', retired.response, retired.data === null,