优化
This commit is contained in:
+1
-1
@@ -87,7 +87,7 @@ Dry-run 只检查根 `pom.xml` 和关键回归测试文件并打印 Maven 命令
|
||||
|
||||
### 本地 MySQL 全量验收
|
||||
|
||||
正式入口是 `local-db-full-acceptance.ps1`,只允许连接本机 `127.0.0.1` 或 `localhost`,默认端口 `3306`;测试库 `8.163.30.128` 会立即以退出码 2 拒绝。脚本固定校验统一 SQL SHA-256 `BE7C5C98712D5202F5D187EA9A37C64EAB9F6AA9AE772C89A51F186507B1AE53` 和 14706 行,并静态确认中文注释升级采用校验入队、每表一次 ALTER、结构签名复核、九库覆盖断言及唯一最终 `PASS`。
|
||||
正式入口是 `local-db-full-acceptance.ps1`,只允许连接本机 `127.0.0.1` 或 `localhost`,默认端口 `3306`;测试库 `8.163.30.128` 会立即以退出码 2 拒绝。脚本固定校验统一 SQL SHA-256 `3E0A02C2E3B971AB7D8AB9C9D8AEE1D933F950DBCE82BD9B6AD431A4DD179F8A` 和 14713 行,并静态确认中文注释升级采用校验入队、每表一次 ALTER、结构签名复核、九库覆盖断言及唯一最终 `PASS`。
|
||||
|
||||
```powershell
|
||||
.\scripts\local-db-full-acceptance.ps1 -DryRun
|
||||
|
||||
@@ -17,7 +17,7 @@ test('retains all clickable container, loading-list and PDA workflow states thro
|
||||
assert.match(source, /\.\/orders\.mjs/)
|
||||
assert.match(source, /\.\/inbound-measurement\.mjs/)
|
||||
assert.doesNotMatch(source, /context\.request\('POST', CONTAINERS/)
|
||||
assert.match(source, /\['WAIT_SPLIT', 'INBOUNDED'\]\.includes/)
|
||||
assert.match(source, /summary\?\.processStatus === 'WAIT_SPLIT'/)
|
||||
const batch = source.slice(source.indexOf('async function pickAll'), source.indexOf('async function complete'))
|
||||
assert.doesNotMatch(batch, /containerNo:/)
|
||||
})
|
||||
|
||||
@@ -88,7 +88,7 @@ async function readInbound(context, fixture) {
|
||||
const value = context.apiSuccess(MODULE, '读取人工装柜独立入库单', response, '', OPTIONS)
|
||||
const warehouseId = id(value?.summary?.warehouseId)
|
||||
context.assert(MODULE, '人工装柜来源入库单可独立排柜', response,
|
||||
['WAIT_SPLIT', 'INBOUNDED'].includes(value?.summary?.processStatus)
|
||||
value?.summary?.processStatus === 'WAIT_SPLIT'
|
||||
&& value?.summary?.measureReviewStatus === 'APPROVED'
|
||||
&& Boolean(warehouseId),
|
||||
`inboundId=${fixture.inboundId}, status=${value?.summary?.processStatus || 'missing'}`, OPTIONS)
|
||||
|
||||
@@ -39,8 +39,8 @@ test('入库不可独立保留状态显式阻断', () => {
|
||||
assert.match(source, new RegExp(`${status}:`))
|
||||
}
|
||||
assert.match(source, /AutomaticInboundCompletionService 在同一调用内立即从 INBOUNDING 推进 WAIT_SPLIT/)
|
||||
assert.match(source, /processStatus=INBOUNDED/)
|
||||
assert.match(source, /查询存量 INBOUNDED 兼容样本/)
|
||||
assert.match(source, /processStatus=WAIT_SPLIT/)
|
||||
assert.match(source, /查询存量 WAIT_SPLIT 样本/)
|
||||
assert.match(source, /没有作废入库单 API/)
|
||||
assert.match(source, /context\.assert\(MODULE, `入库列表保留 \$\{status\}`/)
|
||||
})
|
||||
@@ -48,7 +48,7 @@ test('入库不可独立保留状态显式阻断', () => {
|
||||
test('统一订单声明合法可达状态并显式阻断废弃或无 API 状态', () => {
|
||||
assert.match(source, /result\.unifiedOrders\.PENDING_REVIEW/)
|
||||
assert.match(source, /result\.unifiedOrders\.WAIT_MEASURE/)
|
||||
for (const status of ['INBOUNDED', 'WAIT_SPLIT', 'LOADING', 'LOADED', 'DELIVERED']) {
|
||||
for (const status of ['WAIT_SPLIT', 'LOADING', 'LOADED', 'DELIVERED']) {
|
||||
assert.match(source, new RegExp(`'${status}'`))
|
||||
}
|
||||
assert.doesNotMatch(source, /WAIT_SPLIT 标记为历史废弃状态/)
|
||||
|
||||
@@ -15,10 +15,10 @@ const ORDER_TARGETS = [
|
||||
]
|
||||
const INBOUND_FILTER_STATUSES = [
|
||||
'WAIT_MEASURE', 'MEASURING', 'MEASURE_PENDING', 'MEASURE_REJECTED', 'WAIT_PRICING',
|
||||
'FEE_CONFIRMING', 'INBOUNDING', 'INBOUNDED', 'VOIDED',
|
||||
'FEE_CONFIRMING', 'INBOUNDING', 'WAIT_SPLIT', 'VOIDED',
|
||||
]
|
||||
const UNIFIED_FILTER_STATUSES = [
|
||||
'PENDING_REVIEW', 'WAIT_MEASURE', 'INBOUNDED', 'WAIT_SPLIT', 'LOADING', 'LOADED', 'DELIVERED',
|
||||
'PENDING_REVIEW', 'WAIT_MEASURE', 'WAIT_SPLIT', 'LOADING', 'LOADED', 'DELIVERED',
|
||||
]
|
||||
|
||||
function id(value) { return value == null ? '' : String(value) }
|
||||
@@ -277,19 +277,19 @@ export async function run(context, matrix = context.createdResources.manualState
|
||||
}
|
||||
|
||||
const legacyResponse = await context.request('GET',
|
||||
`/api/platform/v1/inbounds?tenantId=${query(fixture.tenantId)}&processStatus=INBOUNDED&page=1&size=20`)
|
||||
const legacyPage = context.apiSuccess(MODULE, '查询存量 INBOUNDED 兼容样本', legacyResponse, '', OPTIONS)
|
||||
`/api/platform/v1/inbounds?tenantId=${query(fixture.tenantId)}&processStatus=WAIT_SPLIT&page=1&size=20`)
|
||||
const legacyPage = context.apiSuccess(MODULE, '查询存量 WAIT_SPLIT 样本', legacyResponse, '', OPTIONS)
|
||||
const legacyInbound = rows(legacyPage)[0]
|
||||
if (legacyInbound?.id && legacyInbound?.orderId) {
|
||||
const sample = { inboundId: id(legacyInbound.id), orderId: id(legacyInbound.orderId), tenantId: fixture.tenantId,
|
||||
status: 'INBOUNDED', inboundCode: legacyInbound.inboundCode || null }
|
||||
result.inbounds.INBOUNDED = sample
|
||||
result.unifiedOrders.INBOUNDED = sample
|
||||
matrix.pages.inbounds.fixtures.INBOUNDED = {
|
||||
id: sample.inboundId, status: 'INBOUNDED', detailPath: `/orders/${sample.orderId}`,
|
||||
status: 'WAIT_SPLIT', inboundCode: legacyInbound.inboundCode || null }
|
||||
result.inbounds.WAIT_SPLIT = sample
|
||||
result.unifiedOrders.WAIT_SPLIT = sample
|
||||
matrix.pages.inbounds.fixtures.WAIT_SPLIT = {
|
||||
id: sample.inboundId, status: 'WAIT_SPLIT', detailPath: `/orders/${sample.orderId}`,
|
||||
}
|
||||
matrix.pages.unifiedOrders.fixtures.INBOUNDED = {
|
||||
id: sample.orderId, status: 'INBOUNDED', detailPath: `/orders/${sample.orderId}`,
|
||||
matrix.pages.unifiedOrders.fixtures.WAIT_SPLIT = {
|
||||
id: sample.orderId, status: 'WAIT_SPLIT', detailPath: `/orders/${sample.orderId}`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ export async function run(context) {
|
||||
`tenantId=${tenantId}, inboundId=${inboundId}`, OPTIONS)
|
||||
const warehouseId = id(inbound?.summary?.warehouseId)
|
||||
context.assert(MODULE, '柜次候选入库单状态、测量和仓库门禁有效', inboundResponse,
|
||||
['WAIT_SPLIT', 'INBOUNDED'].includes(inbound?.summary?.processStatus)
|
||||
inbound?.summary?.processStatus === 'WAIT_SPLIT'
|
||||
&& inbound?.summary?.measureReviewStatus === 'APPROVED'
|
||||
&& Boolean(warehouseId),
|
||||
`status=${inbound?.summary?.processStatus || 'missing'}, review=${inbound?.summary?.measureReviewStatus || 'missing'}, warehouseId=${warehouseId || 'missing'}`, OPTIONS)
|
||||
|
||||
@@ -108,9 +108,9 @@ export async function run(context) {
|
||||
const initialStatus = initial?.summary?.processStatus
|
||||
const initialVersion = Number(initial?.summary?.version)
|
||||
context.assert(MODULE, '隔离入库单处于智能分柜门禁状态', initialResponse,
|
||||
['INBOUNDED', 'WAIT_SPLIT'].includes(initialStatus) && Number.isInteger(initialVersion),
|
||||
initialStatus === 'WAIT_SPLIT' && Number.isInteger(initialVersion),
|
||||
`status=${initialStatus || 'missing'}, version=${initial?.summary?.version ?? 'missing'}`, OPTIONS)
|
||||
if (!['INBOUNDED', 'WAIT_SPLIT'].includes(initialStatus) || !Number.isInteger(initialVersion)) return
|
||||
if (initialStatus !== 'WAIT_SPLIT' || !Number.isInteger(initialVersion)) return
|
||||
|
||||
const base = `/api/platform/v1/inbounds/${inboundId}`
|
||||
const suffix = context.marker.replace(/\D/g, '').slice(-10)
|
||||
@@ -168,7 +168,7 @@ export async function run(context) {
|
||||
const smartData = context.apiSuccess(MODULE, '智能分柜并生成预装清单', smart, `inboundId=${inboundId}`, OPTIONS)
|
||||
const planId = id(smartData?.preloadPlan?.id)
|
||||
context.assert(MODULE, '智能分柜预装计划 PENDING、版本和明细正确', smart,
|
||||
smartData?.mainStatus === 'INBOUNDED' && Boolean(planId) && smartData?.preloadPlan?.status === 'PENDING'
|
||||
smartData?.mainStatus === 'WAIT_SPLIT' && Boolean(planId) && smartData?.preloadPlan?.status === 'PENDING'
|
||||
&& Number(smartData?.preloadPlan?.version) === 0 && smartData?.preloadPlan?.items?.length === 1,
|
||||
`mainStatus=${smartData?.mainStatus || 'missing'}, planId=${planId || 'missing'}, status=${smartData?.preloadPlan?.status || 'missing'}`, OPTIONS)
|
||||
if (!planId) return
|
||||
|
||||
@@ -628,7 +628,7 @@ async function unifiedOrderModule() {
|
||||
const row = pageRecords(json.data)
|
||||
.find((item) => String(item.orderId) === report.resources.terminalOrderId)
|
||||
assertPresent(row, 'unified terminal order row')
|
||||
assertEqual(row.mainStatus, 'INBOUNDED', 'unified main status')
|
||||
assertEqual(row.mainStatus, 'WAIT_SPLIT', 'unified main status')
|
||||
assertEqual(String(row.inboundId), report.resources.terminalInboundId, 'unified inbound id')
|
||||
assertEqual(row.measurement?.reviewStatus, 'APPROVED', 'unified measurement review status')
|
||||
assertTrue(Number(row.actualGrossWeightKg) > 0, 'unified actual gross weight must be positive')
|
||||
@@ -646,7 +646,7 @@ async function unifiedOrderModule() {
|
||||
}, ({ json }) => {
|
||||
requireSuccess(json)
|
||||
assertEqual(String(json.data?.summary?.orderId), report.resources.terminalOrderId, 'unified order id')
|
||||
assertEqual(json.data?.summary?.mainStatus, 'INBOUNDED', 'unified main status')
|
||||
assertEqual(json.data?.summary?.mainStatus, 'WAIT_SPLIT', 'unified main status')
|
||||
assertEqual(String(json.data?.summary?.inboundId), report.resources.terminalInboundId,
|
||||
'unified inbound id')
|
||||
assertEqual(json.data?.summary?.measurement?.reviewStatus, 'APPROVED',
|
||||
|
||||
@@ -11,8 +11,8 @@ $ErrorActionPreference = 'Stop'
|
||||
$Repo = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
|
||||
$Workspace = (Resolve-Path (Join-Path $Repo '..')).Path
|
||||
$Acceptance = Join-Path $Workspace '.codex-tmp\p23-04-acceptance'
|
||||
$ExpectedSha256 = 'BE7C5C98712D5202F5D187EA9A37C64EAB9F6AA9AE772C89A51F186507B1AE53'
|
||||
$ExpectedLines = 14706
|
||||
$ExpectedSha256 = '3E0A02C2E3B971AB7D8AB9C9D8AEE1D933F950DBCE82BD9B6AD431A4DD179F8A'
|
||||
$ExpectedLines = 14713
|
||||
|
||||
if ($TargetHost -notin @('127.0.0.1', 'localhost')) {
|
||||
[Console]::Error.WriteLine('Refusing non-local database; only 127.0.0.1 or localhost is allowed.')
|
||||
|
||||
@@ -405,16 +405,16 @@ try {
|
||||
$approvedInboundResponse = Invoke-Api GET "/api/platform/inbounds/$($ids.inboundId)?tenantId=$TenantId" $platformToken
|
||||
$approvedInbound = Require-Success '审核后回查入库单' $approvedInboundResponse
|
||||
$versions.inbound = [int]$approvedInbound.summary.version
|
||||
Require-Condition '二期边界停在 INBOUNDED' $approvedInboundResponse ($approvedInbound.summary.processStatus -eq 'INBOUNDED' -and $approvedInbound.summary.measureReviewStatus -eq 'APPROVED') "processStatus=$($approvedInbound.summary.processStatus), reviewStatus=$($approvedInbound.summary.measureReviewStatus)"
|
||||
Require-Condition '二期边界停在 WAIT_SPLIT' $approvedInboundResponse ($approvedInbound.summary.processStatus -eq 'WAIT_SPLIT' -and $approvedInbound.summary.measureReviewStatus -eq 'APPROVED') "processStatus=$($approvedInbound.summary.processStatus), reviewStatus=$($approvedInbound.summary.measureReviewStatus)"
|
||||
|
||||
$feeResponse = Invoke-Api POST "/api/platform/v1/inbounds/$($ids.inboundId)/fees/calculate?tenantId=$TenantId" $platformToken @{} @{ 'Idempotency-Key' = (New-Key 'fee-calculate') }
|
||||
$calculatedFee = Require-Success '二期计费接口试算' $feeResponse
|
||||
$ids.feeId = [string]$calculatedFee.feeId
|
||||
Require-Condition '计费试算保持 INBOUNDED 主流程边界' $feeResponse ($calculatedFee.nextProcessStatus -eq 'INBOUNDED') "nextProcessStatus=$($calculatedFee.nextProcessStatus)"
|
||||
Require-Condition '计费试算保持 WAIT_SPLIT 主流程边界' $feeResponse ($calculatedFee.nextProcessStatus -eq 'WAIT_SPLIT') "nextProcessStatus=$($calculatedFee.nextProcessStatus)"
|
||||
|
||||
$feeConfirmResponse = Invoke-Api POST "/api/platform/v1/inbounds/$($ids.inboundId)/fees/confirm?tenantId=$TenantId" $platformToken $null @{ 'Idempotency-Key' = (New-Key 'fee-confirm') }
|
||||
$confirmedFee = Require-Success '确认二期费用快照' $feeConfirmResponse
|
||||
Require-Condition '费用确认后仍保持 INBOUNDED 主流程边界' $feeConfirmResponse ($confirmedFee.feeStatus -eq 'CONFIRMED' -and $confirmedFee.nextProcessStatus -eq 'INBOUNDED') "feeStatus=$($confirmedFee.feeStatus), nextProcessStatus=$($confirmedFee.nextProcessStatus)"
|
||||
Require-Condition '费用确认后仍保持 WAIT_SPLIT 主流程边界' $feeConfirmResponse ($confirmedFee.feeStatus -eq 'CONFIRMED' -and $confirmedFee.nextProcessStatus -eq 'WAIT_SPLIT') "feeStatus=$($confirmedFee.feeStatus), nextProcessStatus=$($confirmedFee.nextProcessStatus)"
|
||||
}
|
||||
catch {
|
||||
$fatal = $_.Exception.Message
|
||||
|
||||
Reference in New Issue
Block a user