把 103–112 十个迁移收敛为五个,删除在「生产 102 → 当前」路径上的空操作与补丁: - 108(下线人工支出登记)与 109(隔离历史快照主体)在生产库和重建库上都是空操作, 口径注释并入 104; - 111 是给 104 自身种子打的补丁,合并后 104 直接写入 active 0 元占位; - 112 的 cost_exceptions.resolution_note 并入 104,退款表独立为 106; - 106(备用金编号可读化)与 110(积分钱包)合并为 107(人工履约资金层); - 107(履约方式列)并入 105,履约方式本就是销售事实的维度键。 配套调整: - check-sql-guard 改为以 main 为基线校验迁移字节,删除 103–114 的永久豁免; 未合并分支上的新迁移仍可重写,已发布迁移不可修改。 - 本地库原地改造脚本移入 docs/archive,禁止对新环境执行。 验证:清掉 schema_migrations 里 103–112 的记录后重跑,升级结果与全新构建的 schema 完全一致(pg_dump --schema-only 仅随机 token 不同),种子数据一致; 升级前后业务数据量不变(成本版本 713 → 712,差异来自删除占位草稿)。
139 lines
6.8 KiB
PL/PgSQL
139 lines
6.8 KiB
PL/PgSQL
-- ============================================================================
|
||
-- 原地改造脚本(本地库专用,2026-10-23 财务重写)
|
||
--
|
||
-- 目的:把本地库的旧派生表结构(carrier_type / cost_type)改造成新 schema
|
||
-- (cost_model / fulfillment_mode),不重建整库、不动源表。
|
||
--
|
||
-- 改造矩阵(列级 ALTER,不重建表):
|
||
-- product_catalog 删 carrier_type(来源改由 canonical_sku 前缀推导)
|
||
-- cost_items cost_type + carrier_type -> cost_model
|
||
-- cost_snapshots 删 carrier_type(履约方式 join order_items)
|
||
-- cost_exceptions 删 carrier_type(同上)
|
||
-- sales_daily_facts carrier_type -> fulfillment_mode(改名)
|
||
-- manual_expense_records cost_item_id 改 NOT NULL
|
||
-- work_product_rules 删 legacy_cost_source
|
||
-- order_items 不动(履约事实、收入固化、商品指向全部保留)
|
||
--
|
||
-- 约束:
|
||
-- 1. 源表(orders / order_items / work_orders / work_product_rules /
|
||
-- fulfillment_tasks / fund_accounts)一律不动;
|
||
-- 2. 派生表按新 schema 就地改造,历史快照与异常不重建(不丢审计痕迹);
|
||
-- 3. 执行前必须已有备份 backups/postgres/order_site_pre_rewrite_20261023.dump。
|
||
--
|
||
-- 执行:
|
||
-- docker exec -i order_site-postgres-1 psql -U postgres -d order_site \
|
||
-- -v ON_ERROR_STOP=1 < scripts/rewrite-local-db-2026-10-23.sql
|
||
-- ============================================================================
|
||
|
||
\set ON_ERROR_STOP on
|
||
BEGIN;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 1. 清掉旧迁移记录(103–114),让新迁移 103–107 重新执行
|
||
-- ---------------------------------------------------------------------------
|
||
DELETE FROM schema_migrations
|
||
WHERE name IN (
|
||
'103_product_catalog',
|
||
'104_cost_center',
|
||
'105_cost_center_bootstrap_fix',
|
||
'106_product_mapping_match_keys',
|
||
'107_product_catalog_carrier',
|
||
'108_cost_snapshot_runtime',
|
||
'109_sales_daily_facts',
|
||
'110_system_cost_items',
|
||
'111_manual_expense_records',
|
||
'112_cost_reporting_indexes',
|
||
'113_fund_account_no_readable',
|
||
'114_order_item_fulfillment_mode'
|
||
);
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 2. product_catalog:删履约载体列
|
||
-- 来源改由 canonical_sku 前缀表达(aff: / tpl: / wo: / man:)。
|
||
-- ---------------------------------------------------------------------------
|
||
DROP INDEX IF EXISTS idx_product_catalog_status_carrier;
|
||
ALTER TABLE product_catalog DROP COLUMN IF EXISTS carrier_type;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 3. cost_items:cost_type + carrier_type -> cost_model
|
||
-- 成本模型只表达「成本怎么算」,与履约方式正交。
|
||
-- ---------------------------------------------------------------------------
|
||
-- 3.1 先把编码统一到新口径,避免迁移 104 再插一条同义成本项。
|
||
UPDATE cost_items SET code = 'sys_affiliate_purchase' WHERE code = 'auto_purchase';
|
||
|
||
-- 3.2 新增 cost_model 并按旧 cost_type 映射。
|
||
ALTER TABLE cost_items ADD COLUMN IF NOT EXISTS cost_model TEXT;
|
||
UPDATE cost_items
|
||
SET cost_model = CASE cost_type
|
||
WHEN 'auto_purchase' THEN 'affiliate_purchase'
|
||
WHEN 'work_order_reward' THEN 'work_order_reward'
|
||
WHEN 'manual_service' THEN 'manual_actual'
|
||
WHEN 'platform_fee' THEN 'platform_fee'
|
||
WHEN 'payment_fee' THEN 'payment_fee'
|
||
WHEN 'after_sales_loss' THEN 'after_sales_loss'
|
||
WHEN 'shipping_other' THEN 'other'
|
||
WHEN 'other' THEN 'other'
|
||
ELSE 'other'
|
||
END
|
||
WHERE cost_model IS NULL;
|
||
|
||
-- 3.3 删旧列(CHECK 约束随列一起消失)。
|
||
ALTER TABLE cost_items DROP COLUMN IF EXISTS cost_type;
|
||
ALTER TABLE cost_items DROP COLUMN IF EXISTS carrier_type;
|
||
|
||
-- 3.4 删旧 CHECK,让迁移 104 按新枚举重建。
|
||
ALTER TABLE cost_items DROP CONSTRAINT IF EXISTS chk_cost_items_cost_type;
|
||
ALTER TABLE cost_items DROP CONSTRAINT IF EXISTS chk_cost_items_carrier_type;
|
||
ALTER TABLE cost_items DROP CONSTRAINT IF EXISTS chk_cost_items_pricing_mode;
|
||
|
||
-- 3.5 cost_model 必填。
|
||
-- 迁移 104 用 CREATE TABLE IF NOT EXISTS 建表,表已存在时不会补 NOT NULL,
|
||
-- 所以这里先补上,迁移 104 再补 CHECK 枚举。
|
||
ALTER TABLE cost_items ALTER COLUMN cost_model SET NOT NULL;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 4. cost_snapshots:删履约载体列与未被使用的 manual_case_id
|
||
-- 履约方式由 order_items.fulfillment_mode 提供,join 即可。
|
||
-- ---------------------------------------------------------------------------
|
||
ALTER TABLE cost_snapshots DROP COLUMN IF EXISTS carrier_type;
|
||
ALTER TABLE cost_snapshots DROP COLUMN IF EXISTS manual_case_id;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 5. cost_exceptions:删履约载体列
|
||
-- ---------------------------------------------------------------------------
|
||
ALTER TABLE cost_exceptions DROP COLUMN IF EXISTS carrier_type;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 6. sales_daily_facts:carrier_type -> fulfillment_mode
|
||
-- ---------------------------------------------------------------------------
|
||
ALTER TABLE sales_daily_facts DROP CONSTRAINT IF EXISTS chk_sales_daily_facts_carrier;
|
||
DROP INDEX IF EXISTS uq_sales_daily_facts_key;
|
||
ALTER TABLE sales_daily_facts RENAME COLUMN carrier_type TO fulfillment_mode;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 7. manual_expense_records:成本项必填
|
||
-- ---------------------------------------------------------------------------
|
||
ALTER TABLE manual_expense_records
|
||
ALTER COLUMN cost_item_id SET NOT NULL;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 8. work_product_rules:删旧成本回退标记
|
||
-- ---------------------------------------------------------------------------
|
||
ALTER TABLE work_product_rules DROP COLUMN IF EXISTS legacy_cost_source;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 9. 让迁移 104 按新定义重建同名索引
|
||
-- 旧 112 的两个覆盖索引定义与新 104 不同,先删后建。
|
||
-- ---------------------------------------------------------------------------
|
||
DROP INDEX IF EXISTS idx_work_orders_rule_cover;
|
||
DROP INDEX IF EXISTS idx_order_items_revenue_cover;
|
||
|
||
COMMIT;
|
||
|
||
-- ============================================================================
|
||
-- 以上是结构改造;接下来执行:
|
||
-- 1. npm run db:migrate —— 应用新迁移 103–107
|
||
-- 2. npm run fulfillment:backfill —— 重跑履约回填(幂等,NULL=0 时无操作)
|
||
-- 3. 回填脚本 / 同步脚本 —— 重跑商品、成本版本、快照与销售事实
|
||
-- ============================================================================
|