重构:统一财务派生数据真源与重建

This commit is contained in:
yml2213
2026-11-08 19:44:27 +08:00
parent bae9a5ae5e
commit f8cbb645fe
14 changed files with 1011 additions and 541 deletions
@@ -3,7 +3,7 @@ type: 权威架构与实施计划
description: 订单、内部 SKU、履约路由、履约执行、商品、成本与财务的唯一权威口径及重构计划。
tags: [订单, 内部SKU, 履约, 商品, 成本, 财务, 迁移]
status: authoritative
version: 2.0
version: 2.1
updated_at: 2026-11-08
---
@@ -12,7 +12,7 @@ updated_at: 2026-11-08
> 状态:**唯一权威文档**。
> 最后校准:2026-11-08。
> 生产基线:迁移 `146`。
> 开发基线:迁移 `166`(仅本地,尚未部署生产)。
> 开发基线:迁移 `167`(仅本地,尚未部署生产)。
>
> 从本文件生效起,订单、内部 SKU、履约渠道、履约载体、标准商品、成本和财务相关实现,
> 只能以本文件为业务口径。其他旧分析只作为历史资料,不再具备设计或验收效力。
@@ -332,7 +332,7 @@ finance_journal_* -- 总账凭证,可重建
2026-11-08 生产只读核对结果:
- 生产迁移 `146`,本地开发基线迁移 `166`。
- 生产迁移 `146`,本地开发基线迁移 `167`。
- 启用标准商品 `1127`:`aff:` 30、`tpl:` 903、`tpv:` 46、`man:` 148。
- `man:` 商品中只有 105 个当前主渠道为人工;41 个已走其他主渠道,2 个无主渠道。
- 人工页头部显示 `107`,商品列表显示 `148`,相差的 41 个就是跨渠道旧商品。
@@ -395,7 +395,8 @@ A 级数据只能追加新事件或做字段兼容迁移,不能为了“模型
- `cost_snapshots`
- `cost_exceptions`
- `sales_daily_facts`
- `finance_journal_entries` / `finance_journal_lines`
- `finance_journal_entries` / `finance_journal_lines` 仅允许在空库或明确废弃的测试库重建;
已有环境的已过账凭证不得删除,只能追加反向/补差凭证
- `v_fulfillment_item_state` 及其依赖投影
- 商品统计投影、渠道统计投影、页面汇总缓存
- 管道水位与失败重试状态
@@ -531,7 +532,7 @@ has_active_cost
| 2 建立目标身份与投影 | 本地完成 | 只新增结构 |
| 3 迁移路由与商品配置 | 本地完成,生产未执行 | 是,需备份 |
| 4 重建履约模型 | 本地完成,生产未执行 | 是,需备份 |
| 5 重建财务派生数据 | 未开始 | 是,需备份与对账 |
| 5 重建财务派生数据 | 本地完成,生产未执行 | 是,需备份与对账 |
| 6 停止旧写路径并删除兼容层 | 履约侧已完成,全局未开始 | 是,需观察期结束 |
### 阶段 0:口径冻结与文档收口
@@ -609,6 +610,8 @@ assigned 且 carrier_status=missing 必须进入异常队列
- 迁移 `165`:履约事件只阻止 UPDATE,数据库级联删除不再被 append-only 触发器阻断。
- 迁移 `166`:无法解析内部 SKU 时,正式履约行的 `internal_sku` 统一落空字符串,
并进入 `missing_internal_sku` 异常,而不是触发非空约束。
- 迁移 `167`:建立 `v_finance_order_item_scope`,统一销售事实、重建与审计的收入、
退款、商品、渠道和业务日口径;增加销售凭证按日查询索引。
- 商品列表、总览、渠道映射和商品下拉统一读取商品当前渠道。
- 运行期代码停止写入 `product_channel_capabilities`,该表仅保留到兼容期结束。
- 只读审计:`npm run audit:product-routing -- --strict`。
@@ -616,7 +619,7 @@ assigned 且 carrier_status=missing 必须进入异常队列
- 自动/卡券/接单主渠道商品的人工配置均保留为显式 `fallback`,没有被误升为人工主渠道。
- 1 个无主路由、无人工配置、无启用映射的 `man:` 商品已归档,未删除历史引用。
- 旧 `internal_sku_channels` 已冻结:运行时不再读、不再写,也不再有视图或触发器依赖。
- 空库从迁移 `001` 顺序执行到 `166` 已通过;新库不再保留任何旧履约影子同步触发器。
- 空库从迁移 `001` 顺序执行到 `167` 已通过;新库不再保留任何旧履约影子同步触发器。
- 无主路由的活动商品会进入“未路由”,不自动猜测渠道。
当前本地仍需业务处理的数据:
@@ -676,7 +679,7 @@ assigned 且 carrier_status=missing 必须进入异常队列
5. 全部业务读 SQL 切到 `v_order_item_current`,禁止直接读取订单项旧状态列。
6. 状态事件、任务尝试、工单尝试和配置变化触发器统一围绕正式履约表工作。
7. 真实 PostgreSQL 集成测试覆盖状态写入、幂等、事件留痕、当前尝试和配置关联。
8. 本地存量库与空库 `001 → 166` 均完成硬切验证。
8. 本地存量库与空库 `001 → 167` 均完成硬切验证。
验收:
@@ -690,6 +693,8 @@ assigned 且 carrier_status=missing 必须进入异常队列
### 阶段 5:重建财务派生数据
状态:本地完成,生产未执行。
本地提前发现并修复:销售凭证增量同步读取当日余额时,必须统计同一天全部
`sales_revenue_adjustment / sales_refund_adjustment / sales_cost_adjustment`,
不能只按原始凭证的 `ref_id = 日期` 读取,否则重复同步会累计重复补记。
@@ -697,7 +702,9 @@ assigned 且 carrier_status=missing 必须进入异常队列
目标:
- 保留 A 级订单、退款事实和 B 级配置。
- 删除 C 级成本和财务派生数据并从新模型重建。
- 删除可重建的 estimated 成本快照和销售事实;
- 已过账总账保持 append-only,通过反向/补差凭证收敛到新事实;
- 保留真实退款、人工支出、资金流水、actual 快照和对账原始批次。
重建顺序:
@@ -705,10 +712,35 @@ assigned 且 carrier_status=missing 必须进入异常队列
product normalization
→ cost snapshot
→ sales facts
→ journal
→ journal adjustment
→ reconciliation
```
本地产出:
- `v_finance_order_item_scope` 成为销售范围唯一读模型。
- `finance:rebuild-derived` 默认 dry-run,执行需要
`--execute --confirm=REBUILD_DERIVED`。
- 重建前后校验订单数、订单项数、订单收入、退款、人工支出和资金流水,不守恒立即失败。
- 删除旧的 `finance-cutover-v2.ts`;该脚本会删除退款、人工支出和资金流水,违反 A 级保留规则。
- 本地重建区间 `2026-10-30 → 2026-11-08`:
- 财务范围 8 个订单项,收入 `8000` 分,退款 `0`;
- 销售事实收入 `8000` 分,退款 `0`,成本 `0`;
- 总账收入 `8000` 分,退款 `0`,成本 `0`;
- 第二次重建总账调整为 `0`,证明幂等;
- 严格审计关键异常 `0`;
- 遗留 2 个待归一商品项和 2 个 `manual_cost_missing`,均有结构化异常,不自动猜测。
- 重建前派生数据备份在本地 schema
`finance_rebuild_backup_20261108_1915`,不属于生产迁移结构。
验收命令:
```bash
npm run finance:rebuild-derived
npm run finance:rebuild-derived -- --execute --confirm=REBUILD_DERIVED
npm run audit:finance -- --strict
```
验收:
- 收入总额守恒。
@@ -719,7 +751,7 @@ product normalization
### 阶段 6:停止旧写路径并删除兼容层
状态:履约域已在本地停止旧写路径;商品、成本、人工配置的全局兼容清理仍需后续完成。
状态:履约与财务派生写入路径已在本地收敛;商品、成本、人工配置的全局兼容清理与生产观察期仍需后续完成。
只有前五个阶段持续稳定后才允许: