diff --git a/docs/README.md b/docs/README.md index e899418e..5146db02 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,7 +2,7 @@ > 最后校准:2026-10-27,代码基线 `dev`(合并 `dev1023` + 人工成本完整性修复 + 财务 P0 控制,迁移基线收敛为 `103`–`105`;**未部署生产**)。 > 数据基线:生产 dump `backups/postgres/order_site-20261022-092601.dump`(数据 2026-07-10 ~ 2026-10-22);本地已校准到 105(103 财务基础、104 财务控制/L1、105 拼单/寄卖客服),生产按收敛后的 102 → 105 路径执行。历史全量数字仅作基线,**上线验收以 [财务上线初始化与验收-2026-10-26.md](财务上线初始化与验收-2026-10-26.md) 为准**。 -> 本文是 `docs/` 的唯一入口。**财务与履约口径以 [财务与履约口径总纲-2026-10-23.md](财务与履约口径总纲-2026-10-23.md) 为准**;数据模型看 [成本中心与履约模型.md](成本中心与履约模型.md),接口看 [成本中心API契约.md](成本中心API契约.md)。 +> 本文是 `docs/` 的唯一入口。**整体财务流程看 [财务流程总览-2026-11-01.md](财务流程总览-2026-11-01.md)**;数据模型看 [成本中心与履约模型.md](成本中心与履约模型.md),接口看 [成本中心API契约.md](成本中心API契约.md)。 > 新增文档必须在下表登记状态;过期文档不再直接改写结论,统一移入 `docs/archive/`。 ## 一、先记住六条口径 @@ -129,6 +129,7 @@ | 文档 | 状态 | 用途 | | --- | --- | --- | | [财务与履约口径总纲-2026-10-23.md](财务与履约口径总纲-2026-10-23.md) | **现行唯一口径** | 履约方式、成本模型、人工全覆盖、历史策略、实施顺序、运营日检与验收 SQL | +| [财务流程总览-2026-11-01.md](财务流程总览-2026-11-01.md) | 现行 | 断代后财务全流程:六条管道、成本快照、事实、总账、退款、异常、运维与测试 | | [成本中心与履约模型.md](成本中心与履约模型.md) | 现行 | 商品、成本版本、快照、异常、销售事实的数据模型;迁移 `103`–`105`;履约回填;迁移基线与本地库同步;索引与性能 | | [成本中心API契约.md](成本中心API契约.md) | 现行 | 成本中心接口字段替换总表、枚举、模块边界(后端 5 模块 + 前端 4 个固定 Tab) | | [人工支出与备用金.md](人工支出与备用金.md) | 现行(P0 已实施) | 确认履约流程/权限、客服备用金台账、本人账户与编号规则 | diff --git a/docs/成本中心与履约模型.md b/docs/成本中心与履约模型.md index 67050fa0..7f1cb286 100644 --- a/docs/成本中心与履约模型.md +++ b/docs/成本中心与履约模型.md @@ -349,7 +349,7 @@ computed_at - 平台费/支付费属于派生费用,退款后允许按净收入重算;采购成本与打手报酬保持固化。 - 退款所属期间(退款发生月)已关账时直接阻断退款,避免冲减静默丢失。 - 成本版本创建与基线导入都不允许追溯生效;基线导入仅在没有任何快照时可用。 -- 断代前的历史订单退款,按「退款发生日」写 `refund_adjustment` 冲减行,计入当期事实与总账。 +- 断代前的历史订单退款不进入新财务口径(业务侧自行处理),不生成冲减行。 ## 六、履约事实 diff --git a/docs/财务流程总览-2026-11-01.md b/docs/财务流程总览-2026-11-01.md new file mode 100644 index 00000000..03ad352e --- /dev/null +++ b/docs/财务流程总览-2026-11-01.md @@ -0,0 +1,148 @@ +# 财务流程总览(2026-11-01) + +> 状态:**现行**。断代日 `2026-10-31`:历史订单全部归档,财务只统计断代之后的数据。 +> 历史订单的退款不进入本系统财务口径,由业务侧自行处理。 +> 代码基线:`main`(迁移 112–118)。 + +## 一、范围与原则 + +1. **只算断代后**:`orders/order_items` 中 `fulfillment_status='archived'` 的数据不参与成本、事实、总账。 +2. **历史成本固化**:订单一旦生成成本快照,后续改价/版本变更不再覆盖;唯一例外是接单平台 `estimated → actual`,以及平台费/支付费按退款净额重算。 +3. **下游只读上游**:事实只读快照,总账只读事实;任何一层都不回写上一层。 +4. **每条管道幂等**:按订单项 id 增量、水位可续跑,失败不推进水位。 + +## 二、数据链路 + +```text +订单/订单项 + │ + ├─ channel_assign 规则 + 载体证据 → fulfillment_channel / status + ├─ carrier_dispatch 挂人工配置、发现缺载体/缺配置 + ├─ product_normalize 模板/人工配置/aff:/tpv:/映射 → canonical_product_id + ├─ cost_snapshot 渠道成本项 + 平台费/支付费 → cost_snapshots(不可变) + ├─ sales_facts 快照 + 收入 + 退款 → sales_daily_facts(按渠道) + └─ ledger_post 事实差异 → finance_journal_entries / lines +``` + +| 管道 | 输入 | 输出 | 水位 | +|---|---|---|---| +| channel_assign | pending 订单项 | 渠道/状态/来源 | `finance_watermarks.channel_assign` | +| carrier_dispatch | assigned 人工/自动发货/接单 | 配置挂载、异常队列 | `carrier_dispatch` | +| product_normalize | assigned 且无商品 | `canonical_product_id` | `product_normalize` | +| cost_snapshot | assigned 且需核算 | 成本快照 | `cost_snapshot`(冷)+ `cost_snapshot_hot`(热) | +| sales_facts | 最近窗口 + 变更日期 | 销售事实 | `sales_facts.last_stat_date` | +| ledger_post | 最近窗口 + 变更日期 | 总账凭证 | `ledger_post.last_stat_date` | + +## 三、渠道判定 + +- 规则 `sku_channel_rules`:运营指定(10)> 自动发货(60)> 人工配置(70); +- 无规则时看证据:工单 → `work_order`,自动发货任务 → `affiliate_dash`; +- 仍无证据 → `pending`,进「待分类」; +- 运营指定后 `fulfillment_locked=true`,自动判定不再覆盖; +- 多渠道证据冲突 → `routing_conflict` 异常,不静默取其一。 + +## 四、商品归一 + +按优先级匹配: + +1. 人工配置商品(`manual_fulfillment_configs`) +2. 接单工单模板(`tpl:` → `wo:`) +3. 自动发货(`aff:`) +4. 卡券(`tpv:`) +5. 渠道映射(SKU / 名称 / 系列) + +都匹配不到 → `product_mapping_missing` 异常,不自动建商品。 + +## 五、成本 + +渠道成本项: + +| 渠道 | 成本项 | 取值 | +|---|---|---| +| affiliate_dash | `sys_affiliate_purchase` | 商品级采购价 | +| third_party_voucher | `sys_third_party_voucher_cost` | 商品级卡券采购价 | +| work_order | `sys_work_order_reward` | 规则/商品版本;已接单按实际 `reward_amount` | +| manual | 无渠道成本 | 确认履约时按实际录入 `manual_case` | + +通用费用: + +- `platform_fee` / `payment_fee`:每单发生,可按 global 或商品版本,比例按**净收入**(收入 − 已确认退款); +- `after_sales_loss` / `other`:只允许商品级版本,禁止 global 套所有订单。 + +版本选择:按订单业务时间取「有效且最新」的版本(规则 > 商品 > 全局)。 +0 元全局版本是占位,不产生快照,订单进入 `cost_missing`。 + +快照规则: + +- 生成后不可变;改价、停用版本、补配价格都不覆盖历史; +- `estimated → actual` 允许升级; +- 平台费/支付费允许按退款后的净收入重算; +- 快照新增/替换后按业务日重算事实与总账。 + +## 六、销售事实 + +- 只统计 `pay_status IN ('paid','refunded')`; +- 收入取 `order_items.revenue_amount_fen`; +- 退款取 `order_refunds` 中 `confirmed` 的金额,净收入 = 收入 − 退款; +- 渠道维度:`work_order / affiliate_dash / third_party_voucher / manual / unclassified`; +- 成本缺失按「该渠道应有的成本项」判定,通用费用不会掩盖缺口; +- 已关账期间冻结,不重算。 + +## 七、总账 + +- 事实按日与已有凭证比较差异,追加收入/退款/成本调整凭证; +- 已关账期间禁止改账; +- 关账后事实变更会被跳过,不会出现事实与总账不一致。 + +## 八、人工履约 + +1. `carrier_dispatch` 按 SKU 自动挂 `manual_fulfillment_configs`; +2. 缺配置 → `manual_config_missing`;已配置未确认 → `manual_cost_missing`; +3. 确认履约写 `manual_case` 快照、渠道 `manual/assigned`,扣备用金/积分; +4. 确认后立即按业务日重算事实与总账。 + +## 九、退款(仅断代后订单) + +1. 退款写入 `order_refunds`,确认后按订单原销售日更新事实(收入/退款/费用); +2. 比例费用按净收入重算; +3. 退款所属期间已关账 → 直接阻断(`order_refund_period_closed`); +4. **断代前订单(archived)的退款不进入财务系统**,不生成冲减事实,也不影响总账。 + +## 十、异常队列 + +| reason | 含义 | 收口方式 | +|---|---|---| +| `classification_missing` | 待分类 | 指定渠道 | +| `routing_conflict` | 多渠道冲突 | 人工裁决 | +| `product_mapping_missing` | 商品未归一 | 配映射/模板/配置 | +| `carrier_missing` | 指定渠道无载体 | 建工单/任务 | +| `cost_missing` | 缺渠道成本版本 | 配价后管道自动收口 | +| `manual_config_missing` | 人工 SKU 未配置 | 配配置 | +| `manual_cost_missing` | 人工未确认履约 | 确认履约 | + +异常按 `scope_key` 聚合,明细按订单项;解决后自动关闭。 + +## 十一、断代与归档 + +`npm run finance:cutover-v2 -- --execute --confirm=2026-10-31`: + +1. 断代前订单项批量置 `archived`、渠道清空; +2. 清空快照、事实、异常、总账、对账等派生数据; +3. 写入断代记录,重复执行会被拦截; +4. 之后只处理新订单,无需任何历史回填。 + +## 十二、运维 + +- 后台「履约渠道 → 管道状态」查看水位、最近成功、错误; +- 六条管道由定时任务驱动,可单条重跑; +- 成本快照冷通道负责历史 assigned 项轮询,热通道负责新单; +- 改价只能当前或未来生效,禁止追溯。 + +## 十三、测试 + +| 库 | 用途 | +|---|---| +| `order_site_fin_scale` | 生产副本、不断代:40 万级压力测试与 SQL 计划验证 | +| `order_site_fin_cutover` | 生产副本、完整断代:验证归档、派生清理、断代后新单 | + +日常回归使用小型确定性 fixture,不依赖生产数据。