# Salesforce Common Object Create Automation Audit

Date: `2026-07-07`

## Scope

This note audits the commonly used business objects we identified earlier:

- standard CRM/reporting objects:
  `Account`, `Contact`, `Lead`, `Opportunity`, `Campaign`, `CampaignMember`,
  `Contract`, `Quote`, `Order`
- PingCAP-specific reporting/finance objects:
  `Org__c`, `Revenue__c`, `Invoice_Collection__c`,
  `Opportunity_Product__c`, `Order_Product__c`, `Quote_Product__c`

The question being answered is:

If these objects are created through the current CRM API path, which important
fields are expected to be auto-generated or auto-maintained by Salesforce
automation, and therefore are likely to be missing if our side does not trigger
equivalent behavior?

## Method

This audit used the live PingCAP Salesforce org on `2026-07-07` and only
performed read-only metadata inspection.

No production records were created or modified.

Evidence sources:

- live REST `sobjects/<Object>/describe`
- live `ValidationRule` tooling query
- live `ApexTrigger` tooling query
- live `FlowDefinitionView` query
- existing BI usage research from `looker-schema` and `digital-bi-dbt`

## Executive Summary

The common objects do not rely on Flow alone.

For the most important business objects, Salesforce currently layers:

- system/defaulted fields
- auto-number fields
- formula / rollup fields
- active validation rules
- active record-triggered / scheduled flows
- active Apex triggers

The highest-risk objects for API creation gaps are:

1. `Lead`
2. `Opportunity`
3. `Quote`
4. `Order`
5. `Account`
6. `CampaignMember`
7. `Org__c` / `Revenue__c` / `Invoice_Collection__c`

These are also the objects that most directly drive BI:

- Looker direct explores: `Account`, `Lead`, `Opportunity`
- dbt downstream marts: `Opportunity`, `Order`, `Campaign`, `CampaignMember`,
  `Org__c`, `Revenue__c`, `Invoice_Collection__c`

## How To Read This Audit

This note is not a pure "CM bug list".

It combines two different questions:

1. what live Salesforce is currently doing on create / update for these objects
2. whether current NexusCRM + the checked-in PingCAP final pack already cover
   the same behavior

So each finding should be read through the following buckets:

- `already aligned`: NexusCRM has the substrate and the current final pack
  already carries the relevant metadata
- `activation-state mismatch`: the definition already exists locally, but live
  Salesforce runs it as `active` while the current final pack keeps it
  `inactive`
- `exact pack-parity missing`: NexusCRM can do it, but the current final pack
  still lacks a known Flow / validation / auto-number definition
- `intentional replacement`: the local PingCAP pack deliberately chose a
  different policy instead of reproducing the live Salesforce rule literally
- `not supported today`: the live org still depends on Apex trigger/runtime
  behavior that NexusCRM explicitly does not execute

Put differently:

- `activation-state mismatch` and `exact pack-parity missing` are usually not a
  CM platform capability gap
- `intentional replacement` is a business-policy alignment question, not
  automatically a CM bug
- `not supported today` is the column that marks true CM platform/runtime
  boundaries

## Difference Types And Report Reading

The phrase "gap" is overloaded in stakeholder conversations, so this mapping is
the safest shorthand:

| 差异类型 | 这是不是 `CM 没能力` | 典型例子 | 最容易先打歪的报表/模型 | 先怎么处理 |
|---|---|---|---|---|
| `activation-state mismatch` | Usually `No` | `Lead.Nurture_Marketing_Date`, `Lead.Nurture_Sales_Date`, `Opportunity.PingCAP_Contract_Entity_EMEA_only`, the 3 inactive `Quote` validations | `salesforce_leads`, `dim_lead`, `salesforce_opportunities`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration` | 先把已存在但 inactive 的规则单独做激活评审 |
| `exact pack-parity missing` | Usually `No` | `Campaign_Member_Key_Message_Update`, `Order_Org_Auto_Set_Account_Create`, `RevRec_Set_PLG_BD_Pool`, missing auto-number on `Revenue__c` / `Invoice_Collection__c` / line-item objects | `dws_campaign_attribution`, `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec`, `salesforce_org_monthly_revrec` | 直接立 `L2 pack` backlog，按 Flow / validation / auto-number 补齐 |
| `intentional replacement` | `No`, but semantics may differ | local inactive `Order_Activate_*` contract checks replaced by account-level governing-contract policy | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` when users assume Salesforce semantics | 不先回滚；先确认 PingCAP policy 是否就是期望口径 |
| `runtime boundary` | `Yes`, this is the true CM boundary | `LeadTrigger`, `LeadAITrigger`, `OpportunityTrigger`, `OrderTrigger`, `QuoteTrigger`, `RevenueTrigger` | 几乎所有高价值 CRM/BI 面都会被波及，尤其 `salesforce_opportunities`, `salesforce_orders`, `dws_lead_timeline`, `dws_salesforce_arr_summary` | 单独拆 Apex 替代项目，不和普通 parity 任务混排 |
| `name clue / unresolved` | `Unknown yet` | `OpportunityShareToPersalesOwner`, invoice/collection notification surfaces, long-tail Lead notification templates | 先影响审计完整性，暂不直接定义为生产缺口 | 继续做定名审计，再决定是否入 backlog |

Practical reading:

- the report tables below are a `difference inventory`, not a pure `CM
  incapable list`
- most current high-signal items still sit in
  `activation-state mismatch`
  or
  `exact pack-parity missing`
- the clearest true CM boundary remains behavior that still only lives in live
  Apex triggers

## Report-Group Difference Reclassification

If the stakeholder question is
`这些报表风险是不是都等于 CM 目前没能力`
,
the safest answer today is
`No`.

The current report families skew toward
`pack parity`
and
`activation state`
far more than toward pure platform incapability.

| 报表组 | 当前差异主类型 | 能不能直接说成 `CM 没能力` | 代表项 | 真正更像 CM 边界的部分 | 对外最稳口径 |
|---|---|---|---|---|---|
| `Lead Funnel / Qualification` | `exact pack-parity missing` + `activation-state mismatch` | `No` | inactive `Nurture_*`; missing Lead assignment / reminder / notification parity | `LeadTrigger`, `LeadAITrigger` | `Lead 不是平台空白，主要是 live Lead 语义还没在 L2 pack 补齐，剩余 Apex 才是平台边界。` |
| `Pipeline / Forecast / Opportunity Quality` | `exact pack-parity missing` + `activation-state mismatch` | `Mostly no` | inactive `PingCAP_Contract_Entity_EMEA_only`; missing Quote nonstandard-term flows; remaining Opportunity flow parity | `OpportunityTrigger`, `QuoteTrigger` | `Opportunity/Quote 的大头仍是 pack parity，真正未承接的主要是 trigger-only 逻辑。` |
| `Campaign Attribution / ICP Analysis` | `exact pack-parity missing` | `Mostly no` | missing `Campaign_Member_Key_Message_Update` | `Trigger_CampaignMember` if attribution helper logic still depends on it | `当前最直接的是补一条已知 Flow，不该先把整组定义成 CM 能力缺口。` |
| `Order / ARR / RevRec / Collections` | `exact pack-parity missing` + `auto-number parity missing` + partial `intentional replacement` | `Mostly no` | missing Order / RevRec / Invoice flows; missing `Revenue__c.Name` and `Invoice_Collection__c.Name`; inactive `Order_Activate_*` are intentional replacement | `OrderTrigger`, `RevenueTrigger`, line-item trigger surfaces | `Finance 线当前主要还是 parity backlog，只有 trigger-only 残余才更像 CM 真边界。` |
| `Account / Tenant Linkage / Customer Identity` | `exact pack-parity missing` | `Mostly no` | missing `Account_Contract_Valid_Message`, `Account_Current_Order_Type`, `Account_Partner_Sales_Owner_Set` | `AccountTrigger` and downstream carry-over logic if still trigger-bound | `主维表链路不是没 substrate，而是 Account/Order carry-over 语义还没补齐。` |

Stakeholder-safe summary:

- this report is best described as a `BI-risk difference register`
- only the rows that reduce to
  `runtime boundary`
  should default to
  `CM 目前未支持/疑似未支持`
- most other rows belong in
  `CM 已支持，但 pack parity / activation state 还没对齐`

## Three-Bucket Triage Register

The two sections above explain
`why not every difference is a CM platform gap`.

This section makes that statement executable by assigning the highest-value
items into three concrete buckets.

