fix(dashboards): stop rendering failed requests as measured zeros - #1333
fix(dashboards): stop rendering failed requests as measured zeros#1333mrautela365 wants to merge 2 commits into
Conversation
The ED Overview Paid Media and Attribution cards rendered $0 spend, 0 impressions, 0.0x ROAS and $0 won revenue whenever their request failed. Those zeros were fabricated by error fallbacks, not measured: all-zeros was an ambiguous sentinel encoding both "query failed" and "genuinely zero", and both rendered identically as a factual figure. Snowflake returns 52.4M impressions, $456K spend and $28.5M won revenue for the same umbrella window the UI reported as zero. - analytics.service.ts: drop the zero-filled catchError from getSocialReach and getRevenueImpact so failures reach the caller. All five consumers already handle the error stream. - project.service.ts: getSocialReach rethrows instead of returning defaults, so the failure is observable as a non-200 rather than a 200 carrying zeros. getRevenueImpact already rethrew. - analytics-data.interface.ts: type paidCampaign and revenueImpact as nullable on EdEvolutionData, mirroring the education card. - dashboard-metrics.constants.ts: render undefined as an explicit "data unavailable" state — em-dash values, no sparkline, no trend pill — rather than suppressing the card, which in a fixed carousel would read as a layout bug. The drill-down drawers keep their non-nullable inputs and take a placeholder; they refetch their own detail data and are only reachable by explicit click, so they never present it as a measured figure. LFXV2-3005 Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
PR SummaryMedium Risk Overview End-to-end behavior: Reviewed by Cursor Bugbot for commit 044fb27. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit b3b4753. Configure here.
There was a problem hiding this comment.
Pull request overview
Prevents failed ED dashboard analytics requests from appearing as measured zeros.
Changes:
- Propagates social-reach and revenue-impact errors.
- Models failed card data as
undefined. - Renders explicit unavailable card states.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
analytics-data.interface.ts |
Allows failed metrics to be undefined. |
dashboard-metrics.constants.ts |
Builds unavailable card states. |
project.service.ts |
Rethrows social-reach failures. |
analytics.service.ts |
Removes zero-filled client fallbacks. |
marketing-overview.component.ts |
Maps request failures to unavailable data. |
Paid Media and Attribution announced "Data unavailable — could not be loaded" during the initial in-flight window, before any request had failed. EMPTY_ED_EVOLUTION_DATA was passed as both toSignal's initialValue and safe()'s per-call error fallback, so the undefined paidCampaign and revenueImpact that encode "the request failed" were also the values present while the requests were still pending. - marketing-overview.component.ts: add PENDING_ED_EVOLUTION_DATA as a distinct initial value, so the error object no longer doubles as the loading state. - analytics-data.interface.ts: add the optional pending marker that separates "not answered yet" from "answered with a failure". - dashboard-metrics.constants.ts: caption the placeholder as "Loading…" while pending and keep "could not be loaded" for a real failure. Both still render em-dash values with no sparkline or trend pill, so neither is mistakable for a measured zero. Reported by cursor and copilot-pull-request-reviewer on PR #1333. LFXV2-3005 Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Suppressed comments (1)
apps/lfx-one/src/server/services/project.service.ts:3228
- The new failure contract has no regression coverage:
project.service.spec.tstests otherProjectServicemethods but has nogetSocialReachcase. Add a test that makes the Snowflake query reject and assertsgetSocialReachrejects with that error; otherwise the zero-filled fallback this PR removes can be reintroduced without a failing test.
throw error;

Summary
The ED Overview Paid Media and Attribution cards rendered
$0spend,0impressions,0.0xROAS and$0won revenue whenever their request failed. Those zeros were fabricated by error fallbacks, not measured.All-zeros was an ambiguous sentinel encoding both "the query failed" and "genuinely zero" — and both rendered identically, as a factual figure. Snowflake returns 52.4M impressions, $456K spend and $28.5M won revenue for the same umbrella window the UI was reporting as zero.
This PR removes the zero-filled fallbacks so a failure is observable as a failure, and renders an explicit "data unavailable" state instead of an invented number.
Changes
analytics.service.tscatchErrorfromgetSocialReachandgetRevenueImpactso failures reach the caller. All five consumers already handle the error stream.project.service.tsgetSocialReachrethrows instead of returning defaults, so the failure surfaces as a non-200 rather than a 200 carrying zeros.getRevenueImpactalready rethrew.analytics-data.interface.tspaidCampaignandrevenueImpactas nullable onEdEvolutionData, mirroring the education card.dashboard-metrics.constants.tsundefinedas an explicit unavailable state — em-dash values, no sparkline, no trend pill.marketing-overview.component.tsWhy "data unavailable" rather than hiding the card
These cards sit in a fixed carousel. Suppressing one on error would read as a layout bug, so the card stays in place and states plainly that the figure could not be loaded.
Why the drawers keep non-nullable inputs
The drill-down drawers take a placeholder and keep their non-nullable inputs. They refetch their own detail data and are only reachable by explicit click, so they never present the placeholder as a measured figure.
Testing
./check-headers.sh— passed (1919 files)yarn format:check— passedyarn lint:check— 0 errors (1 pre-existing warning incampaigns.component.ts, untouched by this branch)yarn build— passed, SSR bundle generatedNot verified: the rendered card states were not visually confirmed on local. The ED dashboard was brought up and the
social-reach/revenue-impact/email-ctrendpoints returned clean 200s against Snowflake with no errors, but no one eyeballed whether the cards display real figures, the em-dash unavailable state, or$0. Worth a look during review.Notes
main. Test-merged clean —dashboard-metrics.constants.tsis touched by both, but in different regions (main changed the import block; this PR changes metric definitions).LFXV2-3005