From 5bda59f94ed703f7f184e1de9a08fa09cc0e7fc3 Mon Sep 17 00:00:00 2001 From: zhaoxing <2558691827@qq.com> Date: Thu, 12 Nov 2026 16:08:47 +0800 Subject: [PATCH] =?UTF-8?q?chore(db):=20=E5=AF=84=E5=8D=96=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E8=BF=81=E7=A7=BB=E9=A1=BA=E5=BB=B6=E4=B8=BA=20159?= =?UTF-8?q?=EF=BC=8C=E9=81=BF=E5=BC=80=20main=20=E7=9A=84=20152/158=20?= =?UTF-8?q?=E7=BC=96=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/backend/src/db/migrate.test.ts | 26 ++++++++++++++----- apps/backend/src/db/migrate.ts | 14 +++++----- ...tform.sql => 159_consignment_platform.sql} | 2 +- .../consignment-match-engine-guards.test.ts | 2 +- .../consignment-profile-service.test.ts | 10 +++---- .../consignment-spec-service.test.ts | 14 +++++----- 6 files changed, 41 insertions(+), 27 deletions(-) rename apps/backend/src/db/migrations/{152_consignment_platform.sql => 159_consignment_platform.sql} (99%) diff --git a/apps/backend/src/db/migrate.test.ts b/apps/backend/src/db/migrate.test.ts index 33870a74..e1805c36 100644 --- a/apps/backend/src/db/migrate.test.ts +++ b/apps/backend/src/db/migrate.test.ts @@ -33,7 +33,7 @@ test('迁移归一化:生产旧命名 147–152 全部清理,152 未登记 ]) }) -test('迁移归一化:dev 顺延后的 152–158 一并清理(含已登记的 152)', () => { +test('迁移归一化:dev 旧命名 152–158 一并清理(含已登记的 152)', () => { const stale = planLegacyConsignmentMigrationCleanup([ '001_init', '146_voucher_consume_fallback_channel', @@ -47,17 +47,29 @@ test('迁移归一化:dev 顺延后的 152–158 一并清理(含已登记 ]) assert.deepEqual(stale, [ + '152_consignment_platform', '153_consignment_sms_logs', '154_consignment_inventory_category_backfill', '155_work_order_consignment_original_reward', '156_work_order_internal_matching_deadline_guard', '157_consignment_internal_match_cleanup', '158_consignment_match_log_snapshot', - '152_consignment_platform', ]) }) -test('迁移归一化:main 147–151 与 152 都已登记时不做任何清理', () => { +test('迁移归一化:main 147–152、158 已登记且无旧寄卖记录时不清理', () => { + const stale = planLegacyConsignmentMigrationCleanup([ + '001_init', + '146_voucher_consume_fallback_channel', + ...MAIN_MIGRATIONS, + '152_order_source_facts_immutable', + '158_consignment_worker_name_sync', + ]) + + assert.deepEqual(stale, []) +}) + +test('迁移归一化:旧 152 已登记时清理记录,让 159 按新顺序重跑', () => { const stale = planLegacyConsignmentMigrationCleanup([ '001_init', '146_voucher_consume_fallback_channel', @@ -65,7 +77,7 @@ test('迁移归一化:main 147–151 与 152 都已登记时不做任何清理 '152_consignment_platform', ]) - assert.deepEqual(stale, []) + assert.deepEqual(stale, ['152_consignment_platform']) }) test('迁移归一化:main 已执行、只剩旧寄卖记录时只清理旧名字', () => { @@ -79,12 +91,12 @@ test('迁移归一化:main 已执行、只剩旧寄卖记录时只清理旧名 assert.deepEqual(stale, ['147_consignment_platform', '148_consignment_sms_logs']) }) -test('迁移归一化:152 已登记但 main 147–151 缺失时,152 也要重跑', () => { +test('迁移归一化:159 已登记但 main 147–151 缺失时,159 也要重跑', () => { const stale = planLegacyConsignmentMigrationCleanup([ '001_init', '146_voucher_consume_fallback_channel', - '152_consignment_platform', + '159_consignment_platform', ]) - assert.deepEqual(stale, ['152_consignment_platform']) + assert.deepEqual(stale, ['159_consignment_platform']) }) diff --git a/apps/backend/src/db/migrate.ts b/apps/backend/src/db/migrate.ts index 44064349..8352339f 100644 --- a/apps/backend/src/db/migrate.ts +++ b/apps/backend/src/db/migrate.ts @@ -25,8 +25,8 @@ const MIGRATIONS_TABLE = 'schema_migrations' const SHORT_NUMERIC_PREFIX_MESSAGE = /^Can't determine timestamp for \d+$/ const MIGRATION_FILE_PATTERN = /^(\d{3})_.+\.sql$/i -/** 合并后的寄卖迁移文件名(不含 .sql);main 147–151 保持原编号。 */ -const CONSOLIDATED_CONSIGNMENT_MIGRATION = '152_consignment_platform' +/** 合并后的寄卖迁移文件名(不含 .sql);main 的 147–152、158 保持原编号,寄卖合并文件顺延到 159。 */ +const CONSOLIDATED_CONSIGNMENT_MIGRATION = '159_consignment_platform' const MAIN_MIGRATIONS_BEFORE_CONSIGNMENT = [ '147_internal_sku_product_routing', '148_fulfillment_execution_truth', @@ -39,7 +39,8 @@ const MAIN_MIGRATIONS_BEFORE_CONSIGNMENT = [ * 历史上寄卖迁移用过两套编号,且都已被部分环境登记过: * - 147_consignment_platform … 152_consignment_internal_match_cleanup(生产当前状态) * - 152_consignment_platform … 158_consignment_match_log_snapshot(dev 顺延后、合并前) - * 合并后统一为 152_consignment_platform,这些旧名字必须从 schema_migrations 清掉。 + * 合并 main 后 152/158 已被 main 的迁移占用,寄卖合并文件统一为 159_consignment_platform, + * 这些旧名字必须从 schema_migrations 清掉。 */ const LEGACY_CONSIGNMENT_MIGRATION_NAMES = [ '147_consignment_platform', @@ -48,6 +49,7 @@ const LEGACY_CONSIGNMENT_MIGRATION_NAMES = [ '150_work_order_consignment_original_reward', '151_work_order_internal_matching_deadline_guard', '152_consignment_internal_match_cleanup', + '152_consignment_platform', '153_consignment_match_log_snapshot', '153_consignment_sms_logs', '154_consignment_inventory_category_backfill', @@ -170,9 +172,9 @@ function assertMigrationFilesOrdered() { * 计算需要从 schema_migrations 清理的旧寄卖迁移记录(纯函数,便于单测)。 * * node-pg-migrate 的 checkOrder 是按位置逐项比对「已执行列表(ORDER BY run_on, id)」和 - * 「本地迁移文件列表」,因此只改名/改 run_on 都不够:只要 152 已登记而 main 147–151 未登记, - * 152 就会占据第 147 个位置,和 147_internal_sku_product_routing 比对失败。 - * 唯一稳妥的做法是删掉旧记录,让 147–152 按新文件顺序重新执行;152 内容幂等。 + * 「本地迁移文件列表」,因此只改名/改 run_on 都不够:只要 159 已登记而 main 147–152 未登记, + * 159 就会占据错误位置,和 147_internal_sku_product_routing 比对失败。 + * 唯一稳妥的做法是删掉旧记录,让 147–159 按新文件顺序重新执行;152/159 内容幂等。 */ export function planLegacyConsignmentMigrationCleanup(appliedNames: readonly string[]): string[] { const applied = new Set(appliedNames) diff --git a/apps/backend/src/db/migrations/152_consignment_platform.sql b/apps/backend/src/db/migrations/159_consignment_platform.sql similarity index 99% rename from apps/backend/src/db/migrations/152_consignment_platform.sql rename to apps/backend/src/db/migrations/159_consignment_platform.sql index 1bc61866..292371fc 100644 --- a/apps/backend/src/db/migrations/152_consignment_platform.sql +++ b/apps/backend/src/db/migrations/159_consignment_platform.sql @@ -1,4 +1,4 @@ --- 152_consignment_platform.sql(原 147_consignment_platform;153–158 已合并入本文件,main 保留 147–151 后顺延) +-- 159_consignment_platform.sql(原 152_consignment_platform;main 的 147–152、158 保持原编号,本文件顺延) -- 2026-11-09 合并:短信日志 / 分类回填 / 原始报酬 / 截止时间不变量 / 内部匹配清理 / 匹配日志快照。 -- 寄卖平台完整迁移(原 142–148 收敛为一个文件,2026-11-06) -- 142 寄卖配置/库存/内部匹配 diff --git a/apps/backend/src/services/worker-platform/consignment-match-engine-guards.test.ts b/apps/backend/src/services/worker-platform/consignment-match-engine-guards.test.ts index e8073df7..971fc986 100644 --- a/apps/backend/src/services/worker-platform/consignment-match-engine-guards.test.ts +++ b/apps/backend/src/services/worker-platform/consignment-match-engine-guards.test.ts @@ -12,7 +12,7 @@ const ISSUE_REPO = new URL( import.meta.url, ) const FULFILLMENT = new URL('./consignment-fulfillment-service.ts', import.meta.url) -const MIGRATION = new URL('../../db/migrations/152_consignment_platform.sql', import.meta.url) +const MIGRATION = new URL('../../db/migrations/159_consignment_platform.sql', import.meta.url) test('手动匹配不再在事务外改状态:数量不足/并发占库失败不能留下无截止时间的 internal_matching', async () => { const source = await readFile(ENGINE, 'utf8') diff --git a/apps/backend/src/services/worker-platform/consignment-profile-service.test.ts b/apps/backend/src/services/worker-platform/consignment-profile-service.test.ts index f1323208..1e64db2a 100644 --- a/apps/backend/src/services/worker-platform/consignment-profile-service.test.ts +++ b/apps/backend/src/services/worker-platform/consignment-profile-service.test.ts @@ -149,9 +149,9 @@ test('降价提示:未售出时长支持一位小数,按小数小时判断', assert.equal(suggestion?.suggestedPriceFen, 9_000) }) -test('合并迁移 152 必须包含寄卖配置、库存数量/售价与分配表', async () => { +test('合并迁移 159 必须包含寄卖配置、库存数量/售价与分配表', async () => { const source = await readFile( - new URL('../../db/migrations/152_consignment_platform.sql', import.meta.url), + new URL('../../db/migrations/159_consignment_platform.sql', import.meta.url), 'utf8', ) for (const fragment of [ @@ -163,7 +163,7 @@ test('合并迁移 152 必须包含寄卖配置、库存数量/售价与分配 'internal_match_deadline_at', 'consignment_inventory_id', ]) { - assert.ok(source.includes(fragment), `合并迁移 152 缺少 ${fragment}`) + assert.ok(source.includes(fragment), `合并迁移 159 缺少 ${fragment}`) } }) @@ -214,9 +214,9 @@ test('寄售数量上限按分类统计,并在打手配置接口返回 activeQ assert.ok(source.includes('GROUP BY profile_id'), '各分类数量必须一次分组取回') }) -test('合并迁移 152 的苏尔南种子:降价提示默认开启、24 小时、按比例 10%', async () => { +test('合并迁移 159 的苏尔南种子:降价提示默认开启、24 小时、按比例 10%', async () => { const sql = await readFile( - new URL('../../db/migrations/152_consignment_platform.sql', import.meta.url), + new URL('../../db/migrations/159_consignment_platform.sql', import.meta.url), 'utf8', ) assert.match( diff --git a/apps/backend/src/services/worker-platform/consignment-spec-service.test.ts b/apps/backend/src/services/worker-platform/consignment-spec-service.test.ts index 79f91540..8713ebf3 100644 --- a/apps/backend/src/services/worker-platform/consignment-spec-service.test.ts +++ b/apps/backend/src/services/worker-platform/consignment-spec-service.test.ts @@ -36,7 +36,7 @@ function option(label: string, value: string) { return { label, value, enabled: true } } -/** 苏尔南手枪种子配置的五个字段(与合并迁移 152 一致)。 */ +/** 苏尔南手枪种子配置的五个字段(与合并迁移 159 一致)。 */ function surnanSpecs(): ConsignmentSpecField[] { return [ { @@ -522,9 +522,9 @@ test('动态规格:旧列仍由兼容 key 同步', () => { }) }) -test('合并迁移 152 必须包含动态规格的 JSON、匹配 key、文本与改价上限', async () => { +test('合并迁移 159 必须包含动态规格的 JSON、匹配 key、文本与改价上限', async () => { const sql = await readFile( - new URL('../../db/migrations/152_consignment_platform.sql', import.meta.url), + new URL('../../db/migrations/159_consignment_platform.sql', import.meta.url), 'utf8', ) for (const fragment of [ @@ -534,7 +534,7 @@ test('合并迁移 152 必须包含动态规格的 JSON、匹配 key、文本与 'price_cap_fen', 'CREATE INDEX IF NOT EXISTS idx_consignment_inventories_spec_key', ]) { - assert.ok(sql.includes(fragment), `合并迁移 152 缺少 ${fragment}`) + assert.ok(sql.includes(fragment), `合并迁移 159 缺少 ${fragment}`) } }) @@ -549,9 +549,9 @@ test('发布数量:关闭「允许修改寄售数量」时固定为 1,开启 assert.equal(resolveConsignmentPublishQuantity(true, 1.6), 2, '四舍五入') }) -test('合并迁移 152 必须为苏尔南手枪写入已发布的五个单选字段配置', async () => { +test('合并迁移 159 必须为苏尔南手枪写入已发布的五个单选字段配置', async () => { const sql = await readFile( - new URL('../../db/migrations/152_consignment_platform.sql', import.meta.url), + new URL('../../db/migrations/159_consignment_platform.sql', import.meta.url), 'utf8', ) for (const fragment of [ @@ -561,6 +561,6 @@ test('合并迁移 152 必须为苏尔南手枪写入已发布的五个单选字 "'published'", '"key": "brillianceCount"', ]) { - assert.ok(sql.includes(fragment), `合并迁移 152 缺少 ${fragment}`) + assert.ok(sql.includes(fragment), `合并迁移 159 缺少 ${fragment}`) } })