| 桶 | 对象/机制 | 当前判断 | 直接受影响报表/模型 | 建议动作 |
|---|---|---|---|---|
| `CM 已支持，但没配齐` | `Lead.Nurture_Marketing_Date`, `Lead.Nurture_Sales_Date` | local definition exists; the mismatch is activation state, not substrate absence | `salesforce_leads`, `dim_lead`, `dws_lead_timeline` | run a focused activation review first |
| `CM 已支持，但没配齐` | unresolved Lead assignment / reminder / notification Flow parity | current evidence points to `L2 pack` Flow backlog more than platform incapability | `salesforce_lead`, `salesforce_leads`, `dws_lead_timeline`, `cloud-lead-pipeline-insight` | continue exact-name audit and migrate the named Flows |
| `CM 已支持，但没配齐` | `Opportunity.PingCAP_Contract_Entity_EMEA_only` plus 3 inactive Quote validations | definitions already exist locally; current inactive set is `PingCAP_Contract_Entity_EMEA_only`, `Customer_s_Hardware_Configuration`, `Details_of_vCPU_Calculation`, `Version_of_TiDB` | `salesforce_oppo`, `salesforce_opportunities`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration` | activate first, then re-check downstream semantics |
| `CM 已支持，但没配齐` | `Quote_update_nonstandard_conditions_checkbox`, `Quote_update_nonstandard_conditions_checkbox_2` | confirmed exact-name missing Flows; current `Salesforce-PingCAP-L2` pack search is `0 hit` for both names | `salesforce_opportunities`, `dim_opportunity`, `dws_salesforce_arr_summary` | direct `L2 pack` parity work |
| `CM 已支持，但没配齐` | `Campaign_Member_Key_Message_Update` | confirmed exact-name missing Flow; current `Salesforce-PingCAP-L2` pack search is `0 hit` | `salesforce_campaign_members`, `dws_campaign_attribution`, `dws_lead_timeline` | direct `L2 pack` parity work |
| `CM 已支持，但没配齐` | `Account_Contract_Valid_Message`, `Account_Current_Order_Type`, `Account_Partner_Sales_Owner_Set` | confirmed exact-name missing Account Flows; current `Salesforce-PingCAP-L2` pack search is `0 hit` for these names | `crm_account`, `salesforce_accounts`, `dim_account`, `dim_tenant` | direct `L2 pack` parity work |
| `CM 已支持，但没配齐` | `Order_Org_Auto_Set_Account_*`, `Order_Set_PLG_BD_Pool`, `contractOpportunityInset`, `RevRec_Set_PLG_BD_Pool` | confirmed exact-name missing finance Flows; current `Salesforce-PingCAP-L2` pack search is `0 hit` for `Order_Org_Auto_Set_Account_*`, `Order_Set_PLG_BD_Pool`, `RevRec_Set_PLG_BD_Pool` | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec`, `salesforce_revrec`, `salesforce_org_monthly_revrec` | prioritize in finance parity backlog |
| `CM 已支持，但没配齐` | `Revenue__c.Name`, `Invoice_Collection__c.Name`, custom line-item `Name` | missing auto-number parity is metadata backlog, not evidence of missing substrate | `salesforce_revrec`, `stg_salesforce_invoice_collection`, `salesforce_orders`, `salesforce_opportunity_products` | fill `L2 metadata` auto-number definitions |
| `更像 CM 真边界` | `LeadTrigger`, `LeadAITrigger` | still live only as Apex trigger/runtime behavior | `salesforce_leads`, `dws_lead_timeline`, `cloud-lead-pipeline-insight` | open a separate Apex-rewrite/runtime project |
| `更像 CM 真边界` | `OpportunityTrigger`, `QuoteTrigger` | still live only as Apex trigger/runtime behavior | `salesforce_opportunities`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration` | open a separate Apex-rewrite/runtime project |
| `更像 CM 真边界` | `OrderTrigger`, `RevenueTrigger`, custom line-item trigger surfaces | still live only as Apex/runtime behavior | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec`, `salesforce_org_monthly_revrec` | keep this out of ordinary parity queue |
| `更像 CM 真边界` | `AccountTrigger`, `Trigger_CampaignMember` | likely residual trigger-only boundary after ordinary parity backlog is cleared | `salesforce_accounts`, `dim_tenant`, `salesforce_campaign_members`, `dws_campaign_attribution` | clear pack parity first, then inspect what still remains trigger-bound |
| `更像策略/BI 口径差异` | local inactive `Order_Activate_*` contract rules | current evidence supports PingCAP policy replacement rather than accidental drift | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` | confirm desired PingCAP semantics before changing anything |
| `更像策略/BI 口径差异` | incomplete dashboard/owner inventory for marketing and finance | this is an evidence boundary in the audit, not a CM object-capability gap | it weakens consumer-surface attribution, not the upstream object support claim itself | expand dashboard/explore/owner inventory separately |

Fast rule:

- if it is a named Flow / validation / auto-number gap with local peers,
  default it into
  `CM 已支持，但没配齐`
- if it still exists only in live Apex trigger logic,
  default it into
  `更像 CM 真边界`
- if it is an intentional PingCAP semantic replacement or a BI-consumer
  evidence limitation,
  default it into
  `更像策略/BI 口径差异`

## Concrete BI Coupling Proof Points

The most important report-impact claims in this note are backed by direct BI
model reads, not only by intuition:

| 上游对象 | 直接证据 | 说明为什么这个对象差异会打到报表 |
|---|---|---|
| `Lead` | `dws_lead_timeline.sql` reads `salesforce_leads.lead_mql_timestamp`, `lead_iqm_timestamp`, and joins `salesforce_opportunities` for `launch_date`, `mapped_stage_name` | 所以 Lead lifecycle 语义和 Opportunity milestone 语义都会直接改写 lead timeline 报表事件线 |
| `Opportunity` | `salesforce_opportunities.sql` materializes `forecast_category`, `forecast_type`, `region`, `accurate_acv_amount`, `arr_amount_usd`, `owner_team`, `stage_name`, `stage_duration_days`, `cloud_order_type` | 所以 Opportunity Flow / validation / trigger 差异不是抽象问题，而是直接进入 pipeline / ARR / stage-duration 口径 |
| `Order` + `Revenue__c` + `Invoice_Collection__c` | current checked-out `salesforce_orders.sql` combines order base fields with `salesforce_opportunities`, `salesforce_revrec`, and `stg_salesforce_order_product`; it also declares an `invoice_collection` CTE sourced from `stg_salesforce_invoice_collection`, while local `Order` metadata already contains IC-driven rollups filtered by `CollectionsStatus__c = 'Collected'` | 所以 Order / RevRec / Collections 这条线一旦缺 carry-over、PLG pool、auto-number 或 revenue aggregation 语义，会直接扭曲 finance / ARR 视图；其中 collections 侧在当前 checkout 里最强的 confirmed consumer surface 仍是 staging/source + recurring finance outputs，而不是一个已经显式 join 完 IC 的 order mart |
| `Account` + `Org__c` | `salesforce_accounts.sql` builds `tenant_ids` by joining `salesforce_orgs`; `crm_account.view.lkml` exposes `AccountID`, `Industry`, `Region`, `Segmentation`, `TenantStatus`, `TiDBCloudPortalID` | 所以 account-tenant bridge 不只是主数据问题，而是很多下游客户/tenant 维表的共享键 |
| `Lead` + `Account` + `Opportunity` | `cloud-lead-pipeline-insight.model.lkml` joins `salesforce_lead -> crm_account` on `TiDBCloudPortalID`, then `crm_account -> salesforce_oppo` on account name | 所以 lead/account/opportunity 三段中的任一字段漂移，都会直接污染 Looker 的 lead-to-pipeline 漏斗 |
| `CampaignMember` + `Opportunity` | `salesforce_campaign_attribution_details.sql` joins campaigns with `salesforce_opportunities` and contact roles, then computes weights | 所以 `Campaign_Member_Key_Message_Update` 这类归因辅助语义缺失，会真实影响 attribution 明细而不是只影响 CRM 页面显示 |

Fast reading:

- if someone asks "why does this one Flow matter to BI", start from this table
- it is strong evidence for
  `Lead`,
  `Opportunity`,
  `Order`,
  `Revenue__c`,
  `Invoice_Collection__c`,
  `Account`,
  `Org__c`,
  and
  `CampaignMember`
  as the highest-value parity surfaces

## Field-Level BI Blast Radius

This is the most execution-friendly version of the current evidence.

It answers a narrower question than the object matrix:

- not just "which report depends on this object"
- but "which fields inside that report are most likely to drift if Salesforce
  automation parity is missing"

| 对象 | BI 里直接消费的关键字段 | 这些字段为什么容易被自动化差异打歪 | 最直接受影响的模型/报表 |
|---|---|---|---|
| `Lead` | `lead_mql_timestamp`, `lead_iqm_timestamp`, `account_id`, `LeadLifecycleStage`, `LeadStatus`, `Region`, `Segmentation`, `TenantStatus`, `TiDBCloudPortalID` | `dws_lead_timeline.sql` directly emits milestone events from `lead_mql_timestamp` / `lead_iqm_timestamp`; Looker and lead marts also rely on lead/account/tenant linkage fields that are often maintained by Flow/validation side-effects | Looker `salesforce_lead`, `cloud-lead-pipeline-insight`; dbt `salesforce_leads`, `dim_lead`, `dws_lead_timeline`, `dws_icp_summary` |
| `Opportunity` | `forecast_category`, `forecast_type`, `region`, `accurate_acv_amount`, `arr_amount_usd`, `owner_team`, `stage_name`, `stage_duration_days`, `cloud_order_type`, `launch_date` | `salesforce_opportunities.sql` materializes these fields directly and downstream marts compute ARR, pipeline stage duration, and attribution value from them | Looker `salesforce_oppo`, `cloud-lead-pipeline-insight`; dbt `salesforce_opportunities`, `dim_opportunity`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration`, `dws_opportunity_stage_conversion_rates`, `dws_data_quality_alerting`, `salesforce_campaign_attribution`, `salesforce_orders` |
| `Quote` | `service_start_date`, `service_end_date`, support-tier / nonstandard-term helper fields, discount/approval helpers | Quote logic is not only for CRM page display; `salesforce_opportunities` uses quote enrichment, so missing Quote Flow / validation parity can alter the commercial fields carried into pipeline and ARR models | `salesforce_opportunities`, `dim_opportunity`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration`, order/ARR reporting |
| `CampaignMember` | `campaign_member_status`, `first_responded_date`, `has_responded`, `is_contact_involved`, `contact_involvement_level`, `attribution_percentage`, `attributed_acv`, `attributed_arr` | `salesforce_campaign_members.sql` derives `first_responded_date` fallback and involvement categories; `salesforce_campaign_attributions.sql` and `dws_campaign_attribution.sql` convert them into weighted attribution percentages and ARR/ACV values | dbt `salesforce_campaign_members`, `salesforce_campaign_attributions`, `salesforce_campaign_attribution_details`, `dws_campaign_attribution`, `dws_campaign_attribution_details`, `dws_lead_timeline`, `dws_icp_summary` |
| `Account` | `account_number`, `account_name`, `region`, `segmentation`, `icp`, `industry`, `vertical`, `tenant_ids` | `salesforce_accounts.sql` joins `salesforce_orgs` to build `tenant_ids`; Looker `crm_account` exposes `AccountID`, `Industry`, `Region`, `Segmentation`, `TenantStatus`, `TiDBCloudPortalID`, so account-linkage or status side-effects ripple widely | Looker `crm_account`, `cloud-lead-pipeline-insight`; dbt `salesforce_accounts`, `dim_account`, `dim_tenant`, `dws_icp_summary`, `customer_surrogate_keys`, `customers` |
| `Org__c` | `tenant_id`, `account_id`, `accumulate_revenue_to_org_tenant_id`, `org_name` | `salesforce_orgs.sql` defines tenant/account bridge and revenue-rollup target tenant; `salesforce_org_monthly_revrec.sql` and `dim_tenant.sql` rely on that bridge directly | dbt `salesforce_orgs`, `dim_org`, `dim_tenant`, `salesforce_accounts`, `salesforce_org_monthly_revrec`, `customer_surrogate_keys` |
| `Order` | `accumulate_revenue_to_org_tenant_id`, `order_status`, `order_product_family`, `order_products`, `revenues`, `order_net_fees`, `order_service_start_date`, `order_service_end_date`, `accumulated_revenue` | `salesforce_orders.sql` builds nested `order_products` and `revenues`; `salesforce_order_daily_view.sql` explodes them by day to compute accumulated revenue and service-window facts, so any missing carry-over / PLG pool / contract gating logic quickly shows up in finance views | dbt `salesforce_orders`, `salesforce_order_daily_view`, `salesforce_order_current_monthly_arr`, `cp_order_monthly_revrec`, `dws_salesforce_arr_summary`, `salesforce_org_monthly_revrec` |
| `Revenue__c` | `revenue_name`, `revenue_date`, `revenue_status`, `amount_before_adjust`, `amount`, `credit_amount`, `revenue_exchange_rate` | `salesforce_revrec.sql` materializes these fields directly and `salesforce_orders.sql` aggregates them into order-level `revenues`, then `salesforce_order_daily_view.sql` turns them into daily accumulated revenue metrics | dbt `salesforce_revrec`, `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec`, `salesforce_org_monthly_revrec` |
| `Invoice_Collection__c` | `cash_collected_amount`, `cash_collected_amount_usd`, `payable_amount_usd_exc_tax`, plus upstream `invoice_status_c`, `collections_amount_c`, `plg_bd_pool_c`, `actual_billing_date_c` | `stg_salesforce_invoice_collection.sql` materializes these fields directly; local `Order` metadata also already has IC-driven rollups filtered by `CollectionsStatus__c = 'Collected'`. In the current checked-out dbt SQL, `salesforce_orders.sql` declares but does not yet consume its `invoice_collection` CTE, so the strongest confirmed consumer surface today is staging/source plus recurring finance logic that reads order snapshots | `stg_salesforce_invoice_collection`, `salesforce_orders`, `salesforce_order_daily_view`, finance billing / collections reporting |
| `Opportunity_Product__c` / `Order_Product__c` / `Quote_Product__c` | `order_product_id`, `product_id`, `product_name`, `product_code`, `net_fees`, `service_start_date`, `service_end_date`, `product_family` | These line-item objects feed service-window and net-fee rollups; missing auto-number or trigger-only calc parity can break downstream joins and product-family level analysis | `salesforce_opportunity_products`, `salesforce_opportunities`, `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` |

### Finance Output Field Chain

The revrec chain is now strong enough to name the first output fields that will
drift, not just the model names.

| 上游对象/语义 | 当前一手 SQL / contract 证据 | 先打歪哪些 finance outputs |
|---|---|---|
| `Org__c` tenant-account bridge | `salesforce_org_monthly_revrec.sql` builds `accumulate_revenue_to_org_tenant_id` from `salesforce_orgs`, then attaches `account_id`, customer surrogate, region, and mapped tenant payment type before the Python revrec job reads it | `monthly_revrec_collections.adjust_tenant_id`, `account_id`, `account_name`, `account_region`, `payment_type`; also the tenant/order matching key used to allocate order revenue by org-month |
| `Invoice_Collection__c` / billing semantics | `salesforce_org_monthly_revrec.sql` carries `invoice_amount`, `stripe_amount`, `wire_transfer_amount`, `marketplace_amount`, `invoice_status`, and mapped `payment_type`; `monthly_cloud_billing_revrec.py` copies these into org-month outputs and derives `collections_from` plus recognition-mode filtering from `actual_revenue_recognition_date` | `monthly_revrec_collections.total_amount`, `invoice_amount`, `payment_type`, `collections_from`, `marketplace_amount`, `wire_transfer_amount`, `stripe_invoice_*`, `actual_revenue_recognition_date` |
| `Order` service-window / carry-over semantics | `salesforce_order_daily_view.sql` expands `salesforce_orders` by day and materializes `accumulate_revenue_to_org_tenant_id`, `order_status`, `order_product_family`, `order_service_start_date`, `order_service_end_date`, `accumulated_revenue`, `accumulated_revenue_before_adjust`, `accumulated_credit_amount`, and `order_net_fees`; `monthly_cloud_billing_revrec.py` only keeps `Activated` + `TiDB Cloud` orders for revenue allocation | `monthly_revrec_orders.order_number`, `order_start_date`, `order_end_date`, `order_billing_start_date`, `order_billing_end_date`, `is_order_closing`, `order_deferred_revenue_usd`, `billing_allocation_amount`, `end_of_contract_shortfall_amount`, `account_region` |
| `Revenue__c` recognized/adjusted revenue history | `salesforce_orders.sql` aggregates nested `revenues`; `salesforce_order_daily_view.sql` turns them into `accumulated_revenue`, `accumulated_revenue_before_adjust`, and `accumulated_credit_amount`; the Python revrec job uses those values to decide deferred revenue, adjusted revenue, and category allocations | `monthly_revrec_orders.revenue_amount`, `credit_amount`, `adjusted_revenue_amount`, `adjusted_shortfall_amount`, `serverless_revenue_amount`, `dedicated_revenue_amount`, `support_revenue_amount`, and the related `adjusted_*` category fields |

Practical reading:

- if `Order_Org_Auto_Set_Account_*` or other carry-over logic drifts, expect the
  first visible revrec damage on tenant/account alignment fields before
  dashboard totals
- if `RevRec_Set_PLG_BD_Pool` / `RevenueTrigger` / order revenue aggregation
  drifts, expect it to surface first in
  `monthly_revrec_orders.revenue_amount`
  /
  `adjusted_revenue_amount`
  /
  category revenue splits
- if `Invoice_Collection__c` status / payment / marketplace semantics drift,
  expect it to surface first in
  `monthly_revrec_collections.payment_type`,
  `invoice_amount`,
  `collections_from`,
  and channel-specific amount fields

### Commitment-Plan Time Split

The checked-out `cp_order_monthly_revrec` model adds one more important
boundary: the same finance report family does **not** source every month from
the same upstream path.

| 时间层 | 当前一手 SQL / schema 证据 | 这意味着什么 |
|---|---|---|
| `historical months` | `cp_order_monthly_revrec.sql` builds `historical_monthly_revrec` from nested `revenues` on `salesforce_orders`, ultimately sourced from `salesforce_revrec`; `cp_order_monthly_revrec.yml` documents `source = salesforce_revrec for historical months` | 历史月偏差更直接受 `Revenue__c` coverage、`revenue_date`、`amount_before_adjust`、`amount`、`credit_amount`、exchange-rate 语义影响 |
| `current month` | the same model builds `current_month_revrec` from `monthly_revrec_outputs.orders`; the schema explicitly documents `source = monthly_revrec_orders for the current month`; SQL then `QUALIFY ROW_NUMBER() ... ORDER BY CASE WHEN source = 'monthly_revrec_orders' THEN 0 ELSE 1 END` per `order_id, bill_month` | 当前月偏差更直接受 `salesforce_org_monthly_revrec` + `salesforce_order_daily_view` + Python revrec allocation logic影响；一旦 Python output 与 historical revrec 同月并存，当前月优先采用 Python 结果 |

Practical reading:

- if drift is visible mainly in past closed months, start from
  `Revenue__c -> salesforce_revrec -> historical_monthly_revrec`
- if drift is visible mainly in the in-flight current month, start from
  `Org__c / Order / Invoice_Collection__c -> salesforce_org_monthly_revrec + salesforce_order_daily_view -> monthly_revrec_orders`
- if a CP order shows a month-specific mismatch only on the latest bill month,
  do not assume the historical `salesforce_revrec` path is broken first;
  the checked-out model explicitly prefers `monthly_revrec_orders` for that
  current-month slice

Practical reading:

- if the drift symptom is `timestamps / lifecycle / funnel`, start with
  `Lead`
- if the drift symptom is `pipeline / forecast / ARR`, start with
  `Opportunity`
  and
  `Quote`
- if the drift symptom is `attribution weighting`, start with
  `CampaignMember`
  and then re-check the dependent `Opportunity` fields
- if the drift symptom is `tenant / account join mismatch`, start with
  `Account`
  and
  `Org__c`
- if the drift symptom is `finance / revrec / collections`, start with
  `Order`,
  `Revenue__c`,
  and
  `Invoice_Collection__c`

## Known Consumer Surfaces In `gcp-digital-bi`

The checked-out BI repos do not expose a full dashboard inventory for every
mart, so the evidence quality is mixed:

- strongest direct dashboard evidence currently comes from dbt `exposures.yml`
- next strongest evidence comes from Looker `explore` entry points
- after that, dbt mart/model names are still valid consumer-surface evidence,
  but they are one step more indirect than an explicit dashboard manifest
- current repo-wide search across the checked-out Looker/dbt trees found only
  3 direct Looker explores and 1 explicit dashboard exposure tied to these CRM
  surfaces
- the cloned `digital-bi-dbt` tree currently contains exactly one
  `dbt/models/**/exposures.yml` file, and it is the business-operations file
  that declares `Opportunity Data Quality Monitoring`
- the cloned `looker-schema` tree currently contains only 7 checked-out
  `.lkml` / `.dashboard.lookml` files in total, and none of them are separate
  CRM dashboard manifests
- the cloned `looker-schema` tree currently exposes the 3 CRM explores below
  and does not contain additional CRM `.dashboard.lookml` files in the
  checkout
- the marketing marts currently exist as SQL models, but the checkout does not
  add a matching marketing exposure file or marketing-specific schema/owner
  metadata layer
- a later `gh api` pass against remote
  `pingcap-inc/looker-schema`
  confirmed the same boundary at repo-head:
  the full tree still exposes only
  `cloud-lead-pipeline-insight.model.lkml`,
  `digitalbi.model.lkml`,
  `gcp-prod-billing.model.lkml`,
  plus the same three CRM views
  `salesforce_lead.view.lkml`,
  `salesforce_oppo.view.lkml`,
  and
  `crm_account.view.lkml`;
  there are still no separate CRM dashboard manifests at repo-head either
- so absence of more dashboards in this section should be read as
  `inventory gap in the checked-out BI repos`, not proof that no other
  business dashboards exist

### Confirmed Looker Explore Entry Points

| 消费面 | 证据 | 最敏感的对象 |
|---|---|---|
| Looker Explore `crm_account` | declared in `digitalbi.model.lkml`; backed by `crm_account.view.lkml` on `gcp-digital-bi.salesforce.crm_account` | `Account`, `Org__c` |
| Looker Explore `salesforce_oppo` | declared in `digitalbi.model.lkml`; backed by `salesforce_oppo.view.lkml` on `gcp-digital-bi.salesforce.salesforce_oppo` | `Opportunity`, `Quote`, `Order` carry-over |
| Looker Explore `salesforce_lead` in model `cloud-lead-pipeline-insight` | `cloud-lead-pipeline-insight.model.lkml` joins `salesforce_lead -> crm_account -> salesforce_oppo` and hard-filters to `internal_user = false` plus non-empty `TiDBCloudPortalID` | `Lead`, `Account`, `Opportunity` |

### Confirmed Dashboard Exposure

| 消费面 | 证据 | 直接依赖 | 谁会先看到偏差 |
|---|---|---|---|
| Looker Studio dashboard `Opportunity Data Quality Monitoring` | `dbt/models/marts/business_operations/exposures.yml` | `dws_data_quality_alerting`, `rpt_data_quality_wtw_comparison` | business-operations side; owner listed as `Chen Du <chen.du@pingcap.com>` |

Important direct lineage behind that dashboard:

- `dws_data_quality_alerting.sql` reads `salesforce_opportunities` and
  `salesforce_users`, then emits issue rows keyed by
  `stage_name`, `mapped_stage_name`, `owner_team`, `region`,
  `cloud_order_type`, `close_date`, `launch_date`, and
  `last_key_update_date`
- so for `Opportunity` parity gaps, this dashboard is not just generic
  business-operations metadata; it is a direct downstream consumer of
  opportunity stage / forecast / owner-team / launch-date semantics
- a later direct browser attempt against the Looker Studio URL did not land on
  an anonymously readable report; it redirected to Google sign-in instead.
  So the dashboard URL is a confirmed named consumer surface, but current
  report-page contents still need either authenticated browser access or an
  export/screenshot from BI owners if we want page-level metric proof

### Best-Evidence Consumer Map By Report Group

| 报表组 | 当前最强消费面证据 | 一旦有差异，最容易先被谁看到 |
|---|---|---|
| `Lead -> Pipeline Funnel` | Looker model `cloud-lead-pipeline-insight`; dbt `dws_lead_timeline`, `dws_icp_summary` | 用 Looker 看 lead-to-pipeline funnel 的业务/运营同学，以及依赖 `dws_lead_timeline` 的营销分析 |
| `Opportunity / Forecast / Data Quality` | Looker Explore `salesforce_oppo`; dbt `dws_opportunity_stage_duration`, `dws_opportunity_stage_conversion_rates`, `dws_data_quality_alerting`; explicit dashboard `Opportunity Data Quality Monitoring` | 最先是 sales / bizops 看机会质量、stage aging、forecast 的使用者 |
| `Campaign Attribution` | dbt `salesforce_campaign_attributions`, `dws_campaign_attribution`, `dws_campaign_attribution_details` | 营销归因分析使用者会最先看到 `attribution_percentage` / `attributed_arr` 漂移 |
| `Account / Tenant Linkage` | Looker Explore `crm_account`; dbt `salesforce_accounts`, `dim_tenant`, `customer_surrogate_keys`, `customers` | 看 account / tenant 维表和客户主数据链路的人会先看到 join 漂移 |
| `Order / ARR / RevRec / Collections` | dbt `salesforce_orders`, `salesforce_order_daily_view`, `salesforce_org_monthly_revrec`, `cp_order_monthly_revrec`, `dws_salesforce_arr_summary` | finance / revrec / billing 报表使用者会先看到累计收入、回款、tenant 汇总偏差 |

### Evidence Strength Notes For Marketing And Finance

The two remaining broad consumer groups do not currently have the same kind of
evidence:

| 报表组 | 目前最强证据 | 这说明什么 |
|---|---|---|
| `Campaign Attribution` | the checkout has mart SQL for `dws_campaign_attribution`, `dws_campaign_attribution_details`, `dws_lead_timeline`, and `dws_icp_summary`; `dws_campaign_attribution.sql` explicitly computes `attributed_acv` and `attributed_arr`; `dws_lead_timeline.sql` emits `mql_milestone`, `iqm_milestone`, `pipeline_created`, `customer_milestone`, and `campaign_interaction`; `pingcap-inc/dbt-dev` mirrors the same marketing mart family and even has a staging-parity TODO that had to explicitly build `salesforce_campaign_attributions dws_campaign_attribution`; but neither the current checkout nor remote `dbt-dev` / `looker-schema` repo-head adds a matching marketing exposure file or schema/owner metadata layer | 这组模型 clearly serves marketing / ICP / attribution analysis, but current evidence is still mart-lineage-heavy rather than dashboard-owner-heavy |
| `Order / ARR / RevRec / Collections` | `cp_order_monthly_revrec.yml` explicitly defines ongoing Commitment Plan revenue-recognition semantics; `salesforce_order_daily_view.yml` exposes order-by-day accumulated revenue / credit / net-fee surfaces; `monthly_cloud_revrec/sources.yml` declares `monthly_revrec_orders` and `monthly_revrec_collections` as Python-model sources; `monthly_cloud_billing_revrec.py` reads production `gcp-digital-bi.dwh_finance.salesforce_org_monthly_revrec` and `salesforce_order_daily_view`, then writes `monthly_revrec_orders` / `monthly_revrec_collections` outputs | 这说明 finance/revrec 链路不是“理论上的下游”，而是带有 source contract、定期运算和产物落表的实际运营面；即使当前 repo snapshot 里没有单独的 finance dashboard 清单，这条链依然是 load-bearing |

### Live BigQuery Consumer Surfaces

The current machine can also read live BigQuery metadata in
`gcp-digital-bi`, which upgrades the marketing evidence from
`repo semantics only`
to
`repo semantics + live warehouse object existence`.

Confirmed current live objects in region `us-west2`:

| live object | object type | current row evidence | why it matters |
|---|---|---|---|
| `dwh_marketing.salesforce_leads` | `TABLE` | `401,564` rows | this is the live marketing lead base carrying `lead_mql_timestamp`, `lead_iqm_timestamp`, `lead_status`, and contact-conversion context |
| `dws_marketing.dws_lead_timeline` | `TABLE` | `734,525` rows | this is not just a model name in git; it is a populated warehouse table used as the event spine for lead-funnel analysis |
| `dws_marketing.dws_icp_summary` | `TABLE` | `1,861` rows | this is the current ICP summary output with touch-path, IQM, and opportunity flags |
| `dws_marketing.dws_campaign_attribution` | `VIEW` | live `COUNT(*) = 1,045` | this is the current attributed ARR/ACV surface, not just a dormant view definition |
| `dwh_business_operations.salesforce_opportunities` | `TABLE` | `3,438` rows | this is the live opportunity mart feeding stage/ARR/forecast semantics into both bizops and marketing joins |
| `salesforce.crm_account` | `TABLE` | `2,034` rows | this is the live account/tenant-linked table still matching the `crm_account` Looker surface |

Two especially useful live-warehouse clarifications:

- `dwh_marketing.salesforce_leads` currently exposes
  `lead_mql_timestamp`,
  `lead_iqm_timestamp`,
  `lead_status`,
  and
  `contact_status`,
  but **does not** expose
  `date_status_changed`
  or
  `most_recent_working_status_date`
- `dws_marketing.dws_campaign_attribution` live view SQL directly joins
  `dwh_marketing.salesforce_campaign_attributions`,
  `dwh_business_operations.salesforce_accounts`,
  `stg_salesforce.stg_salesforce_contact`,
  `dwh_marketing.salesforce_campaigns`,
  and
  `dwh_business_operations.salesforce_opportunities`,
  then computes
  `attributed_acv`
  and
  `attributed_arr`

This makes the current downstream boundary sharper:

- `Lead_StatusChangeTimestamp` still has a confirmed staging hit, but the live
  warehouse lead base currently carries
  `lead_mql_timestamp` / `lead_iqm_timestamp`
  instead of
  `date_status_changed`
- campaign-member / attribution drift and opportunity ARR/stage drift are
  now proved at both git-definition level and live-warehouse object level

Recent live-job metadata now adds five stronger downstream-consumer proofs:

| downstream object | live definition evidence | recent consumer evidence | why it matters |
|---|---|---|---|
| `anls_business_operations.dim_opportunity` | live BigQuery shows it is a `VIEW` whose `base` CTE selects directly from `dwh_business_operations.salesforce_opportunities`, then joins `salesforce_picklist_labels` for `forecast_type_label` | recent `JOBS_BY_PROJECT` rows show `xiaopeng.zhu@pingcap.com` querying `anls_business_operations.dim_opportunity` fields such as `forecast_category`, `forecast_type`, `mapped_stage_name`, `stage_duration_days`, `arr_amount_usd`, `accurate_acv_amount`, `owner_team`, `cloud_order_type`, quote fields, tasks, and stage history | this upgrades the business-operations side from “there is a dashboard exposure” to “there is also a currently queried analytics view sitting directly on top of the opportunity mart” |
| `dwh_plg.plg_contacts` / `dwh_plg.plg_accounts` | live BigQuery shows `plg_contacts` is a `VIEW` that joins community/HubSpot data with `dwh_marketing.salesforce_leads`, and `plg_accounts` is a `VIEW` that derives PLG account sourcing by joining `dwh_marketing.salesforce_leads` with `dwh_business_operations.salesforce_accounts` | recent `JOBS_BY_PROJECT` rows show `yiming.wang@pingcap.com` repeatedly comparing prod vs `codex_nexuscrm_phase1` for `plg_contacts`, `plg_accounts`, `salesforce.crm_account`, and the underlying lead/account surfaces during staging-parity work | this proves the marketing lead base is not only for `dws_marketing` marts; it also feeds live PLG account/contact derivations that matter for growth/source attribution |
| `dws_marketing.dws_campaign_attribution` | live BigQuery already proved this is the current attributed ARR/ACV surface | recent `JOBS_BY_PROJECT` rows show `yiming.wang@pingcap.com` querying `attributed_arr`, `campaign_name`, `campaign_region`, `contact_response_date`, `opportunity_contact_role`, `opportunity_created_date`, and `opportunity_name` directly from `dws_campaign_attribution` on `2026-06-23` | this upgrades campaign attribution from “warehouse lineage says it matters” to “the live attributed ARR mart is being queried directly by a real user” |
| `dws_marketing.dws_icp_summary` | live BigQuery already proved this is the current ICP summary table | recent `JOBS_BY_PROJECT` rows show `yiming.wang@pingcap.com` querying `region`, `segmentation`, `icp_industry_categorisation`, `lead_surrogate_key`, `opportunity_id`, and `arr_amount` directly from `dws_icp_summary` on `2026-06-23` | this upgrades ICP analysis from “model exists” to “the live ICP summary is actively queried for regional / segmentation / industry cuts” |
| `dws_marketing.dws_lead_timeline` plus `anls_marketing.dim_lead` | live BigQuery already proved `dws_lead_timeline` is a populated event-spine table; `anls_marketing.dim_lead` is a separate live lead analytics table | recent `JOBS_BY_PROJECT` rows show `alfred.wang@pingcap.com` directly querying `dws_lead_timeline`, `yiming.wang@pingcap.com` aggregating `campaign_interaction` / `pipeline_created` / `customer_milestone` patterns from it in January 2026, and later querying `anls_marketing.dim_lead` joined with `fact_cloud_events` on `sign_up_timestamp` / campaign fields in May 2026 | this closes the remaining “who actually touches the lead-funnel marts” gap and shows the lead chain is consumed both as a timeline mart and as a broader marketing lead analytics surface |

Recent live-job metadata also adds four stronger pipeline / finance / account consumer proofs:

| downstream object | live definition evidence | recent consumer evidence | why it matters |
|---|---|---|---|
| `dws_business_operations.dws_data_quality_alerting` | live BigQuery shows it is a `VIEW` built from `dwh_business_operations.salesforce_opportunities` plus `salesforce_users`, then emits issue-oriented fields such as `issue_type`, `owner_team`, `region`, `stage_name`, and `weeks_elapsed` | recent `JOBS_BY_PROJECT` rows show `yiming.wang@pingcap.com` directly querying `dws_data_quality_alerting` on `2026-05-04` / `2026-05-07`, grouping by `issue_type`, `owner_team`, `region`, `cloud_order_type`, and selecting issue-detail rows by `opportunity_number` / `owner_name` / `owner_team` | this upgrades the opportunity data-quality side from “dbt builds a view and one exposure exists” to “the alerting mart itself is actively queried by a real user” |
| `dws_business_operations.rpt_data_quality_wtw_comparison` | live BigQuery shows it is a `VIEW` layered on `dws_data_quality_alerting_daily_view` with `wtw_type` status such as `Fixed` / `Carryover` / `New` | recent `JOBS_BY_PROJECT` rows show `yiming.wang@pingcap.com` directly querying `rpt_data_quality_wtw_comparison` on `2026-05-07`, slicing by `owner_team`, `region`, `issue_type`, `wtw_type`, `cloud_order_type`, and `opportunity_name` | this proves the week-to-week data-quality comparison surface is also a live consumer of opportunity-side semantics such as owner-team, stage, and issue typing |
| `model_fp_and_a.dws_salesforce_arr_summary` | live BigQuery shows this is a populated ARR summary table alongside `dws_business_operations.dws_salesforce_arr_summary` | recent `JOBS_BY_PROJECT` rows show `xiaopeng.zhu@pingcap.com` directly querying `monthly_total_arr`, `order_region`, `revrec_month`, `fiscal_year`, `fiscal_quarter_of_year`, and `quarter_arr_total_quota` from `model_fp_and_a.dws_salesforce_arr_summary` on `2026-07-07` | this proves the ARR summary surface is not only a downstream model name; it is being queried directly for FP&A-style regional and quota views |
| `dwh_finance.salesforce_order_daily_view` plus `dwh_finance.salesforce_org_monthly_revrec` | live BigQuery shows `salesforce_order_daily_view` is a `VIEW` over `dwh_business_operations.salesforce_orders` and nested `order_products` / `revenues`; `salesforce_org_monthly_revrec` is a `VIEW` over Google Sheets billing confirmation plus `salesforce_orgs` and `customer_surrogate_keys` | recent `JOBS_BY_PROJECT` rows show `xiaopeng.zhu@pingcap.com` and `fanfei.kong@pingcap.com` directly querying `salesforce_order_daily_view` on `2026-07-01` / `2026-07-04` for `order_number`, `account_id`, `accumulate_revenue_to_org_tenant_id`, `order_service_start_date`, `order_service_end_date`, and `order_net_fees`; the same users also directly queried `salesforce_org_monthly_revrec` on `2026-07-04` / `2026-07-05` for `tenant_id`, `total_amount`, `actual_revenue_recognition_date`, `raw_byoc_amount`, and billing-month counts | this closes much of the finance-side ownerless gap: order-day and org-month revrec surfaces are being directly inspected by real users, not only rebuilt by dbt or referenced indirectly by recurring outputs |

Important caution on interpreting recent-job metadata:

- in the current `JOBS_BY_PROJECT` passes, we now do have direct query-user
  evidence on
  `dws_marketing.dws_lead_timeline`,
  `dws_marketing.dws_icp_summary`,
  `dws_marketing.dws_campaign_attribution`,
  `anls_marketing.dim_lead`,
  `anls_business_operations.dim_opportunity`,
  and the PLG lead/account views
- the remaining weak spot is no longer
  `is anyone querying these marts at all`
  but rather
  `which named dashboard / explore / business owner sits on top of each one`
- so the current boundary has moved from
  `live object existence + row counts only`
  to
  `live object + direct user query evidence`,
  while dashboard-owner attribution is still thinner than the finance-side
  orchestration evidence
- the strongest currently named report/owner pair is still
  `Opportunity Data Quality Monitoring`
  owned by
  `Chen Du <chen.du@pingcap.com>`;
  the newer direct-query evidence now proves the surrounding
  `dws_data_quality_alerting`,
  `rpt_data_quality_wtw_comparison`,
  `dws_salesforce_arr_summary`,
  `salesforce_order_daily_view`,
  and
  `salesforce_org_monthly_revrec`
  surfaces are also actively consumed, even when we do not yet have a matching
  dashboard metadata file for each one
- a second named-surface family now exists in private repo
  `pingcap-inc/dbt-dev`
  also contains at least one named finance impact artifact beyond bare model
  SQL:
  `REVENUE_CATEGORY_IMPACT_ASSESSMENT.md`
  explicitly analyzes the blast radius of revrec-category changes and names
  `70` downstream models, including
  `dws_salesforce_arr_summary`,
  `dws_salesforce_order_monthly_revrec_usd_v2`,
  `dws_salesforce_order_product_monthly_revrec_usd_v2`,
  and several account/order monthly revrec surfaces
- a third named-surface family now exists in private repo
  `pingcap-inc/digital-bi-discovery`,
  which is not a formal Looker dashboard repo but does provide explicitly named
  analyst/discovery artifacts:
  `Data Discovery for Salesforce Opportunities`
  (`notebooks/data_discovery/bo/1_opportunities.ipynb`),
  `revrec_discovery`
  and
  `monthly_billing_validation`
  (`notebooks/data_discovery/finance/*.ipynb`),
  `01_campaign_discovery`,
  `02_campaign_attribution_discovery`,
  and a deployable
  `Campaign Attribution Tuner`
  app under
  `notebooks/data_discovery/marketing/attribution_app/`
- these files are weaker than a governed dashboard inventory, but they are
  still named consumer surfaces with concrete SQL/object usage:
  the opportunities notebook says
  `Data Discovery for Salesforce Opportunities`
  and explicitly studies Salesforce
  `opportunity`, `account`, `order`, and `quote`;
  the revrec notebook inspects Salesforce
  `order`, `order_product_c`, and `revenue_c`;
  the campaign notebooks and attribution app operate on campaign,
  opportunity, lead/contact, and opportunity-contact-role data
- a fourth marketing-consumer clue now exists directly in live BigQuery job
  labels:
  `INFORMATION_SCHEMA.JOBS_BY_PROJECT`
  on `2026-06-23`
  shows
  `requestor = looker_studio`
  for two report-backed marketing surfaces by
  `yiming.wang@pingcap.com`
- `report_id = 8c6f30a4-c6fe-4536-ac62-d937d0176ebd`
  repeatedly queries
  `gcp-digital-bi.dws_marketing.dws_campaign_attribution`
  with fields including
  `attributed_arr`,
  `campaign_name`,
  `campaign_region`,
  `contact_response_date`,
  `opportunity_created_date`,
  and
  `opportunity_name`
- the same
  `report_id = 8c6f30a4-c6fe-4536-ac62-d937d0176ebd`
  also has another datasource
  `2ff3a1a3-b43c-4143-b512-2d2770d0334ft0c0d1`
  querying
  `gcp-digital-bi.anls_business_operations.dim_opportunity`
  with fields such as
  `lead_source`,
  `mapped_stage_name`,
  `opportunity_id`,
  `opportunity_name`,
  `opportunity_record_type`,
  and
  `region`
- `report_id = fd12e3fc-d36f-4cc5-b2d9-9ed2808489dc`
  repeatedly queries
  `gcp-digital-bi.dws_marketing.dws_icp_summary`
  with fields including
  `opportunity_id`,
  `lead_surrogate_key`,
  `region`,
  `segmentation`,
  and
  `icp_industry_categorisation`
- the same
  `report_id = fd12e3fc-d36f-4cc5-b2d9-9ed2808489dc`
  also queried
  `gcp-digital-bi.dws_marketing.dws_lead_timeline`
  and
  `gcp-digital-bi.anls_marketing.dim_lead`
  on `2026-01-08` and `2026-01-12`,
  with fields such as
  `campaign_interaction`,
  `lead_surrogate_key`,
  `region`,
  `has_oppo`,
  and
  `won_oppo`
- a later wide scan across
  `requestor = looker_studio`
  jobs touching
  `dws_marketing.*`,
  `dwh_marketing.*`,
  and
  `anls_marketing.*`
  between `2026-01-01` and `2026-07-01`
  did not surface a third stable marketing report id.
  Current governed/report-backed marketing evidence still collapses mainly to
  these two report ids:
  `fd12...`
  and
  `8c6f...`
- the same wide scan found no direct
  `requestor = looker_studio`
  query whose SQL text names
  `gcp-digital-bi.dwh_marketing.salesforce_leads`
  ,
  so `salesforce_leads`
  currently reads more like an upstream warehouse feed than a directly proven
  Looker Studio front-door surface
- a broader org-wide GitHub code search for
  `salesforce_lead`,
  `salesforce_oppo`,
  `crm_account`,
  `cloud-lead-pipeline-insight`,
  `dws_salesforce_arr_summary`,
  `salesforce_order_daily_view`,
  `dws_data_quality_alerting`,
  and
  `rpt_data_quality_wtw_comparison`
  did **not** surface a richer governed dashboard inventory beyond the already
  known repos/artifacts above, which reinforces the current boundary:
  named dashboard metadata is sparse, while named discovery / impact-analysis
  artifacts are more findable

Naming caveat from live BigQuery:

- the current Looker checkout still points to singular names such as
  `gcp-digital-bi.salesforce.salesforce_lead`
  and
  `gcp-digital-bi.salesforce.salesforce_oppo`
- but current live BigQuery object search did **not** find those exact tables;
  instead it found
  `dwh_marketing.salesforce_leads`,
  `dwh_business_operations.salesforce_opportunities`,
  and legacy-style rectify views
  `salesforce.salesforce_lead_rectify` /
  `salesforce.salesforce_oppo_rectify`
- so current LookML naming should be treated carefully:
  `crm_account` still maps cleanly to a live base table,
  while the lead/opportunity surfaces appear to straddle
  older singular/rectify naming and newer warehouse mart naming

### Marketing / Pipeline SQL Proof Chain

The current marketing-side evidence is weaker on named dashboards, but it is
already strong enough at the SQL semantics layer to prove a concrete
`upstream object field -> downstream report metric` path.

| 链路 | 当前一手 SQL 证据 | 这意味着什么 |
|---|---|---|
| `CampaignMember -> attribution weights` | `salesforce_campaign_members.sql` maps `campaign_member_status` into `is_contact_involved` / `contact_involvement_level`, and when `first_responded_date` is blank but the contact is involved, it backfills a synthetic response date from the midpoint of `created_date` and `last_modified_date`; `salesforce_campaign_interacted_accounts.sql` then converts lead-side members to contacts, deduplicates to the latest `contact_response_date` per `campaign_id + contact_id`, and keeps only account-linked responses; `salesforce_campaign_attribution_details.sql` links those campaign touches to opportunities by `account_id`, filters to non-null response dates within 180 days, and weights them by campaign type, main-contact match, primary/champion flags, and `opportunity_contact_role`; `salesforce_campaign_attributions.sql` then deduplicates by `opportunity_id + campaign_id` and normalizes `final_weight` into `attribution_percentage`; `dws_campaign_attribution.sql` multiplies that percentage by `accurate_acv_amount` and `arr_amount_usd` to produce `attributed_acv` and `attributed_arr` | 所以 `CampaignMember` 的 response / involvement 语义如果被 Salesforce 自动化维护，而本地没对齐，不会只影响 CRM 页面展示，而会直接改写 attribution 权重和最终的 ARR/ACV 归因金额 |
| `Lead / Opportunity -> timeline events` | `salesforce_leads.sql` derives `lead_mql_timestamp` from Lead/Contact MQL fields and derives `lead_iqm_timestamp` from the earliest Lead history transition where `Lifecycle_Stage__c -> salesqualifiedlead`, with Contact IQM as fallback; `dws_lead_timeline.sql` then emits `mql_milestone` from `lead_mql_timestamp`, `iqm_milestone` from `lead_iqm_timestamp`, `pipeline_created` from `salesforce_opportunities.created_timestamp`, `customer_milestone` from `launch_date`, and `campaign_interaction` from `salesforce_campaign_members.first_responded_date` | 所以 `Lead` 的 lifecycle timestamp、`Opportunity` 的 creation/launch 语义、以及 `CampaignMember.first_responded_date` 任何一段失真，都会直接重排 lead timeline 里的事件顺序和事件缺失情况 |
| `Lead timeline + Opportunity + Account -> ICP summary` | `dws_icp_summary.sql` takes `dws_lead_timeline` as the event spine, combines it with `salesforce_accounts` region/segmentation/industry and `salesforce_opportunities` ARR/ACV/stage context, and computes `first_touch_campaign`, `last_touch_campaign`, `last_touch_before_iqm`, `last_touch_before_opp_creation`, `opp_campaign_touches`, and launched/pipeline flags | 所以 marketing 侧不是只看 campaign hit 数；它会把 lead timeline、account segmentation、以及 opportunity ARR/ACV/stage 串起来，任何前段自动化漂移都会穿透到 ICP 和 lead-to-pipeline 分析 |

Important boundary from the current checked-out BI repos:

- `stg_salesforce_lead.sql` does materialize `date_status_changed`,
  but the current checkout search did **not** show that field flowing into
  `salesforce_leads.sql`,
  `dws_lead_timeline.sql`,
  `dws_icp_summary.sql`,
  or Looker `salesforce_lead.view.lkml`
- a later cross-check against remote
  `ywang-official/digital-bi-dbt`
  and
  `pingcap-inc/dbt-dev`
  via GitHub REST code search found the same thing:
  `date_status_changed` only hit
  `stg_salesforce_lead.sql`,
  while downstream marketing fields such as
  `lead_iqm_timestamp`,
  `lead_mql_timestamp`,
  `attributed_arr`,
  and
  `first_touch_campaign`
  did hit
  `salesforce_leads.sql`,
  `dws_lead_timeline.sql`,
  `dws_campaign_attribution.sql`,
  and
  `dws_icp_summary.sql`
- so `Lead_StatusChangeTimestamp` is now strong evidence of
  `live-vs-local semantic parity mismatch`,
  but in this checkout its most direct confirmed BI hit is still
  staging/raw parity rather than the named marketing marts above

### Marketing / Pipeline Object Drilldown

This is the object-level version of the SQL proof chain above.

It keeps the four recurring questions in one place:

1. what Salesforce is still auto-maintaining
2. what CM/local pack already supports
3. what is still missing / suspicious
4. which downstream report fields will drift first

| 对象 | Salesforce 会做什么 | CM 目前已支持 | CM 目前未支持 / 疑似未支持 | 先打歪哪些字段 / 模型 |
|---|---|---|---|---|
| `Lead` | live Salesforce still maintains lifecycle progression, owner/domain/account linkage, nurture gating, and the timestamps that eventually become `lead_mql_timestamp` / `lead_iqm_timestamp`; the warehouse `salesforce_leads.sql` proves the downstream model takes `lead_mql_timestamp` from Lead/Contact fields and `lead_iqm_timestamp` from Lead history / Contact fallback | current final pack already carries 25 formulas, 17 active validation rules, and 12 Lead Flows including lead-account relate, IQM completion, auto-create-org, region/defaulting, and convert helpers; `Nurture_Marketing_Date` / `Nurture_Sales_Date` definitions already exist locally | 22 live Lead Flows are still absent locally, especially email / partner / scheduled-reminder surfaces; the 2 nurture validations are present but inactive; `LeadTrigger` / `LeadAITrigger` remain true runtime boundaries | first visible drift is on `salesforce_leads.lead_mql_timestamp`, `lead_iqm_timestamp`, `lead_status`, `pre_account_region`, `pre_account_segmentation`, and the Looker `salesforce_lead` dimensions `LeadLifecycleStage`, `LeadStatus`, `LeadSource`, `Region`, `Segmentation`, `TenantStatus`, `TiDBCloudPortalID`; those then flow into `dws_lead_timeline`, `dws_icp_summary`, and `cloud-lead-pipeline-insight` |
| `Opportunity` | live Salesforce still maintains forecast semantics, stage progression, ARR/ACV conversions, owner-team/region fields, close/launch helpers, and quote-derived commercial fields; the warehouse `salesforce_opportunities.sql` proves the downstream model materializes `forecast_category`, `forecast_type`, `region`, `launch_date`, `allow_close`, `accurate_acv_amount`, `arr_amount_usd`, `owner_team`, `stage_duration_days`, `quote_service_start_date`, `quote_service_end_date`, and quote nonstandard-term helpers | current final pack already carries 29 formulas, 5 rollups, 21 active validation rules, and 12 Opportunity Flows including launch-stage, close-date, cloud-order-type, pricebook, stage-derived, and task/key-deal maintenance; `PingCAP_Contract_Entity_EMEA_only` is already defined locally | 17 live Opportunity Flows are still absent locally, especially AWS/defaulting/notification/share logic; `PingCAP_Contract_Entity_EMEA_only` exists but is inactive; `OpportunityTrigger` remains a runtime boundary; quote-side parity gaps can still leak into opportunity enrichment | first visible drift is on `salesforce_opportunities.forecast_category`, `forecast_type`, `region`, `owner_team`, `stage_name`, `stage_duration_days`, `launch_date`, `quote_service_start_date`, `quote_service_end_date`, `accurate_acv_amount`, `arr_amount_usd`, plus downstream issue flags in `dws_data_quality_alerting`; those drive Looker `salesforce_oppo`, `dws_opportunity_stage_duration`, `dws_opportunity_stage_conversion_rates`, `dws_salesforce_arr_summary`, and lead-to-pipeline joins |
| `CampaignMember` | live Salesforce still maintains response/involvement semantics, first/last-touch helper fields, and campaign-member-side update logic; the warehouse `salesforce_campaign_members.sql` proves downstream semantics depend on `campaign_member_status`, `has_responded`, `is_contact_involved`, `contact_involvement_level`, and a backfilled `first_responded_date`; `salesforce_campaign_attribution_details.sql` and `salesforce_campaign_attributions.sql` then convert those interactions into weighted attribution | current final pack already carries 34 formulas and 4 first/last-touch maintenance Flows on Lead/Contact campaign references | one live Flow is still missing locally: `Campaign_Member_Key_Message_Update`; `Trigger_CampaignMember` remains a runtime boundary | first visible drift is on `salesforce_campaign_members.first_responded_date`, `campaign_member_status`, `has_responded`, `is_contact_involved`, `contact_involvement_level`, and then on `salesforce_campaign_attributions.attribution_percentage`, `dws_campaign_attribution.attributed_acv`, `attributed_arr`; the same drift also reorders `dws_lead_timeline` campaign interactions and the touch-path fields in `dws_icp_summary` |

Practical reading:

- `Campaign Attribution` currently has clear metric semantics but weaker
  dashboard-owner evidence
- `Order / ARR / RevRec / Collections` currently has weaker dashboard-owner
  evidence too, but much stronger
  `operational data-contract + parity-test + recurring output`
  evidence
- so if a stakeholder asks
  `which side is more operationally load-bearing today`,
  the finance/revrec chain has the stronger repository evidence even without a
  named dashboard owner

Important limitation:

- from the current repo snapshots, only one dashboard is explicitly declared in
  dbt `exposures.yml`
- the current checked-out Looker repo also exposes only 3 CRM-relevant Explore
  entry points:
  `crm_account`,
  `salesforce_oppo`,
  and
  `salesforce_lead`
- for the rest, the strongest available evidence is currently
  `Looker Explore names + dbt mart lineage`
- so the report can already answer
  `which report family / model is affected`
  confidently,
  but not yet a complete
  `full dashboard inventory`

### Org-Wide Search Upgrade Beyond The Current Checkout

Additional GitHub code search outside the two checked-out BI repos strengthens
the finance-side consumer evidence further.

| 报表组 | repo 外层新增证据 | 这对“影响哪张报表”意味着什么 |
|---|---|---|
| `Order / ARR / RevRec / Collections` | `pingcap-datalake` carries hand-authored curated contracts for `finance.monthly_revrec_orders` and `finance.monthly_revrec_collections`, both owned by `data-platform`, with `P1D` freshness, blocking tests, and declared lineage from `finance.salesforce_org_monthly_revrec` + `finance.salesforce_order_daily_view`; its Airflow source configs name concrete assets `orchestration_dbt_revrec_assets` and `orchestration_python_revrec_assets`, where python job `monthly_cloud_billing_revrec` emits those two finance products in contract order; `netforce-hub` also contains a `FetchMonthlyOrderInfoV2` path that explicitly switches to the new revrec order/collection tables instead of the legacy source | 这已经超过“模型名字存在”的强度，说明 finance/revrec/collections 是带 contract、orchestration、以及至少一个下游服务消费面的真实生产链路 |
| `Campaign Attribution` / `Lead Funnel` | completed org-wide searches in currently accessible repos mainly returned `dbt-dev` model/TODO hits (`dws_lead_timeline`, `dws_icp_summary`, `dws_campaign_attribution`); the strongest extra clue is a staging-parity TODO that had to explicitly select `salesforce_campaign_attributions dws_campaign_attribution`; a later remote tree pass also confirmed `pingcap-inc/looker-schema` repo-head still has only the same 7 LookML files and no extra CRM dashboards; but we still did **not** surface an equivalent external product-contract / orchestration / service-consumer layer before GitHub code-search rate limits kicked in | 当前最稳说法仍然是：marketing 这组下游影响已经能在 dbt/Looker 语义层坐实，但当前 repo-visible证据还没有像 finance 那样升级到 external contract / orchestration / service-consumer 层 |

Practical consequence:

- if the question is
  `哪一组报表现在最像生产运营真正在跑的链路`
  then finance/revrec/collections now has the strongest repository evidence
- if the question is
  `营销归因会不会被打歪`
  the answer is still yes, but the strongest current proof remains
  `dbt mart semantics + Looker Explore adjacency`
  rather than an explicit external contract/dag inventory

## Report-Group Summary Matrix

If the audience is not asking object-by-object questions, this is the most
compact answer in the whole note.

Each row is organized around a report family instead of a CRM object:

- what Salesforce still auto-maintains for that report family
- what CM + the current PingCAP final pack already support
- what is still missing / suspicious
- which report surfaces are most directly affected

| 报表组 | Salesforce 还在自动做什么 | CM 目前已支持 | CM 目前未支持 / 疑似未支持 | 直接受影响报表 / 模型 | 当前证据强度 |
|---|---|---|---|---|---|
| `Lead Funnel / Qualification` | 维护 `LeadLifecycleStage`、`LeadStatus`、`LeadSource`、`lead_mql_timestamp`、`lead_iqm_timestamp`、lead-account / tenant 关联；并驱动部分 assignment / reminder / notification 行为 | Lead 公式、17 条 active validation、12 条 Lead Flow 已迁；`dws_lead_timeline` 所需的核心 lead milestone 字段本地已有大量基础 | 22 个 live Lead Flow 仍未迁；`Nurture_Marketing_Date` / `Nurture_Sales_Date` 已定义但 inactive；`LeadTrigger` / `LeadAITrigger` 仍是 runtime boundary | Looker `salesforce_lead`, `cloud-lead-pipeline-insight`; dbt `salesforce_leads`, `dim_lead`, `dws_lead_timeline`, `dws_icp_summary` | `High` for model/field impact; `Medium` for full dashboard inventory |
| `Pipeline / Forecast / Opportunity Quality` | 维护 `forecast_category`、`forecast_type`、`stage_name`、`stage_duration`、`arr_amount_usd`、`accurate_acv_amount`、`owner_team`、`cloud_order_type`、launch/close-date helpers；Quote side 还维护服务起止与商业条款辅助语义 | Opportunity 公式、rollup、21 条 active validation、12 条 Flow 已有；Quote 公式、rollup、`QuoteNumber` 和部分 validation / Flow 已有；`salesforce_opportunities` 下游核心字段在本地模型中完整存在 | 17 个 live Opportunity Flow 仍未迁；`PingCAP_Contract_Entity_EMEA_only` 已定义但 inactive；2 个 Quote Flow 缺失，3 条 Quote validation 已定义但 inactive；`OpportunityTrigger` / `QuoteTrigger` 仍是 runtime boundary | Looker `salesforce_oppo`, `cloud-lead-pipeline-insight`; dbt `salesforce_opportunities`, `dim_opportunity`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration`, `dws_opportunity_stage_conversion_rates`, `dws_data_quality_alerting`; dashboard `Opportunity Data Quality Monitoring` | `High` |
| `Campaign Attribution / ICP Analysis` | 维护 `CampaignMember.first_responded_date`、response/status/involvement 语义、first/last touch 辅助字段，并把机会侧 `ARR/ACV/stage` 语义带入 attribution | `CampaignMember` 已有 4 个 first/last touch Flow；本地模型会从 campaign member 和 opportunity 计算 `attribution_percentage`, `attributed_acv`, `attributed_arr`；`dws_icp_summary` 已把 campaign path 折进 lead/IQM/opportunity 分析 | `Campaign_Member_Key_Message_Update` 缺失；`Trigger_CampaignMember` 仍是 runtime boundary；营销侧目前没有像 bizops 那样显式暴露在 repo 里的 dashboard owner 证据 | dbt `salesforce_campaign_members`, `salesforce_campaign_attributions`, `dws_campaign_attribution`, `dws_campaign_attribution_details`, `dws_icp_summary`, `dws_lead_timeline` | `High` for metric semantics; `Medium-Low` for named dashboard/owner evidence |
| `Order / ARR / RevRec / Collections` | 维护 order-to-org carry-over、PLG pool、contract gating、`revenues` 聚合、`revenue_name` / `revenue_status` / `amount_before_adjust`、invoice/collection payable/cash fields、服务窗口与累计收入语义 | `OrderNumber`、大量 Order/Revenue/Invoice 公式、本地 finance views、`salesforce_order_daily_view` / `cp_order_monthly_revrec` / `salesforce_org_monthly_revrec` 等核心模型都已存在；`Order` 本地还已支持 `Quote -> Order` 核心字段继承、payment field inheritance、`Order_Default_RevRec_Entity`、以及 account-level governing-contract validation replacement policy；finance 链路有 schema contract、legacy parity tests、python recurring outputs | 4 个 live Order Flow 缺失；`RevRec_Set_PLG_BD_Pool` 缺失；`Revenue__c.Name`、`Invoice_Collection__c.Name` 缺失；Invoice_Collection 4 个 live Flow 未迁；`OrderTrigger` / `RevenueTrigger` 和 line-item trigger surfaces 仍是 runtime boundary；旧的 `Order_Create_Requires_Effective_CSA_MA_Contract` 更应读作已被本地 governing-contract policy 替代的 Salesforce-era 规则，而不是普通未迁 validation | dbt `salesforce_orders`, `salesforce_order_daily_view`, `salesforce_order_current_monthly_arr`, `salesforce_revrec`, `cp_order_monthly_revrec`, `salesforce_org_monthly_revrec`, `dws_salesforce_arr_summary` | `High` for operational load-bearing evidence; `Medium` for named dashboard/owner evidence |
| `Account / Tenant Linkage / Customer Identity` | 维护 `AccountID`、`Region`、`Segmentation`、`TenantStatus`、`TiDBCloudPortalID`、account-to-tenant bridge、`accumulate_revenue_to_org_tenant_id` 等共享维度语义 | `Account_ID__c`、Account/Org 公式、已有 Account Flow、`Org_Set_Account` Flow、`crm_account` / `salesforce_accounts` / `dim_tenant` 所需核心维度字段在本地链路中已存在 | 4 个 live Account Flow 缺失；`AccountTrigger` 仍是 runtime boundary；Order / Revenue 侧 carry-over 缺失也会反向污染 tenant/account 共享维表 | Looker `crm_account`, `cloud-lead-pipeline-insight`; dbt `salesforce_accounts`, `dim_account`, `dim_tenant`, `salesforce_orgs`, `customer_surrogate_keys`, `customers`, `salesforce_org_monthly_revrec` | `High` for lineage; `Medium` for end-dashboard inventory |

Fast reading:

- if the question is
  `哪个报表组最依赖 Salesforce 现网自动化`,
  answer:
  `Pipeline / Forecast`,
  `Lead Funnel`,
  and
  `Order / ARR / RevRec / Collections`
- if the question is
  `哪个报表组最像 CM 平台完全没能力`,
  answer:
  none of the report groups as a whole;
  the clearest true CM boundary is still the subset of behavior that remains
  only in live Apex triggers
- if the question is
  `哪个报表组最适合先修`,
  answer:
  `Pipeline / Forecast`,
  `Lead Funnel`,
  and
  `Order / ARR / RevRec / Collections`
  because these have both the broadest field-level blast radius and the
  strongest current evidence

## Named Surface / Evidence Ladder

If the audience asks
`这些差异到底先打到哪一层分析面`
,
this is the shortest answer:

| 报表组 | 当前最强的命名 surface | 当前最强证据层级 | 先受影响的对象/差异类型 |
|---|---|---|---|
| `Pipeline / Forecast / Opportunity Quality` | dashboard `Opportunity Data Quality Monitoring`; notebook `Data Discovery for Salesforce Opportunities`; live marts `dws_data_quality_alerting`, `rpt_data_quality_wtw_comparison`, `dws_salesforce_arr_summary` | `dashboard metadata` + `named discovery artifact` + `direct user queries` + `view/model lineage` | `Opportunity`, `Quote`; owner-team / stage / forecast / ARR-ACV / quote enrichment drift |
| `Lead Funnel / Qualification` | Looker `cloud-lead-pipeline-insight`; marts `dws_lead_timeline`, `dws_icp_summary`; analytics table `anls_marketing.dim_lead` | `named explore/model` + `direct user queries` + `model lineage`; governed dashboard inventory still weak | `Lead`, then `Opportunity`; lifecycle / MQL-IQM / account-tenant linkage / conversion-path drift |
| `Campaign Attribution / ICP Analysis` | notebooks `01_campaign_discovery`, `02_campaign_attribution_discovery`; app `Campaign Attribution Tuner`; marts `dws_campaign_attribution`, `dws_icp_summary`, `dws_lead_timeline` | `named discovery artifact/app` + `direct user queries` + `model lineage`; governed dashboard metadata still weak | `CampaignMember`, `Lead`, `Opportunity`; first-response / involvement / attribution-weight drift |
| `Order / ARR / RevRec / Collections` | notebooks `revrec_discovery`, `monthly_billing_validation`; named impact doc `REVENUE_CATEGORY_IMPACT_ASSESSMENT.md`; live views `salesforce_order_daily_view`, `salesforce_org_monthly_revrec`; summary table `dws_salesforce_arr_summary` | `named impact artifact` + `named discovery artifact` + `direct user queries` + `contract/orchestration evidence` | `Order`, `Revenue__c`, `Invoice_Collection__c`, `Org__c`; carry-over / pool / status / revrec / collections timing drift |
| `Account / Tenant Linkage / Customer Identity` | Looker `crm_account`; live view `salesforce_accounts`; shared dims `dim_tenant`, `customer_surrogate_keys`, `customers` | `named explore` + `direct user queries` + `shared-dimension lineage`; dashboard inventory still weak | `Account`, `Org__c`; segmentation / ICP / tenant-bridge / shared-key drift |

This ladder is useful because it keeps us from overstating certainty:

- `Pipeline / Forecast` already has a real named dashboard plus live user
  queries
- `Order / ARR / RevRec / Collections` already has named notebooks and a named
  finance blast-radius document, even when dashboard metadata is sparse
- `Lead Funnel` and `Campaign Attribution` are no longer only lineage-heavy,
  but they still lean more on
  `named explore/discovery artifact + direct query evidence`
  than on a rich governed dashboard inventory

### Who Likely Notices First

The current job-log evidence is also strong enough to say which concrete user
surfaces are likely to feel each report-group drift first:

| 报表组 | 当前最强的 user-facing 线索 | 说明 |
|---|---|---|
| `Pipeline / Forecast / Opportunity Quality` | dashboard owner `Chen Du <chen.du@pingcap.com>` on `Opportunity Data Quality Monitoring`; recent direct queries by `yiming.wang@pingcap.com` on `dws_data_quality_alerting` / `rpt_data_quality_wtw_comparison`; recent direct queries by `xiaopeng.zhu@pingcap.com` on `model_fp_and_a.dws_salesforce_arr_summary` | 这是当前最接近“正式 owner + 活跃查询用户”双重证据的一组，所以 Opportunity/Quote drift 最容易先在 pipeline-quality / forecast / ARR summary 面被看到 |
| `Lead Funnel / Qualification` | recent direct queries by `alfred.wang@pingcap.com` on `dws_lead_timeline`; repeated direct queries by `yiming.wang@pingcap.com` on `dws_icp_summary`; direct queries on `anls_marketing.dim_lead` | 说明 Lead 链路的漂移已经不是纯理论风险，至少会先打到 lead timeline、ICP cuts、以及营销 lead analytics 使用者 |
| `Campaign Attribution / ICP Analysis` | repeated direct queries by `yiming.wang@pingcap.com` on `dws_campaign_attribution` and `dws_icp_summary`; named analysis artifacts `01_campaign_discovery`, `02_campaign_attribution_discovery`, `Campaign Attribution Tuner` | 说明 CampaignMember/Lead/Opportunity attribution drift 最可能先在营销归因分析者和 attribution-tuning 使用面暴露出来 |
| `Order / ARR / RevRec / Collections` | repeated direct queries by `xiaopeng.zhu@pingcap.com` and `fanfei.kong@pingcap.com` on `salesforce_order_daily_view` and `salesforce_org_monthly_revrec`; direct queries by `xiaopeng.zhu@pingcap.com` on `dws_salesforce_arr_summary`; named artifacts `revrec_discovery`, `monthly_billing_validation`, `REVENUE_CATEGORY_IMPACT_ASSESSMENT.md` | 这组现在已经有很强的“谁会先痛”证据：order-day / org-month / ARR summary / revrec validation 面会非常早地感知 Order/Revenue/Invoice drift |
| `Account / Tenant Linkage / Customer Identity` | direct queries by `xiaopeng.zhu@pingcap.com` and `chen.du@pingcap.com` on `salesforce_accounts`; direct queries by `laura.luo@pingcap.com` on `anls_core.dim_customer` using `tenant_ids` | 说明 Account/Org shared-dimension drift 不只是背景维表问题，account segmentation / ICP / customer-tenant lookup 使用者会比较快看到 join/key 漂移 |

Important caveat:

- these user names are evidence of
  `who is directly querying the current surfaces`
  ,
  not a complete authoritative owner registry
- still, they are much stronger than a purely abstract statement like
  `some downstream mart would be affected`

### Business Question Wording

The current accessible BI docs are also strong enough to restate each report
group in business language rather than only model names:

| 报表组 | 这些面在业务上主要回答什么问题 | 当前最直接的 doc / SQL 证据 |
|---|---|---|
| `Pipeline / Forecast / Opportunity Quality` | 机会现在在哪个阶段、卡了多久、forecast 属于哪类、金额和 ARR/ACV 多大、关联 quote/task 有没有质量问题 | `dim_opportunity.yml` says it tracks stage, forecast, financial, quote, and task aspects of opportunities; `dws_opportunity_stage_duration.yml` says it analyzes opportunity lifecycles and stage durations; `dws_data_quality_alerting.sql` names concrete issue types such as `Aging`, `No Status Update`, `Past Due`, `Service Start Date Issue`, and `Past Due Launch` |
| `Lead Funnel / Qualification` | 线索如何从最初接触走到 `MQL`、`IQM`、建 opp、再到客户转化；不同 touch path 怎样影响漏斗推进 | `dws_lead_timeline.sql` emits `mql_milestone`, `iqm_milestone`, `pipeline_created`, `customer_milestone`, and `campaign_interaction`; `cloud-lead-pipeline-insight` joins `Lead -> Account -> Opportunity`; live jobs show users aggregating `campaign_interaction` / `pipeline_created` / `customer_milestone` from `dws_lead_timeline` |
| `Campaign Attribution / ICP Analysis` | 哪些 campaign touch 真正贡献了 opp、ARR、ACV；哪些 ICP campaign 更容易在 IQM 前或建 opp 前产生影响 | `dws_campaign_attribution.sql` multiplies `attribution_percentage` into `accurate_acv_amount` / `arr_amount_usd`; `dws_icp_summary.sql` computes `first_touch_campaign`, `last_touch_before_iqm`, `last_touch_before_opp_creation`, and ICP-touch counts; `Campaign Attribution Tuner` explicitly tunes campaign/opportunity attribution weights |
| `Order / ARR / RevRec / Collections` | 订单服务期、累计收入、递延/已确认收入、回款、tenant 汇总是否正确；当前月和历史月 revenue recognition 是否对得上 | `salesforce_order_daily_view.yml` exposes order-by-day service window, accumulated revenue, accumulated credit, and order net fees; `salesforce_org_monthly_revrec.yml` describes reconciled tenant-month billing/revrec rows; `REVENUE_CATEGORY_IMPACT_ASSESSMENT.md` names 70 downstream revrec-impact surfaces |
| `Account / Tenant Linkage / Customer Identity` | 一个 account 对应哪些 tenant、收入该累到哪个 tenant/account、共享的 segmentation/ICP/industry 维度是否一致 | `dim_account.yml` says it is account-level business-operations analytics; `dim_org.yml` says it tracks org/tenant relationships and revenue accumulation; `salesforce_orgs.yml` explicitly states the one-to-many account-to-tenant relationship |

## Report-Group Mechanism Map

The summary matrix above says
`what`
each report family depends on.

This section says
`which exact local mechanisms already exist`
and
`which exact named mechanisms are still missing or suspicious`.

| 报表组 | CM 本地已经有的关键机制 | 当前最关键的缺失 / 可疑机制 | 最短修复路径 |
|---|---|---|---|
| `Lead Funnel / Qualification` | local Lead Flows already include `BN_Lead_Relate_to_Account_by_Email_Domain_Flow`, `BN_Account_Lead_Relate_Leads_to_Accounts`, `IQM_Completion_Flow`, `Lead_Auto_Create_Org`, `Lead_Quick_Set_Region`, `Lead_Status_Duration`, `Lifecycle_Stage_to_Opportunity_Upon_Conversion`, `Std_ConvertLead`, `Std_RelinkLeadChildren`; local validation definitions already include `Nurture_Marketing_Date`, `Nurture_Sales_Date` | 22 live Lead Flows still not fully migrated; `Nurture_Marketing_Date` / `Nurture_Sales_Date` are present but inactive; unresolved Lead assignment / notification / reminder surfaces; `LeadTrigger` / `LeadAITrigger` remain runtime boundary | 先走 `B1` 激活两条 nurture validation，再继续 `B2/B4` 补 Lead assignment / reminder 类 Flow，最后才碰 Apex 替代 |
| `Pipeline / Forecast / Opportunity Quality` | local Opportunity Flows already include `Opportunity_Auto_To_Launch_Stage`, `Opportunity_Close_Date_Auto_Set`, `Opportunity_Cloud_Order_Type_Set`, `Opportunity_Launch_Stage_Validation`, `Opportunity_Pricebook_Default`, `Std_OpportunityStageDerivedFields`, `Task_Update_Opportunity_Key_Deal`; local Quote parity already has `QuoteNumber`, heavy formulas, rollups, and local validation definitions for `Customer_s_Hardware_Configuration`, `Details_of_vCPU_Calculation`, `Version_of_TiDB`; local validation definition also includes `PingCAP_Contract_Entity_EMEA_only` | 17 live Opportunity Flows still absent; `PingCAP_Contract_Entity_EMEA_only` is present but inactive; missing `Quote_update_nonstandard_conditions_checkbox` and `Quote_update_nonstandard_conditions_checkbox_2`; 3 Quote validations are present but inactive; `OpportunityTrigger` / `QuoteTrigger` remain runtime boundary | 先走 `B1` 激活 Opportunity/Quote 已存在规则，再走 `B2` 补两个 Quote Flow 和高价值 Opportunity Flow，最后再单列 trigger 替代 |
| `Campaign Attribution / ICP Analysis` | local CampaignMember support already includes `Lead_Set_First_And_Last_CampaignMember`, `Lead_Set_First_And_Last_CampaignMember_delete`, `Contact_Set_First_And_Last_CampaignMember`, `Contact_Set_First_And_Last_CampaignMember_delete`; downstream local models already compute `attribution_percentage`, `attributed_acv`, `attributed_arr` | `Campaign_Member_Key_Message_Update` is still missing locally; `Trigger_CampaignMember` remains runtime boundary | 先走 `B2` 直接补 `Campaign_Member_Key_Message_Update`，这一步最贴近 `dws_campaign_attribution` / `dws_lead_timeline` |
| `Order / ARR / RevRec / Collections` | local Order side already has `OrderNumber`, 4 local Flows, heavy formulas and rollups, restored `Std_CreateOrderFromQuote`, `Order_Quote_Payment_Field_Inheritance`, and `Order_Default_RevRec_Entity`; local governing-contract validation policy already replaces the old `Order.ContractId`-authoritative checks; local Revenue side already has formulas plus `RevRec_Account` and `RevRec_Partner_Name`; finance local marts and recurring outputs are already built | missing `Order_Org_Auto_Set_Account_Create`, `Order_Org_Auto_Set_Account_Update`, `Order_Set_PLG_BD_Pool`, `contractOpportunityInset`, `RevRec_Set_PLG_BD_Pool`, `Revenue__c.Name`, `Invoice_Collection__c.Name`; `Invoice_Collection__c` now has a mostly recovered 4-flow exact-name backlog (`Collection_Set_PLG_BD_Pool`, `Collection_Amount_and_Payable_Amount_exc_tax`, `Collection_Amount_and_Payable_Amount_exc_tax_Update`, `Cloud_Registration_Source_from_Org_to_Collections`) still absent locally; `OrderTrigger`, `RevenueTrigger`, and line-item trigger surfaces remain runtime boundary; old `Order_Create_Requires_Effective_CSA_MA_Contract` is a superseded Salesforce-era rule name, not the current local authority | 先走 `B2` 补 Order / RevRec / Invoice 的 exact-name gaps，再走 `B3` 补 auto-number；把旧 `Order_Create_Requires_Effective_CSA_MA_Contract` 放到 policy review，而不是默认 parity 补齐；`Order_Activate_*` 继续留在 `B6` |
| `Account / Tenant Linkage / Customer Identity` | local Account side already has `Account_ID__c`, formulas, rollup, `Account_status_Flow`, first-order/date maintenance, and active validation parity; local Org side already has `Org_Set_Account`; shared dimensions already consume local account/org linkage fields | missing `Account_Contract_Valid_Message`, `Account_Contract_Valid_Message_1`, `Account_Current_Order_Type`, `Account_Partner_Sales_Owner_Set`; `AccountTrigger` remains runtime boundary; Order/Revenue carry-over gaps can still back-propagate into tenant/account dimensions | 先走 `B2` 补 4 个 Account Flow，再检查 Order/Revenue carry-over gaps是否继续污染 `dim_tenant` / `customer_surrogate_keys` |

Practical reading:

- this is the best section when someone asks
  `CM 具体已经支持了哪些机制，不只是抽象能力`
- it also makes the split between
  `already landed in pack`,
  `present but inactive`,
  `exact-name missing`,
  and
  `runtime boundary`
  much easier to explain

## Local Pack Evidence Anchors

The sections above summarize the conclusion.

This section records where the strongest local evidence actually lives in the
pack, so future readers do not need to re-run the same repository search.

### Representative `FOUND` Anchors

These are confirmed to exist in the current local pack surfaces
(`pack.json`, `flows/`, `validation/`, `autonumber/`):

| 机制 | 本地证据 |
|---|---|
| `Lead_Auto_Create_Org` | `packs/NOT-EDIT-final-merged-packs/pack.json` -> `flows/Lead_Auto_Create_Org.flow.json`; also present in `packs/Salesforce-PingCAP-L2/pack.json` |
| `BN_Lead_Relate_to_Account_by_Email_Domain_Flow` | `packs/NOT-EDIT-final-merged-packs/pack.json` -> `flows/BN_Lead_Relate_to_Account_by_Email_Domain_Flow.flow.json`; also present in L2 `pack.json` |
| `IQM_Completion_Flow` | `packs/NOT-EDIT-final-merged-packs/pack.json` -> `flows/IQM_Completion_Flow.flow.json`; also present in L2 `pack.json` |
| `Lead_Status_Duration` | `packs/NOT-EDIT-final-merged-packs/pack.json` -> `flows/Lead_Status_Duration.flow.json`; also present in L2 `pack.json` |
| `Org_Set_Account` | `packs/NOT-EDIT-final-merged-packs/pack.json` -> `flows/Org_Set_Account.flow.json`; also present in `packs/AUTO_GEN_Product-pack/live/flow_definitions/flow_definitions.json` and L2 `pack.json` |
| `Nurture_Marketing_Date` | `packs/NOT-EDIT-final-merged-packs/validation/standard_validation_rules.json`; also present in `packs/Salesforce-PingCAP-L2/validation/standard_validation_rules.json` and live export |
| `Nurture_Sales_Date` | `packs/NOT-EDIT-final-merged-packs/validation/standard_validation_rules.json`; also present in L2 validation and live export |
| `PingCAP_Contract_Entity_EMEA_only` | `packs/NOT-EDIT-final-merged-packs/validation/standard_validation_rules.json`; also present in L2 validation and live export |
| local auto-number already landed | `packs/NOT-EDIT-final-merged-packs/autonumber/counters.json` and `formats.json` contain `Account_ID__c`, `ContractNumber`, `OrderNumber`, `QuoteNumber` |

### Representative `MISSING` Anchors

The following names were re-checked across:

- `packs/NOT-EDIT-final-merged-packs/pack.json`
- `packs/Salesforce-PingCAP-L2/pack.json`
- both packs' `flows/`
- both packs' `validation/`

They were not found in the current local surfaces:

| 机制 | Current local result |
|---|---|
| `Account_Contract_Valid_Message` | `MISSING` |
| `Account_Current_Order_Type` | `MISSING` |
| `Order_Org_Auto_Set_Account_Create` | `MISSING` |
| `Order_Org_Auto_Set_Account_Update` | `MISSING` |
| `Order_Set_PLG_BD_Pool` | `MISSING` |
| `contractOpportunityInset` | `MISSING` |
| `Campaign_Member_Key_Message_Update` | `MISSING` |
| `RevRec_Set_PLG_BD_Pool` | `MISSING` |
| `Quote_update_nonstandard_conditions_checkbox` | `MISSING` |
| `Quote_update_nonstandard_conditions_checkbox_2` | `MISSING` |
| `Order_Create_Requires_Effective_CSA_MA_Contract` | `LIVE-ONLY / SUPERSEDED LOCALLY` |

### Auto-number Boundary Note

The local `autonumber/counters.json` and `autonumber/formats.json` currently
prove that these are modeled locally:

- `Account_ID__c`
- `ContractNumber`
- `OrderNumber`
- `QuoteNumber`

And they also strengthen the opposite claim:

- `Revenue__c.Name`
- `Invoice_Collection__c.Name`
- `Opportunity_Product__c.Name`
- `Order_Product__c.Name`
- `Quote_Product__c.Name`

are still missing from the current local auto-number surfaces.

## Repo File Quick Index

When someone needs to inspect the current local implementation directly, these
are the highest-signal file entry points.

| 报表组 | 先看这些本地文件 |
|---|---|
| `Lead Funnel / Qualification` | `packs/Salesforce-PingCAP-L2/flows/BN_Lead_Relate_to_Account_by_Email_Domain_Flow.flow.json`, `IQM_Completion_Flow.flow.json`, `Lead_Auto_Create_Org.flow.json`, `Lead_Status_Duration.flow.json`, `packs/Salesforce-PingCAP-L2/objects/Lead.json`, `packs/Salesforce-PingCAP-L2/validation/standard_validation_rules.json` |
| `Pipeline / Forecast / Opportunity Quality` | `packs/Salesforce-PingCAP-L2/flows/Opportunity_Auto_To_Launch_Stage.flow.json`, `Opportunity_Close_Date_Auto_Set.flow.json`, `Opportunity_Cloud_Order_Type_Set.flow.json`, `Opportunity_Launch_Stage_Validation.flow.json`, `Opportunity_Pricebook_Default.flow.json`, `Std_OpportunityStageDerivedFields.flow.json`, `Task_Update_Opportunity_Key_Deal.flow.json`, `packs/Salesforce-PingCAP-L2/objects/Opportunity.json`, `packs/Salesforce-PingCAP-L2/objects/Quote.json`, `packs/Salesforce-PingCAP-L2/validation/standard_validation_rules.json` |
| `Campaign Attribution / ICP Analysis` | `packs/Salesforce-PingCAP-L2/flows/Lead_Set_First_And_Last_CampaignMember.flow.json`, `Lead_Set_First_And_Last_CampaignMember_delete.flow.json`, `Contact_Set_First_And_Last_CampaignMember.flow.json`, `Contact_Set_First_And_Last_CampaignMember_delete.flow.json`, `packs/Salesforce-PingCAP-L2/objects/CampaignMember.json` |
| `Order / ARR / RevRec / Collections` | `packs/Salesforce-PingCAP-L2/objects/Order.json`, `Revenue__c.json`, `Invoice_Collection__c.json`, `Order_Product__c.json`, `Quote_Product__c.json`, `Opportunity_Product__c.json`, `packs/Salesforce-PingCAP-L2/autonumber/counters.json`, `formats.json`, `packs/Salesforce-PingCAP-L2/validation/standard_validation_rules.json` |
| `Account / Tenant Linkage / Customer Identity` | `packs/Salesforce-PingCAP-L2/objects/Account.json`, `Org__c.json`, `packs/Salesforce-PingCAP-L2/flows/Org_Set_Account.flow.json`, `packs/Salesforce-PingCAP-L2/autonumber/counters.json`, `formats.json`, `packs/Salesforce-PingCAP-L2/validation/standard_validation_rules.json` |

Practical reading:

- for `what exists locally`, start with the `packs/Salesforce-PingCAP-L2/`
  files above
- for `what actually shipped into the merged local pack`, compare against the
  mirrored paths under `packs/NOT-EDIT-final-merged-packs/`
- for `what live Salesforce still has`, cross-check against
  `packs/AUTO_GEN_Product-pack/live/`

## Representative Flow Trigger Snapshots

To strengthen the claim that CM is not only carrying metadata files but is
already modeling real record-triggered automation, these are representative
local examples from `packs/Salesforce-PingCAP-L2/flows/`.

| Flow | Trigger snapshot | What it proves |
|---|---|---|
| `Lead_Auto_Create_Org.flow.json` | `processType=AutoLaunchedFlow`; creates `Org__c` rows from Lead fields and backfills account linkage decisions | CM local pack is already modeling Lead-driven org creation semantics, not just storing passive fields |
| `IQM_Completion_Flow.flow.json` | `object=Lead`, `recordTriggerType=CreateAndUpdate`, `triggerType=RecordBeforeSave`, `status=Active`; stamps `Meeting_Completed_DateTime__c` based on owner/status transitions | CM local pack is already running Lead before-save lifecycle logic relevant to IQM semantics |
| `Opportunity_Cloud_Order_Type_Set.flow.json` | `object=Opportunity`, `recordTriggerType=CreateAndUpdate`, `triggerType=RecordBeforeSave`, `status=Active`; mutates `Cloud_Order_Type__c` under product/stage conditions | CM local pack already models Opportunity-side defaulting/cleanup logic that directly affects pipeline fields |
| `Lead_Set_First_And_Last_CampaignMember.flow.json` | campaign-member-driven flow that reads first/last campaign member and updates Lead first/last campaign references | CM local pack already carries attribution-adjacent maintenance logic, not only the downstream dbt attribution math |
| `Org_Set_Account.flow.json` | `object=Org__c`, `recordTriggerType=CreateAndUpdate`, `triggerType=RecordBeforeSave`, `status=Active`; fills `Account__c` from `Lead__r.ConvertedAccountId` and sets `Name__c` | CM local pack already models the tenant/account bridge maintenance that downstream account-tenant reporting depends on |

Why this matters:

- these are concrete proofs that CM local support already includes
  `record-triggered Flow substrate in active use`
- so many current gaps are more accurately
  `missing parity coverage`
  than
  `missing platform category`

## Business Meaning Of The Report Families

The matrix above is still quite technical.

This table translates the same report groups into business questions the teams
are actually asking.

| 报表组 | 这些报表业务上在回答什么问题 | 代表性证据 |
|---|---|---|
| `Lead Funnel / Qualification` | 线索是怎么从最初接触一路走到 `MQL`、`IQM`、再到机会创建和客户转化的；哪些 lead/campaign path 更容易进入 pipeline | `dws_lead_timeline.sql` emits `mql_milestone`, `iqm_milestone`, `pipeline_created`, `customer_milestone`; `cloud-lead-pipeline-insight.model.lkml` joins `Lead -> Account -> Opportunity` |
| `Pipeline / Forecast / Opportunity Quality` | 机会现在在哪个 stage、卡了多久、forecast 属于哪类、ARR/ACV 多大、close/launch 是否合理、机会质量有没有异常 | `dim_opportunity.yml` describes stage / forecast / financial / quote/task aspects; `dws_opportunity_stage_duration.yml` describes stage progression analysis; `dws_data_quality_alerting` backs the `Opportunity Data Quality Monitoring` dashboard |
| `Campaign Attribution / ICP Analysis` | 哪些 campaign touch 真正贡献了 pipeline / ARR / ACV；某类 ICP campaign 有没有更高的 IQM、建 opp、成交贡献 | `dws_campaign_attribution.sql` computes `attributed_acv` and `attributed_arr`; `dws_icp_summary.sql` aggregates first/last touch, ICP touches, and opportunity-path campaign stats |
| `Order / ARR / RevRec / Collections` | 订单的服务期、收入确认、递延/累计收入、回款、tenant 汇总是否正确；当前月和历史月 revenue recognition 是否对得上 | `cp_order_monthly_revrec.yml` describes monthly revenue-recognition breakdown for CP orders; `salesforce_org_monthly_revrec.yml` describes reconciled tenant-month billing/revrec rows; `monthly_cloud_billing_revrec.py` reads/writes recurring finance outputs |
| `Account / Tenant Linkage / Customer Identity` | 一个客户/账户到底对应哪些 tenant；收入该累到哪个 tenant/account；客户主数据、region、segmentation、ICP 等共享维度是否一致 | `dim_account.yml` describes account-level business-operations analytics; `dim_org.yml` describes org/tenant/revenue accumulation structure; `salesforce_orgs.yml` explicitly states the one-to-many account-to-tenant relationship |

Practical reading:

- this is the best section to use when speaking with BI or business partners
- the earlier sections are better when speaking with CRM/platform implementers

## CM Capability Snapshot

The current repository evidence says the broad picture is:

| Surface | Current CM status | What that means here |
|---|---|---|
| Validation rules | Implemented | This is not a generic CM gap. The runtime and current final pack already carry many active rules on `Lead`, `Opportunity`, `Quote`, `Order`, `Invoice_Collection__c`, etc. |
| Formula fields | Implemented | This is not a generic CM gap. The final pack already carries heavy formula usage on `Account`, `Lead`, `Opportunity`, `Quote`, `Order`, `CampaignMember`, `Revenue__c`, `Invoice_Collection__c`, and the custom line-item objects. |
| Rollup summaries | Implemented | This is not a generic CM gap. The final pack already carries rollups on `Opportunity`, `Campaign`, `Quote`, `Order`, and `Order_Product__c`. |
| Auto-number | Implemented, but incomplete in current pack | `Account_ID__c`, `ContractNumber`, `QuoteNumber`, and `OrderNumber` are modeled locally. But Salesforce auto-numbered `Name` is still missing locally on `Revenue__c`, `Invoice_Collection__c`, `Opportunity_Product__c`, `Order_Product__c`, and `Quote_Product__c`. |
| Record-triggered Flow | Partial / implemented | NexusCRM can run record-triggered Flows and the final pack already contains many of them, but several live Salesforce Flows are still not present in the checked-in final pack. |
| Apex trigger runtime / Apex invocable runtime | Not supported today | This is a real CM parity boundary. NexusCRM does not execute Apex source/bytecode, so any behavior still living only in live Apex triggers must be rewritten into Flow / formula / metadata action substrate before parity exists. |

Counts below compare the live Salesforce org inspected on `2026-07-07` with the
checked-in final pack at `packs/NOT-EDIT-final-merged-packs`.

## CM vs Salesforce Comparison Matrix

| Object | Salesforce today | CM currently has | Pack parity still missing | Unsupported today | BI impact |
|---|---|---|---|---|---|
| `Account` | `Account_ID__c` auto-number; 8 active Flows; 1 active Validation Rule; 4 active Apex triggers | `Account_ID__c` auto-number parity; 13 formulas; 1 rollup; 1 active Validation Rule; 6 Flows including `Account_status_Flow` and first-order/date maintenance | 4 live Flows not found locally: `Account_Contract_Valid_Message`, `Account_Contract_Valid_Message_1`, `Account_Current_Order_Type`, `Account_Partner_Sales_Owner_Set` | Apex-trigger-only logic still in live `AccountTrigger` surface | `crm_account`, `salesforce_accounts` |
| `Lead` | 32 active Flows; 18 active Validation Rules; 5 active Apex triggers | 25 formulas; 17 active Validation Rules; 12 Flows including lead-account relate, IQM, region, convert helpers; local `convertLead` also routes through `Std_ConvertLead` with preview Flow `Std_ConvertLeadCampaignPreview` | 22 live Flows still absent locally, mostly email / partner / scheduled reminder logic; 2 live Validation Rules are present locally but inactive: `Nurture_Marketing_Date`, `Nurture_Sales_Date` | Apex-trigger-only logic still in `LeadTrigger` / `LeadAITrigger` surface | `salesforce_lead`, `salesforce_leads`, `dws_lead_timeline`, `cloud-lead-pipeline-insight` |
| `Opportunity` | 27 active Flows; 21 active Validation Rules; 5 active Apex triggers | 29 formulas; 5 rollups; 21 active Validation Rules; 12 Flows including launch stage, close date, cloud order type, technical validation | 17 live Flows still absent locally, especially AWS/defaulting/notification/share logic; 1 live Validation Rule is present locally but inactive: `PingCAP_Contract_Entity_EMEA_only` | Apex-trigger-only logic still in `OpportunityTrigger` / related trigger surface | `salesforce_oppo`, `salesforce_opportunities`, `dws_salesforce_arr_summary` |
| `Quote` | `QuoteNumber` auto-number; 3 active Flows; 10 active Validation Rules; 1 active Apex trigger | `QuoteNumber` auto-number parity; 75 formulas; 6 rollups; 8 active Validation Rules; 2 Flows | 2 live Flows missing locally: `Quote_update_nonstandard_conditions_checkbox`, `Quote_update_nonstandard_conditions_checkbox_2`; 3 live Validation Rules are present locally but inactive: `Customer_s_Hardware_Configuration`, `Details_of_vCPU_Calculation`, `Version_of_TiDB` | Apex-trigger-only logic still in `QuoteTrigger` surface | `quote` staging source; indirect impact on order / ARR reporting |
| `Order` | `OrderNumber` auto-number; 5 active Flows; 1 active Apex trigger | `OrderNumber` auto-number parity; 50 formulas; 16 rollups; 12 active local Validation Rules; 4 Flows; `Quote -> Order` inheritance, payment inheritance, and `Order_Default_RevRec_Entity` are already implemented locally | 4 live Flows missing locally: `Order_Org_Auto_Set_Account_Create`, `Order_Org_Auto_Set_Account_Update`, `Order_Set_PLG_BD_Pool`, `contractOpportunityInset`; 1 live exported Validation Rule has no same-name local peer: `Order_Create_Requires_Effective_CSA_MA_Contract`, but current repo evidence shows PingCAP intentionally replaced that authority with account-level governing-contract rules; plus 4 live Validation Rules are present locally but intentionally inactive because PingCAP replaced contract checks with account-level governing-contract policy | Apex-trigger-only logic still in `OrderTrigger` surface | `salesforce_orders`, `salesforce_order_daily_view`, `salesforce_order_current_monthly_arr`, `dws_salesforce_arr_summary` |
| `CampaignMember` | 5 active Flows; 1 active Apex trigger | 34 formulas including `Name`, `FirstName`, `LastName`, `Email`, `Phone`, `CompanyOrAccount`; 4 Flows for first/last touch maintenance; local `convertLead` standard action explicitly reads `CampaignMember` for primary campaign attribution preview / child relink | 1 live Flow missing locally: `Campaign_Member_Key_Message_Update` | Apex-trigger-only logic still in `Trigger_CampaignMember` surface | `salesforce_campaign_attributions`, `dws_campaign_attribution`, `campaign_member` |
| `Contract` | `ContractNumber` auto-number; 2 active Flows; 1 active Validation Rule; 1 active Apex trigger | `ContractNumber` auto-number parity; 4 formulas; 1 active Validation Rule; 2 different local Flows (`Contract_Archived_Status_Autopromote`, `Std_ContractActivateStamp`) | 2 live Flows not found locally: `Auto_Expire_Contract`, `Contract_Update_Account_Contract_Valid` | Apex-trigger-only logic still in contract trigger surface | `contract` staging source; downstream contract/order governance reporting |
| `Org__c` | 1 active Flow | 1 formula; 1 matching Flow `Org_Set_Account` | No obvious Flow/Validation parity gap from this audit | No object-specific unsupported surface found in this audit | `salesforce_orgs`, tenant-enriched `salesforce_accounts` |
| `Revenue__c` | `Name` auto-number; 1 active Flow; 1 active Apex trigger | 14 formulas | `Name` auto-number missing locally; live Flow `RevRec_Set_PLG_BD_Pool` missing locally | Apex-trigger-only logic still in `RevenueTrigger` surface | `salesforce_revrec`, `salesforce_org_monthly_revrec` |
| `Invoice_Collection__c` | `Name` auto-number; 4 active Flows; 1 active Validation Rule | 17 formulas; 1 matching active Validation Rule | `Name` auto-number missing locally; all 4 live Flows missing locally: cloud-registration carry-over, collection/payable amount calc, PLG BD pool logic | No Apex-runtime evidence in this audit; main gap is pack parity | `invoice_collection_c` warehouse source; collections / billing finance reporting |
| `Opportunity_Product__c` / `Order_Product__c` / `Quote_Product__c` | Salesforce auto-numbers `Name`; live Apex triggers on all 3; `Order_Product__c` also has an active Validation Rule | Local formulas exist on all 3; `Order_Product__c` has 1 rollup and 1 matching Validation Rule | `Name` auto-number missing locally on all 3 custom line-item objects | Apex-trigger-only logic still exists on all 3 line-item trigger surfaces | `opportunity_product_c`, `order_product_c`, `quote_product_c` |
| `Contact` | 1 active Flow; 4 active Apex triggers | 5 formulas; no matching Flow found locally | Live Flow parity still missing | Apex-trigger-only logic still in contact trigger surface | `contact`, plus lead/contact blended downstream dimensions |
| `Campaign` | Mainly rollup/aggregation behavior; no active Flow / Validation / Apex trigger found in live audit | 8 rollups already modeled locally | No obvious automation parity gap from this audit | No object-specific unsupported surface found in this audit | `salesforce_campaigns` |

The direct implication is:

- the previous audit over-called the whole surface as "CM cannot do this"
- the real picture is that validation/formula/rollup support already exists and
  many live Flows are already migrated
- most matrix rows are therefore parity/migration gaps, not fundamental CM
  capability gaps
- the current high-signal parity gaps are now concentrated in:
  - missing exact Flow migrations on `Lead`, `Opportunity`, `Order`,
    `Quote`, `Revenue__c`, `Invoice_Collection__c`
  - missing auto-number parity for `Revenue__c`, `Invoice_Collection__c`,
    and the three custom product-line objects
  - any logic that still exists only inside live Apex triggers

## Structured Scoreboard

This section is narrower and more mechanical than the main matrix.

It uses structured local artifacts where we have them, mainly:

- `packs/AUTO_GEN_Product-pack/live/validation/standard_validation_rules.json`
- `packs/NOT-EDIT-final-merged-packs/validation/standard_validation_rules.json`
- `packs/AUTO_GEN_Product-pack/live/flow_definitions/flow_definitions.json`
- `packs/NOT-EDIT-final-merged-packs/flows/*.flow.json`

Important boundary:

- the validation comparison below is strong for `active/inactive/missing`
- the flow-definition comparison is only for the exported slice; it does **not**
  replace the broader live-org Flow counts from the read-only audit

### Validation Scoreboard

`live_active` means the rule is active in the live exported validation set.

`local_active_match` means the same rule exists locally and is also active.

`local_inactive` means the rule exists locally but is currently inactive.

`local_missing` means the rule is active in the live exported set but no local
definition was found.

| 对象 | live_active | local_active_match | local_inactive | local_missing | Notes |
|---|---:|---:|---:|---:|---|
| `Lead` | 19 | 17 | 2 | 0 | 两条是 `Nurture_Marketing_Date`, `Nurture_Sales_Date` |
| `Opportunity` | 22 | 21 | 1 | 0 | 一条是 `PingCAP_Contract_Entity_EMEA_only` |
| `Quote` | 11 | 8 | 3 | 0 | 三条是 `Version_of_TiDB`, `Customer_s_Hardware_Configuration`, `Details_of_vCPU_Calculation` |
| `Order` | 8 | 3 | 4 | 1 | 4 条 inactive 是 intentional replacement；1 条 `local_missing` 是旧的 `Order_Create_Requires_Effective_CSA_MA_Contract` 名字，但当前本地 authority 已切到 governing-contract replacement policy，默认不应和普通 parity 缺口同处理 |
| `Account` | 1 | 1 | 0 | 0 | no active-state mismatch in current export |
| `Contact` | 1 | 1 | 0 | 0 | no active-state mismatch in current export |
| `Contract` | 1 | 1 | 0 | 0 | no active-state mismatch in current export |
| `Invoice_Collection__c` | 1 | 1 | 0 | 0 | current validation parity looks aligned |

### Flow-Definition Export Slice Scoreboard

This is only the overlap between the exported live flow-definition slice and the
checked-in final pack.

It is useful for proving that many exported object Flows already have local
peers, but not for disproving the larger live Flow counts from the org audit.

| 对象 | export_slice | local_peer | export_slice_missing | Notes |
|---|---:|---:|---:|---|
| `Account` | 4 | 4 | 0 | exported slice fully has local peers |
| `Lead` | 5 | 5 | 0 | exported slice fully has local peers |
| `Opportunity` | 12 | 12 | 0 | exported slice fully has local peers |
| `Quote` | 2 | 2 | 0 | exported slice fully has local peers |
| `Order` | 2 | 2 | 0 | exported slice fully has local peers |
| `Contract` | 2 | 2 | 0 | exported slice fully has local peers |
| `Org__c` | 1 | 1 | 0 | exported slice fully has local peers |
| `Revenue__c` | 2 | 2 | 0 | exported slice fully has local peers |

Practical reading:

- the biggest high-confidence validation work is on `Lead`, `Opportunity`,
  `Quote`, and `Order`
- the exported flow slice says local peer Flows exist for many core objects,
  which strengthens the case that much of the remaining gap is still `pack
  parity` rather than raw CM substrate absence

## 中文归纳矩阵

下面这张表把当前最重要的问题直接压缩成四个问题：

1. Salesforce 现在到底在帮我们自动做什么
2. CM 现在已经支持了什么
3. CM 还没支持 / 疑似没支持的到底是哪一类
4. 这些问题会砸到哪张报表或哪类模型

其中要特别注意：

- `未支持/疑似未支持` 这一列混合了两种情况：
  `pack parity still missing`
  和
  `true CM runtime boundary`
- 前者通常是 CM 有能力，但我们还没迁完；
  后者才是 CM 平台目前真的做不到

| 对象 | Salesforce 会做什么 | CM 目前已支持 | CM 目前未支持 / 疑似未支持 | 对哪张报表有影响 |
|---|---|---|---|---|
| `Account` | 自动生成 `Account_ID__c`；维护 `ICP__c`、`Segmentation__c`、`Contract_Valid_Days__c`、首单/状态类字段；有 8 个 Flow 和 Apex trigger | `Account_ID__c` auto-number 已有；公式、rollup、验证规则和一批 Account Flow 已在 final pack | 主要是迁移缺口：还缺 4 个 live Flow；另外 live `AccountTrigger` 逻辑仍是平台边界 | Looker `crm_account`、`cloud-lead-pipeline-insight`；dbt `salesforce_accounts`、`dim_account`、`dim_tenant`、`dws_icp_summary`、`customer_surrogate_keys`、`customers` |
| `Lead` | 维护 lifecycle/IQM/owner/domain/account 关联；32 个 Flow；18 个 Validation；多条 Apex trigger | 大量公式、17 条 active 验证规则、12 条 Lead Flow 已迁入；另外 `Nurture_Marketing_Date` / `Nurture_Sales_Date` 规则定义已在 pack 中；记录触发 Flow substrate 已存在 | 主要是迁移缺口：还缺 22 个 live Flow；另有 2 条 validation 定义已存在但当前 inactive；`LeadTrigger` / `LeadAITrigger` 逻辑仍属平台边界 | Looker `salesforce_lead`、`cloud-lead-pipeline-insight`；dbt `salesforce_leads`、`dim_lead`、`dws_lead_timeline`、`dws_icp_summary`、`salesforce_campaign_interacted_accounts` |
| `Opportunity` | 维护 forecast、region、segmentation、ACV/USD、stage duration、AWS/cloud 相关字段；27 个 Flow；21 个 Validation；多条 Apex trigger | 公式、rollup、21 条 active 验证规则、12 条 Opportunity Flow 已存在；`PingCAP_Contract_Entity_EMEA_only` 规则定义已在 pack 中 | 主要是迁移缺口：还缺 17 个 live Flow；另有 1 条 validation 定义已存在但当前 inactive；`OpportunityTrigger` 相关逻辑仍属平台边界 | Looker `salesforce_oppo`、`cloud-lead-pipeline-insight`；dbt `salesforce_opportunities`、`dim_opportunity`、`dws_salesforce_arr_summary`、`dws_opportunity_stage_duration`、`dws_opportunity_stage_conversion_rates`、`dws_data_quality_alerting`、`salesforce_orders` |
| `Quote` | 自动生成 `QuoteNumber`；维护折扣、审批、服务期、support tier、标准/非标准条款等；3 个 Flow；10 条 Validation；1 条 trigger | `QuoteNumber` 已有；大量公式、rollup、8 条 active 验证规则和 2 个 Flow 已迁入；另外 `Customer_s_Hardware_Configuration`、`Details_of_vCPU_Calculation`、`Version_of_TiDB` 规则定义已在 pack 中 | 主要是迁移缺口：还缺 2 个 Flow；另有 3 条 validation 定义已存在但当前 inactive；`QuoteTrigger` 是平台边界 | 先进入 `salesforce_opportunities` 的 quote enrichment，再外溢到 `dim_opportunity`、`dws_salesforce_arr_summary`、`dws_opportunity_stage_duration`、订单/ARR 语义 |
| `Order` | 自动生成 `OrderNumber`；维护 ACV/TCV/USD、递延收入、已确认收入、回款/未回款、cloud order type 等；5 个 Flow；1 条 trigger | `OrderNumber` 已有；大量公式、rollup、validation 和 4 个 Flow 已在 local/final pack；`Quote -> Order` 关键字段继承、payment inheritance、`Order_Default_RevRec_Entity` 也已落地 | 主要是迁移缺口：还缺 4 个 live Flow；另有 1 条 live validation 名字 `Order_Create_Requires_Effective_CSA_MA_Contract` 在本地没有同名 peer，但当前本地已用 governing-contract policy 有意取代它；同时还有 4 条 contract-activation validation 在本地被 PingCAP policy 有意替代为 inactive；`OrderTrigger` 是平台边界 | dbt `salesforce_orders`、`salesforce_order_daily_view`、`cp_order_monthly_revrec`、`salesforce_order_current_monthly_arr`、`dws_salesforce_arr_summary` |
| `CampaignMember` | 维护 first-touch / last-touch / response / 归因辅助字段；5 个 Flow；1 条 trigger | 公式和 4 个 first/last touch Flow 已存在 | 还缺 1 个 live Flow；`Trigger_CampaignMember` 仍是平台边界 | dbt `salesforce_campaign_members`、`salesforce_campaign_attributions`、`dws_campaign_attribution`、`dws_campaign_attribution_details`、`dws_lead_timeline`、`dws_icp_summary` |
| `Contact` | 维护 owner/internal/cloud 默认值和部分 region/account helper；1 个 Flow；多条 trigger | 有公式；Contact 基础对象和下游拼接模型都存在 | live Contact Flow 还没在 pack 中看到；多条 Contact trigger 仍属平台边界 | dbt `salesforce_contacts`、`salesforce_leads`、`dim_lead`、`dws_campaign_attribution`、`dws_campaign_attribution_details`、`dws_lead_timeline` |
| `Contract` | 自动生成 `ContractNumber`；维护 status/approval/effective-date 语义；2 个 Flow；1 条 validation；1 条 trigger | `ContractNumber` 已有；公式、validation、2 个本地 Contract Flow 已存在 | 2 个 live Flow 仍未在本地看到；contract trigger 仍是平台边界 | 目前主要以 `contract_id` 形式进入 `salesforce_opportunities`、`stg_salesforce_order`、`stg_salesforce_quote`、`stg_salesforce_revenue`、`stg_salesforce_invoice_collection` |
| `Org__c` | 默认 `Name`；维护 tenant 到 account 的关联；1 个 Flow | 公式和 `Org_Set_Account` Flow 已有 | 本轮未看到明显平台能力缺口 | Looker `crm_account`；dbt `salesforce_orgs`、`dim_org`、`dim_tenant`、`salesforce_accounts`、`salesforce_org_monthly_revrec`、`customer_surrogate_keys` |
| `Revenue__c` | 自动生成 `Name`；维护 revrec 状态、PLG pool、USD/fiscal period helper；1 个 Flow；1 条 trigger | 公式已存在；对象和下游 revrec 模型已打通 | 双重缺口：`Name` auto-number 和 Flow 仍是迁移缺口；`RevenueTrigger` 是真实平台边界 | dbt `salesforce_revrec`、`salesforce_orders`、`salesforce_order_daily_view`、`cp_order_monthly_revrec`、`salesforce_org_monthly_revrec` |
| `Invoice_Collection__c` | 自动生成 `Name`；维护 payable/collections/invoice-status/payment-status/PLG pool 等；4 个 Flow；1 条 validation | 公式和 matching validation 已存在 | 主要是迁移缺口：`Name` auto-number 缺失，4 个 live Flow 都还没迁入；本轮未发现它的主要问题来自 Apex runtime 边界 | 先进入 `stg_salesforce_invoice_collection`，再进入 `salesforce_orders` 以及基于 order 的 collections / billing / finance 模型 |
| `Opportunity_Product__c` / `Order_Product__c` / `Quote_Product__c` | 自动生成 `Name`；维护 product family / net fee / list price / man-day / surplus 等辅助字段；都有 trigger；`Order_Product__c` 还有 validation | 公式已存在；`Order_Product__c` 的 rollup 和 validation 也有本地映射 | 双重缺口：三个对象的 `Name` auto-number 都还没补；三者 trigger-only 逻辑是平台边界 | `salesforce_opportunity_products`、`salesforce_opportunities`、`salesforce_orders`、`salesforce_order_daily_view`、`cp_order_monthly_revrec`，以及 quote/order/product-family 相关分析 |
| `Campaign` | 默认 type/status/active/exclude-from-attribution 等基础语义 | rollup 已有，基础消费面明确 | 本轮未看到明显平台能力缺口；更多是活动治理/hygiene 问题 | dbt `salesforce_campaigns`、`salesforce_campaign_attributions`、`dws_campaign_attribution`、`dws_lead_timeline`、`dws_icp_summary` |

### 高优先级缺口到报表清单

如果目标是把这份研究直接变成排查顺序，优先看下面这些对象。这里故意把
“缺的是哪个机制” 和 “会打歪哪个字段/模型” 写在一行里。

| 优先级 | 对象 | 当前缺口机制 | 最可能被打歪的字段 | 直接受影响模型 / 报表 | 缺口性质 |
|---|---|---|---|---|---|
| `P1` | `Opportunity` | 17 个 live Flow 未迁；`PingCAP_Contract_Entity_EMEA_only` 已存在但 inactive；`OpportunityTrigger` 仍只在 Salesforce | Looker `ForecastCategory`、`LossReason`、`NetFees`、`OpportunityNumber`、`ProductFamily`、`Region`、`Stage`; dbt `arr_amount_usd`、`accurate_acv_amount`、`owner_team`、`cloud_order_type`、`quote_service_start_date`、`overall_start_date` | `salesforce_oppo`, `cloud-lead-pipeline-insight`, `salesforce_opportunities`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration`, `dws_opportunity_stage_conversion_rates`, `dws_data_quality_alerting`, `salesforce_orders` | 以迁移缺口为主，夹带真实平台边界 |
| `P1` | `Lead` | 22 个 live Flow 未迁；`Nurture_Marketing_Date` / `Nurture_Sales_Date` 已存在但 inactive；`LeadTrigger` / `LeadAITrigger` 仍只在 Salesforce | Looker `LeadLifecycleStage`、`LeadSource`、`LeadStatus`、`Region`、`Segmentation`、`TenantStatus`、`TiDBCloudPortalID`; dbt `lead_mql_timestamp`、`lead_iqm_timestamp`、`account_id`、`pre_account_region`、`pre_account_segmentation` | `salesforce_lead`, `cloud-lead-pipeline-insight`, `salesforce_leads`, `dim_lead`, `dws_lead_timeline`, `dws_icp_summary`, `salesforce_campaign_interacted_accounts` | 以迁移缺口为主，夹带真实平台边界 |
| `P1` | `Order` | 4 个 live Flow 未迁；旧的 `Order_Create_Requires_Effective_CSA_MA_Contract` 名字在本地无同名 peer，但已被 governing-contract replacement policy 取代；`OrderTrigger` 仍只在 Salesforce | `accumulate_revenue_to_org_tenant_id`, `order_status`, `order_product_family`, `order_products`, `revenues`; 下游日视图里的 `accumulated_revenue`, `order_net_fees`, `order_service_start_date`, `order_service_end_date` | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec`, `salesforce_order_current_monthly_arr`, `dws_salesforce_arr_summary` | 以迁移缺口为主，夹带真实平台边界；不要把 superseded policy 名字直接算成平台能力缺口 |
| `P1` | `Account` / `Org__c` | Account 仍缺 4 个 live Flow；`AccountTrigger` 逻辑仍在 Salesforce；Org 主体看起来已基本覆盖，但它承担 tenant-account 桥接 | Looker `AccountID`, `Industry`, `Region`, `Segmentation`, `TenantStatus`, `TiDBCloudPortalID`; dbt `tenant_ids`, `account_name`, `customer_surrogate_key`, `tenant_id`, `accumulate_revenue_to_org_tenant_id` | `crm_account`, `cloud-lead-pipeline-insight`, `salesforce_accounts`, `dim_account`, `dim_tenant`, `salesforce_orgs`, `salesforce_org_monthly_revrec`, `customer_surrogate_keys`, `customers` | Account 以迁移缺口为主并带 trigger 边界；Org 更像已支持桥接面 |
| `P1` | `CampaignMember` | 1 个 live Flow 未迁；`Trigger_CampaignMember` 仍只在 Salesforce | `first_responded_date`, `campaign_member_status`, `has_responded`, `is_contact_involved`, `contact_involvement_level`, attribution weights | `salesforce_campaign_members`, `salesforce_campaign_attributions`, `dws_campaign_attribution`, `dws_campaign_attribution_details`, `dws_lead_timeline`, `dws_icp_summary` | 小规模迁移缺口 + 明确平台边界 |
| `P2` | `Revenue__c` | `Name` auto-number 未迁；`RevRec_Set_PLG_BD_Pool` Flow 未迁；`RevenueTrigger` 仍只在 Salesforce | `revenue_name`, `revenue_date`, `revenue_status`, `plg_bd_pool`, `amount_before_adjust`, `credit_amount`, `revenue_exchange_rate` | `salesforce_revrec`, `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec`, `salesforce_org_monthly_revrec` | 同时包含迁移缺口和真实平台边界 |
| `P2` | `Invoice_Collection__c` | `Name` auto-number 未迁；4 个 live Flow 都未迁 | `invoice_status_c`, `collections_amount_c`, `cash_collected_c`, `payable_amount_usd_2_exc_tax_c`, `collections_amount_usd_exc_tax_c`, `plg_bd_pool_c`, `actual_billing_date_c` | `stg_salesforce_invoice_collection`, `salesforce_orders`, 以及基于 order 的 collections / billing / finance 模型 | 当前更像迁移缺口，不像纯平台边界 |
| `P2` | `Quote` | 2 个 live Flow 未迁；`Customer_s_Hardware_Configuration` / `Details_of_vCPU_Calculation` / `Version_of_TiDB` 已存在但 inactive；`QuoteTrigger` 仍只在 Salesforce | `QuoteNumber`, `quote_status`, `discount`, `service_start_date`, `service_end_date`, `technical_support_level`, `db_cloud_support_tier`, `other_nonstandard_terms_and_conditions` | 经 `salesforce_opportunities` 传播到 `dim_opportunity`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration`, `dws_data_quality_alerting` | 以迁移缺口为主，夹带真实平台边界 |
| `P2` | `Opportunity_Product__c` / `Order_Product__c` / `Quote_Product__c` | 3 个对象的 `Name` auto-number 都未迁；trigger-only 逻辑仍留在 Salesforce | `opportunity_product_name`, `order_product_id`, `net_fees`, `product_name`, `product_code`, `service_start_date`, `service_end_date`, `product_family` | `salesforce_opportunity_products`, `salesforce_opportunities`, `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` | 同时包含迁移缺口和真实平台边界 |

从报表爆炸半径看，最先值得补的是：

1. `Opportunity`
2. `Lead`
3. `Order`
4. `Account` / `Org__c`
5. `CampaignMember`
6. `Revenue__c`
7. `Invoice_Collection__c`

原因不是因为这些对象“最复杂”，而是因为它们同时满足两件事：

- live Salesforce 还在替我们做不少事
- `gcp-digital-bi` 的 Looker / dbt 消费面直接吃这些自动维护结果

### 建议补到哪层

This section is partly evidence-backed and partly engineering inference from the
current support matrix.

Evidence-backed part:

- the current final pack already contains many object-specific Flows for
  `Account`, `Lead`, `Opportunity`, `Order`, `Quote`, `CampaignMember`,
  `Org__c`, and `Revenue__c`
- validation / formula / rollup / auto-number substrates already exist in CM
- Apex trigger runtime does not exist in CM today

Engineering inference:

- if the missing behavior is a named Flow, Validation Rule, or auto-number that
  already has clear peers in the current pack, the first landing zone should be
  `L2 pack metadata`
- if the missing behavior still exists only as live Apex trigger logic, the
  real work item is to rewrite it into Flow / metadata-action form; if the
  rewrite cannot fit current substrate, that becomes `CM runtime capability`

| 对象 | 当前本地已看到的支撑 Flow 证据 | 建议优先补到哪层 | 先补什么最止血 |
|---|---|---|---|
| `Account` | `Account_status_Flow`, `Account_First_Order_Start_Date_Update`, `Account_Related_Leads_Based_on_Website_Domain_Create`, `Account_Related_Leads_Based_on_Website_Domain_Update`, `Account_SetBillingCountryCodeFromCountry` | 先补 `L2 pack Flow`；剩余 trigger 逻辑再判断是否要 runtime 能力 | 先补 4 个缺失 Account Flow，因为它们直接影响 `crm_account` / `salesforce_accounts` 上的状态、contract-valid、current-order-type、partner-owner 语义 |
| `Lead` | `BN_Lead_Relate_to_Account_by_Email_Domain_Flow`, `BN_Account_Lead_Relate_Leads_to_Accounts`, `IQM_Completion_Flow`, `LeadQuicklySet`, `Lead_Assignment_Rule_modification_for_NA_EMEA`, `Lead_Auto_Create_Org`, `Lead_Convert_Filed_Set`, `Lead_Quick_Set_Region`, `Lead_SetCountryCodeFromCountry`, `Lead_Set_First_And_Last_CampaignMember`, `Lead_Status_Duration`, `Lifecycle_Stage_to_Opportunity_Upon_Conversion`, `Std_ConvertLead`, `Std_RelinkLeadChildren` | 先补 `L2 pack Flow`，并把已存在但 inactive 的 validation 对齐到 active；最后再收口 Apex 边界 | 先补最直接影响 `LeadLifecycleStage`、`lead_mql_timestamp`、`lead_iqm_timestamp`、account/tenant 关联和 nurture 日期约束的缺失项；已知 validation 优先看 `Nurture_Marketing_Date` / `Nurture_Sales_Date` 的激活对齐 |
| `Opportunity` | `Opportunity_Auto_To_Launch_Stage`, `Opportunity_Close_Date_Auto_Set`, `Opportunity_Cloud_Order_Type_Set`, `Opportunity_Launch_Stage_Validation`, `Opportunity_Lead_Owner_Set_Create_by`, `Opportunity_Pricebook_Default`, `Opportunity_Service_Start_Date_Close_Date`, `Opportunity_Stage_To_Lunched`, `Std_OpportunityStageDerivedFields`, `Std_SyncOpportunityContactRole`, `Add_or_update_Opt_Owner_s_Role`, `Task_Update_Opportunity_Key_Deal` | 先补 `L2 pack Flow`，并把已存在但 inactive 的 validation 对齐到 active；剩余 trigger-only 行为再评估 runtime | 先补最直接影响 `ForecastCategory`、`OpportunityNumber`、`owner_team`、`cloud_order_type`、服务期/close-date 对齐的缺失逻辑；已知 validation 优先看 `PingCAP_Contract_Entity_EMEA_only` 的激活对齐 |
| `Order` | `Cloud_Registration_Source_from_Org_to_Order`, `Order_Default_RevRec_Entity`, `Order_Quote_Payment_Field_Inheritance`, `Std_OrderActivateStamp`, `Std_CreateOrderFromQuote`, governing-contract replacement validations | 先补 `L2 pack Flow`；trigger-only 残余逻辑视复杂度决定是否需要 runtime 能力 | 先补 4 个缺失 Order Flow，因为它们直接影响 `accumulate_revenue_to_org_tenant_id`、PLG pool、Org/Account carry-over 和 finance 视图；旧 `Order_Create_Requires_Effective_CSA_MA_Contract` 先做 policy review，不默认回补 |
| `CampaignMember` | `Lead_Set_First_And_Last_CampaignMember`, `Lead_Set_First_And_Last_CampaignMember_delete`, `Contact_Set_First_And_Last_CampaignMember`, `Contact_Set_First_And_Last_CampaignMember_delete` | 明显是 `L2 pack Flow` 优先 | 先补 `Campaign_Member_Key_Message_Update`，它离 `dws_campaign_attribution` / `dws_lead_timeline` 最近 |
| `Quote` | `Quote_Account_Opportunity_field`, `Quote_Reset_IsConvert_On_Submit`, `Std_CreateQuoteFromOpportunity`, `QuoteLineItem_Net_Fees_Autocalc` | 先补 `L2 pack Flow`，并把已存在但 inactive 的 validation 对齐到 active；再判断 trigger-only 逻辑是否需 runtime 支持 | 先补 2 个缺失 Quote Flow，再看 `Customer_s_Hardware_Configuration`、`Details_of_vCPU_Calculation`、`Version_of_TiDB` 的激活对齐，因为它们最直接影响 `salesforce_opportunities` 里的 quote enrichment |
| `Org__c` | `Org_Set_Account` | 目前更像 `L2 pack already covered` | 除非后续发现 tenant-account 桥接漏数，否则不建议优先投入 |
| `Revenue__c` | `RevRec_Account`, `RevRec_Partner_Name`, `Order_Default_RevRec_Entity` | `Name` auto-number 和缺失 Flow 先补到 `L2 pack metadata`；剩余 `RevenueTrigger` 逻辑若无法表达，再升为 runtime 能力项 | 先补 `Name` auto-number 和 `RevRec_Set_PLG_BD_Pool`，因为它们最直接影响 `salesforce_revrec`、`salesforce_orders`、`cp_order_monthly_revrec` |
| `Invoice_Collection__c` | current final pack has formulas and validation parity, but no matched local Flow names from this audit | 先补 `L2 pack auto-number + Flow` | 先补 `Name` auto-number，以及最直接影响 `invoice_status_c`、`collections_amount_c`、`cash_collected_c`、`plg_bd_pool_c` 的 4 个 live Flow |
| `Opportunity_Product__c` / `Order_Product__c` / `Quote_Product__c` | `OpportunityLineItem_Net_Fees_Autocalc`, `OpportunityLineItem_ListPrice_Autofill_From_Pricebook`, `OpportunityLineItem_Product2_Autofill_From_Pricebook`, `OpportunityLineItem_Currency_Autofill_From_Pricebook`, `OpportunityLineItem_Expansion_AutoStamp`, `OpportunityLineItem_Recalculate_Handler`, `QuoteLineItem_Net_Fees_Autocalc` | auto-number 先补 `L2 metadata`；trigger-only 逻辑若无法通过 Flow/metadata 表达，再升 runtime 能力项 | 先补 3 个对象的 `Name` auto-number，因为这一步最容易先止住 line-item 标识和下游明细 join 的漂移 |

### 子清单 A: Activation-State Mismatch

These are not "definition missing" gaps.

They are rules that are:

- `active: true` in the live exported validation set
- already present in `packs/NOT-EDIT-final-merged-packs`
- but currently `active: false` locally

| 对象 | 规则名 | live | local | 解释 | 主要报表影响 |
|---|---|---|---|---|---|
| `Lead` | `Nurture_Marketing_Date` | active | inactive | 定义已在 pack 中，缺的是激活状态对齐 | `salesforce_lead`, `salesforce_leads`, `dim_lead`, `dws_lead_timeline` |
| `Lead` | `Nurture_Sales_Date` | active | inactive | 定义已在 pack 中，缺的是激活状态对齐 | `salesforce_lead`, `salesforce_leads`, `dim_lead`, `dws_lead_timeline` |
| `Opportunity` | `PingCAP_Contract_Entity_EMEA_only` | active | inactive | 定义已在 pack 中，缺的是激活状态对齐 | `salesforce_oppo`, `salesforce_opportunities`, `dws_salesforce_arr_summary` |
| `Quote` | `Customer_s_Hardware_Configuration` | active | inactive | 定义已在 pack 中，缺的是激活状态对齐 | 先影响 `salesforce_opportunities` 的 quote enrichment，再影响 `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration` |
| `Quote` | `Details_of_vCPU_Calculation` | active | inactive | 定义已在 pack 中，缺的是激活状态对齐 | 先影响 `salesforce_opportunities` 的 quote enrichment，再影响 `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration` |
| `Quote` | `Version_of_TiDB` | active | inactive | 定义已在 pack 中，缺的是激活状态对齐 | 先影响 `salesforce_opportunities` 的 quote enrichment，再影响 `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration` |
| `Order` | `Order_Activate_Contract_Status` | active | inactive | 这不是简单漏迁。local 说明写明它被 PingCAP 的 account-level governing-contract 规则替代，属于有意偏离 | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` |
| `Order` | `Order_Activate_Contract_Start` | active | inactive | 同上，local 明确标注为 PingCAP 定制替代 | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` |
| `Order` | `Order_Activate_Contract_End` | active | inactive | 同上，local 明确标注为 PingCAP 定制替代 | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` |
| `Order` | `Order_Activate_Requires_Contract` | active | inactive | 同上，local 明确标注为 PingCAP 定制替代 | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` |

Important nuance on `Order`:

- these 4 order activation rules should not be read as accidental drift by
  default
- the local descriptions explicitly say they were disabled for PingCAP because
  activation now validates account-level governing Contracts instead of
  `Order.ContractId`
- so this is closer to `intentional policy replacement` than to
  `migration missing`

### 子清单 B: Exact Named Missing Mechanisms

These are the missing items for which the current audit already has exact
names, not just counts.

| 类型 | 对象 | 机制名 | 当前判断 | 主要报表影响 |
|---|---|---|---|---|
| Flow | `Account` | `Account_Contract_Valid_Message` | 缺失的 live Flow，优先补 `L2 pack Flow` | `crm_account`, `salesforce_accounts` |
| Flow | `Account` | `Account_Contract_Valid_Message_1` | 缺失的 live Flow，优先补 `L2 pack Flow` | `crm_account`, `salesforce_accounts` |
| Flow | `Account` | `Account_Current_Order_Type` | 缺失的 live Flow，优先补 `L2 pack Flow` | `crm_account`, `salesforce_accounts` |
| Flow | `Account` | `Account_Partner_Sales_Owner_Set` | 缺失的 live Flow，优先补 `L2 pack Flow` | `crm_account`, `salesforce_accounts` |
| Flow | `Quote` | `Quote_update_nonstandard_conditions_checkbox` | 缺失的 live Flow，优先补 `L2 pack Flow` | 经 `salesforce_opportunities` 外溢到 quote-derived pipeline / ARR 语义 |
| Flow | `Quote` | `Quote_update_nonstandard_conditions_checkbox_2` | 缺失的 live Flow，优先补 `L2 pack Flow` | 经 `salesforce_opportunities` 外溢到 quote-derived pipeline / ARR 语义 |
| Flow | `Order` | `Order_Org_Auto_Set_Account_Create` | 缺失的 live Flow，优先补 `L2 pack Flow` | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` |
| Flow | `Order` | `Order_Org_Auto_Set_Account_Update` | 缺失的 live Flow，优先补 `L2 pack Flow` | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` |
| Flow | `Order` | `Order_Set_PLG_BD_Pool` | 缺失的 live Flow，优先补 `L2 pack Flow` | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` |
| Flow | `Order` | `contractOpportunityInset` | 缺失的 live Flow，优先补 `L2 pack Flow` | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` |
| Validation | `Order` | `Order_Create_Requires_Effective_CSA_MA_Contract` | live active 但当前更像已被 PingCAP governing-contract policy 有意替代的旧 Salesforce 规则名；先做 policy review，不作为默认 parity 缺口 | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` |
| Flow | `CampaignMember` | `Campaign_Member_Key_Message_Update` | 缺失的 live Flow，优先补 `L2 pack Flow` | `salesforce_campaign_members`, `dws_campaign_attribution`, `dws_lead_timeline` |
| Flow | `Revenue__c` | `RevRec_Set_PLG_BD_Pool` | 缺失的 live Flow，优先补 `L2 pack Flow` | `salesforce_revrec`, `salesforce_orders`, `cp_order_monthly_revrec` |
| Flow | `Invoice_Collection__c` | `Collection_Set_PLG_BD_Pool` | 历史 regression flow 清单已点名；当前本地 pack 搜索未找到同名定义，优先补 `L2 pack Flow` | `stg_salesforce_invoice_collection`, `salesforce_orders`, `salesforce_order_daily_view`, collections / billing reporting |
| Flow | `Invoice_Collection__c` | `Collection_Amount_and_Payable_Amount_exc_tax` | 历史 regression flow 清单已点名；当前本地 pack 搜索未找到同名定义，优先补 `L2 pack Flow` | `stg_salesforce_invoice_collection`, `salesforce_orders`, collections / billing reporting |
| Flow | `Invoice_Collection__c` | `Collection_Amount_and_Payable_Amount_exc_tax_Update` | 历史 regression flow 清单已点名；当前本地 pack 搜索未找到同名定义，优先补 `L2 pack Flow` | `stg_salesforce_invoice_collection`, `salesforce_orders`, collections / billing reporting |
| Flow | `Invoice_Collection__c` | `Cloud_Registration_Source_from_Org_to_Collections` | 已命名 migration/runtime 缺口；当前本地 pack 搜索未找到同名定义，优先补 `L2 pack Flow` | `stg_salesforce_invoice_collection`, `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec`, `salesforce_org_monthly_revrec` |
| Auto-number | `Revenue__c` | `Name` | 缺失的 local auto-number，优先补 `L2 metadata` | `salesforce_revrec`, `salesforce_orders`, `cp_order_monthly_revrec` |
| Auto-number | `Invoice_Collection__c` | `Name` | 缺失的 local auto-number，优先补 `L2 metadata` | `stg_salesforce_invoice_collection`, `salesforce_orders` |
| Auto-number | `Opportunity_Product__c` | `Name` | 缺失的 local auto-number，优先补 `L2 metadata` | `salesforce_opportunity_products`, `salesforce_opportunities` |
| Auto-number | `Order_Product__c` | `Name` | 缺失的 local auto-number，优先补 `L2 metadata` | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` |
| Auto-number | `Quote_Product__c` | `Name` | 缺失的 local auto-number，优先补 `L2 metadata` | quote/order/product-family 下游明细模型 |

Current evidence gap:

- for `Lead` and `Opportunity`, the current report still has exact counts of
  missing live Flows from the org audit
- but the current local export evidence does not yet recover the full exact
  missing Flow-name inventory for all of those counts
- so those two objects still need one more pass if we want a name-complete
  backlog
- this pass did narrow the highest-confidence unresolved exact names:
  `Lead_StatusChangeTimestamp`
  and
  `OpportunityShareToPersalesOwner`
  are still not found in the current local pack surfaces, while the other
  scanned live names
  `lead_convert_opportunity`,
  `Add_or_update_Opt_Owner_s_Role`,
  `MySQL_Family_Capture_upon_Update`,
  `Technical_Validation_Is_Request_Products`,
  and
  `Opportunity_Stage_To_Lunched`
  are all already present locally and should no longer be read as
  definition-missing by default

### 子清单 C: Name Clues For Still-Unresolved Flow Gaps

This section is weaker evidence than the two lists above.

These names are useful investigation clues because they show up in local
migration artifacts, issue inventory, or migrated email-template catalogs, but
this report is **not** claiming all of them are confirmed-missing live Flows.

Use them as the next places to inspect when filling the remaining `Opportunity`
name gaps, the long-tail Lead notification / assignment surfaces, and the
still-partial semantics on long-tail
`Invoice_Collection__c` flows.

| 对象 | 线索类型 | 名字 / 线索 | 为什么值得继续追 |
|---|---|---|---|
| `Lead` | migration issue | `Lead Assignment Rule flow` | `migration_audit.csv` has explicit Lead-assignment parity bugs (`Owner remains empty`), which matches the audit theme that some missing Lead flows are assignment/notification related. |
| `Lead` | migration issue | `LeadQuicklySet` | multiple migration issues call out Salesforce-vs-replica mismatches in this flow, so it remains a high-signal Lead automation surface even when not a "missing definition" case. |
| `Lead` | migrated email templates | `New_Lead_Record_Created_Notification`, `Lead_Assignment_Notification_Other`, `Lead_assigned`, `New_lead_has_been_assigned_To_Sales`, `Lead_Already_Have_Lead_Templates`, `Lead_Already_Have_Account_Templates`, `Tenant_Status_Change`, `Lead_Owner_SDR_Duration_Over_24Hours`, `Lead_Approval_Notification_Ready_for_Conversion` | the live-org gap description already said many missing Lead flows were email / partner / scheduled-reminder logic; these template names are the best current local clue set for those still-unresolved names. |
| `Opportunity` | migrated email templates | `Opportunity_Stage_Duration_Over_14_days`, `Opportunity_Stage_Duration_Over_30_days`, `Opportunity_Stage_Duration_Over_60_days`, `Opportunity_will_expire`, `Push_Launched_opportunity_notification_to_the_operation_and_sales_owner`, `Opp_Won_Notice`, `Opportunity_Create`, `Opportunity_Rject` | the live-org gap description already called out notification / reminder behavior. These names align with stage-duration alerts, launch notifications, and partner submission workflows. |
| `Opportunity` | migration issue | `OpportunityShareToPersalesOwner` | `migration_audit.csv` #1749 names this exact AfterSave Opportunity flow next to `Task_Update_Opportunity_Key_Deal`; a later fix commit for `#1749` also notes that this specific flow is `recordTriggerType=Create`, while update behavior should go through sibling `OpportunityUpdateShareToPerSalOwner`; current local pack search still does not find a matching definition for the named create flow, so it remains the strongest remaining Opportunity exact-name candidate from this pass, but the create/update semantics should be treated carefully. |
| `Invoice_Collection__c` | migrated email templates | `Collected_Notice_to_Sales`, `Invoice_Application_approval`, `Invoice_Issued_Notice`, `Invoice_Notice` | exact names are now mostly recovered from regression-flow evidence, but these template names still help explain the remaining business semantics: collection/payable amount handling, billing status transitions, and invoice notice workflows. |
| `Invoice_Collection__c` | field-level local clues | `Approval_Status__c`, `Invoice_Status__c`, `Collections_Amount__c`, `Collections_Date__c`, `Payable_Amount_USD_2_Exc_Tax__c`, `PLG_BD_Pool__c`, `Marketplace__c` | local email/render catalogs, regression snapshots, and staging fields show these are the operational surfaces most likely touched by the now-mostly-named IC flow family. |

Practical reading:

- `子清单 A` and `子清单 B` are good enough to drive immediate work
- `子清单 C` is the handoff map for the next audit pass when we want the last
  unresolved Flow names

### 子清单 D: Evidence Strength Upgrade For Long-Tail Flows

This section upgrades some of the weaker clues above into clearer evidence
tiers, so future readers do not treat every long-tail name the same way.

| 对象 | 名字 / 线索 | 当前证据强度 | 为什么比普通 clue 更强 | 当前最稳判断 |
|---|---|---|---|---|
| `Lead` | `Lead_Assignment_Rule_modification_for_NA_EMEA` | `High` | `packs/AUTO_GEN_product_l2_filter_pack/flow_definitions/Lead_Assignment_Rule_modification_for_NA_EMEA.json` proves the live-flow slice has it as `Lead` + `RecordBeforeSave`; `staging-inspection/docs/lead-case-business-spec.md` and 14 lead-assignment regression cases prove it is not just metadata drift but an actively tested business flow | 这不是 missing-name gap，而是已经确认存在且高业务价值的 Lead 自动化面；后续缺口更多是同类 assignment / notification 长尾没有补全 |
| `Lead` | `LeadQuicklySet` | `Medium-High` | `phase3-flow-active-preflight-api` explicitly checks it as one of the 8 required active Lead flows; `migration_audit.csv` has multiple parity bugs around it | 它更像“已存在但曾有 parity 问题的核心 Lead flow”，不是单纯模板线索 |
| `Lead` | `Lead_StatusChangeTimestamp` | `High` | `migration_audit.csv` #2107 and `docs/epics/0028-lead-bugs-and-uat.md` both record a production-blocking beforeCreate failure on this exact protected Flow; historical tenant flow JSON and `picklist_tags.json` further recover the exact live rule: `RecordBeforeSave` on `Lead`, `CreateAndUpdate`, only when `Status` enters picklist tag `working_or_later`, stamping `Date_Status_Changed__c = $Flow.CurrentDateTime`; current local pack does not carry this exact flow name, but it does carry `Lead_Status_Duration`, an active `RecordBeforeSave` Lead flow that stamps `Date_Status_Changed__c` on any `Status IsChanged` event | 这条不该再读成“名字还没搞清楚”的 unresolved clue。更稳的读法是：live 语义已经恢复，本地也有近似承接，但当前是 `semantic parity mismatch` 而不是 `CM 真没能力`；按现有 BI 证据，最直接命中的字段仍是 `stg_salesforce_lead.date_status_changed`。而且后续对 `ywang-official/digital-bi-dbt` 与 `pingcap-inc/dbt-dev` 的 GitHub REST code search 也只在 `stg_salesforce_lead.sql` 命中这条字段，没有把它继续坐实到 `salesforce_leads.sql`、`dws_lead_timeline.sql`、`dws_icp_summary.sql` 或 Looker `salesforce_lead`，所以对命名 marketing marts 的 blast radius 现在应读作 plausible-but-not-yet-proved |
| `Opportunity` | `Opportunity_Stage_To_Lunched` | `High` | `packs/AUTO_GEN_product_l2_filter_pack/flow_definitions/Opportunity_Stage_To_Lunched.json` proves the live-flow slice has it as `Opportunity` + `Scheduled`; `migration_audit.csv` #2231 / #2253 and `docs/epics/0024-flow-misc.md` prove it hit scheduled-trigger runtime defects | 这是已命名、已确认 trigger 类型、已发生 runtime 问题的核心 Opportunity automation surface，不只是 notification clue |
| `Opportunity` | `OpportunityShareToPersalesOwner` | `High` | `migration_audit.csv` #1749 and `docs/epics/0024-flow-misc.md` both name it exactly; `MetaDrivenPlatform4AI/docs/design/flow/trigger-automation-design.md` further lists it explicitly in the production `FlowDefinition` inventory as `RecordAfterSave` on `Opportunity`; the merged fix commit for `#1749` adds an important caveat: this exact flow is `recordTriggerType=Create`, and PATCH/update behavior should instead go through sibling `OpportunityUpdateShareToPerSalOwner`; this pass still did not find a matching local definition in `packs/Salesforce-PingCAP-L2` or the merged pack | 这是当前最强的 Opportunity exact-name missing candidate，但最稳读法已经从“#1749 直接证明 update 不触发”收窄为：历史生产里确认有这条 create-flow，且很可能还存在一条 update-sibling；当前本地仍未找到 exact-name peer。当前 checkout 里更硬的下游证据是 `salesforce_opportunities.opt_owner_role_c -> owner_team` 以及 bizops 侧 `dws_data_quality_alerting` / `rpt_data_quality_wtw_comparison`，而不是 marketing marts 直接消费 `owner_team`，所以 BI 风险目前更偏 `owner/access/team attribution` 而不是 `ARR/stage` 核心口径 |
| `Invoice_Collection__c` | `Collection_Set_PLG_BD_Pool` | `High` | `MetaDrivenPlatform4AI/scripts/dump-flow-regression-fixtures/run.sh` and the regression fixture prove this was an active dumped flow; its fixture metadata shows `RecordBeforeSave` on `Invoice_Collection__c` (`CreateAndUpdate`) with entry filter `Account__c IsNull = false`, assigning `$Record.PLG_BD_Pool__c = $Record.Account__r.PLG_BD_Pool__c`; current local pack search did not find a matching definition | 这条 exact-name 已能直接落到字段级语义：本地缺它会让 collections 的 pool 维度直接漂 |
| `Invoice_Collection__c` | `Collection_Amount_and_Payable_Amount_exc_tax` | `High` | dumped regression fixture metadata shows `RecordAfterSave` on `Invoice_Collection__c` (`Create`) and two `RecordUpdate` actions that write `Collections_Amount_USD_exc_tax__c`, `Collections_Amount_exc_tax__c`, and `Payable_Amount_USD2_exc_tax__c`; current local pack search did not find a matching definition | 这条 exact-name 已能直接落到 exc-tax helper 字段级语义，不再只是模板层猜测 |
| `Invoice_Collection__c` | `Collection_Amount_and_Payable_Amount_exc_tax_Update` | `High` | dumped regression fixture metadata shows `RecordAfterSave` on `Invoice_Collection__c` (`Update`) with the same exc-tax helper field family as the create leg; current local pack search did not find a matching definition | 这是上一条金额/应付 exc-tax 逻辑的 update 腿，语义已足够清晰，可直接进入 parity backlog |
| `Invoice_Collection__c` | `Cloud_Registration_Source_from_Org_to_Collections` | `High` | `migration_audit.csv` #2224 names it directly as an IC-create Flow that should dispatch; `MetaDrivenPlatform4AI/backend/internal/features/automation/flow_regression_test.go` includes it in the finance regression flow list; `flow_recordupdate_null_object_test.go` comments and the regression snapshot further show it loops `Org__c` records and updates `Invoice_Collection__c.Marketplace__c` from org-derived source data; current repo search across local pack surfaces still did not find a matching local definition | 这是当前最强的 `Invoice_Collection__c` exact-name candidate，且已能看见一部分具体字段语义，不再只是 carry-over 方向猜测 |
| `Invoice_Collection__c` | `Collected_Notice_to_Sales`, `Invoice_Application_approval`, `Invoice_Issued_Notice`, `Invoice_Notice` | `Medium` | email-template catalog and source `.email` files prove these are real migrated collection / invoice communication surfaces and expose concrete fields like `Collections_Amount__c`, `Collections_Date__c`, `Account__c`, `Name`, `Order`; however `scripts/salesforce_migration/approval_email/README.md` explicitly says the deliverable seeds only the template catalog and does **not** seed `WorkflowAlert` / `ProcessAction` wiring for these non-Quote/non-Account templates | 这些仍然主要是 business-signal clues；它们能证明对象语义和通知面，但还不足以单独证明对应 Flow developerName 或 live alert binding |
| `Lead` | `Lead_Assignment_Notification_Other`, `Lead_assigned`, `New_lead_has_been_assigned_To_Sales`, `New_Lead_Record_Created_Notification` | `Medium` | migrated email-template catalog proves the notification surface really existed, and the subject lines are tightly aligned with partner registration / assignment behavior | 这些模板更适合作为“缺失 notification/assignment 长尾”的方向证据，而不是直接当成 Flow 名字 |
| `Opportunity` | `Opportunity_Stage_Duration_Over_*`, `Opportunity_will_expire`, `Push_Launched_opportunity_notification_to_the_operation_and_sales_owner`, `Opp_Won_Notice`, `Opportunity_Create`, `Opportunity_Rject` | `Medium` | migrated email-template catalog proves the stage-duration / launch / won / partner-submission notification family existed and was concrete enough to migrate | 这些模板能帮助我们把剩余 Opportunity gap 从“未知”收缩到“scheduled reminder / launch notice / partner notice”几类，但还不是 exact-name Flow proof |

Practical reading:

- `Lead_Assignment_Rule_modification_for_NA_EMEA`,
  `Lead_StatusChangeTimestamp`,
  and
  `Opportunity_Stage_To_Lunched`
  should now be read as
  `confirmed high-signal automation surfaces`,
  not ordinary clue rows
- the current Lead / Opportunity naming pass narrows the remaining
  highest-confidence unresolved exact-name backlog to
  `OpportunityShareToPersalesOwner`;
  `Lead_StatusChangeTimestamp`
  should now be read separately as
  `live semantics recovered; local substitute exists but is broader than live`
  rather than as an unresolved exact-name gap;
  the other scanned live names in this pass are already present locally
- the current `Invoice_Collection__c` naming pass is now nearly exact-name
  complete:
  `Collection_Set_PLG_BD_Pool`,
  `Collection_Amount_and_Payable_Amount_exc_tax`,
  `Collection_Amount_and_Payable_Amount_exc_tax_Update`,
  and
  `Cloud_Registration_Source_from_Org_to_Collections`
  are all named in historical regression evidence and are still absent from the
  current local pack surfaces
- the migrated invoice/lead/opportunity templates are stronger than random
  guesses because they preserve real object-specific merge fields, but they are
  still weaker than named-flow or runtime-bug evidence:
  the current approval-email migration explicitly seeds a reusable template
  catalog, not general WorkflowAlert / ProcessAction bindings for those object
  families
- the remaining email-template names are still useful, but they remain
  `notification-surface evidence`
  rather than
  `exact Flow developerName proof`

### Invoice_Collection__c Candidate Family Breakdown

The current `Invoice_Collection__c` gap is no longer a black box, and the
exact-name inventory is now mostly recovered from historical regression
evidence.

#### Recovered Exact-Name Flow Map

| Flow 名字 | 历史 trigger 时机 | 当前已知写入语义 | 当前本地状态 | 最直接受影响字段/报表 |
|---|---|---|---|---|
| `Collection_Set_PLG_BD_Pool` | `RecordBeforeSave`, `CreateAndUpdate` | entry filter `Account__c != null`; assign `Invoice_Collection__c.PLG_BD_Pool__c = Account__r.PLG_BD_Pool__c` | 本地未找到同名 flow | `plg_bd_pool_c`; `stg_salesforce_invoice_collection`, collections / billing segmentation |
| `Collection_Amount_and_Payable_Amount_exc_tax` | `RecordAfterSave`, `Create` | write `Collections_Amount_USD_exc_tax__c`, `Collections_Amount_exc_tax__c`, `Payable_Amount_USD2_exc_tax__c` | 本地未找到同名 flow | `collections_amount_usd_exc_tax_c`, `collections_amount_exc_tax_c`, `payable_amount_usd_2_exc_tax_c`; finance collections / billing |
| `Collection_Amount_and_Payable_Amount_exc_tax_Update` | `RecordAfterSave`, `Update` | create leg的 update 腿；继续维护同一组 exc-tax helper 字段 | 本地未找到同名 flow | 同上；尤其影响 update 后的 payable/collections 口径一致性 |
| `Cloud_Registration_Source_from_Org_to_Collections` | `RecordAfterSave`, `Create` | entry filter uses `Accumulate_revenue_to_Org__c`; lookup `Org__c` by org linkage and update `Invoice_Collection__c.Marketplace__c = Loop_Orgs.source__c` | 本地未找到同名 flow | `marketplace_c` and adjacent cloud-registration carry-over semantics; collections source attribution / recurring finance outputs |

Based on the current local object spec, migration audit, and migrated template
catalog, the unresolved Flow family now breaks down into the following buckets:

| 候选类别 | 当前最强证据 | 受影响字段/语义 | 对报表影响的最短解释 | 当前判断 |
|---|---|---|---|---|
| `Cloud-registration carry-over` | `migration_audit.csv` #2224 names `Cloud_Registration_Source_from_Org_to_Collections`; `flow_recordupdate_null_object_test.go` comments and the regression snapshot further show it loops `Org__c` and updates `Invoice_Collection__c.Marketplace__c` from org-derived source data; local `Order` object has first-class `Cloud_Registration_Source__c`, while current local `Invoice_Collection__c` spec does not expose the same field directly | cloud-registration attribution / related-order carry-over context | 影响 collections/billing 明细在云注册来源、marketplace 以及 related-order carry-over 维度上的一致性，并通过 `salesforce_orders` / recurring finance outputs 外溢 | 这是已命名且语义最具体的一条，不再只是方向性 candidate |
| `Collection-received transition / notification` | `MetaDrivenPlatform4AI/backend/internal/features/automation/flow_regression_test.go` names `Collection_Amount_and_Payable_Amount_exc_tax` and `Collection_Amount_and_Payable_Amount_exc_tax_Update`; `Collected_Notice_to_Sales` template references `Collections_Amount__c`, `Collections_Date__c`, `Account__c`, `Order.Name`; local `Order` rollups explicitly sum `Invoice_Collection__c` amounts only when `CollectionsStatus__c = 'Collected'` | received/collected transition, amount/date communication, collected-state rollup timing, payable/collections exc-tax helper values | 不只是通知问题；如果 live Flow 负责把 IC 推到 `Collected` 或同步 collected/payable amount helpers，而 local 没补，cash-collected 和 payable 相关指标都会直接漂 | 现在 exact-name 已基本恢复，但具体字段写法仍需后续拿到原始 flow metadata 做最终确认 |
| `Invoice-approval / invoice-issued notification` | `Invoice_Application_approval`, `Invoice_Notice`, `Invoice_Issued_Notice` templates reference `Approval_Status__c`, `PingCAP_Contracting_Entity__c`, `Account__c` | invoice approval state, pending approval notice, invoice issued notice | 更直接对应 billing / invoice-state operational semantics，间接影响用户如何理解 `invoice_status_c` / `actual_billing_date_c` 这些字段的业务时点 | 当前更像通知/状态语义补充，而不是剩余未知的 exact-name 黑盒 |
| `PLG BD pool / helper carry-over` | `MetaDrivenPlatform4AI/backend/internal/features/automation/flow_regression_test.go` names `Collection_Set_PLG_BD_Pool`; local `Invoice_Collection__c` still carries `PLG_BD_Pool__c`; audit already proves live object has 4 active Flows while local has none | pool classification / segmentation helper | 若 live 对 IC 层还维护 pool/carry-over 语义，缺失会沿 `stg_salesforce_invoice_collection` / `salesforce_orders` / collections reporting 把 pool 维度打歪 | 这条 exact name 已恢复，接下来主要缺的是原始 flow metadata 级细节 |

Important inference from the local object spec:

- current local `Invoice_Collection__c` already has many active formulas for
  `Collections_Amount_USD__c`,
  `Payment_Status__c`,
  `Uncollected_Amount__c`,
  `Uncollected_Amount_USD__c`,
  and related payable/status helpers
- local validation parity already covers the
  `Actual_Billing_Date__c`
  requirement

So the remaining live Flow gap on this object now looks more like:

- carry-over / status-transition / notification logic

than:

- missing basic numeric formula support

That is an important practical split when deciding whether this belongs in
ordinary `L2 pack parity`
work or in
`CM runtime boundary`
work.

Another concrete implication:

- because current local `Order` metadata already contains rollups filtered by
  `Invoice_Collection__c.CollectionsStatus__c = 'Collected'`,
  the missing IC Flow family is likely to affect
  `when`
  a collection starts contributing to order-level cash/payable metrics,
  not only
  `whether`
  a notification email is sent
- the current local evidence boundary is also asymmetric:
  `packs/AUTO_GEN_Product-pack/live/flow_definitions/flow_definitions.json`
  returns `0`
  `Invoice_Collection__c`
  rows in the filtered live-flow slice,
  while
  `scripts/salesforce_migration/reports/2026-05-21/salesforce_object_export_coverage.csv`
  marks
  `Invoice_Collection__c`
  as
  `not_covered`
  for object export coverage.
  So the current exact-name gap on this object is still driven more by live-org
  counts, migration issues, and template/field evidence than by a complete
  local live-export mirror.

### Finance Chain Blast-Radius Refinement

The current evidence is now strong enough to split the finance-side gaps into
two very different BI severities.

| 差异类型 | 当前最强证据 | 为什么更影响 `gcp-digital-bi` | 当前优先级判断 |
|---|---|---|---|
| `Flow / status / carry-over parity` | local `Order` rollups sum `Invoice_Collection__c` only when `CollectionsStatus__c = 'Collected'`; dbt `stg_salesforce_invoice_collection.sql` exposes `collections_status_c`, `invoice_status_c`, `cash_collected_c`, `payable_amount_usd_2_exc_tax_c`, `plg_bd_pool_c`; current checked-out `salesforce_orders.sql` declares but does not consume its `invoice_collection` CTE; `cp_order_monthly_revrec.sql` and `monthly_cloud_billing_revrec.py` consume order-level finance snapshots directly from `gcp-digital-bi` | 这类缺口会直接改变 cash collected、payable、collections timing、pool segmentation、tenant revenue attribution，属于真正改指标的差异；同时也说明当前 confirmed direct consumer surface 更强在 staging/source 和 recurring outputs，而不是一张已经把 IC 明细完全 join 进来的 SQL mart | 高于 finance 侧 auto-number 缺口，应先补 |
| `Name auto-number parity` | current dbt usage shows `Revenue__c.Name` is exposed as `revenue_name`, but downstream finance assembly currently keys primarily on `order_id`, `order_name`, dates, and amounts; `Invoice_Collection__c.Name` appears more clearly in migrated notification templates than in the current dbt finance joins | 这类缺口更像 record identity / human-readable document number parity。它当然值得补，但按当前仓库证据，对核心 finance metrics 的直接扭曲弱于状态切换 / carry-over Flow 缺口 | 仍在 backlog 里，但 BI 止血优先级低于 Flow parity |

Another useful comparison:

- local pack already includes
  `Cloud_Registration_Source_from_Org_to_Order`
  for `Order`
- the unresolved migration/runtime evidence names
  `Cloud_Registration_Source_from_Org_to_Collections`
  for `Invoice_Collection__c`

That pattern strongly suggests the Collections-side cloud-registration gap is
not "CM has no way to express this business rule at all". It is more likely:

- the same carry-over family is already implemented on `Order`
- but the neighboring `Invoice_Collection__c` parity leg is still missing or
  still hitting a Flow-runtime dispatch defect

This is an important reason to keep the current `Invoice_Collection__c`
classification biased toward:

- `L2 pack parity`

before escalating it to:

- `CM runtime boundary`

### 实施 Backlog 草案

This is the most execution-oriented view in the current report.

The goal is not to prove every item is the final answer forever. The goal is to
separate:

- things we can start fixing now with high confidence
- things that still need one more audit pass for exact names
- things that are actually CM runtime boundary work

| 工作流 | 现在就能做什么 | 典型对象/机制 | 主要止血报表 | 证据强度 |
|---|---|---|---|---|
| `B1` 激活已有规则 | 把已在 pack 中、但 local inactive / live active 的规则逐条核对并激活 | `Lead.Nurture_Marketing_Date`, `Lead.Nurture_Sales_Date`, `Opportunity.PingCAP_Contract_Entity_EMEA_only`, `Quote.Customer_s_Hardware_Configuration`, `Quote.Details_of_vCPU_Calculation`, `Quote.Version_of_TiDB` | `salesforce_lead`, `salesforce_opportunities`, `salesforce_oppo`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration` | 高 |
| `B2` 补齐已知名字的 L2 Flows / Rules | 直接按名字补 `L2 pack Flow`，并补高置信缺失 validation，优先处理最贴近 BI 的对象 | `Account_Contract_Valid_Message`, `Account_Current_Order_Type`, `Order_Org_Auto_Set_Account_Create`, `Order_Set_PLG_BD_Pool`, `Campaign_Member_Key_Message_Update`, `RevRec_Set_PLG_BD_Pool`, `Quote_update_nonstandard_conditions_checkbox`, `Collection_Set_PLG_BD_Pool`, `Collection_Amount_and_Payable_Amount_exc_tax`, `Collection_Amount_and_Payable_Amount_exc_tax_Update`, `Cloud_Registration_Source_from_Org_to_Collections` | `crm_account`, `salesforce_accounts`, `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec`, `dws_campaign_attribution`, `stg_salesforce_invoice_collection` | 高 |
| `B3` 补齐 auto-number | 在 `L2 metadata` 里补 document/line-item 编号 | `Revenue__c.Name`, `Invoice_Collection__c.Name`, `Opportunity_Product__c.Name`, `Order_Product__c.Name`, `Quote_Product__c.Name` | `salesforce_revrec`, `stg_salesforce_invoice_collection`, `salesforce_orders`, `salesforce_opportunity_products` | 高 |
| `B4` 追全缺失 Flow 名字 | 用 `子清单 C` 继续做定名审计，再决定是否补 Flow | `Lead` 的 assignment / notification / reminder surfaces；`Opportunity` 的 stage-duration / launch-notice surfaces；`Invoice_Collection__c` 的 invoice / collection notice surfaces | `salesforce_lead`, `dws_lead_timeline`, `salesforce_opportunities`, `salesforce_orders` | 中 |
| `B5` 评估 Apex 替代 | 把仍只活在 live Apex trigger 里的逻辑改写为 Flow / metadata-action，或立 runtime 能力项 | `LeadTrigger`, `LeadAITrigger`, `OpportunityTrigger`, `AccountTrigger`, `OrderTrigger`, `QuoteTrigger`, `RevenueTrigger`, line-item trigger surfaces | 几乎所有高价值 CRM/BI 面都会受影响，但这是更重的工作流 | 中 |
| `B6` 保持 intentional replacement | 对明确写明“本地有意替代”的规则不要当成误差直接补回 | `Order_Activate_Contract_Status`, `Order_Activate_Contract_Start`, `Order_Activate_Contract_End`, `Order_Activate_Requires_Contract` | `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec` | 高 |

Recommended execution order:

1. `B1` 激活已有规则
2. `B2` 补齐已知名字的 L2 Flows
3. `B3` 补齐 auto-number
4. `B4` 追全缺失 Flow 名字
5. `B5` 评估 Apex 替代

Why this order is pragmatic:

- `B1` / `B2` / `B3` are the highest-confidence, shortest-path parity work
- `B4` improves backlog completeness, but does not block starting the first
  three buckets
- `B5` is the real platform-boundary work and should not be mixed into the same
  queue as ordinary pack parity fixes
- inside finance specifically, the current evidence says
  `status/carry-over Flow parity`
  should be executed before
  `Name auto-number parity`
  if the goal is fastest BI-risk reduction

### 报表视角 Remediation Map

The sections above are mostly object-first.

If the operating question is instead "which backlog bucket most quickly stops
which report from drifting?", this report-centric map is the fastest reading.

| 报表/模型组 | 直接依赖的核心模型 | 最敏感的上游对象/字段 | 优先 Backlog 桶 | 为什么先修这些最值 |
|---|---|---|---|---|
| `Pipeline / Forecast` | Looker `salesforce_oppo`, `cloud-lead-pipeline-insight`; dbt `salesforce_opportunities`, `dim_opportunity`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration`, `dws_opportunity_stage_conversion_rates`, `dws_data_quality_alerting`, `dws_data_quality_alerting_daily_view` | `Opportunity.stage_name`, `forecast_category`, `forecast_type`, `loss_reason`, `opportunity_number`, `arr_amount_usd`, `accurate_acv_amount`, `owner_team`, `cloud_order_type`; plus Quote-enriched `service_start_date`, `service_end_date`, support-tier / nonstandard-term fields | `B1`, `B2`, then `B5` | 这是最直接的营收/pipeline 面。先激活 `Opportunity` / `Quote` 已存在但 inactive 的 validation，再补缺失 Opportunity / Quote Flows，最后才轮到 trigger-only 边界。 |
| `Lead Funnel / Qualification` | Looker `salesforce_lead`, `cloud-lead-pipeline-insight`; dbt `salesforce_leads`, `dim_lead`, `dws_lead_timeline` | `LeadLifecycleStage`, `LeadStatus`, `LeadSource`, `Region`, `Segmentation`, `TenantStatus`, `TiDBCloudPortalID`, `lead_mql_timestamp`, `lead_iqm_timestamp`, `account_id` | `B1`, `B2`, `B4`, then `B5` | Lead 报表最依赖 lifecycle / MQL / IQM / account-linkage。已知 inactive validation 和 assignment/notification 类 Flow 优先级高，剩余名字不全的再走 `B4`。 |
| `Campaign Attribution` | dbt `salesforce_campaign_members`, `salesforce_campaign_attributions`, `dws_campaign_attribution`, `dws_campaign_attribution_details`, `dws_icp_summary` | `CampaignMember.first_responded_date`, `campaign_member_status`, `has_responded`, `contact_involvement_level`; Opportunity-side `accurate_acv_amount`, `arr_amount_usd`, `mapped_stage_name`; Contact/Lead stitching keys | `B2`, then `B5` | 这里最直接的高置信修复是补 `Campaign_Member_Key_Message_Update`。不需要先等全量 Lead/Opportunity flow 名字补齐。 |
| `Order / ARR / RevRec / Collections` | dbt `salesforce_orders`, `salesforce_order_daily_view`, `salesforce_order_current_monthly_arr`, `cp_order_monthly_revrec`, `salesforce_revrec`, `salesforce_org_monthly_revrec`, `dws_salesforce_arr_summary` | `accumulate_revenue_to_org_tenant_id`, `order_status`, `order_product_family`, `order_products`, `revenues`, `revenue_name`, `revenue_status`, `plg_bd_pool`, `invoice_status_c`, `collections_amount_c`, `cash_collected_c`, `payable_amount_usd_2_exc_tax_c` | `B2`, `B3`, then `B5`; keep `B6` separate | Finance 面最先受益的是补 `Order` / `Revenue__c` / `Invoice_Collection__c` 的缺失 Flow、缺失 validation 和 auto-number。注意 `Order_Activate_*` 那组是 intentional replacement，不应直接并回 live 行为。 |
| `Account / Tenant Linkage` | Looker `crm_account`, `cloud-lead-pipeline-insight`; dbt `salesforce_accounts`, `dim_account`, `dim_tenant`, `salesforce_orgs`, `customer_surrogate_keys`, `customers`, `salesforce_org_monthly_revrec` | `AccountID`, `Industry`, `Region`, `Segmentation`, `TenantStatus`, `TiDBCloudPortalID`, `tenant_ids`, `customer_surrogate_key`, `accumulate_revenue_to_org_tenant_id` | `B2`, `B3`, then `B5` | 这是很多下游模型的 shared dimension。补 Account Flow、Org/Order carry-over、Revenue/Invoice auto-number，能同时减少多条链路漂移。 |

Fastest "report stop-the-bleeding" reading:

1. if pipeline / forecast numbers look wrong, start from `Opportunity` + `Quote`
   in `B1` and `B2`
2. if funnel / attribution timestamps or lifecycle stages drift, start from
   `Lead` + `CampaignMember`
3. if finance / ARR / revrec drifts, start from `Order` + `Revenue__c` +
   `Invoice_Collection__c`
4. if tenant/account joins drift across many surfaces, start from `Account` +
   `Org__c` + `Order` carry-over fields

## What Salesforce Automatically Does

### 1. System/default fields

Every key object gets at least the normal Salesforce system values:

- `Id`
- `CreatedDate`
- `CreatedById`
- `LastModifiedDate`
- `LastModifiedById`
- `SystemModstamp`
- object-level default picklists / booleans / owner defaults

These are not the main gap risk because any normal Salesforce insert path will
generate them.

### 2. Auto-number fields

The following report-relevant objects have important auto-number behavior:

- `Account.Account_ID__c`
- `Contract.ContractNumber`
- `Quote.QuoteNumber`
- `Order.OrderNumber`
- `Revenue__c.Name`
- `Invoice_Collection__c.Name`
- `Opportunity_Product__c.Name`
- `Order_Product__c.Name`
- `Quote_Product__c.Name`

If the current CRM API does not emulate these values when creating records
outside Salesforce-native persistence, these IDs/numbers will be blank and many
downstream reporting joins or operator workflows will degrade.

### 3. Formula / rollup / derived fields

These are heavily used in the live org and especially important for reporting.

Examples:

- `Account`: `ICP__c`, `Segmentation__c`, `Contract_Valid_Days__c`,
  `Open_Pipeline_ACV__c`
- `Lead`: MQL/SQL aging, owner/profile derivations, IQM quality metrics,
  conversion age, domain-derived fields
- `Opportunity`: `Region__c`, `Forecast_Quarter__c`, `Segmentation__c`,
  `Industry__c`, `Vertical__c`, `Stage_Duration__c`, ACV/USD derived amounts
- `Quote`: discount/approval flags, overall term dates, USD/TCV/ACV amounts,
  approval-routing helper fields
- `Order`: cash / deferred revenue / recognized revenue / TCV / ACV / region /
  fiscal-period derived fields
- `CampaignMember`: lifecycle / region / lead-source / campaign-name helper
  fields
- `Revenue__c`: amount USD, fiscal period, revrec grouping fields
- `Invoice_Collection__c`: payable / collected / uncollected USD amounts,
  payment status, fiscal year, product-family derived fields

If our CRM API path writes objects without equivalent formula/rollup support, BI
will not just lose “nice to have” labels. It will lose core finance, pipeline,
segment, and attribution dimensions.

### 4. Validation rules

Live Salesforce is using validation rules as part of the business contract, not
just UI decoration.

High-signal examples:

- `Lead` has 18 active validations around IQM, segmentation, AE/SDR ownership,
  nurture/disqualified dates, cloud vendor, job role, and “converted lead must
  create opportunity”.
- `Opportunity` has 21 active validations around partner attribution, forecast
  type, loss reason, cloud vendor, cloud order type, ARR amount, launch date,
  opportunity source, stage entry, and EMEA contracting entity.
- `Quote` has 10 active validations around partner margin/rebate, cloud quote
  completeness, TiDB version/hardware config, and support tier.
- `Order_Product__c` has an active validation that order price cannot be lower
  than quoted price.
- `Invoice_Collection__c` requires `Actual_Billing_Date__c` in a specific
  billing state.

If our API path bypasses these validations, BI may ingest records that would
never exist in Salesforce, which is often worse than a blank field because it
creates semantically invalid pipeline and finance facts.

### 5. Flows

The live org uses many active flows on the key objects:

- `Lead`: 32 active flows
- `Opportunity`: 27 active flows
- `Account`: 8 active flows
- `Order`: 5 active flows
- `CampaignMember`: 5 active flows
- `Invoice_Collection__c`: 4 active flows
- `Quote`: 3 active flows
- `Contract`: 2 active flows
- `Contact`: 1 active flow
- `Org__c`: 1 active flow
- `Revenue__c`: 1 active flow

High-signal flow themes:

- `Lead`
  - relate lead to account by email domain
  - default country / region
  - IQM completion stamping
  - owner setting and owner-email notifications
  - lead-to-org creation
  - conversion field stamping and validation
  - campaign-member first/last touch maintenance
- `Opportunity`
  - close-date and launch-stage logic
  - AWS defaulting and sync helpers
  - owner-role maintenance
  - cloud-order-type maintenance
  - stage-duration notifications
  - launch notifications
- `Account`
  - contract-valid reminders
  - current-order-type maintenance
  - first-order-start-date maintenance
  - partner/lead linkage by website domain
  - account status flow
- `Order`
  - org/account auto-linking
  - cloud registration source carry-over
  - PLG BD pool maintenance
- `CampaignMember`
  - first/last campaign member maintenance for both leads and contacts
- `Invoice_Collection__c`
  - payable/collection amount calculations
  - cloud registration source / PLG BD pool carry-over

If our API creation path does not trigger equivalent flow logic, the resulting
records will often be technically insertable but analytically incomplete.

### 6. Apex triggers

This org also relies on Apex triggers on many key objects, so the automation
surface is not “Flow only”.

Observed active trigger coverage includes:

- `Account`
- `Contact`
- `Lead`
- `Opportunity`
- `CampaignMember`
- `Contract`
- `Quote`
- `Order`
- `Revenue__c`
- `Opportunity_Product__c`
- `Order_Product__c`
- `Quote_Product__c`
- `Task`
- `Event`
- `Case`

This means any non-Salesforce-native create path that only tries to mimic field
defaults but ignores trigger-time business logic is still likely to diverge from
Salesforce truth.

## Object-by-Object Audit

### Account

Required input on create:

- `Name`

What Salesforce is maintaining for us:

- auto-number: `Account_ID__c`
- many default flags such as `OwnerId`, `Internal_User__c`,
  `Cloud_Production_Customer__c`, `AccountStatus__c`
- derived reporting fields such as `ICP__c`, `Segmentation__c`,
  `Open_Pipeline_ACV__c`, `Contract_Valid_Days__c`
- 8 active flows and active Apex triggers

BI risk if automation is missing:

- account segmentation / ICP / contract-health reporting drifts
- tenant-to-account and first-order signals become unreliable
- account-number-based joins or exports break

### Lead

Required input on create:

- `LastName`
- `Company`

What Salesforce is maintaining for us:

- many defaults such as `Status`, `OwnerId`, `IsConverted`, `IQM__c`,
  `IQM_Completed__c`, `Approvalstatus__c`, internal-user flags
- 29 derived fields including MQL/SQL aging, owner/profile helper fields,
  duration metrics, IQM scoring
- 32 active flows
- 18 active validations
- multiple active Apex triggers

BI risk if automation is missing:

- lifecycle stage and IQM metrics become incomplete
- account/tenant association is weaker
- source/channel / campaign / qualification views become inconsistent
- converted-lead reporting diverges, especially if converted leads do not create
  opportunities or lack follow-on stamping

### Opportunity

Required input on create:

- `Name`
- `StageName`
- `CloseDate`

Record type risk:

- live object exposes `New`, `Expansion`, `Downscale`, `Churn`,
  `Contract Only`, plus `Master`
- if the API path omits `RecordTypeId`, the default may be wrong for BI and
  validation semantics

What Salesforce is maintaining for us:

- default probability / open/closed/won / forecast-category fields
- many business defaults such as `Allow_Close__c`, `Forecast_Type__c`,
  AWS sync flags, channel / referral / cloud flags
- 33 derived fields including ACV/USD, region, segmentation, industry,
  stage duration, forecast quarter
- 27 active flows
- 21 active validations
- multiple active Apex triggers

BI risk if automation is missing:

- pipeline stage, forecast, ARR, region, vertical, and cloud-deal metrics drift
- launched / closed-lost / AWS-synced reporting becomes wrong
- invalid stage-state combinations enter the warehouse

### Quote

Required input on create:

- `Name`
- `OpportunityId`

Record type risk:

- live object exposes `New`, `Expansion`, `Renewal`, `Master`

What Salesforce is maintaining for us:

- auto-number: `QuoteNumber`
- default status/payment/approval booleans
- 80 derived fields, especially around discount, approval routing, ACV/TCV/USD,
  term dates, support tier, standard vs non-standard commercial terms
- 3 active flows
- 10 active validations
- active Apex trigger

BI risk if automation is missing:

- quote approval readiness and commercial-standardness are under-reported
- quote-to-order downstream facts lose pricing/discount semantics
- cloud quote completeness checks are bypassed

### Order

Required input on create:

- `EffectiveDate`
- `Status`

Record type risk:

- live object exposes `New`, `Expansion`, `Renewal`, `Master`

What Salesforce is maintaining for us:

- auto-number: `OrderNumber`
- default order status/payment/archive flags
- 63 derived fields including ACV/TCV/USD, deferred revenue, recognized
  revenue, cash collected/uncollected, region, cloud order type
- 5 active flows
- active Apex trigger

BI risk if automation is missing:

- ARR / revrec / collections reporting is immediately affected
- org/account carry-over fields become incomplete
- finance and operations reports lose derived contract/order state

### Campaign

Required input on create:

- `Name`

What Salesforce is maintaining for us:

- default type / status / active-state flags
- attribution exclusion default

BI risk if automation is missing:

- lower than lead/opportunity/order
- mostly affects campaign hygiene and attribution inclusion/exclusion rules

### CampaignMember

Required input on create:

- `CampaignId`

Important caveat:

- although Salesforce metadata marks only `CampaignId` as hard-required, in
  practice analytics expects either a lead/contact relation plus the related
  lifecycle/source context

What Salesforce is maintaining for us:

- response/opt-out/internal-user defaults
- 17 derived fields
- 5 active flows for first/last campaign member maintenance
- active Apex trigger

BI risk if automation is missing:

- first-touch / last-touch campaign attribution degrades
- campaign-member lifecycle reporting drifts

### Contact

Required input on create:

- `LastName`

What Salesforce is maintaining for us:

- owner/internal/TiDB-cloud defaults
- region/account-segmentation helper formulas
- 1 active flow
- active Apex triggers

BI risk if automation is missing:

- contact-level qualification and account-segmentation rollups weaken
- less severe than lead/opportunity, but still relevant for attribution joins

### Contract

Required input on create:

- `AccountId`

Record type risk:

- many live contract record types exist; omitting `RecordTypeId` can change the
  business meaning of the contract

What Salesforce is maintaining for us:

- auto-number: `ContractNumber`
- default status / approval / effective-date flags
- 2 active flows
- active validation and trigger

BI risk if automation is missing:

- contract state, validity, and downstream order-governance reporting drift

### Org__c

Required input on create:

- no metadata-hard-required field because `Name` is defaulted in the live org

What Salesforce is maintaining for us:

- defaulted `Name`
- default flags such as `AcceptService__c`, `TiDB_Cloud_User__c`
- formula: `Account_Name__c`
- 1 active flow (`Org Set Account`)

BI risk if automation is missing:

- tenant-to-account linking breaks or becomes partial
- this directly hurts `crm_account` / tenant-linked account reporting

### Revenue__c

Required input on create:

- `Order__c`

What Salesforce is maintaining for us:

- auto-number name
- default date/status/PLG flags
- 15 derived fields including USD amounts and fiscal-period helpers
- 1 active flow
- active trigger

BI risk if automation is missing:

- revrec and finance warehouse models become materially wrong

### Invoice_Collection__c

Required input on create:

- `Order__c`

What Salesforce is maintaining for us:

- auto-number name
- default approval / invoice-status flags
- 17 derived fields including payable/collected/uncollected USD metrics and
  payment status
- 4 active flows
- active validation requiring actual billing date in relevant cases

BI risk if automation is missing:

- collections and billing reports drift immediately

### Opportunity_Product__c / Order_Product__c / Quote_Product__c

Required input on create:

- `Opportunity_Product__c`: `Opportunity__c`
- `Order_Product__c`: `Order__c`
- `Quote_Product__c`: `Quote__c`

What Salesforce is maintaining for us:

- auto-number names
- product-family / net-fee / list-price / man-day / surplus helper derivations
- active triggers on all three
- active validation on `Order_Product__c`

BI risk if automation is missing:

- line-item revenue and product-family reporting drift
- quote/order pricing consistency weakens

## Report Impact

### Evidence boundary

The concrete BI model / report names below come from the earlier `2026-07-07`
repo search notes we already captured for `looker-schema` and
`digital-bi-dbt`.

Update from this follow-up pass:

- those repos were not present in the local filesystem
- but the current machine's authenticated `gh` session could read both private
  repos directly on GitHub
- the file-path evidence below is therefore based on real private-repo reads in
  this turn, not just the earlier notes
- similarly, `packs/AUTO_GEN_Product-pack/live/flow_definitions/flow_definitions.json`
  is useful as a live-exported flow-definition slice, but it is not the whole
  live-org Flow inventory. In the current workspace it mostly confirms that
  many already-exported object Flows have local peers; it does not by itself
  explain the larger live Flow counts seen in the read-only org audit.

### Repo-backed BI evidence

Direct Looker evidence from `pingcap-inc/looker-schema`:

- `models/cloud-lead-pipeline-insight.model.lkml`
  defines one explore chain:
  `salesforce_lead -> crm_account -> salesforce_oppo`
- `views/crm_account.view.lkml`
  exposes account segmentation / ICP / tenant status / portal id style fields
- `views/salesforce_lead.view.lkml`
  exposes lead lifecycle / source / region / segmentation / tenant linkage
- `views/salesforce_oppo.view.lkml`
  exposes forecast category, loss reason, net fees, product family, region,
  opportunity number, and related pipeline facts

Direct dbt evidence from `ywang-official/digital-bi-dbt`:

- `dbt/models/staging/salesforce/sources.yml`
  confirms the raw source objects currently modeled from Salesforce:
  `account`, `lead`, `contact`, `opportunity`, `opportunity_product_c`,
  `quote`, `quote_product_c`, `order`, `order_product_c`, `org_c`,
  `revenue_c`, `invoice_collection_c`, `campaign`, `campaign_member`,
  `campaign_member_status`, `contract`, and related history/record-type tables
- `dbt/models/warehouse/business_operations/salesforce_accounts.sql`
  builds account reporting from `stg_salesforce_account` and joins
  `salesforce_orgs` to add tenant ids
- `dbt/models/warehouse/business_operations/salesforce_opportunities.sql`
  builds opportunity reporting from `stg_salesforce_opportunity`, joins
  `stg_salesforce_account`, `stg_salesforce_record_type`, and enriches with
  `stg_salesforce_quote` plus opportunity history
- `dbt/models/warehouse/business_operations/salesforce_orders.sql`
  builds order reporting from `stg_salesforce_order`, then joins
  `stg_salesforce_order_product`, `stg_salesforce_invoice_collection`,
  `salesforce_revrec`, and `salesforce_opportunities`
- `dbt/models/warehouse/business_operations/salesforce_orgs.sql`
  builds tenant/org reporting from `stg_salesforce_org`
- `dbt/models/warehouse/business_operations/salesforce_revrec.sql`
  builds revrec reporting from `stg_salesforce_revenue`
- `dbt/models/warehouse/finance/salesforce_order_daily_view.sql`
  derives daily order finance state from `salesforce_orders`
- `dbt/models/warehouse/finance/salesforce_org_monthly_revrec.sql`
  joins tenant billing confirmation with `salesforce_orgs`
- `dbt/models/warehouse/marketing/salesforce_campaign_members.sql`
  builds campaign-member reporting from `stg_salesforce_campaign_member`
- `dbt/models/warehouse/marketing/salesforce_campaign_attributions.sql`
  materializes campaign attribution weights
- `dbt/models/marts/marketing/dws_campaign_attribution.sql`
  joins campaign attribution with `salesforce_accounts`,
  `stg_salesforce_contact`, `salesforce_campaigns`,
  and `salesforce_opportunities`
- `dbt/models/warehouse/marketing/salesforce_leads.sql`
  combines `stg_salesforce_lead`, `stg_salesforce_contact`,
  and `stg_salesforce_lead_history`
- `dbt/models/analytics/marketing/dim_lead.sql`
  joins `salesforce_leads` with `salesforce_accounts` and cloud / GA4 identity
- `dbt/models/marts/marketing/dws_lead_timeline.sql`
  joins `salesforce_leads`, `salesforce_opportunities`,
  `salesforce_campaign_members`, and `salesforce_campaigns`

### Direct Looker layer

The direct Looker explores are mainly:

- `crm_account`
- `salesforce_lead`
- `salesforce_oppo`

So the most visible report breakage from missing automation will show up as:

- blank or stale account segmentation / ICP / tenant linkage
- lead lifecycle / IQM / qualification drift
- opportunity stage / forecast / ARR / region / owner-team drift

Concrete object-to-report mapping at this layer:

| Object | Concrete Looker / semantic model impact |
|---|---|
| `Account` | `crm_account`, `salesforce_accounts`, `cloud-lead-pipeline-insight` |
| `Lead` | `salesforce_lead`, `salesforce_leads`, `cloud-lead-pipeline-insight`, `dim_lead` |
| `Opportunity` | `salesforce_oppo`, `salesforce_opportunities`, `cloud-lead-pipeline-insight` |
| `Contact` | `dim_lead` merge logic and any lead/contact blended analysis |
| `Org__c` | tenant enrichment inside `salesforce_accounts` / `crm_account` views |

Why these three Looker surfaces are especially sensitive:

- `cloud-lead-pipeline-insight.model.lkml` literally joins `Lead -> Account ->
  Opportunity`, so any missing lead/account/opportunity automation distorts the
  same funnel view instead of staying isolated inside one object table
- `crm_account.view.lkml` consumes fields like segmentation, industry, region,
  tenant status, and portal id that are exactly the kinds of account/org
  derivations most likely to drift if Account/Org flows or formulas do not fire
- `salesforce_oppo.view.lkml` consumes forecast / net-fee / loss-reason /
  product-family style fields that depend on opportunity and downstream quote or
  product semantics being correct

### dbt / warehouse layer

The dbt layer additionally depends heavily on:

- `Order`
- `Campaign`
- `CampaignMember`
- `Org__c`
- `Revenue__c`
- `Invoice_Collection__c`
- `Quote`
- `Contact`

If the API path does not preserve Salesforce-equivalent automation, the likely
warehouse/reporting failures are:

- wrong ARR / ACV / TCV / revrec / collections metrics
- broken tenant-to-account linkage
- broken campaign attribution and first/last touch logic
- invalid opportunity/quote/order state transitions entering marts

Concrete object-to-model mapping at this layer:

| Object | Concrete warehouse model / report families most likely affected |
|---|---|
| `Opportunity` | `salesforce_opportunities`, `dws_salesforce_arr_summary` |
| `Order` | `salesforce_orders`, `salesforce_order_daily_view`, `salesforce_order_current_monthly_arr`, `dws_salesforce_arr_summary` |
| `Quote` | quote staging + any downstream order / ARR logic fed from quote-derived commercial semantics |
| `Campaign` | `salesforce_campaigns` |
| `CampaignMember` | `salesforce_campaign_attributions`, `dws_campaign_attribution` |
| `Lead` | `salesforce_leads`, `dws_lead_timeline`, `dim_lead` |
| `Account` | `salesforce_accounts` |
| `Org__c` | `salesforce_orgs`, tenant-enriched `salesforce_accounts`, `salesforce_org_monthly_revrec` |
| `Revenue__c` | `salesforce_revrec`, `salesforce_org_monthly_revrec` |
| `Invoice_Collection__c` | `invoice_collection_c` source-backed collections / billing marts |
| `Opportunity_Product__c` | `opportunity_product_c` downstream product / pipeline detail models |
| `Order_Product__c` | `order_product_c` downstream order-line finance / product models |
| `Quote_Product__c` | `quote_product_c` downstream quote-line pricing models |
| `Contract` | contract-governed order / service-period logic feeding finance or governance analysis |

Repo-backed object lineage highlights:

- `Account` does not stop at account reporting:
  `salesforce_accounts.sql` joins `salesforce_orgs`, so Account / Org parity
  issues propagate into tenant-aware account reporting
- `Opportunity` does not stop at pipeline dashboards:
  `salesforce_opportunities.sql` enriches with `Quote` and history, so missing
  quote validation/defaulting can leak into opportunity analytics
- `Order` is the central finance hub:
  `salesforce_orders.sql` reads `Order`, `Order_Product__c`,
  `Invoice_Collection__c`, `Revenue__c`, and `Opportunity`
- `Lead` is not only a top-of-funnel object:
  `salesforce_leads.sql`, `dim_lead.sql`, and `dws_lead_timeline.sql` pull in
  `Lead`, `Contact`, `Account`, `Opportunity`, `CampaignMember`, and `Campaign`
- `CampaignMember` affects both marketing attribution and lead chronology:
  it feeds `salesforce_campaign_members`, `salesforce_campaign_attributions`,
  `dws_campaign_attribution`, and `dws_lead_timeline`

Repo-wide downstream consumers from the checked BI repos:

| Object | Real downstream consumers found in repo search | Why this is the practical report blast radius |
|---|---|---|
| `Account` | Looker `crm_account`, `cloud-lead-pipeline-insight`; dbt `salesforce_accounts`, `dim_account`, `dim_tenant`, `dws_icp_summary`, `dws_campaign_attribution`, `dws_campaign_attribution_details`, `dws_opportunity_stage_duration`, `customer_surrogate_keys`, `customers` | Account segmentation / ICP / industry / region and account-to-tenant linkage are reused across marketing, pipeline, and customer identity models, not only account reporting. |
| `Lead` | Looker `salesforce_lead`, `cloud-lead-pipeline-insight`; dbt `salesforce_leads`, `dim_lead`, `dws_lead_timeline`, `dws_icp_summary`, `salesforce_campaign_interacted_accounts` | Lead lifecycle, IQM/MQL stamps, contact conversion, and domain/account linkage drive both top-of-funnel views and downstream attribution logic. |
| `Contact` | dbt `salesforce_contacts`, `salesforce_leads`, `dim_lead`, `salesforce_campaign_interacted_accounts`, `dws_campaign_attribution`, `dws_campaign_attribution_details`, `dws_lead_timeline` | Contact parity problems do not stay isolated to contact records; they distort lead/contact stitching and campaign attribution joins. |
| `Opportunity` | Looker `salesforce_oppo`, `cloud-lead-pipeline-insight`; dbt `salesforce_opportunities`, `dim_opportunity`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration`, `dws_opportunity_stage_conversion_rates`, `dws_data_quality_alerting`, `dws_campaign_attribution`, `dws_campaign_attribution_details`, `dws_icp_summary`, `salesforce_orders` | Opportunity is the center of pipeline, forecast, stage-conversion, ARR summary, marketing attribution, and order-finance handoff. |
| `Quote` | dbt `salesforce_opportunities` via `stg_salesforce_quote`; then downstream `dim_opportunity`, `dws_salesforce_arr_summary`, `dws_opportunity_stage_duration`, `dws_data_quality_alerting`, and any order-derived finance using opportunity commercial semantics | Quote is not exposed as a top-level mart here, but quote status / service dates / discount and support-tier semantics are folded into opportunity analytics and then spread downstream. |
| `Opportunity_Product__c` | dbt `salesforce_opportunity_products`; then `salesforce_opportunities` and its downstream marts | Opportunity line-item dates, product family, quantity, and net fees affect opportunity service dates, product-family metrics, and data-quality checks. |
| `Order` | dbt `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec`; plus FP&A-fed `salesforce_order_current_monthly_arr`, then `dws_salesforce_arr_summary` | Order is the main bridge from CRM commercial state into ARR, deferred revenue, and monthly revrec reporting. |
| `Order_Product__c` | dbt `salesforce_orders`; then `salesforce_order_daily_view`, `cp_order_monthly_revrec`, finance ARR/revrec summaries | Order-line service windows and net fees are used directly to compute order service periods, commitment-plan logic, and recognized/deferred revenue views. |
| `Org__c` | Looker `crm_account`; dbt `salesforce_orgs`, `dim_org`, `dim_tenant`, `salesforce_accounts`, `salesforce_org_monthly_revrec`, `customer_surrogate_keys` | Org is the critical tenant-to-account bridge, so parity issues show up in tenant enrichment, customer identity, and monthly cloud revrec. |
| `Revenue__c` | dbt `salesforce_revrec`; then `salesforce_orders`, `salesforce_order_daily_view`, `cp_order_monthly_revrec`, `salesforce_org_monthly_revrec` | Revenue rows feed recognized revenue history and roll forward into order-level and org-level finance views. |
| `Invoice_Collection__c` | dbt `stg_salesforce_invoice_collection`; then `salesforce_orders` and the finance models built on it | Collections / payable / invoice-status fields land inside order finance logic, so missing automation leaks into collections and billing reporting quickly. |
| `Campaign` / `CampaignMember` | dbt `salesforce_campaigns`, `salesforce_campaign_members`, `salesforce_campaign_interacted_accounts`, `salesforce_campaign_attributions`, `dws_campaign_attribution`, `dws_campaign_attribution_details`, `dws_lead_timeline`, `dws_icp_summary` | First-touch / last-touch, campaign interaction chronology, and attributed ARR/ACV all depend on campaign-member status and first-response maintenance being correct. |
| `Contract` | mostly staging-level today, but `contract_id` is carried through `salesforce_opportunities`, `stg_salesforce_order`, `stg_salesforce_quote`, `stg_salesforce_revenue`, `stg_salesforce_invoice_collection` | Contract is not a headline mart in this repo, but it remains a cross-object governance key across opportunity, quote, order, revenue, and invoice collection records. |

### Gap Classification By Object

If we normalize the matrix into "real CM capability boundary" versus "tenant
parity gap", the picture is:

| Object group | Primary issue type | Current evidence |
|---|---|---|
| `Lead`, `Opportunity`, `Account`, `Order`, `Quote`, `CampaignMember`, `Contact` | Mixed, but mostly migration/parity gaps plus residual Apex boundary | Most missing items are absent Flows or a few Validation Rules in the current pack; the true platform boundary is the live Apex-trigger-only logic still attached to these objects. |
| `Revenue__c` | Both migration gap and real boundary | Missing `Name` auto-number and missing `RevRec_Set_PLG_BD_Pool` Flow are migration gaps; the remaining `RevenueTrigger` dependency is a real CM runtime boundary. |
| `Invoice_Collection__c` | Mostly migration/parity gap | The audited gap is almost entirely missing local auto-number and missing local Flows; this audit did not find object-specific Apex-runtime-only behavior as the main issue. |
| `Opportunity_Product__c`, `Order_Product__c`, `Quote_Product__c` | Both migration gap and real boundary | Missing `Name` auto-number is migration work; trigger-only logic on all three line-item objects is a real CM boundary until rewritten. |
| `Org__c`, `Campaign` | No obvious current platform gap from this audit | Current evidence points to modeled formulas / rollups / matching Flow behavior rather than an obvious unsupported runtime surface. |

So when somebody says "this report line is a CM gap", the safer translation is:

- if it comes from the `Pack parity still missing` column, CM usually has the
  substrate and we still need migration / pack completion
- if it comes from the `Unsupported today` column, that is the genuine CM
  platform/runtime boundary

If we collapse this to the most sensitive report families, the practical order is:

1. pipeline / forecast: `salesforce_opportunities`, `salesforce_oppo`,
   `dws_salesforce_arr_summary`
2. lead funnel / attribution: `salesforce_lead`, `salesforce_leads`,
   `dws_lead_timeline`, `salesforce_campaign_attributions`,
   `dws_campaign_attribution`
3. order / ARR / revrec / collections:
   `salesforce_orders`, `salesforce_order_daily_view`,
   `salesforce_order_current_monthly_arr`, `salesforce_revrec`,
   `salesforce_org_monthly_revrec`
4. account / tenant linkage: `crm_account`, `salesforce_accounts`,
   `salesforce_orgs`

## Practical Conclusion

For the common business objects, the safe assumption is:

- creating the raw row is not enough
- the row becomes report-usable only after defaults, formulas, rollups,
  validations, flows, and triggers have all played their part

So if the current CRM API path is not fully Salesforce-native, the highest-risk
missing fields are not just system timestamps. The most important missing values
will be:

- auto numbers and business document numbers
- stage / forecast / lifecycle helper fields
- account / tenant / partner linkage fields
- pricing / discount / ACV / ARR / TCV / revrec / collections derived fields
- campaign attribution helper fields

## Recommended Next Step

For any parity audit against the current CRM API, prioritize this order:

1. `Lead`
2. `Opportunity`
3. `Account`
4. `Quote`
5. `Order`
6. `CampaignMember`
7. `Org__c`
8. `Revenue__c`
9. `Invoice_Collection__c`

That ordering matches both live automation density and BI/reporting impact.
