Files
order_site/docs/archive/2026-10-17/载体判定与成本中心落地-复核与草案.md
yml2213 43f402cf72 docs(finance): 现行财务文档收敛为 5 篇,履约口径只定义一次
原 9 篇 3,647 行,履约分类口径在总纲、模型文档、交接总结里重复三遍,
且仍留着"三块履约""按小时人工成本"等已作废表述。本次收敛为 5 篇
1,778 行:

- 财务与履约口径总纲-2026-10-23.md(300 行):唯一口径来源
  七条硬口径、三个正交维度、真实履约构成、成本模型规则、人工全覆盖、
  实施顺序、进度、验收 SQL、防回归清单
- 成本中心与履约模型.md(471 行):数据模型、迁移 103–107、履约回填、
  销售事实、本地库原地改造、索引与性能
- 成本中心API契约.md(270 行):字段替换总表、枚举、前后端模块边界
- 人工支出与备用金.md(218 行):人工支出登记字段/状态机/权限 +
  客服备用金台账
- 财务系统集成方案.md:复式总账层(未实施)

旧的 4 篇(成本中心与三块履约模型、人工支出登记落地方案、
客服备用金台账实施方案、财务履约改造交接总结)移入
docs/archive/2026-10-23/ 并加归档提示。

履约分类判定 SQL 只在总纲保留一份,其它文档改为链接。
2026-10-23 16:06:40 +08:00

14 KiB
Raw Permalink Blame History

载体判定与成本中心落地:复核与草案(2026-10-17 第二轮)

状态:历史(2026-10-17 第二轮复核,已归档);基线:main @ ccd5ed2a;代码未改动。 说明:本文的现行结论已吸收进 成本中心与三块履约模型.md 与 财务系统集成方案.md;本文件只用于追溯 2026-10-17 的数据量化与 DDL 验证过程,不再作为实现依据。 数据来源:本地只读克隆(生产快照,orders 316,597 行,数据截至 2026-10-14 14:52),全程只读 SELECT,未连生产、未写入任何业务库。 金额单位:分(orders.total_amount / work_orders.reward_amount / source_order_amount_fen 均为分)。 上游文档:成本中心与三块履约模型.md、项目全量分析报告-2026-10-17.md。

本轮任务是把上一轮「只分析」的结论复核到底、量化到数、落成可执行草案。三件事:① 提交并推送待提交文档;② 收敛本机生产备份暴露面;③ 用只读 SQL 量化载体分布与人工块,并产出载体判定 + 成本中心两份 SQL 草案。


一、本轮执行结果

# 事项 结果
1 提交并推送文档 ccd5ed2a docs: 补充三块执行载体与通用成本中心方案,已推送 6850bc64..ccd5ed2a main -> main;pre-push 两端全量 check 通过
2 备份目录加固 backups/ 与子目录 chmod 700,两份 dump chmod 600;删除残留临时 dump(见 §六)
3 数据量化 只读克隆上完成 8 组聚合(见 §二、§三)
4 SQL 草案 载体判定 + 成本中心/销售事实两份,已在沙箱库零错误应用验证(见 §五)

二、独立复核:上一轮结论逐条对照

上一轮结论 本轮复核方式 结果
后端 740 测试(737 pass / 3 skipped) 本地实跑 npm test ✅ tests 740 / pass 737 / fail 0 / skipped 3
前端 143 测试全绿 本地实跑 ✅ 143 pass / 0 fail
typecheck 通过 实跑 tsc --noEmit ✅ 通过
99 个迁移 / 53 张表 数文件 + 数 CREATE TABLE + 查库 ✅ 99 迁移、53 条 CREATE TABLE;本地库 55 张 = 53 业务表 + schema_migrations + pg_stat_statements×2
后端非测试源码 371 文件 find 实测 ✅ 371(另有测试 109)
无 CI、实际单分支 查 .github / .gitlab-ci.yml;git log main..dev ✅ 均不存在;main..dev 为 0
巨文件行数(3686/2015/1499/1478) wc -l ✅ 完全一致

风险项抽查(读源码确认,非复述):发单金额后端只校验 > 0(admin-work-order-management-service.ts:228)✅;寄卖审核 payload.workerId 覆盖归属(consignment-admin-service.ts:606)✅;抢单先锁钱包、指派先锁工单(work-order-grab-repo.ts:25 vs :156)✅ 锁序反转成立;自动工单押金硬编码 0(sync-worker-orders-service.ts:245)✅;Webhook 先落库去重后处理(douyin-mashida/notify-service.ts:95 → :112)✅;/collect/upload 不校验订单存在、/redeem 仅凭订单号、/files/object 无鉴权、CLAIM_TOKEN_TTL_HOURS=0 ✅;Caddy 无 CSP/HSTS ✅。


三、载体分布(近 30 天,只读克隆实测)

判定口径:已支付订单项为单位,「人工块」= 既无 fulfillment_tasks 也无 work_orders。

