feat(fleet): attach scoped evidence to measured trip records

This commit is contained in:
2026-10-03 16:38:37 +08:00
parent d05ff1cd26
commit e49ad96cc4
22 changed files with 584 additions and 27 deletions
@@ -123,6 +123,15 @@ test('independent runner requires explicit service readiness and only the specif
assert.throws(() => requireReady([`--ready-commit=${READY_COMMIT}`], [`--env-file=${env.replace('test-acceptance', 'dev-acceptance')}`]), /授权目录/)
assert.ok(requireReady([`--ready-commit=${READY_COMMIT}`], [`--env-file=${env}`]).endsWith('test-acceptance.env'))
})
test('readiness gate accepts only the full production anchor, not old anchors, shorthand or another commit', () => {
const profile = ['--env-file=C:/Users/BY-OY/.codex/env/chongchong-global/test-acceptance.env']
assert.equal(READY_COMMIT, '8700fc34238bc33339351c73c15f3af8de8ce517')
for (const commit of ['a6fd0ba3', 'cb6c54ff', '8700fc34', 'd05ff1cd', `${READY_COMMIT}0`]) {
assert.throws(() => requireReady([`--ready-commit=${commit}`], profile), /就绪/)
}
assert.ok(requireReady([`--ready-commit=${READY_COMMIT}`], profile).endsWith('test-acceptance.env'))
})
test('company cost verifier exercises CNY/USD, void/rebuild, payment replay and customer isolation without direct transport', async () => {
const { context, calls, vehicles, records, costs } = fixture()
await run(context, options)
@@ -8,7 +8,7 @@ function harness(fault) {
const marker = 'FLEET-CURRENT-RUN', tripNo = 'TR-CURRENT', departedAt = '2026-10-03T01:00:00Z'
const rows = new Map(), histories = new Map(), commands = new Map(), measuredKeys = new Map(), calls = []
let next = 0, supplierStatus = 'ACTIVE'
let measured = { tripNo, recordVersion: '0', details: { actualDistanceMiles: null, actualFuelLitres: null, remark: null } }
let measured = { tripNo, recordVersion: '0', details: { actualDistanceMiles: null, actualFuelLitres: null, remark: null, evidenceFiles: [] } }
const measuredHistory = []
const expected = { physicalPallets: 1, palletSpaces: 2, ownPackages: 11, externalPackages: 4, externalAgreedAmounts: [{ currency: 'USD', amount: 0 }], costs: [] }
const response = (data, code = '200', http = 200) => ({ http, body: { code, data: copy(data) }, requestId: 'offline-request', traceId: 'offline-trace' })
@@ -75,7 +75,9 @@ function harness(fault) {
const prior = measuredKeys.get(body.idempotencyKey)
if (prior) { if (fault === 'measured replay adds history') measuredHistory.push(copy(measured)); return response(prior) }
if (String(body.recordVersion) !== measured.recordVersion) return response(null, 'A0409')
measured = { tripNo, recordVersion: String(Number(measured.recordVersion) + 1), details: copy(body.details) }
assert.deepEqual(body.details.evidenceFileIds, []); assert.equal(Object.hasOwn(body.details, 'evidenceFiles'), false)
const { evidenceFileIds, ...values } = body.details
measured = { tripNo, recordVersion: String(Number(measured.recordVersion) + 1), details: { ...copy(values), evidenceFiles: [] } }
measuredKeys.set(body.idempotencyKey, copy(measured)); measuredHistory.unshift(copy(measured)); return response(measured)
}
if (p === '/api/platform/v1/last-leg/fleet/operations') {
@@ -285,12 +285,12 @@ async function execute(context, { scope, writeMeasured = false, idempotencyNames
const recordPath = `${OPERATIONS}/${encode(fixture.tripNo)}/record`
const initial = await command('GET', recordPath, undefined, '核对本轮车次尚无实测记录')
check('禁止覆盖已有实测历史样本', null, id(initial.recordVersion) === '0' && initial.details.actualDistanceMiles == null && initial.details.actualFuelLitres == null)
const measured = { recordVersion: initial.recordVersion, idempotencyKey: key('measured-zero'), details: { actualDistanceMiles: 0, actualFuelLitres: null, remark: context.marker }, reason: null }
const measured = { recordVersion: initial.recordVersion, idempotencyKey: key('measured-zero'), details: { actualDistanceMiles: 0, actualFuelLitres: null, remark: context.marker, evidenceFileIds: [] }, reason: null }
const first = await command('PUT', recordPath, measured, '登记明确零里程和未知油耗')
check('实测明确零值不变成未填写', null, first.details.actualDistanceMiles != null && Number(first.details.actualDistanceMiles) === 0 && first.details.actualFuelLitres == null)
const firstAgain = await command('PUT', recordPath, measured, '重放实测保存')
check('实测重放保留原版本', null, id(firstAgain.recordVersion) === id(first.recordVersion))
const corrected = await command('PUT', recordPath, { recordVersion: first.recordVersion, idempotencyKey: key('measured-correct'), details: { actualDistanceMiles: 25.5, actualFuelLitres: 8.2, remark: context.marker }, reason: '核对受控实测' }, '更正实测里程油耗')
const corrected = await command('PUT', recordPath, { recordVersion: first.recordVersion, idempotencyKey: key('measured-correct'), details: { actualDistanceMiles: 25.5, actualFuelLitres: 8.2, remark: context.marker, evidenceFileIds: [] }, reason: '核对受控实测' }, '更正实测里程油耗')
await reject('PUT', recordPath, { ...measured, idempotencyKey: key('measured-stale') }, 'A0409', '旧实测版本拒绝')
const measuredHistory = await command('GET', `${recordPath}/history?page=1&size=20`, undefined, '读取实测更正历史')
check('实测重放与冲突没有追加历史', null, Number(measuredHistory.total) === 2 && version(corrected.recordVersion) === version(first.recordVersion) + 1n)