Plaid v2: turn the approval-level producer ON for the canary diff harness
Flips plaidApprovalLevelV2 for the offline diff harness only, so v2 computes real SBCF_Approval_Level__c values against v1 ground truth — production orgs stay default-OFF.
buildHarnessDryRunQliPayload and the harness replay path, so the canary diff harness now emits real L1–L4 levels instead of 0.
false/undefined. Every non-harness caller is bit-for-bit identical to main. No prod orgs are opted in.
SBCF_Approval_Level__c structural diffs dropped 385 → 176 on the run-13 parity window. Zero engine failures across 30 replayed quotes.
1. Why this exists
PR #5750 shipped a producer that resolves SBCF_Approval_Level__c for each Plaid QLI by comparing its price to per-product L1–L4 ceilings. The producer is fully tested, but gated behind plaidApprovalLevelV2Enabled, which today is OFF for every org.
The canary diff harness replays v1 production quotes through the v2 writeback path and compares the payloads. With the flag off, every harness-produced QLI writes SBCF_Approval_Level__c: 0 — so the entire approval-level field shows as a structural diff against v1.
This PR is the smallest possible change that lets the harness exercise the producer end-to-end without touching real orgs: an opt-in param on buildHarnessDryRunQliPayload, set to true only by the harness script.
2. Architecture: where the wiring lives
The harness reconstructs a PricingQuoteInput from v1 Salesforce rows, but it never builds a real OpportunityV2 or runs the pricing engine. The producer, however, reads its ceilings from output.pricingEngineSummary.byProduct[id].variables.{l1..l4}price — which is empty on the harness path. Walk through the steps to see how this PR closes that loop.
3. The three pieces of the change
Adds two optional params to buildHarnessDryRunQliPayload: plaidApprovalLevelV2Enabled and pricingEngineSummary.
When the flag is on, sets this.plaidApprovalLevelV2Enabled, folds the summary onto fakePricingQuote.output, and calls resolvePlaidApprovalCeilings — mirroring executeWriteBack's setup.
The harness's replayV2QuoteInput now runs PricingEngineSummary.calculateSummary against the reconstructed input, then passes both plaidApprovalLevelV2Enabled: true and the resulting summary into the writeback call.
Uses a supplied canaryPricebookId to avoid needing a real OpportunityV2 row.
570 lines, 9 Mocha + sinon tests covering: flag-ON resolution (L2 and L4 bands), regression guards that flag-omitted is bit-identical to today, source-level assertions that the harness call site plumbs both params, an e2e path with the real resolver, and tier-wiring.
4. Before / after: buildHarnessDryRunQliPayload
const { pricingQuoteInput,
organizationId,
userId = '' } = params;
// ...
const fakePricingQuote = {
// ...
input: pricingQuoteInput,
// output not accessed by Phase 2
output: {} as PricingQuote['output'],
};
const references =
await this.resolvePlaidProductReferences({
pricingQuote: fakePricingQuote, ...
});
Producer flag stays false, ceilings map is never populated, output is {}. Every harness QLI writes 0.
const {
pricingQuoteInput, organizationId, userId = '',
plaidApprovalLevelV2Enabled = false,
pricingEngineSummary,
} = params;
this.plaidApprovalLevelV2Enabled =
!!plaidApprovalLevelV2Enabled;
const fakePricingQuote = {
// ...
output: (pricingEngineSummary
? { pricingEngineSummary }
: {}) as PricingQuote['output'],
};
if (this.plaidApprovalLevelV2Enabled) {
this.plaidApprovalCeilingsByProductId =
this.resolvePlaidApprovalCeilings(fakePricingQuote);
}
When opted in, mirrors executeWriteBack lines ~460–465. Defaults preserve today's behavior.
5. The "Option B" decision: where ceilings come from
The PR description and inline test comments call this out explicitly. There were two ways to get real L1–L4 ceilings into the harness:
| Option | Approach | Verdict |
|---|---|---|
| A (rejected) | Have the harness build a real OpportunityV2 row on the canary org, then go through PricebookController the way production does. |
Heavy. Needs DB writes per replay. |
| B (chosen) | Run PricingEngineSummary.calculateSummary directly against the reconstructed input, with a synthetic opportunity and a supplied canaryPricebookId. Pass the resulting summary into the writeback call. |
The ceiling-variable path (l1..l4price) reads only DataPoints + pricingSpec keyed by (productId, pricebookId, tier) — opportunityV2Data is not load-bearing. |
The synthetic opportunity in replayV2QuoteInput uses id: '__harness_synthetic__' and an empty custom: {} map — explicitly fine because the producer never reads it.
6. Failure handling
getPricingSpec, getDataSheet, the pricebook lookup, or calculateSummary throws, the catch block logs a warning and leaves pricingEngineSummary as undefined. buildHarnessDryRunQliPayload then sees an empty output: {}, ceilings resolve to an empty map, and the producer returns level 0 for every QLI on that quote. Per-quote replay_failure plumbing is untouched — one bad quote does not abort the canary run.
7. Canary results on the run-13 parity window
Spot-checks confirm the remaining "v2 = 0" lines are legitimate ramped resolutions, not silent fallback. The ~94% residual is v1 omitting SBCF_Approval_Level__c on multidim/segmented lines while v2 emits a value — tracked separately, mirroring the carve-out from #5755.
8. Tests, in detail
| Test | Asserts |
|---|---|
| flag ON → level 2 (flat, price 700) | Producer resolves price 700 against {l1:1000, l2:800, l3:600, l4:400} as level 2. |
| flag ON → level 4 (flat, price 300) | Below the deepest ceiling resolves to L4. |
| flag OMITTED → level 0 | Regression guard: default path is bit-identical to main. |
flag ON → resolvePlaidApprovalCeilings invoked | Verifies the ceilings map gets populated before the producer runs. |
| flag OMITTED → resolver NOT invoked | Off-path regression guard. |
harness source: plaidApprovalLevelV2Enabled: true | Source-level regex check on runPlaidDiffHarness.ts. |
harness source: calculateSummary + pricingEngineSummary plumbed | Catches the "param accepted but never propagated" regression class. |
| e2e: real resolver + injected summary → level 2 | Closes the false-green gap a naive wiring would sail through. |
| e2e: tiered product → tier child QLIs carry correct levels | Tier-1 (price 750) → L2; Tier-2 (price 300) → L4. |
Note: replayV2QuoteInput is module-private and the live path does real SF/engine reads, so its contract is pinned with source-string regex checks — same pattern as the beadops-bvv.2 test in PlaidWriteBack.mm.test.ts.
9. What this doesn't change
- Prod orgs:
plaidApprovalLevelV2.enabledOrgsstays empty. No real org sees the producer. - The producer itself —
resolvePlaidApprovalLevelForQliandcomputePlaidApprovalLevel— landed in #5750 and is not modified. executeWriteBack(the production writeback entry point) is untouched.- Per-quote
replay_failureplumbing in the harness. - The smart-approval cutover, which remains the gating event for real-org rollout.
- Non-harness callers of
buildHarnessDryRunQliPayload: both new params default such that behavior is bit-for-bit identical tomain.
10. Risk & follow-ups
PlaidWriteBack.approvalLevel.test.ts; this PR only pins the wiring.
- Multidim / segmented-line cosmetic v1-parity bucket — carve-out mirroring #5755.
- A small flat-line resolution discrepancy on the Assets product family.
- Real-org rollout remains gated on the smart-approval cutover.