来源 已支付项 自动发货 affiliate_dash 接单工单 人工块 双载体冲突 人工块金额 人工占比
kuaishou-91 112,520 30,900 42,907 38,451 0 ¥4,853,281 34.2%
pdd 3,714 0 1,648 2,066 0 ¥361,364 55.6%
douyin-mashida 4 2 0 2 0 ¥63 50.0%
合计 116,238 30,902 44,555 40,519 0 ¥5,214,708 34.9%

补充说明(都已核对):

  • 91 的 112,520 减去上述三类后还差 262 项,经查是历史执行器 kuaishou_ct_assisted(= KUAISHOU_CLOUD,已下线,活到 2026-09-15)的存量任务。这是载体建模必须单列 legacy 的原因,否则这 262 项会被错算成人工。
  • 双载体冲突 = 0 条,说明文档「一个订单项只有一个执行载体」的不变式在当前数据上成立。
  • 人工块 order_status 全部 paid、pay_status 全部 paid、claim_status 全部 active —— 零完成信号,与上一轮结论一致。

人工块的形状(监管收益判断)

来源 涉及店铺 单均 p50 p90 ≥¥100 ≥¥500
91 8 ¥126.22 ¥53 ¥288 13,229 2,708
PDD 4 ¥174.91 ¥141 ¥306 1,353 150

Top 店铺(人工块):向日葵游戏服务店 14,903 项 / ¥183.9 万;西瓜游戏交易店 7,768 项 / ¥118.0 万;小鱼儿游戏服务店 8,190 项 / ¥97.4 万;佳佳游戏交易店 7,460 项 / ¥84.5 万;PDD 向日葵网络游戏专营店 1,885 项 / ¥32.8 万。

结论:人工块店铺高度集中(91 只有 8 个店铺),意味着「先上线人工 case 队列」的监管收益集中在少数店铺上,容易先抓重点、快速看到效果。

月度趋势(确认不是历史遗留)

月份 已支付项 人工块
2026-08 142,969 46,337
2026-09 103,010 39,148
2026-10(截至 14 日) 55,647 17,469

人工成本区间(单均人工成本 X 元的月度量级)

X ¥3 ¥5 ¥8 ¥15
月人工成本 ¥121,557 ¥202,595 ¥324,152 ¥607,785

这是「人工履约投入」的量级估算,不含商品/货源成本(那部分属于 cost_versions)。


四、两个口径硬问题(比上一轮描述更严重)

1. 数量:quantity 不可用,低估约 7.3 倍

指标 实测值(全量已支付 316,585 项)
quantity = 1 316,578(99.998%)
quantity > 1 7
名称里带「N个」但 quantity = 1 104,710
sum(quantity) 316,593
按 SKU 名称解析的数量合计 2,316,222

用 quantity 统计「卖了多少件」会低估约 7.3 倍。必须在订单项固化 normalized_quantity(草案已加列)。

2. SKU 多码一名:比上一轮更严重

商品名 不同 sku_code 数 项数
苏尔南钻石100颗 47 3,319
99999 44 540
指挥官密钥1个 42 26,748
指挥官密钥5个 41 3,608
指挥官密钥10个 37 3,059
苏尔南钻石50颗 35 379

(上一轮报的是近 30 天窗口的 27/35/10;本轮是全量已支付口径,两者不矛盾,但都指向同一个结论:不做 channel_product_mappings 就无法统计销量。)


五、对上一轮结论的 4 处修正

# 上一轮说法 本轮修正
1 C5「订单项无金额字段」是当下风险 是潜在缺口:实测每笔已支付订单恰好 1 个订单项(316,585 单 = 316,585 项),订单级金额暂时等价;但 schema 允许多项,应在做销售事实前补齐
2 三载体互斥(设计不变式) 数据上已验证:近 30 天双载体 = 0 条
3 自动发货执行器只剩 affiliate_dash 还有 262 项历史 kuaishou_ct_assisted 任务(已下线,2026-09-15 停);载体建模需单列 legacy,且这类任务仍在领取页给出「已下线」提示
4 手动履约 manual_dispatch 任务极少 补充:affiliate_dash 侧仍在途 552 项(link_generated 300 + waiting_binding 252),属运营待跟进而非人工块

六、两份 SQL 草案

放在 docs/drafts/,未接入 apps/backend/src/db/migrations(接入时再拆分编号并先跑 npm run check:sql,避免本地栈重启时自动迁移)。

文件 内容
载体判定与人工块量化.sql §1 八组只读量化查询(含实测值注释);§2 判定规则与优先级(含 legacy 与冲突处理);§3 加列 + 回填 + 索引 + 回滚;§4 守恒校验与异常队列查询;§5 人工成本区间
成本中心与销售事实-DDL草案.sql product_catalog、channel_product_mappings、cost_items、cost_versions、cost_snapshots、cost_exceptions、sales_daily_facts;订单项口径补齐(normalized_quantity/revenue_amount_fen/revenue_basis/refunded_at);work_product_rules.cost_item_id 过渡列;§5 对平校验;§6 已确认口径与剩余待确认
人工支出登记-DDL草案.sql manual_fulfillment_cases(轻量处理记录)+ manual_expense_records(付款项目/金额/订单号/付款人/收款人/凭证/审批)+ manual_expense_events 审计;§3 校验查询;§4 与影子总账的分录约定

