From 41d8387cd50d51c530b89aba0218531280cad92f Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Tue, 29 Sep 2026 15:06:42 +0800 Subject: [PATCH] test: align acceptance contracts with current initialization and service clients --- ...t-prototype-field-matrix-contract.test.mjs | 2 +- ...merged-overseas-coverage-contract.test.mjs | 2 +- ...se3-container-regression-contract.test.mjs | 2 +- scripts/overseas-deployment-contract.test.mjs | 34 +++++++++---------- scripts/synchronous-dependency-baseline.mjs | 8 +++++ .../synchronous-dependency-contract.test.mjs | 9 ++--- 6 files changed, 32 insertions(+), 25 deletions(-) diff --git a/scripts/admin-test-env-modules/fulfillment-prototype-field-matrix-contract.test.mjs b/scripts/admin-test-env-modules/fulfillment-prototype-field-matrix-contract.test.mjs index 059d2c520..dfc1239ed 100644 --- a/scripts/admin-test-env-modules/fulfillment-prototype-field-matrix-contract.test.mjs +++ b/scripts/admin-test-env-modules/fulfillment-prototype-field-matrix-contract.test.mjs @@ -123,7 +123,7 @@ test('字段断言接入正式生产模块和默认全量入口', () => { }) test('矩阵登记 LANDED 与 UNKNOWN 且禁止 fixture 伪造未知字段', () => { - const matrix = read(workspace, 'docs', '国内货柜履约', '货柜履约原型字段验收矩阵-2026-08-17.md') + const matrix = read(workspace, 'docs', '国内货柜履约', '归档', '货柜履约原型字段验收矩阵-2026-08-17.md') assert.match(matrix, /LANDED/) assert.match(matrix, /UNKNOWN/) assert.match(matrix, /不得由 fixture 伪造|不生成假值/) diff --git a/scripts/admin-test-env-modules/merged-overseas-coverage-contract.test.mjs b/scripts/admin-test-env-modules/merged-overseas-coverage-contract.test.mjs index b271ee44a..ccbe7dbb7 100644 --- a/scripts/admin-test-env-modules/merged-overseas-coverage-contract.test.mjs +++ b/scripts/admin-test-env-modules/merged-overseas-coverage-contract.test.mjs @@ -28,7 +28,7 @@ test('transfer review integration covers both source types and known blank-reaso const source = await read('warehouse-transfer-review.mjs') const caller = await read('phase4-overseas-client-services.mjs') assert.match(caller, /return verifyWarehouseTransferReview\(context, token, order.row.customerId, body, transferNo\)/) - for (const value of ['WAIT_PDA_RECEIVING', 'PENDING_ASSIGNMENT', 'WAIT_DELIVERY', 'CANCELLED', + for (const value of ['WAIT_PDA_RECEIVING', 'INBOUND_MEASURING', 'CANCELLED', 'REJECTED', 'APPROVED', 'customerId=', 'rejected(denied, 403)', 'rejected(missingScope, 400)', 'rejected(reverse, 409)', 'rejected(emptyReason, 400)', "sourceLastlegOrderIds: []"]) assert.ok(source.includes(value), value) diff --git a/scripts/admin-test-env-modules/phase3-container-regression-contract.test.mjs b/scripts/admin-test-env-modules/phase3-container-regression-contract.test.mjs index ff083903f..211ec91ec 100644 --- a/scripts/admin-test-env-modules/phase3-container-regression-contract.test.mjs +++ b/scripts/admin-test-env-modules/phase3-container-regression-contract.test.mjs @@ -22,7 +22,7 @@ const containerOverviewPanel = read(`${adminRoot}container-loading/components/Co const containerLoadingAcceptance = read('phase3-container-loading.mjs') const phase3LoadingAcceptance = read('phase3-loading.mjs') const truckAcceptance = read('truck-appointments.mjs') -const matrix = read('../../../docs/国内货柜履约/货柜管理全链验收矩阵-2026-08-13.md') +const matrix = read('../../../docs/国内货柜履约/归档/货柜管理全链验收矩阵-2026-08-13.md') test('container acceptance reads the canonical domestic workbench route', () => { assert.match(containerLoadingAcceptance, /const DOMESTIC_CONTAINERS = `\$\{CONTAINERS\}\/domestic`/) diff --git a/scripts/overseas-deployment-contract.test.mjs b/scripts/overseas-deployment-contract.test.mjs index 33ad829cf..4f294563b 100644 --- a/scripts/overseas-deployment-contract.test.mjs +++ b/scripts/overseas-deployment-contract.test.mjs @@ -152,16 +152,17 @@ test('domestic Auth receives the overseas JWT signing configuration', async () = ]) assert.match(compose, new RegExp(`${key}: \\$\\{${key}`)) }) -test('domestic event bridge SQL converges legacy tenant columns to the customer entity contract', async () => { +test('domestic event bridge initialization defines customer columns without legacy migration', async () => { const baseline = await read('event-bridge-service/src/main/resources/db/event-bridge.sql') const incremental = await read('deploy/sql/头程数据库统一增量-MySQL8.sql') assert.equal((baseline.match(/customer_id VARCHAR\(128\) NOT NULL/g) || []).length, 2) - assert.equal((incremental.slice(0, incremental.indexOf('CREATE TABLE IF NOT EXISTS bridge_delivery_attempt')) - .match(/customer_id VARCHAR\(128\) NOT NULL/g) || []).length, 2) - assert.match(incremental, /ALTER TABLE bridge_inbox RENAME COLUMN tenant_id TO customer_id/) - assert.match(incremental, /ALTER TABLE bridge_outbox RENAME COLUMN tenant_id TO customer_id/) - assert.match(incremental, /bridge_inbox_customer_column = 0 AND @bridge_inbox_tenant_column = 1/) - assert.match(incremental, /bridge_outbox_customer_column = 0 AND @bridge_outbox_tenant_column = 1/) + for (const table of ['bridge_inbox', 'bridge_outbox']) { + const definition = incremental.match(new RegExp(`CREATE TABLE ${table} \\(([\\s\\S]*?)\\) ENGINE`))?.[1] + assert.ok(definition, `${table} must be defined by the empty-database baseline`) + assert.match(definition, /customer_id varchar\(128\)[^\n]*NOT NULL/i) + assert.doesNotMatch(definition, /\btenant_id\b/) + } + assert.doesNotMatch(incremental, /RENAME COLUMN tenant_id TO customer_id/) }) test('both overseas PDF consumers explicitly connect to the existing CN Print service', async () => { @@ -176,15 +177,12 @@ test('both overseas PDF consumers explicitly connect to the existing CN Print se } }) -test('domestic unified SQL creates the overseas hold version before queuing its comment', async () => { +test('domestic initialization defines the overseas hold version and comment in the table', async () => { const incremental = await read('deploy/sql/头程数据库统一增量-MySQL8.sql') - const addColumn = incremental.indexOf('CALL add_inbound_overseas_hold_version();') - const queueComment = incremental.indexOf("CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_order', 'last_overseas_hold_version'") - - assert.notEqual(addColumn, -1) - assert.notEqual(queueComment, -1) - assert.ok(addColumn < queueComment, - 'existing databases must add last_overseas_hold_version before the strict comment queue reads it') + const definition = incremental.match(/CREATE TABLE fl_inbound_order \(([\s\S]*?)\) ENGINE/)?.[1] + assert.ok(definition) + assert.match(definition, /last_overseas_hold_version bigint unsigned DEFAULT NULL COMMENT '[^']+'/i) + assert.doesNotMatch(incremental, /CALL (?:add_inbound_overseas_hold_version|queue_column_comment)\(/) }) test('overseas unified SQL initializes the isolated Event Bridge database before services start', async () => { @@ -192,15 +190,15 @@ test('overseas unified SQL initializes the isolated Event Bridge database before assert.match(overseas, /CREATE DATABASE IF NOT EXISTS baiyue_event_bridge_overseas/) assert.match(overseas, /USE baiyue_event_bridge_overseas;/) for (const table of ['bridge_outbox', 'bridge_inbox', 'bridge_delivery_attempt']) { - assert.match(overseas, new RegExp(`CREATE TABLE IF NOT EXISTS ${table}`)) + assert.match(overseas, new RegExp(`CREATE TABLE ${table} \\(`)) } for (const index of [ 'uk_bridge_outbox_idempotency', 'idx_bridge_outbox_schedule', 'uk_bridge_inbox_idempotency', 'idx_bridge_inbox_consume', 'uk_bridge_attempt', 'idx_bridge_attempt_event' ]) assert.match(overseas, new RegExp(index)) - assert.match(overseas, /COUNT\(DISTINCT CONCAT\(table_name, ':', index_name\)\)/) - assert.match(overseas, /CALL assert_overseas_event_bridge_schema\(\);/) + assert.doesNotMatch(overseas, /CREATE TABLE IF NOT EXISTS/) + assert.match(overseas, /initialization_status/) assert.ok(overseas.indexOf('USE baiyue_event_bridge_overseas;') < overseas.indexOf('USE baiyue_lastleg;'), 'overseas Event Bridge schema must be initialized before Lastleg tables') }) diff --git a/scripts/synchronous-dependency-baseline.mjs b/scripts/synchronous-dependency-baseline.mjs index 1c7845f0f..977e42208 100644 --- a/scripts/synchronous-dependency-baseline.mjs +++ b/scripts/synchronous-dependency-baseline.mjs @@ -15,6 +15,14 @@ const http = (path, source, target, contexts, access, idempotency, note) => ({ }) export const SYNCHRONOUS_CLIENTS = Object.freeze([ + feign('firstleg/src/main/java/com/baiyue/firstleg/client/DomesticPdaOperatorClient.java', + 'firstleg-service', 'iam-service', ['REQUEST'], 'READ', 'SAFE_READ', '按作业仓与账号查询有效国内 PDA 操作人,内部服务令牌保护'), + feign('order/src/main/java/com/baiyue/order/client/LegacyImportPricingClient.java', + 'order-service', 'firstleg-service', ['REQUEST'], 'READ', 'SAFE_READ', '历史订单导入按客户与始发仓只读匹配渠道'), + feign('order/src/main/java/com/baiyue/order/client/LegacyImportWarehouseClient.java', + 'order-service', 'warehouse-service', ['REQUEST'], 'READ', 'SAFE_READ', '历史订单导入只读匹配仓库目录'), + http('lastleg-service/src/main/java/com/baiyue/lastleg/transfer/gateway/HttpTransferMeasurementPhotoFileGateway.java', + 'lastleg-service', 'file-service', ['REQUEST'], 'READ_WRITE', 'MIXED', '转仓测量照片上传无幂等键,元数据与下载按客户、业务类型和转仓单校验归属'), feign('lastleg-service/src/main/java/com/baiyue/lastleg/client/PrintPdfClient.java', 'lastleg-service', 'print-service', ['REQUEST'], 'READ', 'SAFE_READ', '根据已授权排车快照生成 BOL PDF,内部令牌保护,无业务状态写入'), feign('auth/src/main/java/com/baiyue/auth/client/IamAuthorizationClient.java', diff --git a/scripts/synchronous-dependency-contract.test.mjs b/scripts/synchronous-dependency-contract.test.mjs index bb70439d8..d94f07c7c 100644 --- a/scripts/synchronous-dependency-contract.test.mjs +++ b/scripts/synchronous-dependency-contract.test.mjs @@ -101,15 +101,15 @@ async function discoverFeignEdges() { return clients.sort((left, right) => left.path.localeCompare(right.path)) } -test('all 60 Feign clients have reviewed context, access and idempotency metadata', async () => { +test('all Feign clients have reviewed context, access and idempotency metadata', async () => { const reviewed = SYNCHRONOUS_CLIENTS.filter(client => client.transport === 'FEIGN') .map(({ path, source, target }) => ({ path, source, target })) .sort((left, right) => left.path.localeCompare(right.path)) - assert.equal(reviewed.length, 60) + assert.equal(reviewed.length, 63) assert.deepEqual(await discoverFeignEdges(), reviewed) }) -test('all 23 raw HTTP transports have reviewed context, access and idempotency metadata', async () => { +test('all raw HTTP transports have reviewed context, access and idempotency metadata', async () => { const discovered = [] for (const module of ['common-audit', 'event-bridge-service', 'gateway-overseas', 'lastleg-service', 'integration-service']) { for (const file of await javaFiles(path.join(root, module, 'src', 'main', 'java'))) { @@ -121,7 +121,7 @@ test('all 23 raw HTTP transports have reviewed context, access and idempotency m } const reviewed = SYNCHRONOUS_CLIENTS.filter(client => client.transport === 'HTTP') .map(client => client.path).sort() - assert.equal(reviewed.length, 23) + assert.equal(reviewed.length, 24) assert.deepEqual(discovered.sort(), reviewed) }) @@ -224,6 +224,7 @@ test('Order, Firstleg and Finance form the reviewed REQUEST SCC', () => { 'order/src/main/java/com/baiyue/order/client/FirstlegInboundClient.java', 'order/src/main/java/com/baiyue/order/client/FirstlegPricingClient.java', 'order/src/main/java/com/baiyue/order/client/FirstlegUnifiedOrderClient.java', + 'order/src/main/java/com/baiyue/order/client/LegacyImportPricingClient.java', 'order/src/main/java/com/baiyue/order/client/MerchantPricingCatalogClient.java' ]) assert.deepEqual(firstlegToOrder.map(client => client.path).sort(), [