refactor(finance): 人工成本收敛为「人工录单 → 扣备用金 → 写快照」
公司人工支出登记单与审批报销状态机整链下线,人工成本只留一条链路。
口径调整(2026-10-23 确认):
- 历史人工支出找不回来,直接放弃:不补录、不做样本校准、不做均价估算,
只保证上线后的新单不丢。
- 人工成本逐单按实际金额,从客服备用金扣款,客服只能用本人账户;
没有登记单、没有审批、没有报销,录入即计入毛利。
后端:
- 新增 services/finance/manual-order-cost-service.ts:扣备用金 + 写 actual
成本快照,同一事务,余额不足直接拒绝不允许负余额。
- 成本快照主体从「人工支出登记单 id」改为「客服备用金支出单 id」
(subject_type='manual_case',subject_id=manual_expenses.id)。
- 删除 services/finance/manual-expense-service.ts(1263 行)与
routes/admin/finance.ts 下 /finance/manual-expenses* 全套接口。
前端:
- 删除 AdminManualExpensePage.tsx(778 行)与 /admin/manual-expenses 菜单页。
- ManualOrderCostModal 去掉「提交审核 / 立即计入成本」开关,录入即生效。
- 新增 services/admin/manual-order-cost.ts。
迁移:
- 106_manual_expense_records.sql → 106_fund_account_no_readable.sql,
只保留备用金账户编号可读化。
- 108_drop_manual_expense_records.sql:删除 manual_expense_records 与
manual_expense_events 两张表。
- 109_isolate_legacy_manual_snapshots.sql:把来源为旧登记链的历史孤儿快照
subject_id 改为负数,与 manual_expenses.id 彻底隔离。
踩坑修复(E2E 实测发现):主体 id 换空间后与历史孤儿快照撞唯一索引
uq_cost_snapshots_active_subject_item,INSERT ... ON CONFLICT DO NOTHING
静默跳过,导致「钱从备用金扣了、成本快照却没写成」。修法是迁移 109 隔离
legacy 主体 + 后端快照写失败必须抛错回滚(409),杜绝账实不符。
文档:现行 5 篇 + README 基线校准为 dev @ 43f402cf + 迁移 103–109,
修正已删除的旧迁移号,删除「人工支出登记 + 审批 + 报销」口径,
已作废 DDL 草案移入 docs/archive/2026-10-23/。
校验:后端 765 项 / 0 失败(含 check:sql 迁移护栏),前端 143 项全通过;
E2E 实测两笔同订单项各自独立主体、余额扣减与快照金额一一对应;
本地库迁移 108/109 执行后数据量与改造前完全一致。
Co-Authored-By: Claude Opus 4.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
43f402cf72
commit
fb679d76f6
+17
-12
@@ -1,6 +1,6 @@
|
||||
# order_site 文档索引
|
||||
|
||||
> 最后校准:2026-10-23,代码基线 `feat/finance-rewrite @ 7557de6d + 迁移 103–107`。
|
||||
> 最后校准:2026-10-23,代码基线 `dev @ 43f402cf + 迁移 103–109`(已合并到 `dev`,**未推送、未部署生产**)。
|
||||
> 本文是 `docs/` 的唯一入口。**财务与履约口径以 [财务与履约口径总纲-2026-10-23.md](财务与履约口径总纲-2026-10-23.md) 为准**;数据模型看 [成本中心与履约模型.md](成本中心与履约模型.md),接口看 [成本中心API契约.md](成本中心API契约.md)。
|
||||
> 新增文档必须在下表登记状态;过期文档不再直接改写结论,统一移入 `docs/archive/`。
|
||||
|
||||
@@ -43,20 +43,24 @@
|
||||
- 订单/工单/人工单只保存 `cost_snapshot_id`,历史成本永不回写
|
||||
- 自动发货、接单平台、人工客服共用同一个成本解析器;匹配不到成本进入 `cost_missing`,不默认 0
|
||||
|
||||
### 5. 两个“人工支出”不是一回事
|
||||
### 5. 人工成本只有一条链路
|
||||
|
||||
```text
|
||||
订单页「人工录单」→ 扣客服备用金(manual_expenses)→ 写 cost_snapshots(manual_case)
|
||||
```
|
||||
|
||||
| 名称 | 业务含义 | 当前状态 |
|
||||
| --- | --- | --- |
|
||||
| `manual_expenses` | **客服备用金支出明细**:客服从自己的备用金里充值/采购/赔偿,减少客服余额 | 已实施(迁移 100) |
|
||||
| `manual_expense_records` | **公司人工支出/垫付登记**:按订单/成本项记录公司实际付出去的钱、付款人、收款人、凭证、审批 | 已实施 P0(迁移 106) |
|
||||
| `manual_expenses` | **客服备用金支出明细**:客服从自己的备用金里充值/采购/赔偿,减少客服余额 | 已实施(迁移 100);人工录单也写这里 |
|
||||
| `cost_snapshots` | **人工成本的唯一落点**:`subject_type='manual_case'`,`subject_id=manual_expenses.id` | 已实施(迁移 104) |
|
||||
|
||||
后续做财务系统时,**不要把 `manual_expenses` 直接改名或复用为 `manual_expense_records`**。两者业务含义、审批链和报表口径不同,必须通过 `fund_expense_id` 关联;新人工支出登记会先扣备用金,再写人工支出记录。
|
||||
**没有独立的登记单,也没有审批与报销环节。** `manual_expense_records` / `manual_expense_events` 已随迁移 `108` 删除。后续做财务系统时,人工成本的钱与账都从这条链路走,不要再另造一张人工支出表。
|
||||
|
||||
### 6. 历史人工支出不补录,上线后必须全覆盖
|
||||
### 6. 历史人工直接放弃,上线后必须全覆盖
|
||||
|
||||
- 历史人工支出只取少量样本做校准,不补录、不阻塞上线;
|
||||
- 历史人工支出找不回来,**直接放弃**:不补录、不做样本校准、不阻塞上线;
|
||||
- 上线后每一笔人工单必须有处理人、实际金额、备用金支出与成本快照;
|
||||
- 人工单无成本记录、人工支出无 `fund_expense_id`、金额与备用金流水不一致,均不允许关账。
|
||||
- 人工单无成本记录、人工单未扣备用金、金额与备用金流水不一致,均不允许关账。
|
||||
|
||||
### 7. 文档状态
|
||||
|
||||
@@ -76,13 +80,13 @@
|
||||
| 商品主数据 + 渠道 SKU 映射 | **已实施 P0** | 745 个标准商品、4,426 条映射;只覆盖自动发货 38 个 + 接单平台 707 个。人工 11,349 项虽已归一但全部挂 `tpl:*` 模板商品,需在 P1 复核;人工专用商品尚未建立 |
|
||||
| 成本中心 | **已实施 P0** | 迁移 `104`;`cost_items.cost_model` 取代 `cost_type + carrier_type`;38 个商品级版本 + 662 个规则级版本;人工走 `sys_manual_service` 实际快照 |
|
||||
| 销售事实 / 订单毛利 | **已实施 P0** | 迁移 `105`;94 天事实收入 ¥2,650.87 万、成本 ¥950.27 万;`sales_daily_facts.fulfillment_mode` |
|
||||
| 公司人工支出登记 | **已实施 P0** | 迁移 `106`;登记时强制扣客服备用金并写 `fund_expense_id`;客服只能使用本人账户 |
|
||||
| 人工成本录入(人工录单) | **已实施 P0** | 迁移 `106/108`;录入即扣客服备用金并写 `actual` 快照;无登记单/审批/报销;客服只能使用本人账户 |
|
||||
| 履约方式统一 | **已实施 P0** | 迁移 `107`;316,585 项已回填,四项计数与总纲 §二 一致;订单页、成本快照、销售事实只读 `fulfillment_mode` |
|
||||
| 人工商品归一 | **未实施(P1)** | 人工单按 `spec.skuId` 建 `man:<skuId>`;历史 11,349 项 `tpl:*` 商品待复核 |
|
||||
| 影子总账 | 未实施 | 现有财务页仍是 `UNION ALL` 业务事件拼装,不是复式总账 |
|
||||
| 退款冲减 / 平台对账 / 期间关账 | 未实施 | 仅方案 |
|
||||
|
||||
> 分支状态(2026-10-23):重写分支 `feat/finance-rewrite` 把原 `103–114` 十二个迁移合并为 `103–107` 五个;本地库已按新 schema 原地改造并重跑回填,**尚未合并到 `dev`、未部署生产**;生产口径仍以 `main` 为准。
|
||||
> 分支状态(2026-10-23):原 `103–114` 十二个迁移已合并为 `103–107` 五个,另加 `108` 清理迁移(删人工支出登记两表);已快进合并到 `dev`(tip `43f402cf`),本地库已按新 schema 改造并重跑回填,**未推送远端、未部署生产**;生产口径仍以 `main` 为准。
|
||||
> 财务与履约口径以 [财务与履约口径总纲-2026-10-23.md](财务与履约口径总纲-2026-10-23.md) 为准。
|
||||
|
||||
## 三、统一实施顺序
|
||||
@@ -91,6 +95,7 @@
|
||||
0. 统一履约事实(fulfillment_mode + 成本模型正交) 已完成 P0(迁移 107)
|
||||
1. 商品主数据 + 渠道 SKU 映射 已完成 P0(仅自动发货/接单平台)
|
||||
2. 成本中心 + 销售事实 已完成 P0
|
||||
2.5 人工成本链路收敛(人工录单 → 扣备用金 → 写快照) 已完成 P0(迁移 106/108)
|
||||
3. 人工商品归一与上线后人工成本全覆盖 未实施(下一阶段)
|
||||
4. 退款冲减与异常队列 未实施
|
||||
5. 影子总账(订单、工单、押金、提现、寄卖、售后) 未实施
|
||||
@@ -121,7 +126,7 @@
|
||||
| [财务与履约口径总纲-2026-10-23.md](财务与履约口径总纲-2026-10-23.md) | **现行唯一口径** | 履约方式、成本模型、人工全覆盖、历史策略、实施顺序、运营日检与验收 SQL |
|
||||
| [成本中心与履约模型.md](成本中心与履约模型.md) | 现行 | 商品、成本版本、快照、异常、销售事实的数据模型;迁移 `103–107`;履约回填;本地库原地改造;索引与性能 |
|
||||
| [成本中心API契约.md](成本中心API契约.md) | 现行 | 成本中心接口字段替换总表、枚举、模块边界(后端 5 模块 + 前端 8 面板) |
|
||||
| [人工支出与备用金.md](人工支出与备用金.md) | 现行(P0 已实施) | 人工支出登记字段/状态机/权限、客服备用金台账、本人账户与编号规则 |
|
||||
| [人工支出与备用金.md](人工支出与备用金.md) | 现行(P0 已实施) | 人工录单字段/流程/权限、客服备用金台账、本人账户与编号规则 |
|
||||
| [财务系统集成方案.md](财务系统集成方案.md) | 现行方案(总账未实施) | 复式记账、总账表、对账、关账 |
|
||||
| [影子总账说明.md](影子总账说明.md) | 现行说明(未实施) | 影子总账是什么、和钱包流水的区别、对账与转正标准 |
|
||||
| [项目全量分析报告-2026-10-17.md](项目全量分析报告-2026-10-17.md) | 历史参考 | 2026-10-17 架构与风险;财务口径以总纲为准 |
|
||||
@@ -144,7 +149,7 @@
|
||||
| --- | --- | --- |
|
||||
| [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` / `fulfillment_mode` 取代,仅作设计追溯 |
|
||||
| [drafts/2026-10-17-人工支出登记-DDL草案.sql](drafts/2026-10-17-人工支出登记-DDL草案.sql) | `manual_fulfillment_cases`、`manual_expense_records`、`manual_expense_events` | 人工支出登记已落地为 `106`;轻量人工 case 仍为草案 |
|
||||
| [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` 已随迁移 `108` 删除,人工成本改走「人工录单 → 扣备用金 → 写快照」;文件已移入 archive |
|
||||
|
||||
## 六、厂商协议与外部资料
|
||||
|
||||
|
||||
Reference in New Issue
Block a user