fix(gooddata-widget): AI Credits dashboard display, labeling, and scale fixes - #227
Open
goodbounties-nanoclaw-agent[bot] wants to merge 12 commits into
Open
fix(gooddata-widget): AI Credits dashboard display, labeling, and scale fixes#227goodbounties-nanoclaw-agent[bot] wants to merge 12 commits into
goodbounties-nanoclaw-agent[bot] wants to merge 12 commits into
Conversation
Adds an optional subLabel? prop rendered as a dim caption line below the value row, reusing the trend row's spacing tier. Needed by the AI Credits dashboard's "Total Credits Bought in G$" scorecard to show a streaming/subscription breakdown line (#222), but kept generic in packages/ui since it's a reusable KPI-card capability, not AI-Credits specific. Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
…om 365 to 30 days A full year of daily points was an unnecessary perf hit for a dashboard that only visualizes the trailing month. Per #222 (fix 6). Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
…ts (USD) column .toFixed(2) rounded most rows' sub-cent daily AI Credit usage to $0.00. Per #222 (fix 5). Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
…monthly total Replaces flowRateToDaily with flowRateToMonthly (plain multiplication by 2629746 seconds/month, mirroring the existing BigInt-safe reduction) and relabels "G$ Flow Rate" -> "Total Monthly Subscriptions", dropping the "/day" suffix that read as a daily rate. Per #222 (fix 3). Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
…USD equivalent Relabels the first AI Credits scorecard from "Total G$ Spent" to "Total Credits Bought in G$" and appends the USD-equivalent value (already computed for the separate "AI Credits Used" card) as a suffix, per CEO feedback after the PR #179 production deploy (#222, fix 1). Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
…ine on total scorecard Adds a "out of X G$ in subscription (streaming)" caption under the first scorecard's value, using the already-computed streamed total, so the breakdown between one-time and recurring credit purchases is visible at a glance (#222, fix 2). Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
…ility + cover scorecard label fixes Fix #4 investigation: the G$ Volume chart's secondaryYAxis mechanism (in LineAreaChart, present since #179) already computes each axis's scale independently from only its own series' values, so a large magnitude gap between one-time deposits and streamed G$ doesn't flatten the streamed line. Confirmed this against a fixture shaped after real production data pulled from the live AntSeed Worker (sparse deposit spikes up to ~40x the streamed band) — both lines render clearly distinguishable on their own axes. No LineAreaChart or dashboard code change was needed; the deliverable is the new "RealisticVolume" QA fixture plus a Playwright assertion so this stays covered going forward instead of relying on the smooth demo/live ramp. Also retrofits the live-state spec with text assertions for fixes #1-#3's renamed scorecard labels and sub-line, which had been verified visually but not covered by the Playwright spec, and refreshes all baseline screenshots to reflect the new label copy. Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
goodbounties-nanoclaw-agent
Bot
requested review from
a team and
L03TJ3
and
a lite review from Copilot
August 31, 2026 21:21
Contributor
There was a problem hiding this comment.
Pull request overview
Updates the GoodData widget’s AI Credits dashboard to improve labeling, value presentation, and scale/legibility under realistic production-like data, and tightens the default analytics fetch window.
Changes:
- Renames/retunes dashboard scorecards (adds USD equivalent + subscription sub-line; switches flow-rate to monthly subscriptions via a new conversion).
- Improves daily table USD precision (3 decimals) and reduces analytics fetch window to 30 days.
- Adds a production-shaped Storybook fixture plus a Playwright regression test targeting dual-axis volume-chart legibility.
Reviewed changes
Copilot reviewed 7 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/widgets/gooddata-widget/states.spec.ts | Adds assertions for updated scorecard copy and a new “realistic volume” chart regression check. |
| packages/ui/src/components/Scorecard.tsx | Adds subLabel support to render a caption line under the value row. |
| packages/gooddata-widget/src/dashboards/aiCredits/connector.ts | Reduces default analytics history window from 365 days to 30 days. |
| packages/gooddata-widget/src/dashboards/aiCredits/analyticsConversions.ts | Introduces flowRateToMonthly() conversion using average seconds per month. |
| packages/gooddata-widget/src/dashboards/aiCredits/AiCreditsDashboard.tsx | Applies updated scorecard labels/values, monthly conversion, and 3-decimal USD formatting. |
| examples/storybook/src/stories/helpers/goodDataWidgetStories.tsx | Adds a realistic 30-day analytics fixture and story wrapper for QA/regression coverage. |
| examples/storybook/src/stories/gooddata-widget/GoodDataWidgetQA.stories.tsx | Exposes the new “RealisticVolume” QA story. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+127
to
+136
| global: { | ||
| gdOneTimeDepositsWei: String( | ||
| REALISTIC_VOLUME_DAILY.reduce((sum, day) => sum + BigInt(day.gdOneTimeDepositsWei), 0n), | ||
| ), | ||
| gdStreamedWei: REALISTIC_VOLUME_DAILY[REALISTIC_VOLUME_DAILY.length - 1].gdStreamedWei, | ||
| aiCreditsUsedWei: String( | ||
| REALISTIC_VOLUME_DAILY.reduce((sum, day) => sum + BigInt(day.aiCreditsUsedWei), 0n), | ||
| ), | ||
| gdTotalFlowRateWeiPerSecond: REALISTIC_VOLUME_DAILY[REALISTIC_VOLUME_DAILY.length - 1].gdTotalFlowRateWeiPerSecond, | ||
| updatedAt: `${REALISTIC_VOLUME_DAILY[REALISTIC_VOLUME_DAILY.length - 1].date}T23:59:59.999Z`, |
Comment on lines
+108
to
+111
| // The rotated axis title can wrap onto two lines (each its own text node), so | ||
| // match the distinctive word rather than the full label string. | ||
| await expect(volumeChart.getByText('Deposits', { exact: false }).first()).toBeVisible() | ||
| await expect(volumeChart.getByText('Streamed', { exact: false }).first()).toBeVisible() |
…rd for flow rate, flag USD-deposit gap Total Monthly Subscriptions showed G$0.00 in the live preview because the flow-rate scorecard read global.gdTotalFlowRateWeiPerSecond directly, which mirrors the Worker's most recent daily record even when that record is today's still-accumulating, missing:true snapshot — right after a day boundary this reads as 0 until the new day's first streaming event lands. Reuse dailyRecords (already filtered to exclude missing:true records for the chart/table) so the scorecard reads the same latest-complete-day value. Also fixes Scorecard 1's USD line incorrectly reusing aiCreditsUsedWei (a different metric, "AI credits consumed") instead of the USD equivalent of the deposited/bought G$ total. The Worker's schema exposes no G$/USD exchange rate to compute that client-side, so per explicit request the USD line stays (not removed) but now reads as a labeled data-source-gap placeholder pending a rate field from the data team. Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
…oss from wei-space truncation generateDemoData's per-day flow rate divided streamedGd (a plain integer, 200-800) by SECONDS_PER_DAY before scaling to wei, which always floors to exactly 0 for that range. Do the division after scaling to wei so the fractional per-second rate survives instead of being truncated away first. This is a separate root cause from the live-data flow-rate bug fixed separately (that one reads a stale/missing daily record; this one is pure integer-division precision loss) — fixing one does not fix the other. Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
…m and scope dual-axis test to svg RealisticVolume fixture's global.gdStreamedWei used only the last day's value instead of summing the window, breaking the "out of X G$ in subscription" figure for that fixture (Copilot review on #227). The dual-axis Playwright test matched "Deposits"/"Streamed" text anywhere in the chart container, which could pass via the legend (rendered as a sibling YStack outside the chart's <svg>) even if the axis titles themselves were broken. Scope the lookup to the chart's own <svg> so the test actually guards axis-title legibility, which is its stated purpose. Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
…r bugfix round Regenerated after fixing the flow-rate/USD-line bugs and the two Copilot-flagged test/fixture issues. Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
…rate for deposited-total USD line Per Thales's call: replace the "(USD rate pending)" placeholder with an actual estimate, computed as totalGdSpent * TEMP_GD_USD_RATE (0.00013), until the Worker exposes a live rate. Kept clearly marked as temporary in a code comment so it's easy to find and swap out — Thales is following up with Mike/Hadar on a real rate field. Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
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 #222. Implements the plan from #224.
Fixes
weiToUsd(data.global.aiCreditsUsedWei).weiToGd(data.global.gdStreamedWei).flowRateToMonthly()conversion helper instead of the old daily rate./v1/analytics) and tracingLineAreaChart's dual-axis scaling code directly. ThesecondaryYAxismechanism has computed each axis independently since the original feat(apps): AI Credits analytics data widget #179 PR and already renders both series legibly, including at the ~40x deposit-vs-streamed magnitude disparity seen in real production data — no functional bug found, so no code change was needed here. Added a newRealisticVolumeStorybook QA fixture shaped after that real data plus a Playwright regression test asserting both axis labels stay visible, so this is guarded going forward instead of only being covered by the smooth demo/live ramp fixture..toFixed(2)→.toFixed(3).ANALYTICS_DAYS_REQUESTED: 365 → 30 inconnector.ts.The same commit (150ddd0) also retrofits
tests/widgets/gooddata-widget/states.spec.tswith text assertions covering fixes #1-#3's renamed labels/sub-line (previously verified only visually, not by the committed spec) and refreshes all baseline screenshots for the new copy, per repo convention.Out of scope, flagging rather than fixing here
While tracing the flow-rate conversion, found
generateDemoData.ts's demo-mode flow rate is computed asMath.floor(streamedGd / SECONDS_PER_DAY), which floors to0for any realistic demostreamedGdvalue — so demo mode'sgdTotalFlowRateWeiPerSecondis always"0". Not one of #222's 6 acceptance criteria and not touched by this PR; flagging so it can be tracked as its own fix rather than silently left in place.Verified
Each fix above was committed individually and visually verified via Storybook + Playwright before moving to the next, per the process used for the #179 rounds. Full pipeline (
pnpm build, scopedlint,npx playwright test tests/widgets/gooddata-widget/states.spec.ts) passes.Note on commit signatures: commits on this branch show as unsigned (neither the Git Data API nor the Contents API produce GPG/SSH-signed commits in this environment — confirmed empirically). This repo's ruleset requires signed commits on
main. Squash-merging this PR is safe (GitHub signs the resulting squash commit itself, independent of source-branch signatures) — please don't rebase-merge, which would carry the unsigned commits ontomaindirectly.Co-Authored-By: Claude noreply@anthropic.com