验证方式:在本地副本上 pg_dump --schema-only 建了一个一次性沙箱库(55 张表),按依赖顺序(载体判定 → 成本中心 → 人工支出登记)用 psql -v ON_ERROR_STOP=1 应用三份草案 —— 零错误:生成 10 张新表(共 65 张)、order_items 由 9 列增至 19 列、27 个 CHECK 约束、169 个索引;校验查询与回填语句均可执行。验证后沙箱库已 DROP。

关键设计约束(三份草案共同遵循):

  1. 改价只发生在 cost_versions,历史成本靠 cost_snapshots 固化,永不回写;
  2. 匹配不到成本不默认 0,写入 cost_exceptions,报表必须暴露 open 数量;
  3. carrier_type/carrier_status 是派生列,事实来源仍是任务/工单存在性,必须有重算作业与守恒校验;
  4. 报表维度统一 canonical_product_id + shop_id + stat_date,禁止直接用 sku_code 或 orders.total_amount。

七、本机卫生记录(第 2 项执行细节)

项 处理前 处理后
backups/、backups/postgres/、backups/douyin-platform-clear-20261014/ 755 700
order_site_latest.dump(559 MB)、order_site_remote.dump(105 MB) 644 600
.order_site_readonly.dump.nKbeRp8kUA(137,330,688 B) 600,残留 已删除,backups/ 由 765 MB 降至 634 MB

删除前已确认:① 解析后绝对路径为 …/order_site/backups/postgres/.order_site_readonly.dump.nKbeRp8kUA;② 是完整可读的 PostgreSQL 自定义 dump(pg_restore --list 795 条目 / 53 个 TABLE DATA),sha256 1a666af11ae9df2058bc2a5afa2196baefb9c125daf0cdecf18dfd20c59cc075;③ 全仓库无任何脚本引用该文件或其余两份 dump 名;④ 无进程占用;⑤ 与同分钟产出的 order_site_latest.dump 属同一批快照,且本地克隆数据(截至 10-14)比这两份 10-10 快照更新。

遗留建议:本机仍存两份全量生产 dump(含买家信息与平台凭据)。建议确认磁盘已加密;若后续以本地克隆为唯一分析基线,可只保留一份最新 dump。

分析基线建议:本地 docker 栈(order_site-postgres-1)已含 10-14 生产快照(orders 316,597),后续所有 SQL 迭代直接打本地克隆即可,无需再连生产。


八、业务口径确认(2026-10-17)

业务已就四个阻塞问题给出结论;其中两条已用克隆数据独立核验。

# 问题 结论 数据核验
1 91 的 total_amount 是收入还是成本上限? 收入:它就是用户付款金额,与快手发码配合 ✅ 91 已支付 312,569 笔,其中 235,271 笔含快手 kuaishouSendCode.paymentFen;235,268 笔与 total_amount 完全一致(100.00%),仅 3 笔差 ¥1.80 / ¥1.85 / ¥2.00(2026-09-05 / 09-18 / 10-04)
2 打手报酬是成本还是代收代付? 支出/成本:工单结算 → 打手可提现 → 提现打款,属我方真实支出 → 总额法 —
3 人工块的目标? 先把流程搞清楚:谁处理了哪些、付了多少钱。现状「很多地方需要人工付款,但不知道付款项目、金额、订单号」→ 新增人工支出登记草案;SLA/监管指标延后 —
4 退款/仲裁? 暂未接入,先预留:字段 + reversal_of_id + 事件类型,本轮不实现逻辑 —

影响:

  • 收入口径统一为 revenue_amount_fen = orders.total_amount(revenue_basis = 'user_payment'),草案中原本枚举的三家字段名已简化;
  • 成本侧确认「打手报酬 = 支出」,cost_items.cost_type = 'work_order_reward' 计入履约成本,不做净额;
  • 人工块方案重心从「case + SLA」改为「人工支出登记(付款项目 / 金额 / 订单号 / 付款人 / 收款人 / 凭证 / 审批)」;
  • 退款相关列与冲正关系保留为预留,不写逻辑。

九、下一步

  1. 业务仍待拍板 1 个关键口径:收入确认时点(付款 / 发货 / 验收 / 售后期结束)—— 它决定利润表与预收账款;金额口径已定。
  2. 工程可先做两件不改业务代码的事:
    • 建 channel_product_mappings 初始映射,把 47 个 sku_code 归到 1 个标准商品;
    • 用现有 resolveSkuNameQuantity 解析并回填 normalized_quantity。
  3. 紧接着做人工支出登记(业务当前最痛):manual_fulfillment_cases + manual_expense_records,先解决「谁付的、什么项目、多少钱、哪个订单」。
  4. 之后按「商品主数据 → 成本中心影子期 → 人工支出 → 影子总账 → 对账转正」推进。