docs: 补充三块执行载体与通用成本中心方案
- 新增 docs/成本中心与三块履约模型.md:三块执行载体、统一成本中心、销售事实表、人工 case 模型 - 同步 docs/README.md 口径(执行载体三块、成本只改一处、报表维度) - 财务系统集成方案 / 影子总账说明 / 多发货平台链路 补充前置关系与边界 - 项目全量分析报告补充生产只读数据与 C1~C5 风险
This commit is contained in:
+15
-3
@@ -3,7 +3,7 @@
|
||||
> 最后校准:2026-10-17,代码基线 `main @ 6850bc64`。
|
||||
> 本文是 `docs/` 的唯一入口。新增文档必须在上表登记状态;过期文档不再直接改写结论,统一移入 `docs/archive/`。
|
||||
|
||||
## 一、先记住三条口径
|
||||
## 一、先记住四条口径
|
||||
|
||||
### 1. 来源只有三个,不是四个
|
||||
|
||||
@@ -19,9 +19,18 @@
|
||||
|
||||
- 骨架:`orders` + `order_items`
|
||||
- 买家凭证:快手电子凭证(`kuaishou_industry_vouchers`)或抖音券(`redeem_certificates`)
|
||||
- 执行载体:`affiliate_dash` 自动发货任务,或 `work_orders` 工单,二者业务上互斥
|
||||
- 执行载体只有三种:`affiliate_dash` 自动发货、`work_orders` 工单、`manual` 人工客服
|
||||
- 三者业务上互斥;无自动任务且无工单的已支付订单项就是人工块,必须进入人工 case,不能静默消失
|
||||
|
||||
### 3. 文档状态
|
||||
### 3. 成本只在一个地方改
|
||||
|
||||
- 商品主数据:`product_catalog`
|
||||
- 渠道 SKU 映射:`channel_product_mappings`
|
||||
- 成本金额:只在 `cost_versions` 改,按生效日期新增版本
|
||||
- 订单/工单/人工单只保存 `cost_snapshot_id`,历史成本永不回写
|
||||
- 自动发货、接单平台、人工客服共用同一个成本解析器;匹配不到成本进入 `cost_missing`,不默认 0
|
||||
|
||||
### 4. 文档状态
|
||||
|
||||
| 状态 | 含义 |
|
||||
| --- | --- |
|
||||
@@ -34,6 +43,7 @@
|
||||
| 文档 | 状态 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| [项目全量分析报告-2026-10-17.md](项目全量分析报告-2026-10-17.md) | 现行 | 当前架构、业务链路、风险与改进路线 |
|
||||
| [成本中心与三块履约模型.md](成本中心与三块履约模型.md) | 现行(方案) | 自动发货/接单平台/人工客服三块、统一成本中心、销售事实与人工监管 |
|
||||
| [财务系统集成方案.md](财务系统集成方案.md) | 现行(方案) | 财务系统边界、复式记账模型、分期落地 |
|
||||
| [影子总账说明.md](影子总账说明.md) | 现行(方案) | 影子总账的定义、运行方式、对账与转正标准 |
|
||||
| [接单模板匹配引擎重构设计.md](接单模板匹配引擎重构设计.md) | 现行(P0/P1 已实施) | `kuaishou-91 / pdd / douyin-mashida` 三来源匹配引擎 |
|
||||
@@ -72,3 +82,5 @@
|
||||
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`。
|
||||
|
||||
@@ -23,6 +23,18 @@ kuaishou-cloud / kuaishou-feifei 通道已下线,affiliate-dash 负责真实
|
||||
快手电子凭证负责把领取页里的核销码输入步骤自动化
|
||||
```
|
||||
|
||||
### 1.1 执行载体三块
|
||||
|
||||
真正决定成本和监管方式的是订单项的**执行载体**:
|
||||
|
||||
| 载体 | 当前实现 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `affiliate_dash` | 自动履约任务 | 上游固定成本,适合店铺/日期/皮肤销量统计 |
|
||||
| `work_order` | 接单平台工单 | 变动成本,适合影子总账与打手结算 |
|
||||
| `manual` | 目前没有显式 case | 无自动任务且无工单的已支付订单项;当前最大监管缺口 |
|
||||
|
||||
详细设计见 [../成本中心与三块履约模型.md](../成本中心与三块履约模型.md)。
|
||||
|
||||
## 2. 目标链路
|
||||
|
||||
```text
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
> 代码基线:`main @ 6850bc64`
|
||||
> 配套方案:[财务系统集成方案.md](财务系统集成方案.md)
|
||||
> 一句话:**影子总账是一套“跟着真实业务跑、但暂时不接管余额”的复式会计账。** 它先把每一笔业务翻译成借贷分录,和现有钱包/订单/提现数据逐日对账;确认长期对得平之后,再让它成为正式总账。
|
||||
>
|
||||
> 边界:影子总账解决“钱怎么记、怎么对”,不负责“商品是什么、成本是多少、人工谁处理”。商品与成本见 [成本中心与三块履约模型.md](成本中心与三块履约模型.md),人工履约见同一文档第八节。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,534 @@
|
||||
# 成本中心与三块履约模型
|
||||
|
||||
> 状态:**现行分析 / 设计基线(未写代码)**
|
||||
> 代码基线:`main @ 6850bc64`
|
||||
> 数据基线:2026-10-17 生产库只读聚合(`default_transaction_read_only=on`,仅 SELECT,无写入)
|
||||
> 关联:
|
||||
> - [项目全量分析报告-2026-10-17.md](项目全量分析报告-2026-10-17.md)
|
||||
> - [影子总账说明.md](影子总账说明.md)
|
||||
> - [财务系统集成方案.md](财务系统集成方案.md)
|
||||
|
||||
---
|
||||
|
||||
## 一、先纠正一个口径:三块不是“订单来源”,是“执行载体”
|
||||
|
||||
同一个来源的订单,可能走自动发货、接单平台或人工。正确的拆分维度是**订单项最终由谁履约**:
|
||||
|
||||
| 块 | 执行载体 | 成本特征 | 监管重点 |
|
||||
| --- | --- | --- | --- |
|
||||
| ① 自动发货 | `affiliate_dash` 履约任务 | 固定成本,按皮肤/SKU,很少变化 | 上游成本、店铺/日期/皮肤销量 |
|
||||
| ② 接单平台 | `work_orders` + 拼单份额 | 变动成本,按模板/单价/固定价/拼单 | 发单价格、打手提现、售后追缴、毛利 |
|
||||
| ③ 人工客服 | 目前**无载体** | 人工工时/按单服务成本 | 谁处理、何时完成、证据、成本、异常 |
|
||||
|
||||
硬不变式:
|
||||
|
||||
```text
|
||||
一个订单项 = 订单骨架 + 买家凭证 + 一个执行载体
|
||||
执行载体 ∈ { affiliate_dash, work_order, manual }
|
||||
```
|
||||
|
||||
当前代码对抖音有 `snapshot.classification` 守卫,但 91/PDD 仍然主要靠 `isConfigured=false` 隐式表达“人工”。这会导致人工单在系统里没有显式状态,也没有处理记录。
|
||||
|
||||
---
|
||||
|
||||
## 二、生产数据证据(2026-10-17 只读)
|
||||
|
||||
### 2.1 最近 30 天无载体订单
|
||||
|
||||
“无载体”定义:已支付订单项,既没有 `fulfillment_tasks`,也没有 `work_orders`。
|
||||
|
||||
| 来源 | 无载体订单数 | 无载体金额 | 说明 |
|
||||
| --- | ---: | ---: | --- |
|
||||
| 91 | **42,391** | 约 ¥624 万 | 几乎全部 `snapshot.isConfigured=false` |
|
||||
| PDD | **2,258** | 约 ¥39 万 | 几乎全部 `isConfigured=false` |
|
||||
| 抖音 | **8** | 约 ¥595 | 仅 8 单未命中,抖音分流已基本收口 |
|
||||
|
||||
补充:
|
||||
|
||||
- 2026-09 无载体订单项约 **37,708**;2026-08 约 **46,322**。这不是历史遗留,是持续发生。
|
||||
- `manual_dispatch` 任务全库只有 **6 条**,全部为 `manual_review`。
|
||||
- 这些无载体订单的 `claim_status` 全部为 `active`,没有完成信号。
|
||||
- 已验收工单对应的订单,`orders.order_status` 仍然是 `paid`:**订单主状态不能代表履约完成**。
|
||||
|
||||
结论:**人工块不是少量兜底,而是每天上千单、金额很大的主业务块,但基本没有进入系统任务与状态机。**
|
||||
|
||||
### 2.2 接单成本占比
|
||||
|
||||
最近 30 天已验收工单:
|
||||
|
||||
| 来源 | 工单数 | 打手报酬 | 订单金额口径 | 报酬/订单金额 |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| 91 | 60,902 | ¥235.9 万 | ¥274.4 万 | 86.0% |
|
||||
| PDD | 1,289 | ¥20.3 万 | ¥25.4 万 | 80.0% |
|
||||
| 抖音 | 478 | ¥2.14 万 | ¥2.21 万 | 96.5% |
|
||||
|
||||
**注意:91 的 `orders.total_amount` 来自 `maxAmount`(91 给的可接受金额/结算口径),PDD 来自 `order_amount`,抖音来自 `pay_amount`。三者不是同一财务口径,不能直接相加当收入。**
|
||||
|
||||
### 2.3 SKU 口径问题
|
||||
|
||||
最近 30 天,同一个商品名会对应多个 `sku_code`:
|
||||
|
||||
- 「指挥官密钥1个」:**27 个** `sku_code`
|
||||
- 「1个精致荣耀专属礼盒」:10 个
|
||||
- 「苏尔南钻石100颗」:35 个
|
||||
|
||||
因此:
|
||||
|
||||
- 不能直接按 `sku_code` 做“什么皮肤卖了多少”;
|
||||
- 必须先建 `product_catalog` + `channel_product_mappings`,把平台 SKU 归一到 `canonical_product_id`;
|
||||
- 数量也不能只读 `order_items.quantity`,要从 SKU 文本解析(如「指挥官密钥5个」)。
|
||||
|
||||
### 2.4 当前订单结构
|
||||
|
||||
最近 30 天,三个来源的订单基本都是 **1 个订单 1 个订单项**。这让第一版销售统计可以做简化,但模型必须按“订单项”设计,不能把“一单一品”写死。
|
||||
|
||||
---
|
||||
|
||||
## 三、统一商品维度:先解决“什么皮肤”
|
||||
|
||||
### 3.1 商品主数据
|
||||
|
||||
```text
|
||||
product_catalog
|
||||
id
|
||||
canonical_sku -- 内部标准编码,统计/成本/报表唯一口径
|
||||
product_name -- 展示名
|
||||
category -- 皮肤/礼包/密钥/改名卡/其他
|
||||
game -- 和平精英等
|
||||
status
|
||||
attributes_json
|
||||
```
|
||||
|
||||
### 3.2 渠道 SKU 映射
|
||||
|
||||
```text
|
||||
channel_product_mappings
|
||||
id
|
||||
provider -- kuaishou-91 / pdd / douyin-mashida
|
||||
shop_id
|
||||
external_sku_code -- 平台原始 sku_code / productNo / code
|
||||
external_sku_name
|
||||
canonical_product_id
|
||||
valid_from / valid_to
|
||||
confidence
|
||||
source -- manual / import / rule
|
||||
```
|
||||
|
||||
匹配优先级:
|
||||
|
||||
```text
|
||||
shop_id + external_sku_code
|
||||
> provider + external_sku_code
|
||||
> external_sku_name 归一化
|
||||
> 人工映射
|
||||
```
|
||||
|
||||
匹配不到的商品进入 `product_mapping_missing` 异常队列,**不能直接拿原始 `sku_code` 当报表维度**。
|
||||
|
||||
### 3.3 店铺维度
|
||||
|
||||
`shop_id` 是稳定键;`shop_name` 会变。报表以 `shop_id` 为准,展示名取最新或按时间快照。
|
||||
|
||||
---
|
||||
|
||||
## 四、统一成本中心
|
||||
|
||||
### 4.1 当前成本散落点
|
||||
|
||||
| 成本 | 当前来源 | 问题 |
|
||||
| --- | --- | --- |
|
||||
| 自动发货采购成本 | `affiliate-dash` 商品接口 `cost_amount` | 代码已映射,但没有落库/展示/快照 |
|
||||
| 工单报酬 | `work_product_rules.reward_amount` / `unit_price_fen` / `sharing_unit_reward` | 价格与匹配规则混在一张表,改价无版本 |
|
||||
| 工单实际成本 | `work_orders.reward_amount`、`share_reward` | 实际值有了,但没有统一成本项/版本 |
|
||||
| 人工成本 | 无 | 完全缺失 |
|
||||
| 平台费/支付费/售后损失 | 分散或未建模 | 无法算真实毛利 |
|
||||
|
||||
### 4.2 成本类型
|
||||
|
||||
| 类型 | 说明 | 典型单位 |
|
||||
| --- | --- | --- |
|
||||
| `auto_purchase` | 自动发货上游采购成本 | 按件 |
|
||||
| `work_order_reward` | 接单平台打手报酬 | 按件/按单/按份 |
|
||||
| `manual_service` | 人工客服成本 | 按单/按小时 |
|
||||
| `platform_fee` | 平台服务费/佣金 | 按单/按比例 |
|
||||
| `payment_fee` | 支付通道费 | 按单/按比例 |
|
||||
| `after_sales_loss` | 售后损失/赔付 | 按单 |
|
||||
| `shipping_other` | 其他履约费用 | 按单 |
|
||||
|
||||
### 4.3 成本表
|
||||
|
||||
```text
|
||||
cost_items
|
||||
id
|
||||
cost_key
|
||||
cost_type
|
||||
name
|
||||
unit -- per_item / per_order / per_hour / percent
|
||||
currency
|
||||
status
|
||||
|
||||
cost_versions
|
||||
id
|
||||
cost_item_id
|
||||
amount_fen -- 固定金额;percent 类型用 rate_bps
|
||||
rate_bps
|
||||
effective_from
|
||||
effective_to
|
||||
scope_type -- global / provider / shop / product / rule
|
||||
provider
|
||||
shop_id
|
||||
canonical_product_id
|
||||
work_product_rule_id
|
||||
source -- manual / upstream_sync / import
|
||||
status -- draft / active / retired
|
||||
change_reason
|
||||
created_by
|
||||
approved_by
|
||||
```
|
||||
|
||||
### 4.4 成本快照
|
||||
|
||||
```text
|
||||
cost_snapshots
|
||||
id
|
||||
order_id
|
||||
order_item_id
|
||||
work_order_id
|
||||
manual_case_id
|
||||
cost_item_id
|
||||
cost_version_id
|
||||
cost_type
|
||||
quantity
|
||||
unit_amount_fen
|
||||
total_amount_fen
|
||||
snapshot_stage -- estimated / actual / adjustment
|
||||
resolved_at
|
||||
metadata_json
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
- 改价只新增 `cost_versions`,不覆盖历史;
|
||||
- 订单/工单/人工单创建或完成时写 `cost_snapshot`;
|
||||
- 匹配不到成本时写 `cost_missing`,**不能默认 0**;
|
||||
- 历史成本永远从快照读,不从当前成本表倒推。
|
||||
|
||||
### 4.5 “只改一个地方”的过渡方案
|
||||
|
||||
目标状态:
|
||||
|
||||
- 金额只在 `cost_versions` 改;
|
||||
- `work_product_rules` 只保留匹配条件 + 计价方式 + `cost_item_id`;
|
||||
- `channel_product_mappings` 引用自动发货 `cost_item_id`;
|
||||
- 人工成本引用 `manual_service` 成本项;
|
||||
- 业务表只保存 `cost_snapshot_id`。
|
||||
|
||||
过渡:
|
||||
|
||||
1. 给 `work_product_rules` 增加可空 `cost_item_id`;
|
||||
2. 有 `cost_item_id` 走成本中心;
|
||||
3. 没有则回退旧 `reward_amount/unit_price_fen`,标记 `legacy_cost_source`;
|
||||
4. 659 条规则逐步迁移;
|
||||
5. 全部迁移后旧字段变只读/删除。
|
||||
|
||||
这样不会一次性打断发单,又能逐步做到“成本改动只在一个地方”。
|
||||
|
||||
---
|
||||
|
||||
## 五、销售事实与店铺日报
|
||||
|
||||
### 5.1 销售事实表
|
||||
|
||||
```text
|
||||
sales_daily_facts
|
||||
stat_date -- Asia/Shanghai
|
||||
provider
|
||||
shop_id
|
||||
canonical_product_id
|
||||
sales_channel -- auto / work_order / manual
|
||||
order_count
|
||||
item_count
|
||||
quantity -- 归一化件数(SKU 文本解析后)
|
||||
gross_revenue_fen
|
||||
refund_fen
|
||||
net_revenue_fen
|
||||
auto_cost_fen
|
||||
work_order_cost_fen
|
||||
manual_cost_fen
|
||||
platform_fee_fen
|
||||
after_sales_loss_fen
|
||||
gross_profit_fen
|
||||
cost_missing_count
|
||||
```
|
||||
|
||||
### 5.2 三个必须统一的字段
|
||||
|
||||
1. **商品**:`canonical_product_id`,不是原始 `sku_code`。
|
||||
2. **数量**:`normalized_quantity`,不是简单的 `order_items.quantity`。
|
||||
3. **收入**:`revenue_amount_fen` + `revenue_basis`,不是直接 `orders.total_amount`。
|
||||
|
||||
收入口径建议:
|
||||
|
||||
| 来源 | 当前字段 | 建议 |
|
||||
| --- | --- | --- |
|
||||
| 91 | `maxAmount` | 明确是结算收入还是成本上限,再归一 |
|
||||
| PDD | `order_amount` | 作为订单收入候选 |
|
||||
| 抖音 | `pay_amount` | 作为买家支付收入候选 |
|
||||
|
||||
### 5.3 退款日期
|
||||
|
||||
现在只有 `pay_status=refunded` 和 `updated_at`,不足以做按日净销售。建议补 `refunded_at` / `refund_amount_fen`,或从退款事件表聚合。
|
||||
|
||||
### 5.4 统计实现
|
||||
|
||||
第一版可以用物化视图:
|
||||
|
||||
```text
|
||||
orders + order_items + channel_product_mappings + cost_snapshots
|
||||
-> sales_daily_facts
|
||||
```
|
||||
|
||||
数据量目前约 35 万订单、每天 4k+ 单,物化视图 + 索引足够;后续再改增量表。
|
||||
|
||||
---
|
||||
|
||||
## 六、自动发货块
|
||||
|
||||
```text
|
||||
订单项 -> 命中 affiliate_dash SKU 映射 -> fulfillment_task
|
||||
-> 上游商品成本 cost_amount -> cost_snapshot
|
||||
-> 履约完成 -> sales_daily_facts
|
||||
```
|
||||
|
||||
要点:
|
||||
|
||||
- 上游商品接口已有 `price_amount` / `cost_amount`,但当前只映射、不落库;需要同步到成本中心。
|
||||
- `price_amount` 是售价/积分,`cost_amount` 是成本,不能混用。
|
||||
- 成本变化生成新版本;变动超阈值告警/审批。
|
||||
- 店铺/日期/皮肤统计必须走 `canonical_product_id`,不能按原始 `sku_code`。
|
||||
- 统计件数要解析 SKU 文本中的数量。
|
||||
|
||||
---
|
||||
|
||||
## 七、接单平台块
|
||||
|
||||
```text
|
||||
订单项 -> 命中接单模板 -> work_order
|
||||
-> 创建/发布/抢单/验收 -> 工单报酬 -> cost_snapshot
|
||||
-> 押金冻结/释放/没收 -> 影子总账(负债,不直接进成本)
|
||||
-> 提现/售后/欠款 -> 影子总账
|
||||
```
|
||||
|
||||
要点:
|
||||
|
||||
- 工单报酬是主成本;押金是负债,不是成本。
|
||||
- 模板改价必须生成 `cost_versions`,不能直接改历史工单。
|
||||
- 工单实际结算金额写入 `cost_snapshot(actual)`。
|
||||
- 影子总账负责收入/成本/押金/提现/售后的复式记录;成本中心负责“金额是多少、用了哪个版本”。
|
||||
|
||||
生产数据提示:91/PDD/抖音已验收工单的报酬/订单金额分别约 86%/80%/96.5%。在收入口径未确认前,这个比例只能作为量级参考,不能直接当毛利率。
|
||||
|
||||
---
|
||||
|
||||
## 八、人工客服块(当前最需要补的)
|
||||
|
||||
### 8.1 问题本质
|
||||
|
||||
不是“客服效率低”,而是**人工单没有进入系统状态机**:
|
||||
|
||||
- 没有 case;
|
||||
- 没有处理人;
|
||||
- 没有开始/完成时间;
|
||||
- 没有交付证据;
|
||||
- 没有人工成本;
|
||||
- 订单完成状态无法回写。
|
||||
|
||||
### 8.2 载体判定
|
||||
|
||||
建议在订单项上增加显式字段:
|
||||
|
||||
```text
|
||||
carrier_type: affiliate_dash / work_order / manual
|
||||
carrier_status: pending / active / completed / failed / cancelled
|
||||
carrier_decided_at
|
||||
carrier_reason
|
||||
```
|
||||
|
||||
判定:
|
||||
|
||||
1. 命中自动发货 -> `affiliate_dash`
|
||||
2. 命中接单模板 -> `work_order`
|
||||
3. 都没有 -> `manual`
|
||||
4. 宽限期后仍无载体 -> 自动创建人工 case
|
||||
|
||||
### 8.3 人工 case 模型
|
||||
|
||||
```text
|
||||
manual_fulfillment_cases
|
||||
id
|
||||
case_no
|
||||
order_id
|
||||
order_item_id
|
||||
provider
|
||||
shop_id
|
||||
canonical_product_id
|
||||
quantity
|
||||
priority
|
||||
status
|
||||
assignee_admin_user_id
|
||||
assigned_at
|
||||
due_at
|
||||
started_at
|
||||
completed_at
|
||||
outcome -- delivered / refunded / failed / cancelled
|
||||
delivery_reference
|
||||
evidence_json
|
||||
cost_snapshot_id
|
||||
notes
|
||||
|
||||
manual_case_events
|
||||
id
|
||||
case_id
|
||||
event_type
|
||||
actor_type
|
||||
actor_id
|
||||
payload_json
|
||||
created_at
|
||||
```
|
||||
|
||||
状态:
|
||||
|
||||
```text
|
||||
pending_assign -> assigned -> processing -> waiting_customer
|
||||
-> pending_review -> completed / failed / cancelled
|
||||
```
|
||||
|
||||
### 8.4 监管规则
|
||||
|
||||
- 每个无载体订单必须有 case;
|
||||
- 完成必须填 outcome + 交付凭证/参考号;
|
||||
- 失败必须填原因并决定重试/退款/升级;
|
||||
- 高价值订单主管复核;
|
||||
- 超时自动升级;
|
||||
- 所有状态变更写 `manual_case_events`,不可改;
|
||||
- 客服不能私下改价/退款,必须走审批。
|
||||
|
||||
### 8.5 人工成本
|
||||
|
||||
- 按单固定成本:简单,先落地;
|
||||
- 按小时:`agent_hourly_rate × (completed_at - started_at)`;
|
||||
- 建议两者都记录:固定服务成本 + 工时,便于后续校准;
|
||||
- 完成时写 `cost_snapshot`;缺失进入 `cost_missing`。
|
||||
|
||||
### 8.6 监管指标
|
||||
|
||||
- 待处理量、平均等待、最长挂起;
|
||||
- 客服处理量、平均处理时长、完成率;
|
||||
- 退款率、投诉率、返工率;
|
||||
- 单均人工成本;
|
||||
- 无凭证完成率;
|
||||
- 同一买家/客服异常重复;
|
||||
- 高价值订单抽样复核。
|
||||
|
||||
### 8.7 与现有任务系统的关系
|
||||
|
||||
现有 `manual_dispatch` 任务只有 6 条,且缺少 assignee/SLA/证据/成本字段。建议:
|
||||
|
||||
- 新人工 case 作为主模型;
|
||||
- 如果存在对应 `manual_dispatch` 任务,完成时桥接现有完成接口;
|
||||
- 不把所有人工作业强行塞进 `fulfillment_tasks`。
|
||||
|
||||
---
|
||||
|
||||
## 九、三块统一数据流
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
O["订单项"] --> C["载体判定"]
|
||||
C -->|命中自动| A["affiliate_dash 任务"]
|
||||
C -->|命中模板| W["work_order"]
|
||||
C -->|都没有| M["manual_case"]
|
||||
|
||||
A --> CS["cost_snapshots"]
|
||||
W --> CS
|
||||
M --> CS
|
||||
|
||||
CS --> F["sales_daily_facts / 毛利"]
|
||||
A --> L["影子总账"]
|
||||
W --> L
|
||||
M --> L
|
||||
|
||||
P["product_catalog + channel_product_mappings"] --> F
|
||||
V["cost_items + cost_versions"] --> CS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十、分期落地
|
||||
|
||||
### P0:商品与销售事实(先能做报表)
|
||||
|
||||
- `product_catalog`
|
||||
- `channel_product_mappings`
|
||||
- `sales_daily_facts`(可先物化视图)
|
||||
- 数量归一、收入口径、退款日期补齐
|
||||
|
||||
### P1:成本中心影子期
|
||||
|
||||
- `cost_items` / `cost_versions` / `cost_snapshots`
|
||||
- 自动发货先接固定成本
|
||||
- 工单先接现有规则金额
|
||||
- 人工先接按单/按小时成本
|
||||
- 缺失成本进异常队列
|
||||
|
||||
### P2:人工 case
|
||||
|
||||
- 载体判定
|
||||
- 无载体自动建 case
|
||||
- 分配/SLA/证据/主管复核
|
||||
- 人工成本快照
|
||||
- 监管指标
|
||||
|
||||
### P3:影子总账
|
||||
|
||||
- 订单收入、工单成本、押金、提现、寄卖、售后
|
||||
- 日对账、差异清单
|
||||
- 连续对平后转正
|
||||
|
||||
---
|
||||
|
||||
## 十一、需要业务确认的问题
|
||||
|
||||
1. **91 的 `orders.total_amount = maxAmount` 到底是“我方收入”还是“成本上限”?**
|
||||
2. 收入确认时点:付款 / 发货 / 验收 / 售后期结束?
|
||||
3. 打手报酬是成本,还是代收代付?
|
||||
4. 自动发货的 `cost_amount` 是否稳定、是否含平台积分/汇率?
|
||||
5. 人工成本按单还是按小时?客服是否在系统内记录工时?
|
||||
6. 退款/仲裁按什么日期冲减收入?
|
||||
7. 平台服务费/支付通道费由谁承担?
|
||||
8. 高价值人工单的复核阈值是多少?
|
||||
|
||||
---
|
||||
|
||||
## 十二、生产只读与克隆建议
|
||||
|
||||
本次已通过 SSH 连接生产库并执行只读聚合:
|
||||
|
||||
```sql
|
||||
SET default_transaction_read_only = on;
|
||||
SET statement_timeout = '20s';
|
||||
```
|
||||
|
||||
没有写入、没有改表、没有改数据。
|
||||
|
||||
建议暂时不做全量克隆:
|
||||
|
||||
- 聚合数据已足够支撑第一轮设计;
|
||||
- 全量库包含买家信息、原始报文、平台凭据,复制到本地有安全风险;
|
||||
- 后续需要反复迭代 SQL 时,再做**选定表只读逻辑克隆**:`orders`、`order_items`、`work_orders`、`fulfillment_tasks`、`work_product_rules`、`worker_wallet_ledgers`、`worker_finance_requests`。
|
||||
|
||||
---
|
||||
|
||||
## 十三、一句话结论
|
||||
|
||||
**自动发货解决“固定成本 + 店铺/日期/皮肤销量”,接单平台解决“变动成本 + 影子总账”,人工客服解决“载体可见 + case 监管 + 人工成本”;三者共用一套商品主数据、成本中心和销售事实表,成本改价只发生在 `cost_versions` 一个地方。**
|
||||
+27
-2
@@ -55,6 +55,28 @@
|
||||
| 寄卖货款结算 | `consignment-deposit-repo.ts` | 采购成本/存货 → 应付卖家 |
|
||||
| 平台服务费/通道费 | 目前未单独建模 | 销售费用/财务费用 |
|
||||
|
||||
### 1.4 三块履约与成本中心的前置关系
|
||||
|
||||
财务总账不是孤立存在的,它需要先知道“这笔钱属于哪个商品、哪个店铺、哪个执行载体、用了哪个成本版本”:
|
||||
|
||||
| 块 | 载体 | 成本来源 | 财务侧 |
|
||||
| --- | --- | --- | --- |
|
||||
| 自动发货 | `affiliate_dash` | 上游固定 `cost_amount` → `cost_versions` | 采购成本 |
|
||||
| 接单平台 | `work_orders` | 模板价格 → `cost_versions` / 工单实际报酬快照 | 履约成本 + 押金负债 |
|
||||
| 人工客服 | `manual_fulfillment_cases` | 按单/按小时人工成本 | 人工成本 + 履约完成 |
|
||||
|
||||
因此建议顺序是:
|
||||
|
||||
```text
|
||||
商品主数据 + 渠道SKU映射
|
||||
-> 成本中心(cost_items / cost_versions / cost_snapshots)
|
||||
-> 销售事实(sales_daily_facts)
|
||||
-> 影子总账(finance_*)
|
||||
-> 对账 / 转正
|
||||
```
|
||||
|
||||
详细设计见 [成本中心与三块履约模型.md](成本中心与三块履约模型.md)。
|
||||
|
||||
---
|
||||
|
||||
## 二、建设原则
|
||||
@@ -372,15 +394,18 @@ POST /periods/:key/close
|
||||
|
||||
### P0:影子总账(1–2 周)
|
||||
|
||||
> 前置:先完成商品主数据、渠道 SKU 映射、成本中心与销售事实(见 [成本中心与三块履约模型.md](成本中心与三块履约模型.md))。否则影子总账只能记“总额”,无法按店铺/皮肤/成本版本出毛利。
|
||||
|
||||
- 建 `finance_accounts / business_events / journal_entries / journal_lines / periods`。
|
||||
- 先接 4 类高频事件:订单支付、工单结算、押金冻结/释放/没收、提现。
|
||||
- 写总账但不改现有钱包逻辑。
|
||||
- 每日对账:钱包余额 vs 总账余额。
|
||||
- 补金额守恒与幂等测试。
|
||||
|
||||
### P1:寄卖与售后(1 周)
|
||||
### P1:寄卖、售后与人工成本(1–2 周)
|
||||
|
||||
- 接寄卖发布押金、货款结算、售后欠款/抵扣。
|
||||
- 接人工 case 的人工成本快照(按单/按小时)。
|
||||
- 建 `finance_settlements` / `finance_settlement_items`。
|
||||
- 后台增加凭证簿与试算平衡。
|
||||
|
||||
@@ -438,4 +463,4 @@ POST /periods/:key/close
|
||||
|
||||
## 九、一句话结论
|
||||
|
||||
**财务系统应作为“总账层”接入,而不是继续扩展业务钱包。** 先以影子总账 + 幂等业务事件 + 每日对账落地,确认钱包与总账长期一致后,再切换余额读模型;这样既能保护现有抢单/押金/寄卖链路,也能为后续平台结算、订单损益和关账留出正确底座。
|
||||
**财务系统应作为“总账层”接入,而不是继续扩展业务钱包。** 先把商品主数据、成本中心、人工 case 与销售事实补齐,再以影子总账 + 幂等业务事件 + 每日对账落地;确认钱包与总账长期一致后,再切换余额读模型。这样既能保护现有抢单/押金/寄卖链路,也能为平台结算、订单损益和关账留出正确底座。
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
> 状态:**现行**
|
||||
> 代码基线:`main @ 6850bc64`(工作区干净)
|
||||
> 复核范围:后端、前端、数据库迁移、部署脚本、现行文档
|
||||
> 复核方式:源码走查 + 类型检查 + Lint + 格式检查 + 全量测试 + 生产构建
|
||||
> 说明:本次没有连接生产数据库;历史数据量引用自既有生产快照,已在文中标注。
|
||||
> 复核方式:源码走查 + 类型检查 + Lint + 格式检查 + 全量测试 + 生产构建 + 2026-10-17 生产库只读聚合(`default_transaction_read_only=on`)
|
||||
> 说明:本次没有做全量数据克隆;历史数据量引用自生产库只读聚合,已在文中标注。
|
||||
|
||||
---
|
||||
|
||||
@@ -141,6 +141,27 @@ pending_material → unassigned → open → in_progress
|
||||
|
||||
两套表、两套状态机,**不可混用**。发布/指派时按来源分流:`publish-voucher-service.ts`。
|
||||
|
||||
### 5.5 三块履约与成本(2026-10-17 只读数据增补)
|
||||
|
||||
真正决定成本和监管方式的是**执行载体**,不是订单来源:
|
||||
|
||||
| 块 | 载体 | 成本 | 生产数据 |
|
||||
| --- | --- | --- | --- |
|
||||
| 自动发货 | `affiliate_dash` 任务 | 固定,按皮肤/SKU | 上游已有 `cost_amount`,但未落库 |
|
||||
| 接单平台 | `work_orders` | 变动,按模板/单价/拼单 | 最近 30 天已验收 62,669 单 |
|
||||
| 人工客服 | 目前无载体 | 人工工时/按单 | 最近 30 天 **44,657 个已支付订单项无任务也无工单** |
|
||||
|
||||
关键数据:
|
||||
|
||||
- 91 无载体订单 42,391、PDD 2,258、抖音 8;全部 `claim_status=active`。
|
||||
- `manual_dispatch` 任务全库只有 6 条,说明人工块基本没进任务系统。
|
||||
- 已验收工单的 `orders.order_status` 仍为 `paid`,订单主状态不能代表履约完成。
|
||||
- 最近 30 天已验收工单:91 报酬/订单金额约 86.0%、PDD 80.0%、抖音 96.5%(91 的 `total_amount` 是 `maxAmount`,口径待确认)。
|
||||
- 同一个商品名对应多个 `sku_code`:「指挥官密钥1个」27 个、「苏尔南钻石100颗」35 个,不能直接按 `sku_code` 做销量统计。
|
||||
- 当前 30 天订单基本是一单一品,但模型必须按订单项设计。
|
||||
|
||||
详细设计见 [成本中心与三块履约模型.md](成本中心与三块履约模型.md)。
|
||||
|
||||
---
|
||||
|
||||
## 六、工程质量亮点
|
||||
@@ -196,6 +217,16 @@ pending_material → unassigned → open → in_progress
|
||||
| 21 | 本地 Node 24,生产镜像 Node 22;前端主 chunk 524.69 kB 警告 | 构建输出、`deploy/docker/backend.Dockerfile:11` |
|
||||
| 22 | 备份会把 `apps/backend/data` 配置打包上传 OSS,可能含 PDD RSA 私钥/平台 Cookie | `deploy/backup-db.sh:119` |
|
||||
|
||||
### 三块履约与成本增补(2026-10-17)
|
||||
|
||||
| # | 发现 | 证据 | 影响 |
|
||||
| --- | --- | --- | --- |
|
||||
| C1 | **人工块没有载体、没有 case、没有完成状态** | 最近 30 天 44,657 个已支付订单项无任务也无工单;`manual_dispatch` 仅 6 条;已验收工单的订单仍 `order_status=paid` | 人工履约不可监管、不可计量、不可对账 |
|
||||
| C2 | **成本数据散落且无版本/快照** | 自动发货 `cost_amount` 只映射不落库;工单价格在 `work_product_rules`;人工无成本表 | 改价无法追溯,历史毛利不可重算,三块成本口径不一致 |
|
||||
| C3 | **订单金额口径不统一** | 91 `totalAmount=maxAmount`(`platforms/ninetyone/order-service.ts:48`);PDD `order_amount`;抖音 `pay_amount` | 直接汇总 `orders.total_amount` 会把不同财务口径相加 |
|
||||
| C4 | **SKU 与数量口径不稳定** | 同一商品名对应 27/35 个 `sku_code`;`order_items.quantity` 对「5个」类商品不可靠 | 店铺/日期/皮肤销量统计会漏计、重计或错并 |
|
||||
| C5 | **无订单项级金额字段** | `order_items` 仅有 `sku_code/sku_name/quantity/spec_json/item_snapshot_json` | 多商品订单无法直接分摊收入,需要快照/分摊规则 |
|
||||
|
||||
---
|
||||
|
||||
## 八、文档现状与本次整理
|
||||
@@ -218,12 +249,14 @@ pending_material → unassigned → open → in_progress
|
||||
- 匹配引擎:P0 + P1 已实施,P2/P3 待办。
|
||||
- 抖音三层分流:抖音侧已实施。
|
||||
6. 校正过期测试数:抖音总览中的 636/115 改为 2026-10-17 复核的 740/143。
|
||||
7. 2026-10-17 增补:新增 [成本中心与三块履约模型.md](成本中心与三块履约模型.md),把自动发货/接单平台/人工客服三块、统一成本中心、销售事实与人工 case 纳入现行设计;本报告同步补入生产只读数据与 C1~C5 风险。
|
||||
|
||||
仍保留为“设计/待办”的内容:
|
||||
|
||||
- `work_product_match_entries` 新表尚未落地(只在设计中),当前仍靠 `compile.ts` 编译旧模板/绑定。
|
||||
- 匹配触发点收敛、寄卖建议价/大厅改价统一走 `pricing.ts` 尚未完成。
|
||||
- 抖音“待人工队列”仍未做。
|
||||
- `product_catalog` / `channel_product_mappings` / `cost_items` / `cost_versions` / `cost_snapshots` / `sales_daily_facts` / `manual_fulfillment_cases` 均未落地。
|
||||
|
||||
---
|
||||
|
||||
@@ -245,7 +278,7 @@ pending_material → unassigned → open → in_progress
|
||||
5. 余额是可变字段,缺少“由流水重算”的校验。
|
||||
6. 资金事件缺少统一的 `business_event_id` 幂等键。
|
||||
|
||||
建议:先建**影子总账 + 对账**,不要一开始替换钱包。详见 [财务系统集成方案.md](财务系统集成方案.md)。
|
||||
建议:先建**影子总账 + 对账**,不要一开始替换钱包。成本金额与商品维度单独由成本中心负责,人工块由人工 case 负责;三者关系见 [成本中心与三块履约模型.md](成本中心与三块履约模型.md),总账细节见 [财务系统集成方案.md](财务系统集成方案.md) 与 [影子总账说明.md](影子总账说明.md)。
|
||||
|
||||
---
|
||||
|
||||
@@ -263,17 +296,20 @@ pending_material → unassigned → open → in_progress
|
||||
1. 发布与凭证核销统一为“失败即不发布”,或明确异步补偿。
|
||||
2. `/collect`、`/redeem` 增加一次性 token/二次校验;上传前校验订单存在。
|
||||
3. 生产强制 `CLAIM_TOKEN_TTL_HOURS > 0`;私有文件短期签名;补安全响应头。
|
||||
4. 财务影子总账落地:`finance_journal_entries / lines` + 业务事件映射。
|
||||
4. 先落商品主数据 + 销售事实:`product_catalog`、`channel_product_mappings`、`sales_daily_facts`,解决店铺/日期/皮肤销量与数量归一。
|
||||
5. 再落成本中心影子期:`cost_items / cost_versions / cost_snapshots`,自动发货接上游固定成本,工单接现有规则金额,人工接按单/按小时成本。
|
||||
|
||||
### 中期(1 个月)
|
||||
|
||||
1. CI + PostgreSQL 集成测试;补金额守恒、并发抢单、Webhook 失败恢复测试。
|
||||
2. 财务对账:平台账单/支付流水/钱包流水三方核对。
|
||||
3. 订单级损益:收入、履约成本、打手报酬、平台费、退款。
|
||||
4. 拆分巨型文件;补前端组件测试与 1–2 条 E2E。
|
||||
1. 人工 case:载体判定、无载体自动建 case、分配/SLA/证据/主管复核、人工成本快照。
|
||||
2. 财务影子总账:`finance_journal_entries / lines` + 业务事件映射。
|
||||
3. CI + PostgreSQL 集成测试;补金额守恒、并发抢单、Webhook 失败恢复测试。
|
||||
4. 财务对账:平台账单/支付流水/钱包流水三方核对。
|
||||
5. 订单级损益:收入、履约成本、打手报酬、人工成本、平台费、退款。
|
||||
6. 拆分巨型文件;补前端组件测试与 1–2 条 E2E。
|
||||
|
||||
---
|
||||
|
||||
## 十一、一句话总结
|
||||
|
||||
**代码与工程纪律足以支撑下一阶段的财务系统;但财务系统必须建在“不可变复式分录 + 业务事件幂等 + 对账”之上,而不是继续给 `worker_wallets` 加字段。** 先修资金门禁、Webhook 恢复、锁序与公开接口,再接财务总账,风险最低。
|
||||
**代码与工程纪律足以支撑下一阶段的财务系统;但财务系统必须建在“商品主数据 + 成本中心 + 不可变复式分录 + 业务事件幂等 + 对账”之上,而不是继续给 `worker_wallets` 加字段。** 先修资金门禁、Webhook 恢复、锁序与公开接口;再把人工块纳入 case 监管,最后接财务总账,风险最低。
|
||||
|
||||
Reference in New Issue
Block a user