fix(renewable): disclose hardcoded fallback data in Renewable Energy panel (#5497)#5521
Conversation
…panel (koala73#5497) fetchRenewableEnergyData() silently substituted a static 2022 World Bank snapshot when the live seed and cache were both unavailable, and RenewableEnergyPanel rendered it with no staleness indicator. This applies the same fix pattern already shipped for the sibling Human Progress panel (koala73#3758). - Add a 'source' provenance field (hydrated | bootstrap | fallback) to RenewableEnergyData, set on every code path in fetchRenewableEnergyDataFresh(). - Skip persisting the static fallback to IndexedDB via shouldCache so the banner clears once the seed/network recovers. - Render a fallback disclosure banner in RenewableEnergyPanel when source === 'fallback', mirroring ProgressChartsPanel. - Add en.json fallbackBadge/fallbackTooltip keys and sync all 24 locales. - Decouple the fresh-fetch path from the EIA client graph (direct circuit-breaker import + lazy economic import) so the service is testable in isolation. - Add regression test covering bootstrap and fallback paths.
|
@HoneyTyagii is attempting to deploy a commit to the World Monitor Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryAdds provenance and a visible disclosure for hardcoded renewable-energy fallback data.
Confidence Score: 3/5The legacy cache compatibility issue should be fixed before merging because upgraded users can still receive undisclosed hardcoded fallback data. The new predicate correctly excludes newly tagged fallback results, but source-less fallback records persisted by the previous release are accepted and rendered without the banner this change is intended to guarantee. src/services/renewable-energy-data.ts Important Files Changed
Reviews (1): Last reviewed commit: "fix(renewable): disclose hardcoded fallb..." | Re-trigger Greptile |
| // swallows errors and returns FALLBACK_DATA, which the breaker would | ||
| // otherwise cache to IndexedDB for the 1h TTL and keep showing the | ||
| // disclosure banner long after the seed/network recovers. | ||
| { shouldCache: (result) => result.source !== 'fallback' }, |
There was a problem hiding this comment.
Legacy fallbacks bypass disclosure
When a returning user has a pre-upgrade IndexedDB entry containing the hardcoded fallback without a source field, this predicate accepts it because undefined !== 'fallback'; the panel then receives the unchanged record and omits the fallback banner, causing the 2022 snapshot to remain undisclosed until the cache expires or a live refresh replaces it.
|
Fixed properly in #5551 |
Summary
Fixes #5497.
fetchRenewableEnergyData()silently substituted a hardcoded 2022 World Bank snapshot (FALLBACK_DATA) whenever the live seed and the local cache were both unavailable, andRenewableEnergyPanelrendered it with nosource/stale/fallbackindicator. Because World Bank renewable data genuinely lags ~2 years, the "29.6%, 2022" figure looked indistinguishable from a live read.This applies the exact fix pattern already shipped for the sibling Human Progress panel (#3758): tag the data with its provenance and disclose the degraded state in the UI.
Changes
source: 'hydrated' | 'bootstrap' | 'fallback'toRenewableEnergyData, set on every code path infetchRenewableEnergyDataFresh()(hydration cache, live bootstrap fetch, static fallback).shouldCache: (r) => r.source !== 'fallback'so the static fallback is never persisted to IndexedDB, matching the progress-data fix. The banner clears once the seed/network recovers.RenewableEnergyPanel.setData()renders arenewable-fallback-banner(role="status") whensource === 'fallback', mirroringProgressChartsPanel's banner.components.renewable.fallbackBadgeandfallbackTooltiptoen.jsonand synced all 24 locale files (npm run sync:locales).createCircuitBreakerfrom the direct@/utils/circuit-breakerpath and lazy-imports the heavy@/services/economicmodule insidefetchEnergyCapacity(), so the World Bank path is testable in isolation (same lean-import approach as the siblingprogress-data.ts).Acceptance criteria
RenewableEnergyDatacarries a provenance field populated on every code path.RenewableEnergyPanelvisibly indicates non-live data whensource === 'fallback', mirroringProgressChartsPanel.Testing
tests/renewable-energy-fallback-disclosure.test.mts(new): 4 passing (bootstrap tag, network-failure fallback, non-OK status fallback, empty-payload fallback).tests/progress-data-fallback-disclosure.test.mts(sibling): still 4 passing.tsc --noEmit: clean.npm run sync:locales:check: all 24 locales match en.json.biome linton changed files: clean.