Files
order_site/docs/archive/2026-10-23/2026-10-23-本地库原地改造.sql
T
yml2213 472769a977 refactor(db): 财务迁移收敛为 103–107
把 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,差异来自删除占位草稿)。
2026-10-25 11:38:12 +08:00

139 lines
6.8 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ============================================================================
-- 原地改造脚本(本地库专用,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. 回填脚本 / 同步脚本 —— 重跑商品、成本版本、快照与销售事实
-- ============================================================================