docs(marketing): campaign metrics are live, not snapshotted at completion - #1695
Merged
Merged
Conversation
…tion The campaign metric block has been kept live by four refresh hooks since #597, but two customer-facing marketing pages still described the retired completion-time snapshot as current behaviour. A reader following them would expect an in-progress campaign to report zeros, and would therefore distrust the live dashboard numbers. Corrected across all three locale faces (en, zh-Hans, zh-Hant): - campaigns.mdx status table: "metrics are final, ROI is calculated" — both halves stale. A completed campaign's numbers still move, and `roi` is a formula over actual_cost/actual_revenue evaluated on read. - campaigns.mdx auto-complete bullet: the 2 AM sweep flips the status only. - index.mdx lifecycle step 4: "metrics are snapshotted". Each page now states the live behaviour positively in its own bullet rather than only dropping the false claim, so the reader ends up trusting numbers that are in fact usable right now. The status-table row contained no occurrence of "snapshot" — it is why the originating audit saw two lines instead of three, and it was found by searching the behaviour description rather than the identifier. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018xtjdpZFjgWh4Ad9Wcx68J
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
os-steve
marked this pull request as ready for review
September 6, 2026 11:26
This was referenced Sep 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1691
Two customer-facing marketing pages still described the completion-time metric snapshot that #597 retired. The metric block is kept live by four refresh hooks —
campaign_metrics_refresh,campaign_attribution_refresh,campaign_lead_conversion_refresh(campaign.hook.ts) andcampaign_member_metrics_refresh(campaign_member.hook.ts) — so the numbers move as members are enrolled, as members respond, as their leads convert and as opportunities are attributed. Completion is one morestatustransition over numbers that were already current, exactly ascampaign-completion.flow.ts's header has said since #1668 / PR #1690, which is the wording reference this PR follows.The harm, and the acceptance bar
The defect was directional, not merely factual. A reader following these pages would expect an in-progress campaign to report zeros, and would therefore distrust the live dashboard numbers — the docs talked them out of a feature that works. So every page now states the live behaviour positively in its own bullet rather than only dropping the false claim. The reader finishes knowing the numbers are usable right now, and also knowing what completion does do (it flips the status), so that step does not read as if nothing happens.
Three stale lines per locale face, not two
marketing/campaigns.mdxmarketing/campaigns.mdxmarketing/index.mdxThe status-table row was wrong in both halves: metrics are not final (a completed campaign's numbers still move — enrolling a member into one is precisely the case
flow-campaign-enrollmentguards against), androiis a formula overactual_cost/actual_revenue, evaluated on read. It is never "calculated" at a moment; it has always had a value.⭐ The difference set — reported as the card requires
Search A (identifier/keyword,
snapshot|快照acrosscontent/docs) — 63 files. Every non-marketing hit was classified and none is this defect, so nothing was over-deleted:sales/forecasting(a forecast genuinely is a frozen snapshot — a real, current feature),analytics/cubes(says nothing snapshots the pipeline),analytics/dashboards(reads forecast snapshots),marketplace/*(immutablesys_package_version),customization/testing-and-ci(vitesttoMatchSnapshot),ai-copilot/*("Account Snapshot" as a section name;sales-copilotexplicitly says "not a cached snapshot"),administration/*,service/index,guides/import-and-export,reference/security-and-compliance. In scope, Search A findscampaigns.mdx:58andindex.mdx:29(×3 faces).Search B (behaviour description) —
final metrics·at that moment·when/once the campaign completes·metrics are (final|frozen|locked)·at completion·no longer change·stops updating, and the Chinese equivalents 完成时 · 最终指标 · 指标最终确定 · 定格 · 冻结 · 不再变化.B \ A is NOT empty:
campaigns.mdx:16× 3 faces. "metrics are final, ROI is calculated" carries the retired model and contains no occurrence ofsnapshot. This is the card's own lesson reproduced one level down: a keyword search finds the bullet at line 58 and stops 42 lines short of the same claim on the same page. An auditor working from the identifier would have fixed line 58 and left the status table telling readers the numbers are final. Notably even a proximity search (campaignwithin 120 chars of a finality word) misses it, because the table row never says "campaign" — only the un-anchored phrase search reached it.A \ B in scope is empty — no other page carries this defect.
Checks the dispatch asked for
docs-*test asserts these sentences;grepfor every fragment acrosstest/andscripts/returns nothing.docs-view-rostersdoes readcampaigns.mdx, but only its Standard list views roster section.automation-docs-coveragereadsadministration/automation.mdxonly.docs-metadata-countswalks every.mdxbut matches digit-form counts of objects/flows/dashboards/datasets/actions/positions — the new prose states no count. Nothing went red; no assertion was touched.campaign-members.mdx(×3) — checked, needed nothing. It already said the campaign-level metrics are "always live" / 「始终是实时的」/「始終是即時的」, so the two corrected pages had been contradicting their own sibling page. Its register is the vocabulary these fixes adopt.test/flow-campaign-enrollment.test.ts:121— read, deliberately NOT changed. Reasoning below.content/docs/releases/untouched. Surface stayed insidecontent/docs/marketing/**; no overlap with Retirecrm_case.customer_rating/customer_feedbackunder ADR-0049, and retire or rewritecase_csat_followupwith them (ruled A, 2026-09-03; theinternal_noteshalf landed in PR #1506) #1428 or [finding] ~25 form fields author an absolutecolSpan, andobjectstack validatewarns every one of them #1524.Why the third candidate was left alone
The comment reads "Enrolling into a finished campaign corrupts its final snapshot metrics." Its operative claim is true, and true only because of the live model: under the retired snapshot the metric block was written once on
→ completed, so a late enrolment could not have disturbed it. It is the live refresh (campaign_member_metrics_refreshfiring on member insert) that makes a late enrolment move a completed campaign's numbers at all — which is exactly the harm the guard prevents. Only the two words "final snapshot" carry the old vocabulary; the sentence is not misinforming anyone.It is also an internal test rationale, not published documentation, so it cannot produce this card's harm — no reader is talked out of trusting the dashboard by it. Changing it would widen a docs card's diff into
test/for a vocabulary preference. Left as-is, per the card's own "worth a read, not asserted as wrong" and the PM's "read it and decide". Not filed as a separate issue either: #1691 already records it, and a new card would duplicate that text.Verification
pnpm verifyfully green at7c9af2e5— all eight stages ran (validate→typecheck→lint→lint:i18n-gate→hygiene→hygiene:tokens→build→test):All three locale faces were written, not machine-translated, reusing the vocabulary already on these pages (发送/响应/转化 · 傳送/回應/轉化, 线索 · 潛在客戶) and the 实时 / 即時 register
campaign-membersestablished. One changeset (patch).Generated by Claude Code