Task Impacted Revenue 归因设计
本文是
revenue-attribution.md的后续设计,不修改或替代原文件。本文以当前 Task Policy、数据库 schema 和 Dashboard 实现为基础,记录已经确认的产品口径。金额均为 operational estimate,不是 Billing、POS 或 CRM 中的实际入账收入。
一、产品结论
Impacted Revenue 用 Task 的 positive outcome 回答一个运营问题:员工完成这些 Task 后,大约保护或创造了多少业务价值?
当前产品只展示两类指标:
- Estimated Recurring Revenue Impact:与会员月度经常性收入有关的估算影响;
- Estimated One-time Revenue Impact:Intro booking 和 qualified referral 等一次性价值的估算影响。
不再使用以下四分类:
- One-time Revenue;
- MRR Impact;
- Recovered Payments;
- Lead Acquisition Value。
原因是 Payment Recovery 本质上属于 recurring membership revenue,Referral 的 qualified lead value 本质上属于 one-time value。把它们拆成四个并列 KPI 会混合“收入周期”和“业务来源”两个分类维度,不利于理解和比较。
1.1 当前事实边界
系统目前没有 Billing、POS 或 CRM 等权威收入事实。Impacted Revenue 只能使用:
- 已被系统接受的 Task positive outcome;
- Task type 与 positive result 的受控映射;
- 门店配置的 benchmark 单价。
因此:
- 不检查 Card on file;
- 不从语音识别客户购买的具体课程或会员方案;
- 不按语音中的具体金额计算;
- 不把估算称为 actual、booked、collected 或 confirmed revenue;
- Product Catalog 只用于解释默认 benchmark 的来源,不参与逐条 outcome 的价格匹配。
1.2 核心公式
Positive outcome 表示 Task 的业务目标成功,不天然等于 revenue。只有本文明确列出的 8 种 Task type 才参与金额估算。
二、Task、Positive Result 与 Revenue Impact 映射
2.1 10 种 Task type
当前产品使用 10 种 Task type。其中 8 种产生 revenue impact,2 种只有业务上的 positive result、但不货币化。
2.2 两类 Revenue Impact
Estimated Recurring Revenue Impact
Estimated One-time Revenue Impact
2.3 Booked 与 Converted 必须分开
Booked 和 Converted 是连续 funnel 中两个独立的业务事件:
不能把二者合并。否则一次 US$12 的 Intro booking 会被错误估算成 US$152 的 membership conversion。即使同一个 contact 先 Booked、之后 Converted,只要来自两个独立 Task outcome,就分别计入 one-time 与 recurring impact。
2.4 不货币化的 positive outcome
- Lead Outreach · Contacted:证明首次联系目标达成,但尚未产生 booking 或 membership revenue;
- Member Issue · Issue Resolved:证明服务问题已解决,但当前没有稳定、可解释的金额 benchmark。
它们继续进入 Task positive outcome rate,但不进入 Impacted Revenue。
三、Benchmark Setup
3.1 默认值
所有金额使用可配置的平均 benchmark。默认值来自 OTF 课程与会员组合说明 及已确认的产品假设。
会员 benchmark 的默认计算:
Upgrade benchmark 的默认计算:
Qualified Referral 使用 lead acquisition cost 的替代值。默认 US$60 是可编辑的 purchased lead price,不是 OTF membership revenue。
3.2 配置规则
- Benchmark setup 展示 8 个可编辑金额;
- 输入使用 USD,存储使用 integer cents 或 decimal,不能依赖 JavaScript float;
Reset恢复上述默认值;Save benchmarks保存门店级配置;- Dialog 打开后焦点落在标题或容器,不自动选中第一个金额;
- 默认值和自定义值都必须注明为 estimate benchmark,不是实际交易价格;
- 配置按
store_id隔离; - 更新 benchmark 后必须能解释当前报表使用了哪个版本或 snapshot。
3.3 单项计算
四、Outcome 计数规则
4.1 可计入的基本单位
一个可计入的 attribution unit 是一个已接受的 terminal Task Outcome,至少满足:
当前金额计算不附加 Card-on-file、产品识别或外部付款验证门槛。
4.2 业务时间
报表按 outcome_occurred_at 归属日期:
created_at:Task 创建时间;closed_at:用户或系统执行关闭操作的时间;outcome_occurred_at:业务结果实际发生时间;calculated_at:估算金额的计算时间。
不能用 closed_at 静默填补未知的 outcome_occurred_at。缺少业务时间的记录应进入 coverage,而不是被分配到错误日期。
4.3 去重
最低去重键:
如果后续引入 attribution ledger,应增加稳定的 outcome_id 或 command receipt identity,防止 close command 重试造成重复计数。
Booked 与 Converted 是不同 Task type、不同业务事件,不应跨阶段去重掉。只有同一 terminal outcome 的重复写入需要去重。
4.4 Reopen 与 correction
Task reopen 后:
- 当前 snapshot 的 terminal result 和
revenue_mapping_code失效; - Current-state 报表不再计入旧结果;
- 如果存在历史 attribution ledger,旧金额标记为 reversed 或 superseded;
- 重新关闭后按新的 Outcome 产生新的 attribution unit。
Outcome 被更正时不能覆盖审计历史,应写入 superseding record,并让 Dashboard 使用最新有效版本。
五、当前数据库与后端基础
5.1 tasks 已有字段
5.2 当前写入逻辑
V3 Outcome 写入链路:
- 调用方提交结构化 Outcome;
- Policy Catalog 根据
task_kind + policy_version解析合法结果; - 代码校验
result_code、closure reason、verification type 和 evidence; - mutation kernel 原子更新 Task snapshot,并写 timeline / receipt;
revenue_mapping_code从 Policy Outcome 复制到 Task,不信任前端或 AI 自报;- reopen 清除 terminal outcome 与
revenue_mapping_code。
这套链路适合作为 Impacted Revenue 的事实入口。AI 可以提出 Outcome,但受控代码决定是否接受、如何写库及是否进入 revenue projection。
5.3 当前 Policy 与目标映射的差异
当前仍需核对或补齐:
- Lead Outreach、Lead Follow-up、Post-Intro Follow-up 是否已经具备完全独立的 managed Policy;
Booked是否已经是 Lead Follow-up 的 terminal positive result,而不只是 progress;- Member Issue 是否已经具备独立的
issue_resolvedPolicy Outcome; - 当前 7 个
revenue_mapping_code是否已补齐 Intro booking 对应的第 8 个 mapping; referral_captured与前端展示文案Referral Obtained的 canonical result code 是否已统一。
上述差异不能通过前端字符串判断补齐,必须由 Policy Catalog 和 schema 定义。
5.4 当前配置基础
store_config 已有:
store_id;pricingJSONB;updated_at。
但 Revenue Benchmark 仍需要正式的 typed schema、校验、版本和 API 接线。不能仅靠一个无约束 JSON object 作为长期 contract。
5.5 当前 reporting 基础
Dashboard 已有 Task Outcome proof query 的基础能力,但历史实现主要覆盖 membership conversion。Impacted Revenue 需要把 read contract 扩展到全部 8 个 revenue-related Task type,并统一返回:
- selected period outcome counts;
- previous period outcome counts;
- benchmark snapshot;
- two metric totals;
- per-day trend;
- unknown-time、rejected、reopened / reversed 等 coverage。
六、Dashboard 产品与 UI 规则
6.1 导航与页面结构
- Dashboard 顶部 tab 顺序:
Leads、Tasks、Calls、Team、Impacted Revenue; Impacted Revenue放在Team后面;- 页面复用 Dashboard 全局 date range 与 compare controls;
- 日期、comparison、currency 和
store_id在 summary 与 chart 中必须一致。
6.2 Summary
顶部使用一个共享的横向 summary card,顺序为:
- Estimated Recurring Revenue Impact;
- Estimated One-time Revenue Impact。
每个指标显示:
- 当前期间金额;
- 与选定 comparison period 的趋势;
- 不再显示旧的长说明副标题。
Help 与 Benchmark setup 放在 summary 同一行右侧,使用一致的 lightweight text action 样式,不设计成两个不同重量的按钮。
6.3 Trend chart
- 标题:
Impacted Revenue Trend; - 默认线顺序:Estimated Recurring Revenue Impact、Estimated One-time Revenue Impact;
- 线和 legend 使用空心圆点;
- 默认使用 UI core palette 中对比明确的颜色;
- 日期只显示
Jul 28这类格式,不显示星期; - chart card 默认填满 summary 以下剩余浏览器高度;
- 保留 resize handle;
- tooltip 中金额右对齐,并使用相同 currency format;
- 无数据点保持 gap,不用 0 伪装未知数据。
6.4 Customize
Customize 只有一个选择维度:Revenue line。不再让用户先选 revenue category、再选 Task type,因为 Task type 与 Revenue Impact metric 的映射是固定的。
选择树按 Revenue Impact 分组,顺序如下:
规则:
- 选项展示
Task type · Revenue impact,不展示 result 名称; - Revenue metric 可以作为汇总线;
- 单个 Task type 可以作为明细线;
Add line、delete、Done、Reset 的交互与 Tasks chart 一致;- 默认添加两条 metric 汇总线;
- 所有图表、legend、dropdown 和 tooltip 使用同一套名称。
6.5 Comparison 文案
存在有效 previous period 时:
previous period total 为 0 或不可用时,使用全站一致的小写文案:
不得使用 New vs previous period,因为它不能表达基数为 0、数据缺失或第一次出现之间的差异。
6.6 Help 内容
Help 标题使用 How impacted revenue is estimated,至少说明:
- Count the Task-specific positive outcome;
- Apply the configured benchmark;
- Amounts are operational estimates, not billing, POS, or CRM revenue。
并提供 Revenue Impact by Task Type:
Help 使用 Task type · Positive result — Revenue impact,与 Customize 的 Task type · Revenue impact 分工不同:Customize 用于选线,Help 用于解释为什么这条 Task 会产生该类影响。
七、推荐 API Contract
推荐新增独立 endpoint,不扩展 Legacy close-result counters:
availability 至少区分:
disabled:功能关闭,金额为null;unconfigured:没有可用 benchmark;estimated:存在有效 Outcome 和 benchmark,可返回估算。
当前不定义 confirmed。未来即使接入 Billing、POS 或 CRM,也应新增独立的 actual revenue contract,不能把现有 estimate 字段悄悄改变语义。
八、建议新增的数据模型
8.1 Revenue Benchmark
短期可以扩展 store_config.pricing,但必须增加 typed schema 和版本:
要求:
- 金额必须为非负数;
- currency 为 ISO 4217;
- 定义版本、更新时间和修改主体可审计;
- benchmark 更新对历史数据采用 snapshot 或明确的重算规则;
- API 根据授权
store_id读写。
8.2 Attribution Ledger
当前可以查询时实时计算。为了稳定历史、benchmark versioning、reopen reversal 和 correction,后续可新增 append-only task_revenue_attributions:
Ledger 由受控 service 根据 accepted Outcome 和 benchmark 生成,不能由 AI 或前端直接写入。
九、Legacy 数据策略
Legacy Task 可能只有 type_category、close_result、close_type、closed_at,缺少 result_code、Policy identity、evidence 或 outcome_occurred_at。
如果上线初期必须展示 Legacy 趋势,应使用独立 definition version 和清晰标签,不能与受控 Outcome 混成同一个不可解释的数字。
十、当前还缺什么
P0:Task Outcome 定义
- 确认 10 种 Task type 的 canonical positive result;
- 确认 Lead Follow-up 的
Booked是 terminal positive result; - 确认 Post-Intro Follow-up 的
Converted独立于 Booked; - 为 Member Issue 补齐不货币化的
Issue Resolvedpositive result; - 将 8 种 revenue-related Outcome 映射固化到 Policy Catalog;
- 统一 Referral 的 canonical result code 与 UI 文案。
P1:Benchmark 与 Reporting
- 门店级 Revenue Benchmark typed schema、migration、读写 API 和权限;
- Reset defaults 与 benchmark audit history;
- 8 种 Outcome 的统一 reporting query;
- selected period、previous period、trend 与 comparison contract;
- unknown-time、rejected、duplicate 和 reopened coverage;
- benchmark snapshot 或可解释的重算策略。
P2:Dashboard
- 两指标 summary;
- 可调整高度的 trend chart;
- Revenue line customize;
- Help 与 Benchmark setup;
- Task type drilldown;
- feature flag、telemetry 和 staged rollout。
Future:权威收入集成
Billing、POS 或 CRM 不在当前范围。未来接入后可以新增 actual revenue reconciliation,但必须与 Estimated Revenue Impact 并存,不能回写或改写历史 estimate 的定义。
十一、验收不变量
Booked和Converted必须作为两个独立 Task Outcome 计价;- Lead Outreach 和 Member Issue 可以 positive,但不能因为 positive 就自动计 revenue;
- 只有 8 种明确映射的 Task type 进入金额估算;
- 每种 Task type 只能映射到一个 Revenue Impact metric;
revenue_mapping_code只能来自 Policy Catalog,不能信任前端或 AI 自报;- 金额只等于 positive outcome count × configured benchmark;
- 当前不得增加 Card-on-file 或具体产品识别门槛;
- 当前不得把语音中的具体金额作为单项价格;
- 所有金额必须标识为 Estimated Revenue Impact;
- Estimated Recurring 与 Estimated One-time 不得使用旧四分类重复计入;
outcome_occurred_at未知时不得用closed_at静默代替;- reopen、correction 或 command retry 不得重复计数;
- disabled / unavailable 返回
null,不能伪装成$0; - 所有 benchmark、查询和聚合按授权
store_id隔离; - benchmark 更新必须有 definition version 或 snapshot;
- previous period 不可用时使用全站统一文案
no previous period data; - Dashboard、Customize、Help、legend 和 tooltip 使用同一套 metric 名称;
- AI 只能提出 Outcome,受控代码决定是否接受并生成 revenue projection;
- rejected、unknown-time 和 duplicate candidates 必须可见,不能静默丢弃;
- 未来 actual revenue 不能改变当前 estimate contract 的语义。
十二、最终原则
Impacted Revenue 不是“给每个 Task 标签随便贴一个价格”,而是:
这套边界确保:
- Task 仍然描述业务目标和结果;
- AI 不直接决定金额;
- Booked 的 Intro revenue 与 Converted 的 membership revenue 不会混淆;
- Lead Outreach 和 Member Issue 的 positive result 不会被强行货币化;
- Payment Recovery 被归入 recurring impact,Referral 被归入 one-time impact;
- 产品在只有 communication 和 Task outcome 的数据条件下,始终诚实地表达 estimate,而不冒充财务事实。