-- ============================================================================ -- 原地改造脚本(本地库专用,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. 回填脚本 / 同步脚本 —— 重跑商品、成本版本、快照与销售事实 -- ============================================================================