重构:统一商品渠道投影并收敛权威文档
This commit is contained in:
+37
-182
@@ -1,200 +1,55 @@
|
||||
# order_site 文档索引
|
||||
# order_site 文档入口
|
||||
|
||||
> 最后补充:2026-11-05,新增《履约系统架构复盘与优化方案》;生产代码基线 `e8b76b3b` / 迁移 `136`,开发分支 `dev_11.5_2` 已推进到迁移 `141`(履约统一状态、追加事件与正式影子模型)。
|
||||
> 数据基线:生产 dump `backups/postgres/order_site-20261022-092601.dump`(数据 2026-07-10 ~ 2026-10-22);历史全量数字仅作基线,**上线验收以 [财务上线初始化与验收-2026-10-26.md](财务上线初始化与验收-2026-10-26.md) 为准**。
|
||||
> 本文是 `docs/` 的唯一入口。**整体财务流程看 [财务流程总览-2026-11-01.md](财务流程总览-2026-11-01.md)**;数据模型看 [成本中心与履约模型.md](成本中心与履约模型.md),接口看 [成本中心API契约.md](成本中心API契约.md)。
|
||||
> 新增文档必须在下表登记状态;过期文档不再直接改写结论,统一移入 `docs/archive/`。
|
||||
本文件只负责导航,不定义业务口径。
|
||||
|
||||
## 一、先记住六条口径
|
||||
## 唯一权威
|
||||
|
||||
### 1. 来源只有三个,不是四个
|
||||
[统一订单履约与财务模型-权威版](统一订单履约与财务模型-权威版.md)
|
||||
|
||||
| sourceKey | 包含的数据通道 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `kuaishou-91` | 91 回调 + 快手 send-code | **同一个来源的两条通道**:91 是订单骨架权威源,快手 send-code 是数据补全源与兜底源;共享店铺键空间与同一套匹配上下文 |
|
||||
| `pdd` | 拼多多订单同步 | 两段式 `pdd_raw_orders → orders` |
|
||||
| `douyin-mashida` | 抖音码速达推送 | 抖店订单、DYC 券、H5/兑换页 |
|
||||
所有订单、内部 SKU、履约渠道、履约状态、商品归一、成本与财务相关开发,必须先阅读该文档。
|
||||
|
||||
**不要把 91 与快手 send-code 拆成两个来源、两个适配器或两条业务线。** 产品匹配层的唯一来源键是 `kuaishou-91`(`apps/backend/src/services/product-match/types.ts`),适配器是 `adapters/kuaishou-91.ts`。但订单表与成本映射里存储的 `provider` 仍是 `orders.provider = 91kaquan`;成本中心会把 `91 / open_91 / kuaishou-91` 这些别名归一为 `91kaquan`,映射键必须按落库值建。
|
||||
## 项目规则
|
||||
|
||||
### 2. 一个订单 = 骨架 + 买家凭证 + 一个履约方式
|
||||
[AGENTS.md](../AGENTS.md)
|
||||
|
||||
- 骨架:`orders` + `order_items`
|
||||
- 买家凭证:快手电子凭证(`kuaishou_industry_vouchers`)或抖音券(`redeem_certificates`)
|
||||
- 履约方式只有四种:`affiliate_dash` 自动发货、`work_orders` 接单平台、`legacy_platform` 已下线历史平台、`manual` 人工
|
||||
- **电子凭证只是核销码,不参与履约方式判定**;有核销码的订单仍可能是自动发货/接单平台/人工
|
||||
- 判定顺序固定:工单 → 自动发货任务 → 历史平台任务 → 其余为人工
|
||||
- 人工块必须进入人工支出与成本快照,不能静默消失
|
||||
包含任务读取顺序、数据安全边界、文档维护规则和提交要求。
|
||||
|
||||
### 3. 履约方式与成本模型必须分开
|
||||
## 运维资料
|
||||
|
||||
- `fulfillment_channel`(+ `fulfillment_status`)回答“谁执行”;`cost_model` 回答“成本怎么算”
|
||||
- 自动发货:`affiliate_purchase`
|
||||
- 接单平台:`work_order_reward`
|
||||
- 人工:`manual_actual`(逐单实际金额)
|
||||
- 历史平台:`legacy_cost`(历史未采集则显式标记)
|
||||
- 电子凭证不建成本项,也不作为成本类型
|
||||
- 未确认成本时保持 `cost_missing`,不默认 0
|
||||
|
||||
### 4. 成本只在一个地方改
|
||||
|
||||
- 商品主数据:`product_catalog`
|
||||
- 渠道 SKU 映射:`channel_product_mappings`
|
||||
- 成本金额:只在 `cost_versions` 改,按生效日期新增版本
|
||||
- 订单/工单/人工单只保存 `cost_snapshot_id`,历史成本永不回写
|
||||
- 自动发货、接单平台、人工客服共用同一个成本解析器;匹配不到成本进入 `cost_missing`,不默认 0
|
||||
|
||||
### 5. 人工成本只有一条链路
|
||||
|
||||
```text
|
||||
订单列表/详情「确认履约」→ 扣客服积分/备用金 → 写 cost_snapshots(manual_case)
|
||||
```
|
||||
|
||||
| 名称 | 业务含义 | 当前状态 |
|
||||
| --- | --- | --- |
|
||||
| `manual_expenses` | **客服备用金支出明细**:客服从自己的备用金里充值/采购/赔偿,减少客服余额 | 已实施(迁移 100);确认履约的现金支出也写这里 |
|
||||
| `cost_snapshots` | **人工成本的唯一落点**:`subject_type='manual_case'`,`subject_id=order_item_id`(资金来源写 metadata) | 已实施(迁移 104) |
|
||||
|
||||
**没有独立的登记单,也没有审批与报销环节。** `manual_expense_records` / `manual_expense_events` 已随迁移 `104` 归并下线(这两张表在生产 102 上从未创建)。后续做财务系统时,人工成本的钱与账都从这条链路走,不要再另造一张人工支出表。
|
||||
|
||||
### 6. 历史人工直接放弃,上线后必须全覆盖
|
||||
|
||||
- 历史人工支出找不回来,**直接放弃**:不补录、不做样本校准、不阻塞上线;
|
||||
- 上线后每一笔人工单必须有处理人、实际金额、备用金支出与成本快照;
|
||||
- 人工单无成本记录、人工单未扣备用金、金额与备用金流水不一致,均不允许关账。
|
||||
|
||||
### 7. 文档状态
|
||||
|
||||
| 状态 | 含义 |
|
||||
| 文档 | 用途 |
|
||||
| --- | --- |
|
||||
| 现行 | 与当前代码一致,改动代码时必须同步更新 |
|
||||
| 方案 | 尚未实施,但作为下一阶段实现依据 |
|
||||
| 参考 | 外部协议、历史数据或解释性材料,不作为实现依据 |
|
||||
| 历史 | 只用于追溯,不得作为实现依据;位于 `docs/archive/` |
|
||||
| [部署启动与数据库重建](部署启动与数据库重建.md) | 本地与生产部署、数据库重建 |
|
||||
| [数据库备份与恢复](数据库备份与恢复.md) | 备份、恢复、OSS |
|
||||
| [数据库SQL约束与运维](数据库SQL约束与运维.md) | SQL 护栏与生产观测 |
|
||||
|
||||
## 二、财务系统当前进度
|
||||
## 专项参考
|
||||
|
||||
| 模块 | 状态 | 事实 |
|
||||
| --- | --- | --- |
|
||||
| 客服备用金台账 | **已实施 P0** | 迁移 `100/101/107`;账户、流水、支出、对账;编号 `FA-<用户名>`;客服只能使用本人账户 |
|
||||
| 后台用户中文显示名 | **已实施** | `admin_users.display_name`,备用金姓名触发器同步;审计、登录记录、任务处理人优先显示中文名 |
|
||||
| 商品主数据 + 渠道 SKU 映射 | **已实施 P0/P1** | 2,017 个标准商品、4,897 条映射:`tpl:` 710、`man:` 1,195、`aff:` 49、`wo:` 63;订单项已按履约证据/人工内部 SKU 归一 |
|
||||
| 成本中心 | **已实施 P0** | 迁移 `103`;710 个规则级版本 + 2 个全局占位版本;工单成本快照 151,939 条,其中 actual 129,430、estimated 22,509 |
|
||||
| 销售事实 / 订单毛利 | **已实施 P0** | 迁移 `103`;375,447 项、收入 ¥3,143.61 万、成本 ¥572.95 万、毛利 ¥2,570.66 万;`sales_daily_facts.channel` |
|
||||
| 人工成本录入(确认履约) | **已实施 P0(2026-10-26 单事务 + 防重复)** | 确认即扣积分/备用金并写 `actual` 快照;钱与成本同事务、订单项级唯一;无登记单/审批/报销 |
|
||||
| 人工 SKU 配置自动匹配 | **已实施(2026-10-26)** | 保存配置立即回填 + 定时 rematch + 确认时按 SKU 兜底匹配 |
|
||||
| 人工缺成本监控 | **已实施(2026-10-26)** | `manual_cost_missing`:首次人工配置之后的订单项未确认即入队,确认后自动收口 |
|
||||
| 履约方式统一 | **已实施 P0** | 迁移 `103`;375,447 项全部回填:接单平台 153,148、人工 115,194、历史平台 53,901、自动发货 53,204 |
|
||||
| 人工商品归一 | **已实施 P1(本次快照恢复执行)** | 人工 115,194 项已归一为 1,195 个 `man:<内部SKU>` 商品;历史人工支出仍不补录 |
|
||||
| 影子总账 | **已实施 P0(2026-10-26)** | `finance_accounts/journal_entries/journal_lines/periods`;销售事实按日凭证 + 手工凭证 + 试算平衡;不接管钱包余额 |
|
||||
| 成本异常归档 | **已实施** | 迁移 `108`;已处理异常超 60 天搬入 `cost_exceptions_archive`,open 行不归档;`COST_EXCEPTION_RETENTION_DAYS` 可调 |
|
||||
| 平台对账 / 期间关账 | **已实施 P0** | 平台账单 JSON 导入匹配、差异明细、标记解决;关账/反关账;见 `/admin/finance/ledger` |
|
||||
| 平台退款 API | **部分实施** | 快手行业(91)同意退款已接入;抖音/拼多多暂未接 API,仍手工登记 |
|
||||
专项参考只解释具体平台、工具或历史问题,不能覆盖唯一权威文档。
|
||||
|
||||
> 分支状态(2026-10-27):`dev` 已合并 `dev1023` 与人工成本完整性修复,迁移收敛为 `103`–`105`(103 财务基础、104 财务控制/L1、105 拼单/寄卖客服);已验证 001→105 与 102→105 两条升级路径。**未推送、未部署生产**;生产口径仍以 `main` 为准。上线前按 [财务上线初始化与验收-2026-10-26.md](财务上线初始化与验收-2026-10-26.md) 初始化资金与人工 SKU。
|
||||
> 财务与履约口径以 [财务与履约口径总纲-2026-10-23.md](财务与履约口径总纲-2026-10-23.md) 为准。
|
||||
|
||||
## 三、统一实施顺序
|
||||
|
||||
```text
|
||||
0. 统一履约事实(渠道 + 成本模型正交) 已完成(迁移 113)
|
||||
1. 商品主数据 + 渠道 SKU 映射 已完成 P0(仅自动发货/接单平台)
|
||||
2. 成本中心 + 销售事实 已完成 P0
|
||||
2.5 人工成本链路收敛(确认履约 → 扣积分/备用金 → 写快照) 已完成 P0(迁移 104)
|
||||
3. 人工商品归一与上线后人工成本全覆盖 已完成代码;生产数据需上线后配置 SKU(历史不补录)
|
||||
4. 退款冲减与异常队列 已完成手工退款 + 快手平台退款;人工缺成本已入队
|
||||
5. 影子总账(销售事实 + 手工凭证) 已完成 P0(迁移 108)
|
||||
6. 平台对账、期间关账 已完成 P0(手工账单导入);平台自动拉单未实施
|
||||
```
|
||||
|
||||
**第 0 步已完成。** 迁移、回填、代码改造与验收结果见 [成本中心与履约模型](成本中心与履约模型.md) §六、§八。下一步只做第 3 步人工商品归一,不要同时改退款或总账。
|
||||
|
||||
## 四、当前必须拍板
|
||||
|
||||
| # | 问题 | 当前结论 | 影响 |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | 收入金额口径 | ✅ 用户实付(`orders.total_amount`) | 收入基数 |
|
||||
| 2 | 收入确认时点 | ✅ 先按 `paid_at` 归属销售日;成本在快照生成后回填 | 利润表与预收账款 |
|
||||
| 3 | 打手报酬 | ✅ 支出/成本,总额法 | 履约成本 |
|
||||
| 4 | 退款/仲裁 | ✅ 暂不实现,只预留反向凭证 | 后续冲减 |
|
||||
| 5 | 人工支出如何入账 | ✅ 逐单实际金额;从客服备用金扣款;客服只能用本人账户 | 人工成本与备用金 |
|
||||
| 6 | 历史人工支出 | ✅ **不补录**,只取少量样本校准 | 上线范围 |
|
||||
| 7 | 电子凭证是否作为分类 | ✅ **不作为履约/成本分类**,只是核销码状态 | 报表口径 |
|
||||
| 8 | 平台服务费/支付通道费 | ⏳ 待定 | 费用科目与对账 |
|
||||
| 9 | 寄卖货款成本确认时点 | ⏳ 待定 | 存货/采购成本 |
|
||||
| 10 | 是否需要发票/税务、是否多币种 | ⏳ 待定 | 当前按 CNY、无税务实现 |
|
||||
|
||||
## 五、现行与参考文档
|
||||
|
||||
| 文档 | 状态 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| [财务与履约口径总纲-2026-10-23.md](财务与履约口径总纲-2026-10-23.md) | **现行唯一口径** | 履约方式、成本模型、人工全覆盖、历史策略、实施顺序、运营日检与验收 SQL |
|
||||
| [财务流程总览-2026-11-01.md](财务流程总览-2026-11-01.md) | 现行 | 断代后财务全流程:六条管道、成本快照、事实、总账、退款、异常、运维与测试 |
|
||||
| [订单全流程与内部SKU架构.md](订单全流程与内部SKU架构.md) | 现行 | 平台入单、中文内部 SKU、渠道判定、四类履约载体、商品归一与财务落账的完整链路 |
|
||||
| [履约系统架构复盘与优化方案-2026-11-05.md](履约系统架构复盘与优化方案-2026-11-05.md) | 方案 | 履约状态、载体、尝试、异常队列与后台信息架构的分阶段重构方案 |
|
||||
| [订单服务收集与状态页设计-2026-11-03.md](订单服务收集与状态页设计-2026-11-03.md) | 现行 | 分类级资料配置、发布版本与工单快照、`/o` 客户状态页、自动发布核销和通知预留 |
|
||||
| [成本中心与履约模型.md](成本中心与履约模型.md) | 现行 | 商品、成本版本、快照、异常、销售事实的数据模型;迁移 `103`–`105`;履约回填;迁移基线与本地库同步;索引与性能 |
|
||||
| [成本中心API契约.md](成本中心API契约.md) | 现行 | 成本中心接口字段替换总表、枚举、模块边界(后端 5 模块 + 前端 4 个固定 Tab) |
|
||||
| [人工支出与备用金.md](人工支出与备用金.md) | 现行(P0 已实施) | 确认履约流程/权限、客服备用金台账、本人账户与编号规则 |
|
||||
| [财务上线初始化与验收-2026-10-26.md](财务上线初始化与验收-2026-10-26.md) | **现行上线手册** | 迁移后资金/人工 SKU 初始化、验收 SQL、日常监控 |
|
||||
| [财务系统集成方案.md](财务系统集成方案.md) | 现行方案(影子总账 P0 已实施) | 复式记账、总账表、对账、关账;P1/P2 平台自动对账待接 |
|
||||
| [财务系统深度分析-2026-10-27.md](财务系统深度分析-2026-10-27.md) | 参考(一次性审计,不改变现行口径) | 2026-10-27 代码/数据/权限审计、风险清单与上线前修复路线 |
|
||||
| [dev合并main评估-2026-10-27.md](dev合并main评估-2026-10-27.md) | 参考(合并评估) | dev 领先 main 的改动、迁移收敛、生产规模升级实测与发布检查清单 |
|
||||
| [财务代码审计复核-2026-10-27.md](财务代码审计复核-2026-10-27.md) | 参考(代码复核) | 对“旧报表重复扣减、总账 DELETE、钱包 BIGINT、死锁”等结论的逐条校正与补充 |
|
||||
| [打手重复奖励核对-2026-10-27.md](打手重复奖励核对-2026-10-27.md) | 待人工核对 | 8 组疑似重复奖励、16 条流水、多计 ¥196.20;含 84886 寄卖误报说明 |
|
||||
| [影子总账说明.md](影子总账说明.md) | 现行说明(P0 已实施) | 影子总账是什么、和钱包流水的区别、对账与转正标准 |
|
||||
| [项目全量分析报告-2026-10-17.md](项目全量分析报告-2026-10-17.md) | 历史参考 | 2026-10-17 架构与风险;财务口径以总纲为准 |
|
||||
| [接单模板匹配引擎重构设计.md](接单模板匹配引擎重构设计.md) | 现行(P0/P1 已实施) | `kuaishou-91 / pdd / douyin-mashida` 三来源匹配引擎 |
|
||||
| [履约配置/多发货平台与电子凭证整体链路.md](履约配置/多发货平台与电子凭证整体链路.md) | 现行 | 进单、履约、领取、电子凭证的整体链路 |
|
||||
| [affiliate-dash-发货平台/affiliate-dash对接.md](affiliate-dash-发货平台/affiliate-dash对接.md) | 现行 | affiliate-dash 自动履约接口与字段 |
|
||||
| [履约配置/cloudtentacles发货平台.md](履约配置/cloudtentacles发货平台.md) | 历史参考 | 已下线通道的第三方接口样例,不代表现行实现 |
|
||||
| [91卡券/6.开发设计.md](91卡券/6.开发设计.md) | 现行 | `kuaishou-91` 来源的 91 侧接入设计 |
|
||||
| [抖音-码速达/00-总览.md](抖音-码速达/00-总览.md) | 现行 | 抖音码速达接入总览与增量记录 |
|
||||
| [抖音-码速达/12-按SKU分类改造总设计.md](抖音-码速达/12-按SKU分类改造总设计.md) | 现行 | 抖音三层分流与载体唯一 |
|
||||
| [部署启动与数据库重建.md](部署启动与数据库重建.md) | 现行 | 本地/生产启动、迁移、重建 |
|
||||
| [数据库备份与恢复.md](数据库备份与恢复.md) | 现行 | 备份、恢复、OSS |
|
||||
| [数据库SQL约束与运维.md](数据库SQL约束与运维.md) | 现行 | SQL 护栏与生产观测 |
|
||||
|
||||
### SQL 草案(未接入迁移)
|
||||
|
||||
草案只作设计与复盘依据;接入 `apps/backend/src/db/migrations/` 时再拆成 `NNN_slug.sql`,并先跑 `npm run check:sql`。
|
||||
|
||||
| 文件 | 用途 | 接入前必须处理 |
|
||||
| --- | --- | --- |
|
||||
| [drafts/2026-10-17-载体判定与人工块量化.sql](drafts/2026-10-17-载体判定与人工块量化.sql) | 载体分布/人工块量化查询、`carrier_type` 判定与回填 | **已过时**:`carrier_type` 已从商品/成本/快照/异常表删除;只读查询里的口径结论已吸收进总纲 §二 |
|
||||
| [drafts/2026-10-17-成本中心与销售事实-DDL草案.sql](drafts/2026-10-17-成本中心与销售事实-DDL草案.sql) | `product_catalog`、`channel_product_mappings`、`cost_items/versions/snapshots/exceptions`、`sales_daily_facts` | 已落地为 `103`–`105`;草案里的 `carrier_type` 已被 `cost_model` / 渠道三列取代,仅作设计追溯 |
|
||||
| [drafts/2026-10-31-112-履约渠道拆分-迁移草案.sql](drafts/2026-10-31-112-履约渠道拆分-迁移草案.sql) | 渠道/状态/来源拆列、`sku_channel_rules`、异常两级化、水位表、卡券成本项 | 已落地为 `apps/backend/src/db/migrations/112_fulfillment_channel_split.sql`;草案保留作设计追溯 |
|
||||
| [drafts/2026-10-31-同步链路重构-旧函数对照.md](drafts/2026-10-31-同步链路重构-旧函数对照.md) | 16 个旧同步/回填入口 → 6 个新管道作业的对照与验收口径 | 已落地:三条管道服务 + 六个定时任务 + 后台「履约渠道」页 |
|
||||
| [archive/2026-10-23/2026-10-17-人工支出登记-DDL草案.sql](archive/2026-10-23/2026-10-17-人工支出登记-DDL草案.sql) | `manual_fulfillment_cases`、`manual_expense_records`、`manual_expense_events` | **已作废**:`manual_expense_records` / `manual_expense_events` 已随迁移 `104` 归并下线,人工成本改走「人工录单 → 扣备用金 → 写快照」;文件已移入 archive |
|
||||
|
||||
## 六、厂商协议与外部资料
|
||||
|
||||
这些目录是平台方文档或抓取资料,**不作为本项目实现说明**:
|
||||
|
||||
| 目录 | 内容 |
|
||||
| 文档或目录 | 用途 |
|
||||
| --- | --- |
|
||||
| `91卡券/` | 91 卡券公开接口、签名、加密示例(项目接入结论见 `91卡券/6.开发设计.md`) |
|
||||
| `行业电子凭证/` | 快手电子凭证接口、售后、测试指南 |
|
||||
| `发货平台-2/` | 早期发货平台协议,现行为 `affiliate_dash`;保留作历史接口对照 |
|
||||
| `抖音-码速达/接口API/` | 抖音码速达出网接口 |
|
||||
| `抖音-码速达/消息推送/` | 抖音码速达推送消息字段与签名 |
|
||||
| [设备认证-dcauth协议](设备认证-dcauth协议.md) | 设备认证协议 |
|
||||
| [affiliate-dash-发货平台](affiliate-dash-发货平台/) | affiliate-dash 对接资料 |
|
||||
| [91卡券](91卡券/) | 91 卡券接口与签名资料 |
|
||||
| [抖音-码速达](抖音-码速达/) | 抖音码速达接口、消息与接入资料 |
|
||||
| [行业电子凭证](行业电子凭证/) | 快手行业电子凭证协议 |
|
||||
| [发货平台-2](发货平台-2/) | 历史发货平台协议 |
|
||||
| [履约配置](履约配置/) | 专项接入与排障参考 |
|
||||
| [微博微豆-CK接口与兑换链路确认-2026-11-07](微博微豆-CK接口与兑换链路确认-2026-11-07.md) | 微博微豆接口与兑换链路 |
|
||||
| [打手重复奖励核对-2026-10-27](打手重复奖励核对-2026-10-27.md) | 历史财务核对记录 |
|
||||
|
||||
## 七、历史文档
|
||||
## 历史归档
|
||||
|
||||
| 位置 | 说明 |
|
||||
| --- | --- |
|
||||
| [archive/README.md](archive/README.md) | 2026-10-08 及更早的阶段分析、寄卖方案、性能快照、一次性迁移检查脚本;2026-10-17 复核文档 |
|
||||
| [archive/2026-10-17/载体判定与成本中心落地-复核与草案.md](archive/2026-10-17/载体判定与成本中心落地-复核与草案.md) | 2026-10-17 第二轮复核与数据量化;结论已吸收进现行成本中心文档,仅作历史追溯 |
|
||||
| [archive/2026-10-23/](archive/2026-10-23/) | 2026-10-23 重写前的四篇:`成本中心与三块履约模型`、`人工支出登记落地方案`、`客服备用金台账实施方案`、`财务履约改造交接总结`;结论已分别并入现行 5 篇文档 |
|
||||
[archive](archive/) 中的文档均已失效,只用于追溯。
|
||||
|
||||
## 八、维护规则
|
||||
2026-11-08 统一重构前的订单、履约、成本、财务、架构与 SQL 草案已归档到:
|
||||
|
||||
1. 改代码影响业务口径时,先改现行文档,再提交代码。
|
||||
2. 文档头部必须写「状态 + 最后校准日期 + 代码基线」。
|
||||
3. 旧分析不要在原文件上继续堆结论;新建当期报告,旧文件移入 `docs/archive/<日期>/`。
|
||||
4. 行号只用于当期基线;跨版本引用优先写文件与函数名。
|
||||
5. 新增来源时只加一个 `ProductMatchSourceKey` + 一个适配器;**91 + 快手 send-code 永远算一个 `kuaishou-91`**。
|
||||
6. 成本金额只改 `cost_versions`,不要在多个业务表直接改价;历史订单只读 `cost_snapshots`。
|
||||
7. 报表维度统一用 `canonical_product_id + shop_id + stat_date`,不要直接用原始 `sku_code` 或 `orders.total_amount`。
|
||||
8. 新增 SQL 草案放 `docs/drafts/`,命名 `<日期>-<主题>.sql`;**不得**直接放进 `apps/backend/src/db/migrations/`(后端启动会自动迁移),接入时再拆编号并先跑 `npm run check:sql`。
|
||||
9. 财务系统实现顺序以本索引 §三 为准;单篇文档里的分期若与本索引冲突,以本索引为准。
|
||||
[archive/2026-11-08](archive/2026-11-08/)
|
||||
|
||||
## 维护规则
|
||||
|
||||
1. 业务和架构口径只修改唯一权威文档。
|
||||
2. 不再新增第二份“现行架构”“现行财务口径”或“总纲”。
|
||||
3. 外部平台协议可以保留,但不得覆盖项目自身模型。
|
||||
4. 已被替代的内部设计文档移入 `docs/archive/<日期>/`。
|
||||
5. 文档中的代码与迁移基线必须来自实际仓库和生产只读核对。
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# 2026-11-08 历史文档归档
|
||||
|
||||
本目录保存 2026-11-08 统一重构前使用的订单、履约、成本、财务和架构文档。
|
||||
|
||||
这些文档只用于追溯当时的设计与数据来源,不再作为现行口径、开发依据或验收标准。
|
||||
|
||||
现行唯一权威文档:
|
||||
|
||||
[统一订单履约与财务模型-权威版](../../统一订单履约与财务模型-权威版.md)
|
||||
+14
-4
@@ -1,7 +1,8 @@
|
||||
# 历史文档归档
|
||||
|
||||
> 这里的文档只用于追溯当时的分析过程,**不是现行实现说明**。
|
||||
> 代码、数据库结构与线上行为以仓库当前 `main` 和 `docs/README.md` 中标记为「现行」的文档为准。
|
||||
> 代码、数据库结构与线上行为只以
|
||||
> [统一订单履约与财务模型-权威版](../统一订单履约与财务模型-权威版.md) 为准。
|
||||
|
||||
## 2026-10-08
|
||||
|
||||
@@ -18,7 +19,7 @@
|
||||
|
||||
| 文档 | 归档原因 |
|
||||
| --- | --- |
|
||||
| `2026-10-17/载体判定与成本中心落地-复核与草案.md` | 2026-10-17 第二轮复核与数据量化;现行结论已吸收进 `成本中心与三块履约模型.md` 与 `财务系统集成方案.md`,仅保留作数据与 DDL 验证追溯 |
|
||||
| `2026-10-17/载体判定与成本中心落地-复核与草案.md` | 2026-10-17 第二轮复核与数据量化;仅保留作数据和 DDL 验证追溯 |
|
||||
|
||||
## 2026-10-23
|
||||
|
||||
@@ -26,9 +27,18 @@
|
||||
| --- | --- |
|
||||
| `2026-10-23/2026-10-23-本地库原地改造.sql` | 逐列把 `carrier_type` / `cost_type` 改成 `cost_model` / `fulfillment_mode` 的一次性脚本;迁移收敛为 `103`–`107` 后不再成立,**禁止在新环境执行**,仅作改造矩阵追溯 |
|
||||
|
||||
## 2026-11-08
|
||||
|
||||
2026-11-08 完成订单、履约、商品、成本和财务口径统一。
|
||||
|
||||
此前所有相关业务架构、财务方案、字段契约和 SQL 草案整体归档到:
|
||||
|
||||
[2026-11-08](2026-11-08/)
|
||||
|
||||
## 使用建议
|
||||
|
||||
- 需要当前架构与风险:看 `docs/项目全量分析报告-2026-10-17.md`(参考)和 `docs/README.md`(状态索引)。
|
||||
- 需要财务系统设计:看 `docs/财务系统集成方案.md`;实施顺序以 `docs/README.md` §三 为准。
|
||||
- 需要当前架构、数据边界和实施计划:只看
|
||||
[统一订单履约与财务模型-权威版](../统一订单履约与财务模型-权威版.md)。
|
||||
- 需要某个平台协议:看对应的厂商文档目录(`91卡券/`、`行业电子凭证/`、`发货平台-2/`、`抖音-码速达/接口API/`、`抖音-码速达/消息推送/`)。
|
||||
- 历史文档中的代码行号、测试数量、迁移数量不要直接引用。
|
||||
- 历史文档不得重新标记为“现行”,需要复活时必须并入唯一权威文档。
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
|
||||
### 2)接单模板匹配引擎重构(`10464fea`,P0+P1)
|
||||
|
||||
按 [接单模板匹配引擎重构设计.md](../接单模板匹配引擎重构设计.md) 抽出 `services/product-match/`(适配器按**来源**划分:`kuaishou-91` / `pdd` / `douyin-mashida`,其中 `kuaishou-91` 同时覆盖 91 回调与快手 send-code 两条数据通道)。生产回放 6000 条订单项:`kuaishou-91`/PDD 决策 **0 差异**,抖音 5 条全为修正。旧 `work-product-match-mappers.ts` 变为门面,签名不变。
|
||||
按 [接单模板匹配引擎重构设计.md](../archive/2026-11-08/接单模板匹配引擎重构设计.md) 抽出 `services/product-match/`(适配器按**来源**划分:`kuaishou-91` / `pdd` / `douyin-mashida`,其中 `kuaishou-91` 同时覆盖 91 回调与快手 send-code 两条数据通道)。生产回放 6000 条订单项:`kuaishou-91`/PDD 决策 **0 差异**,抖音 5 条全为修正。旧 `work-product-match-mappers.js` 改为兼容门面,签名不变。
|
||||
|
||||
### 3)工单「发布并核销」支持抖音券(本次)
|
||||
|
||||
|
||||
@@ -348,7 +348,7 @@
|
||||
| 可观测性 | `utils/logger.ts:96/122`、`repositories/task-event-repo.ts:16`、`repositories/admin-notification-repo.ts:25`、`services/realtime/realtime-event-service.ts:92` | 日志 / 任务事件 / 后台待办 + SSE |
|
||||
| 环境变量白名单(硬约束) | `config/env-documentation.test.ts:57/63`、`.env.server.example`、`.env.mac-docker.example` | 新增 env 必须登记,否则测试红 |
|
||||
| 隐私红线 | `services/worker-platform/sync-worker-orders-service.ts:206-220` | 打手工单素材不含买家信息 |
|
||||
| 平台接入设计范本 | `docs/91卡券/6.开发设计.md`(来源建模/配置/签名/代码落点/测试范围)、`docs/履约配置/多发货平台与电子凭证整体链路.md` | 本项目的「新平台接入」方法论 |
|
||||
| 平台接入设计范本 | `docs/91卡券/6.开发设计.md`(来源建模/配置/签名/代码落点/测试范围)、`docs/archive/2026-11-08/多发货平台与电子凭证整体链路.md` | 本项目的「新平台接入」方法论 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,760 @@
|
||||
---
|
||||
type: 权威架构与实施计划
|
||||
description: 订单、内部 SKU、履约路由、履约执行、商品、成本与财务的唯一权威口径及重构计划。
|
||||
tags: [订单, 内部SKU, 履约, 商品, 成本, 财务, 迁移]
|
||||
status: authoritative
|
||||
version: 1.0
|
||||
updated_at: 2026-11-08
|
||||
---
|
||||
|
||||
# 统一订单、履约与财务模型
|
||||
|
||||
> 状态:**唯一权威文档**。
|
||||
> 最后校准:2026-11-08。
|
||||
> 生产基线:迁移 `146`。
|
||||
> 开发基线:迁移 `158`(仅本地,尚未部署生产)。
|
||||
>
|
||||
> 从本文件生效起,订单、内部 SKU、履约渠道、履约载体、标准商品、成本和财务相关实现,
|
||||
> 只能以本文件为业务口径。其他旧分析只作为历史资料,不再具备设计或验收效力。
|
||||
|
||||
## 一、最终结论
|
||||
|
||||
系统按六个业务域拆分:
|
||||
|
||||
```text
|
||||
订单接入
|
||||
→ 商品身份
|
||||
→ 履约路由
|
||||
→ 履约执行
|
||||
→ 财务核算
|
||||
→ 运营治理
|
||||
```
|
||||
|
||||
换一种更具体的表达:
|
||||
|
||||
```text
|
||||
平台订单与原始行
|
||||
→ 中文内部 SKU
|
||||
→ 主渠道与兜底渠道
|
||||
→ 当前履约单与执行尝试
|
||||
→ 标准商品与成本事实
|
||||
→ 销售事实、总账与报表
|
||||
```
|
||||
|
||||
每一层只能回答一个问题:
|
||||
|
||||
| 层 | 唯一问题 | 唯一真源 |
|
||||
| --- | --- | --- |
|
||||
| 订单接入 | 平台实际发生了什么 | `orders` / `order_items` / 原始报文 |
|
||||
| 商品身份 | 业务上这是什么商品 | `internal_skus` |
|
||||
| 履约路由 | 这个商品默认由谁履约 | `sku_channel_routes` |
|
||||
| 履约执行 | 当前实际执行到哪一步 | `fulfillments` / `fulfillment_attempts` |
|
||||
| 财务商品 | 收入与成本归到哪个标准商品 | `product_catalog` / `channel_product_mappings` |
|
||||
| 财务核算 | 应该记多少钱 | `cost_snapshots` / `sales_daily_facts` / `journal_*` |
|
||||
|
||||
任何页面、接口、任务和报表都必须从各自真源读取,不得根据另一层的字段反推。
|
||||
|
||||
## 二、不可违反的规则
|
||||
|
||||
1. **原始订单事实永不删除。**
|
||||
`orders`、`order_items`、平台原始报文、平台售后与退款事实、真实工单执行记录、
|
||||
真实钱包和资金流水、后台审计日志必须保留。
|
||||
|
||||
2. **标准商品不表达当前履约渠道。**
|
||||
`canonical_sku` 前缀、`product_catalog.category` 和商品名称都不能反推当前渠道。
|
||||
|
||||
3. **人工配置不等于当前走人工。**
|
||||
人工配置只表示具备人工执行或人工兜底能力。当前渠道必须来自路由结果。
|
||||
|
||||
4. **一个内部 SKU 最多一个主渠道。**
|
||||
其他启用渠道只能是显式兜底,并记录优先级与用途。
|
||||
|
||||
5. **`assigned` 不等于履约完成。**
|
||||
`assigned` 只允许表示路由已确定;载体是否存在由 `carrier_status` 单独表达。
|
||||
|
||||
6. **财务层只读上游。**
|
||||
成本、事实和总账不得反向修改订单、路由、载体或商品来源。
|
||||
|
||||
7. **派生数据必须可重建。**
|
||||
成本快照、销售事实、总账、异常队列、投影和影子履约模型都必须能够从原始订单、
|
||||
输入配置和事件重算。
|
||||
|
||||
8. **页面与统计使用同一读模型。**
|
||||
同一个数量,页签、卡片、列表和导出不得各自拼口径。
|
||||
|
||||
9. **历史文档不再定义现行规则。**
|
||||
旧架构、旧财务方案和旧迁移说明只能放入归档目录。
|
||||
|
||||
10. **一次只允许一个权威写入口。**
|
||||
核心状态只允许由对应领域服务修改;其他模块只能调用该服务。
|
||||
|
||||
## 三、领域边界
|
||||
|
||||
### 3.1 订单接入域
|
||||
|
||||
负责:
|
||||
|
||||
- 接收 91、快手送码、拼多多、抖音码速达的数据。
|
||||
- 保存平台订单、订单项、原始报文、支付和售后事实。
|
||||
- 保证来源重放幂等。
|
||||
- 将平台商品字段解析为中文内部 SKU。
|
||||
|
||||
不负责:
|
||||
|
||||
- 选择履约渠道。
|
||||
- 创建工单或履约任务。
|
||||
- 计算成本。
|
||||
- 决定标准商品。
|
||||
|
||||
订单项上的 `fulfillment_*`、`canonical_product_id` 等字段在过渡期保留,
|
||||
但只能由对应领域服务通过兼容投影维护,不允许入单服务自行猜测。
|
||||
|
||||
### 3.2 商品身份域
|
||||
|
||||
目标真源:
|
||||
|
||||
```text
|
||||
internal_skus
|
||||
id
|
||||
internal_sku_key -- NFKC、去空白、小写后的稳定键
|
||||
display_name -- 运营可读名称
|
||||
status -- active / disabled / merged
|
||||
merged_into_id -- 合并目标
|
||||
```
|
||||
|
||||
所有人工配置、渠道路由、订单项快照和渠道规则都必须通过 `internal_sku_id` 关联,
|
||||
不再长期依赖多张表重复保存同一个中文文本。
|
||||
|
||||
平台字段到内部 SKU 的唯一入口:
|
||||
|
||||
```text
|
||||
internal_sku_mappings
|
||||
provider
|
||||
shop_id
|
||||
match_type
|
||||
match_value
|
||||
internal_sku_id
|
||||
priority
|
||||
enabled
|
||||
```
|
||||
|
||||
匹配顺序固定:
|
||||
|
||||
```text
|
||||
provider + shop 精确
|
||||
→ provider 精确
|
||||
→ shop 精确
|
||||
→ 全局
|
||||
```
|
||||
|
||||
### 3.3 履约路由域
|
||||
|
||||
目标真源:
|
||||
|
||||
```text
|
||||
sku_channel_routes
|
||||
id
|
||||
internal_sku_id
|
||||
channel
|
||||
route_role -- primary / fallback
|
||||
priority
|
||||
enabled
|
||||
carrier_config_json
|
||||
source
|
||||
created_by
|
||||
updated_at
|
||||
```
|
||||
|
||||
渠道枚举:
|
||||
|
||||
```text
|
||||
affiliate_dash
|
||||
work_order
|
||||
third_party_voucher
|
||||
manual
|
||||
on_account
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
- `active + primary` 每个内部 SKU 最多一条。
|
||||
- `fallback` 可以多条,按 `priority` 依次尝试。
|
||||
- 主渠道失败时才能尝试兜底渠道。
|
||||
- 运营指定和自动判定必须写差异化 `source`。
|
||||
- 路由配置不能保存“当前订单结果”;当前结果属于履约域。
|
||||
|
||||
### 3.4 履约执行域
|
||||
|
||||
当前 `order_items.fulfillment_channel/status` 和 `v_fulfillment_item_state`
|
||||
属于过渡读模型。目标模型使用:
|
||||
|
||||
```text
|
||||
fulfillments
|
||||
id
|
||||
order_item_id
|
||||
internal_sku_id
|
||||
route_status -- unrouted / configured / locked
|
||||
channel
|
||||
carrier_status -- not_required / missing / creating / ready / failed / terminal
|
||||
current_attempt_id
|
||||
issue_code
|
||||
issue_category
|
||||
retryable
|
||||
owner_role
|
||||
created_at
|
||||
updated_at
|
||||
|
||||
fulfillment_attempts
|
||||
id
|
||||
fulfillment_id
|
||||
attempt_no
|
||||
attempt_type -- task / work_order / manual
|
||||
source_id
|
||||
status
|
||||
result_code
|
||||
result_message
|
||||
is_current
|
||||
started_at
|
||||
finished_at
|
||||
context_json
|
||||
|
||||
fulfillment_issues
|
||||
id
|
||||
fulfillment_id
|
||||
issue_code
|
||||
issue_category
|
||||
severity
|
||||
retryable
|
||||
auto_retryable
|
||||
owner_role
|
||||
status -- open / acknowledged / waiting / resolved
|
||||
detail_json
|
||||
first_seen_at
|
||||
last_seen_at
|
||||
resolved_at
|
||||
```
|
||||
|
||||
状态必须正交:
|
||||
|
||||
```text
|
||||
商业订单状态
|
||||
≠ 路由状态
|
||||
≠ 载体状态
|
||||
≠ 当前尝试状态
|
||||
≠ 异常状态
|
||||
≠ 锁定原因
|
||||
≠ 财务状态
|
||||
```
|
||||
|
||||
同一订单项只能有一个当前尝试。历史尝试只追加,不覆盖。
|
||||
|
||||
### 3.5 商品与财务域
|
||||
|
||||
标准商品目标结构:
|
||||
|
||||
```text
|
||||
product_catalog
|
||||
id
|
||||
canonical_sku
|
||||
canonical_name
|
||||
source_kind -- affiliate / work_order / voucher / manual / settlement
|
||||
internal_sku_id -- 可空;关联业务内部 SKU
|
||||
category -- 仅展示,不参与路由
|
||||
unit_name
|
||||
status
|
||||
```
|
||||
|
||||
`canonical_sku` 前缀只用于兼容识别。运行时和统计必须读取 `source_kind`,
|
||||
不能再散落 `LIKE 'man:%'` 之类的业务判断。
|
||||
|
||||
商品映射:
|
||||
|
||||
```text
|
||||
channel_product_mappings
|
||||
provider + shop_id + platform_sku
|
||||
→ product_catalog
|
||||
```
|
||||
|
||||
渠道规则关联的产品只用于说明该渠道执行时对应的财务商品,
|
||||
不能反向决定路由。
|
||||
|
||||
成本与财务:
|
||||
|
||||
```text
|
||||
cost_versions -- 成本规则与价格版本,是输入真源
|
||||
cost_snapshots -- 单个订单项在某时点的成本事实,可重建
|
||||
sales_daily_facts -- 收入、退款、成本汇总,可重建
|
||||
finance_journal_* -- 总账凭证,可重建
|
||||
```
|
||||
|
||||
## 四、单一真源矩阵
|
||||
|
||||
| 信息 | 唯一写入方 | 唯一真源 | 明确禁止 |
|
||||
| --- | --- | --- | --- |
|
||||
| 平台订单与订单项 | 订单接入服务 | `orders` / `order_items` | 财务或履约服务改写平台事实 |
|
||||
| 平台原始报文 | 各平台适配器 | 原始表 / `raw_payload_json` | 覆盖历史报文 |
|
||||
| 中文内部 SKU | 商品身份服务 | `internal_skus` | 各业务表各自发明同义 SKU |
|
||||
| 平台字段到内部 SKU | 映射服务 | `internal_sku_mappings` | 按名称猜测渠道 |
|
||||
| 主渠道与兜底 | 路由服务 | `sku_channel_routes` | UI 根据商品前缀筛选 |
|
||||
| 当前履约状态 | 履约状态服务 | `fulfillments` | 多服务直接更新订单项 |
|
||||
| 执行尝试 | 履约尝试服务 | `fulfillment_attempts` | 用最大 ID 猜当前任务 |
|
||||
| 当前异常 | 履约异常服务 | `fulfillment_issues` | 自由 JSON 字符串代替问题模型 |
|
||||
| 标准商品 | 商品主数据服务 | `product_catalog` | 用商品来源反推渠道 |
|
||||
| 平台商品到财务商品 | 商品归一服务 | `channel_product_mappings` | 人工在多个页面重复维护 |
|
||||
| 成本规则 | 成本中心 | `cost_versions` | 业务表直接改金额 |
|
||||
| 成本事实 | 成本快照服务 | `cost_snapshots` | 改价覆盖历史 |
|
||||
| 销售事实 | 事实服务 | `sales_daily_facts` | 报表直接从订单表现算另一套 |
|
||||
| 总账 | 总账服务 | `finance_journal_*` | 业务端直接写凭证 |
|
||||
| 页面投影 | 只读投影 | `v_*` / materialized view | 页面自行拼口径 |
|
||||
|
||||
## 五、当前系统的问题证据
|
||||
|
||||
2026-11-08 生产只读核对结果:
|
||||
|
||||
- 生产迁移 `146`,本地开发基线迁移 `158`。
|
||||
- 启用标准商品 `1127`:`aff:` 30、`tpl:` 903、`tpv:` 46、`man:` 148。
|
||||
- `man:` 商品中只有 105 个当前主渠道为人工;41 个已走其他主渠道,2 个无主渠道。
|
||||
- 人工页头部显示 `107`,商品列表显示 `148`,相差的 41 个就是跨渠道旧商品。
|
||||
- 41 个跨渠道 `man:` 商品中:卡券 33、自动发货 3、接单平台 2、统一结算 3。
|
||||
- 另有 2 个 `man:` 商品无主渠道,但保留人工配置,属于人工兜底。
|
||||
- 自动发货的 3 个商品中,`man:suit_shadow_gothic` 与 `man:套装-狂沙舞者`
|
||||
有有效人工兜底配置,必须保持 active,但不能出现在“人工客服”页签。
|
||||
- 最终可归档对象是 36 个:卡券 33、接单平台 2、无人工兜底的自动发货 1。
|
||||
- 生产活动履约视图共 31744 行,其中 1226 行仍有结构化异常:
|
||||
- 用户退款 532;
|
||||
- 平台取消 126;
|
||||
- 缺内部 SKU 29;
|
||||
- 缺渠道 26;
|
||||
- 人工配置缺失 19;
|
||||
- 其余为载体重试、人工复核、状态不一致等。
|
||||
- 当前任务重复为 0,多个活跃工单为 0,说明“当前尝试”约束已经开始生效。
|
||||
|
||||
这些问题证明:
|
||||
|
||||
1. 旧模型不是完全不可用,但多个真源同时存在。
|
||||
2. 页面已经出现“总览按渠道、列表按来源”的口径分叉。
|
||||
3. 历史清理功能曾经存在,但在后续重构中被移除。
|
||||
4. 文档基线和生产基线不一致,旧文档仍在被当作现行依据。
|
||||
|
||||
## 六、数据保留与重建边界
|
||||
|
||||
本次重构允许清理派生数据,但必须严格分级。
|
||||
|
||||
### A 级:永久保留,不得删除或重写历史
|
||||
|
||||
- `orders`
|
||||
- `order_items` 的原始平台字段
|
||||
- 平台原始订单表与原始报文字段
|
||||
- 平台售后、退款、支付事实
|
||||
- `work_orders`、`work_order_shares`、`work_order_events`
|
||||
- `fulfillment_tasks` 中真实执行与结果记录
|
||||
- `worker_wallet_ledgers`、`fund_accounts` 的真实资金流水
|
||||
- `admin_audit_logs`
|
||||
- 财务期间、已确认退款和真实资金账户
|
||||
|
||||
A 级数据只能追加新事件或做字段兼容迁移,不能为了“模型整齐”重写历史事实。
|
||||
|
||||
### B 级:业务输入,必须迁移而不是重建
|
||||
|
||||
- `internal_sku_mappings`
|
||||
- `internal_sku_channels` 中仍有效的路由意图
|
||||
- `work_product_rules` 及模板匹配配置
|
||||
- `manual_fulfillment_configs`
|
||||
- `product_catalog` 中仍有效的标准商品
|
||||
- `channel_product_mappings`
|
||||
- `cost_versions`
|
||||
- 第三方平台配置、店铺配置和账号配置
|
||||
|
||||
迁移时必须人工核对冲突,不得自动选最新或按出现次数猜测。
|
||||
|
||||
### C 级:可删除并从 A/B 级重建
|
||||
|
||||
- `cost_snapshots`
|
||||
- `cost_exceptions`
|
||||
- `sales_daily_facts`
|
||||
- `finance_journal_entries` / `finance_journal_lines`
|
||||
- `fulfillments` / `fulfillment_attempts` / `fulfillment_issues`
|
||||
- `v_fulfillment_item_state` 及其依赖投影
|
||||
- 商品统计投影、渠道统计投影、页面汇总缓存
|
||||
- 管道水位与失败重试状态
|
||||
|
||||
重建前必须备份;重建后必须通过 A/B 级数据守恒检查。
|
||||
|
||||
### D 级:兼容期结束后删除
|
||||
|
||||
- `product_channel_capabilities`
|
||||
- `manual_sku_registry` 中可由配置重建的登记行
|
||||
- 订单项上的重复履约结果字段,在正式模型切换后删除
|
||||
- 商品表中的历史来源前缀判断代码
|
||||
- 旧路由补丁脚本和一次性迁移工具
|
||||
|
||||
## 七、UI 与 API 统一口径
|
||||
|
||||
“标准商品目录”的页签必须表示**当前路由状态**,不是商品来源:
|
||||
|
||||
```text
|
||||
全部
|
||||
自动发货
|
||||
接单平台
|
||||
第三方卡券
|
||||
人工客服
|
||||
统一结算
|
||||
未路由
|
||||
```
|
||||
|
||||
商品来源作为独立列展示:
|
||||
|
||||
```text
|
||||
aff: / tpl: / wo: / tpv: / man:
|
||||
```
|
||||
|
||||
列表必须显示:
|
||||
|
||||
```text
|
||||
商品
|
||||
来源
|
||||
当前主渠道
|
||||
兜底渠道
|
||||
当前状态
|
||||
成本状态
|
||||
```
|
||||
|
||||
以下行为禁止:
|
||||
|
||||
- “人工客服”页签显示当前主渠道不是 `manual` 的商品。
|
||||
- 用 `product_catalog.category` 决定路由或页签。
|
||||
- 用 `man:` 前缀判断当前人工订单量。
|
||||
- 通过商品名称或标题自动猜测渠道。
|
||||
- 同一页面使用两个不同统计 SQL。
|
||||
|
||||
统一读模型至少提供:
|
||||
|
||||
```text
|
||||
product_id
|
||||
canonical_sku
|
||||
canonical_name
|
||||
source_kind
|
||||
internal_sku_id
|
||||
current_primary_channel
|
||||
fallback_channels
|
||||
manual_config_id
|
||||
current_status
|
||||
has_active_cost
|
||||
```
|
||||
|
||||
## 八、存量数据处理方案
|
||||
|
||||
### 8.1 已被其他渠道接管的 `man:` 商品
|
||||
|
||||
处理原则:
|
||||
|
||||
1. 先确认目标主渠道已有活动商品。
|
||||
2. 将仍指向旧 `man:` 的人工兜底改指目标商品。
|
||||
3. 保留订单项、成本版本、成本快照和历史引用。
|
||||
4. 只把旧 `man:` 商品置为 `archived`,不硬删除。
|
||||
5. 如果历史成本快照必须保留旧商品维度,不改变历史快照。
|
||||
|
||||
预期清理范围:
|
||||
|
||||
- 33 个卡券重复商品;
|
||||
- 2 个接单平台重复商品;
|
||||
- 1 个没有有效人工兜底配置的自动发货重复商品。
|
||||
|
||||
以上共 36 个 `manual_normalization` 旧商品,属于可确认归档对象。
|
||||
|
||||
另外 2 个自动发货 `man:` 商品有有效人工兜底配置,不归档、不进入人工主渠道页签。
|
||||
|
||||
### 8.2 统一结算商品
|
||||
|
||||
3 个当前主渠道为 `on_account` 的商品不是人工商品。
|
||||
|
||||
处理方式:
|
||||
|
||||
- 保留商品和历史引用;
|
||||
- 增加统一结算分类;
|
||||
- 从人工页签移出;
|
||||
- 由 `on_account` 路由与结算成本口径管理。
|
||||
|
||||
### 8.3 无主渠道但有人工配置的商品
|
||||
|
||||
目前有 2 个,属于合法人工兜底。
|
||||
|
||||
处理方式:
|
||||
|
||||
- 保留;
|
||||
- 在商品页显示“未路由 / 人工兜底”;
|
||||
- 不计入“已分配”;
|
||||
- 由运营决定是否补主渠道。
|
||||
|
||||
### 8.4 历史清理功能
|
||||
|
||||
`31b6d2d6` 曾实现跨渠道 `man:` 商品归档,但 `974044a4` 在人工 SKU 重构中删除了入口,
|
||||
并把筛选测试改成保留所有 `man:` 商品。
|
||||
|
||||
后续清理必须:
|
||||
|
||||
- 作为一次性数据迁移,而不是临时页面按钮;
|
||||
- 有 dry-run、数量、样本和备份;
|
||||
- 有真实 PostgreSQL 集成测试;
|
||||
- 不依赖“运营记得点清理”。
|
||||
|
||||
## 九、目标迁移路线
|
||||
|
||||
| 阶段 | 状态 | 是否改生产数据 |
|
||||
| --- | --- | --- |
|
||||
| 0 口径冻结与文档收口 | 已完成 | 否 |
|
||||
| 1 只读审计与领域约束 | 本地进行中 | 否 |
|
||||
| 2 建立目标身份与投影 | 本地完成 | 只新增兼容结构 |
|
||||
| 3 迁移路由与商品配置 | 本地进行中 | 是,需备份 |
|
||||
| 4 重建履约模型 | 未开始 | 是,需断代 |
|
||||
| 5 重建财务派生数据 | 未开始 | 是,需备份与对账 |
|
||||
| 6 停止旧写路径并删除兼容层 | 未开始 | 是,需观察期结束 |
|
||||
|
||||
### 阶段 0:口径冻结与文档收口
|
||||
|
||||
状态:本次完成。
|
||||
|
||||
产出:
|
||||
|
||||
- 本文件成为唯一权威。
|
||||
- 旧业务架构文档全部归档。
|
||||
- `docs/README.md` 只保留入口。
|
||||
- `AGENTS.md` 固定执行规则。
|
||||
|
||||
验收:
|
||||
|
||||
- 活跃文档中不再存在竞争性的架构结论。
|
||||
- 所有 Agent 和开发者从本文件开始。
|
||||
|
||||
### 阶段 1:只读审计与领域约束
|
||||
|
||||
目标:
|
||||
|
||||
- 不改变生产数据,先建立全量审计。
|
||||
- 核对内部 SKU、路由、商品、履约和财务的冲突。
|
||||
|
||||
工作:
|
||||
|
||||
1. 建立内部 SKU 重复与合并候选报告。
|
||||
2. 建立商品来源与主渠道冲突报告。
|
||||
3. 建立无主渠道、多主渠道、无载体和退款混入履约报告。
|
||||
4. 建立成本快照无法重建报告。
|
||||
5. 为每类冲突定义责任角色和处理动作。
|
||||
|
||||
验收 SQL:
|
||||
|
||||
```text
|
||||
同一内部 SKU 主渠道数 > 1 必须为 0
|
||||
启用商品无 source_kind 必须为 0
|
||||
人工配置指向非 man 商品 必须为 0
|
||||
当前主渠道非 manual 的 man 商品出现在人工页 必须为 0(保留则必须有显式兜底)
|
||||
assigned 且 carrier_status=missing 必须进入异常队列
|
||||
退款/取消出现在普通履约队列 必须为 0
|
||||
同一订单项当前尝试 > 1 必须为 0
|
||||
```
|
||||
|
||||
### 阶段 2:建立目标身份与投影
|
||||
|
||||
目标:
|
||||
|
||||
- 建立 `internal_skus`。
|
||||
- 为 `product_catalog` 增加 `source_kind` 和 `internal_sku_id`。
|
||||
- 建立统一商品投影 `v_product_current`。
|
||||
- 建立统一履约投影 `v_fulfillment_current`。
|
||||
|
||||
本地已完成身份表、商品来源字段和 `v_product_current`,并已切换商品列表、
|
||||
总览与渠道映射的读取口径。生产未执行。
|
||||
|
||||
本地产出:
|
||||
|
||||
- 变更前备份:`backups/postgres/order_site-pre-unified-20261108.dump`,
|
||||
SHA-256 `661d7751d76fcd7db80af92e97d1e84245a25c60b0ec76b8d83ca930fcbb5142`。
|
||||
- 迁移 `154`:建立 `internal_skus`、`sku_channel_routes` 与兼容同步触发器。
|
||||
- 迁移 `155`:建立 `v_product_current`,并归档可确认失效的旧 `man:` 商品。
|
||||
- 迁移 `156`:修复 `source_kind` 默认值导致的前缀回填失效。
|
||||
- 迁移 `157`:保证只有兜底配置的 SKU 不会被误升级成主渠道。
|
||||
- 迁移 `158`:禁止 `man:` 来源直接冒充人工主渠道;没有 primary route 时显示“未路由”。
|
||||
- 商品列表、总览、渠道映射和商品下拉统一读取商品当前渠道。
|
||||
- 运行期代码停止写入 `product_channel_capabilities`,该表仅保留到兼容期结束。
|
||||
|
||||
验收:
|
||||
|
||||
- 旧字段与新投影差异有清单。
|
||||
- 商品列表和总览读取同一投影后数量一致。
|
||||
- 目前 41 个跨渠道 `man:` 商品和 2 个无主渠道商品全部能分类。
|
||||
|
||||
### 阶段 3:迁移路由与商品配置
|
||||
|
||||
目标:
|
||||
|
||||
- 将 `internal_sku_channels` 迁移到 `sku_channel_routes`。
|
||||
- 将人工配置、卡券配置、自动发货配置和接单模板配置关联到 `internal_sku_id`。
|
||||
- 清理旧商品和错误兜底。
|
||||
|
||||
规则:
|
||||
|
||||
- 一个内部 SKU 一个主渠道。
|
||||
- 其余渠道全部显式 `fallback`。
|
||||
- 自动创建的标准商品必须有 `source_kind`。
|
||||
- 历史 `man:` 清理只归档,不删除。
|
||||
|
||||
验收:
|
||||
|
||||
- 路由迁移前后主渠道结果一致。
|
||||
- 人工页数量等于当前人工渠道商品数。
|
||||
- 卡券和统一结算不再出现在人工页。
|
||||
|
||||
### 阶段 4:重建履约模型
|
||||
|
||||
目标:
|
||||
|
||||
- 以 A 级原始订单和真实载体为输入,重建 `fulfillments`、`fulfillment_attempts`、
|
||||
`fulfillment_issues`。
|
||||
- 停止写入过渡字段。
|
||||
|
||||
工作:
|
||||
|
||||
1. 清空旧影子履约和派生异常。
|
||||
2. 回填当前履约单。
|
||||
3. 回填当前尝试与历史尝试。
|
||||
4. 生成结构化 issue。
|
||||
5. 对比新旧读模型。
|
||||
6. 切换后台与调度读路径。
|
||||
|
||||
验收:
|
||||
|
||||
- 同一订单项只有一个当前尝试。
|
||||
- 所有 `assigned` 都有明确 `carrier_status` 或开放 issue。
|
||||
- 退款、取消进入售后队列。
|
||||
- 页面按钮作用域与后端动作一致。
|
||||
|
||||
### 阶段 5:重建财务派生数据
|
||||
|
||||
目标:
|
||||
|
||||
- 保留 A 级订单、退款事实和 B 级配置。
|
||||
- 删除 C 级成本和财务派生数据并从新模型重建。
|
||||
|
||||
重建顺序:
|
||||
|
||||
```text
|
||||
product normalization
|
||||
→ cost snapshot
|
||||
→ sales facts
|
||||
→ journal
|
||||
→ reconciliation
|
||||
```
|
||||
|
||||
验收:
|
||||
|
||||
- 收入总额守恒。
|
||||
- 退款总额守恒。
|
||||
- 成本快照无重复。
|
||||
- 事实与总账可对平。
|
||||
- 所有成本缺失有结构化异常。
|
||||
|
||||
### 阶段 6:停止旧写路径并删除兼容层
|
||||
|
||||
只有前五个阶段持续稳定后才允许:
|
||||
|
||||
- 删除 `product_channel_capabilities`。
|
||||
- 删除 `manual_sku_registry` 的派生行。
|
||||
- 删除订单项重复渠道字段。
|
||||
- 删除商品前缀业务判断。
|
||||
- 删除旧管道、旧同步脚本和兼容 API。
|
||||
|
||||
禁止一次性同时删除旧字段和旧数据。
|
||||
|
||||
## 十、测试与生产门禁
|
||||
|
||||
以下检查必须进入代码测试或每日生产审计。
|
||||
|
||||
### 数据模型
|
||||
|
||||
- 一个内部 SKU 最多一个 primary route。
|
||||
- 一个 fulfillment 最多一个 current attempt。
|
||||
- 一个订单项最多一个 fulfillment。
|
||||
- issue code 只能来自受控枚举。
|
||||
- assigned 必须有 route 和 channel。
|
||||
|
||||
### 商品
|
||||
|
||||
- 每个 active product 必须有 `source_kind`。
|
||||
- `source_kind` 与渠道专用商品类型一致。
|
||||
- 人工页数量必须等于当前 primary manual 商品数。
|
||||
- 总览、列表、导出必须使用同一投影。
|
||||
- 旧 `man:` 商品不得在没有主渠道或收口状态时继续显示为人工。
|
||||
|
||||
### 履约
|
||||
|
||||
- 用户退款、平台取消不得出现在普通补载体队列。
|
||||
- 同一订单项不得同时有活跃工单和活跃自动发货任务。
|
||||
- 当前尝试必须是已存在且唯一的历史尝试。
|
||||
- 所有重试动作必须按 issue_code 限定作用域。
|
||||
|
||||
### 财务
|
||||
|
||||
- 成本事实不可变,只能新增、替代或冲减。
|
||||
- 事实、总账、退款和订单收入必须可对平。
|
||||
- 财务重建必须从 A 级数据可重复执行。
|
||||
|
||||
### 文档
|
||||
|
||||
- 任何架构变更必须更新本文件。
|
||||
- 旧文档不得再标记为“现行”。
|
||||
- 文档中的迁移号和代码基线必须与生产一致。
|
||||
|
||||
## 十一、禁止事项
|
||||
|
||||
1. 不删除原始订单、平台报文、真实工作单、真实资金流水和审计日志。
|
||||
2. 不根据商品名称、前缀或分类猜测履约渠道。
|
||||
3. 不让多个服务同时写履约核心状态。
|
||||
4. 不用自由 JSON 字符串代替结构化 issue。
|
||||
5. 不以“最新”“出现最多”或“看起来像”解决映射冲突。
|
||||
6. 不在没有投影和差异报告时切换读写路径。
|
||||
7. 不把历史清理做成依赖运营点击的临时按钮。
|
||||
8. 不为兼容旧口径保留第二份“现行文档”。
|
||||
9. 不在一次发布中同时完成数据清理、模型切换和旧字段删除。
|
||||
10. 不把“已经跑过测试”当成生产口径正确的证明。
|
||||
|
||||
## 十二、执行后的文档结构
|
||||
|
||||
```text
|
||||
AGENTS.md
|
||||
常驻规则、任务路由、数据安全边界
|
||||
|
||||
docs/README.md
|
||||
文档总入口
|
||||
|
||||
docs/统一订单履约与财务模型-权威版.md
|
||||
唯一业务与架构权威
|
||||
|
||||
docs/部署启动与数据库重建.md
|
||||
docs/数据库备份与恢复.md
|
||||
docs/数据库SQL约束与运维.md
|
||||
运维参考
|
||||
|
||||
docs/91卡券/
|
||||
docs/发货平台-2/
|
||||
docs/抖音-码速达/
|
||||
docs/行业电子凭证/
|
||||
docs/affiliate-dash-发货平台/
|
||||
外部协议与平台参考,不得覆盖本文件
|
||||
|
||||
docs/archive/
|
||||
历史方案、旧口径和一次性分析
|
||||
```
|
||||
|
||||
## 十三、当前下一步
|
||||
|
||||
本轮只完成文档和计划,不修改业务代码、不执行生产数据清理。
|
||||
|
||||
后续按以下顺序启动:
|
||||
|
||||
1. 完成阶段 1 的只读审计脚本与冲突清单。
|
||||
2. 确定 `internal_skus`、`sku_channel_routes`、`product_catalog.source_kind`
|
||||
的最终字段和迁移顺序。
|
||||
3. 先建立投影,不直接切换写路径。
|
||||
4. 清理派生数据前先做可恢复备份。
|
||||
5. 每个阶段单独验收,不合并成一次性大迁移。
|
||||
|
||||
Reference in New Issue
Block a user