Skip to content

fix(gooddata-widget): AI Credits dashboard display, labeling, and scale fixes - #227

Open
goodbounties-nanoclaw-agent[bot] wants to merge 13 commits into
mainfrom
feat/ai-credits-dashboard-fixes-222
Open

goodbounties-nanoclaw-agent[bot] wants to merge 13 commits into
mainfrom
feat/ai-credits-dashboard-fixes-222

Conversation

@goodbounties-nanoclaw-agent

Copy link
Copy Markdown
Contributor

Closes #222. Implements the plan from #224.

Fixes

  1. Total scorecard rename + USD equivalent (8ac9e4b) — "AI Credits Used" → "Total Credits Bought in G$", now shows the USD equivalent via weiToUsd(data.global.aiCreditsUsedWei).
  2. Subscription sub-line (3653fb7) — adds "out of X G$ in subscription (streaming)" under the total scorecard via weiToGd(data.global.gdStreamedWei).
  3. Flow-rate scorecard rename (7d1bb8e) — "G$ Flow Rate" (per-day) → "Total Monthly Subscriptions", backed by a new flowRateToMonthly() conversion helper instead of the old daily rate.
  4. G$ Volume chart streamed-line legibility (150ddd0) — investigated by pulling real production data from the live AntSeed Worker (/v1/analytics) and tracing LineAreaChart's dual-axis scaling code directly. The secondaryYAxis mechanism 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 new RealisticVolume Storybook 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.
  5. Daily table USD precision (713da80) — "AI Credits (USD)" column: .toFixed(2) → .toFixed(3).
  6. Analytics fetch window (00f1ae9) — ANALYTICS_DAYS_REQUESTED: 365 → 30 in connector.ts.

The same commit (150ddd0) also retrofits tests/widgets/gooddata-widget/states.spec.ts with 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 as Math.floor(streamedGd / SECONDS_PER_DAY), which floors to 0 for any realistic demo streamedGd value — so demo mode's gdTotalFlowRateWeiPerSecond is 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, scoped lint, 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 onto main directly.

Co-Authored-By: Claude noreply@anthropic.com

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)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

…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)
@thalescb

Copy link
Copy Markdown
Collaborator

@copilot Please work on this PR's existing branch and push your changes here. Do not open a new pull request.
Merge main into this branch and resolve the 5 conflicts:

packages/ui/src/components/Scorecard.tsx: keep main's version, which has the subtitle prop from #228. Remove this PR's subLabel prop.
packages/gooddata-widget/src/dashboards/aiCredits/AiCreditsDashboard.tsx: change the Scorecard subLabel= to subtitle=.
Regenerate the 4 conflicting screenshots in tests/widgets/gooddata-widget/test-results/ (gdw-02 to gdw-05). Make no other changes. Then run the checks and list the files you changed and any failing tests. For each failing test, say whether this PR caused it or it already fails on main (for example the live Celo RPC test in #268).

…oard-fixes-222

# Conflicts:
#	packages/ui/src/components/Scorecard.tsx
#	tests/widgets/gooddata-widget/test-results/gdw-02-live.png
#	tests/widgets/gooddata-widget/test-results/gdw-03-demo.png
#	tests/widgets/gooddata-widget/test-results/gdw-04-live-unavailable.png
#	tests/widgets/gooddata-widget/test-results/gdw-05-empty.png

Co-authored-by: thalescb <8635591+thalescb@users.noreply.github.com>

Copilot AI commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

@copilot Please work on this PR's existing branch and push your changes here. Do not open a new pull request.
Merge main into this branch and resolve the 5 conflicts:

...

Pushed merge commit 24ba2ad to this existing branch. Main’s Scorecard is preserved byte-for-byte; the dashboard uses subtitle. No additional task-specific changes.

Resolution files:

  • /home/runner/work/GoodWidget/GoodWidget/packages/ui/src/components/Scorecard.tsx
  • /home/runner/work/GoodWidget/GoodWidget/packages/gooddata-widget/src/dashboards/aiCredits/AiCreditsDashboard.tsx
  • /home/runner/work/GoodWidget/GoodWidget/tests/widgets/gooddata-widget/test-results/gdw-02-live.png
  • /home/runner/work/GoodWidget/GoodWidget/tests/widgets/gooddata-widget/test-results/gdw-03-demo.png
  • /home/runner/work/GoodWidget/GoodWidget/tests/widgets/gooddata-widget/test-results/gdw-04-live-unavailable.png
  • /home/runner/work/GoodWidget/GoodWidget/tests/widgets/gooddata-widget/test-results/gdw-05-empty.png

Passed: workspace build, 17 unit tests, affected-package lint, all 6 GoodData smoke tests, Scorecard subtitle smoke test, secret scan, focused review, and CodeQL (0 alerts).

Remaining failures, both reproduced against isolated main sources and not caused by this PR:

  • Root lint: unused ProfileTextAreaField import in /home/runner/work/GoodWidget/GoodWidget/packages/governance-widget/src/onboarding/steps/ProfileStepContent.tsx:5.
  • CitizenClaimWidget shows not_whitelisted for fresh wallet (live Celo RPC): 30-second timeout; main also timed out in 1 of 3 repeat runs (2 passed).

Working tree is clean. No new PR was opened.

@thalescb

Copy link
Copy Markdown
Collaborator

Conflicts with main are resolved in 24ba2ad. The dashboard now uses the Scorecard subtitle prop from #228, and Scorecard.tsx matches main. Two checks fail, both on main too: the live Celo RPC test (#268) and root lint (#270). Ready for review @L03TJ3

@sirpy

sirpy commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

@thalescb there are two unresolved comments and if there are failing tests they should be fixed before asking for review

@thalescb

Copy link
Copy Markdown
Collaborator

@copilot Please work on this PR's existing branch and push your changes here. Do not open a new pull request.
Fix the two open review comments:

examples/storybook/src/stories/helpers/goodDataWidgetStories.tsx: set global.gdStreamedWei to the total streamed over the whole fixture window, the same way generateDemoData() and FIXED_ANALYTICS_RESPONSE compute it, so the "out of X G$ in subscription" line is right in the RealisticVolume story.
tests/widgets/gooddata-widget/states.spec.ts: scope the "Deposits" and "Streamed" axis-title assertions to the chart's svg, so the legend text can't make them pass. Make no other changes. Then run the checks and list the files you changed.

Copilot AI commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

@copilot Please work on this PR's existing branch and push your changes here. Do not open a new pull request.
Fix the two open review comments:

...

Both requested fixes are already committed in 1b1e078 and remain present at this branch’s HEAD (24ba2ad):

  • /home/runner/work/GoodWidget/GoodWidget/examples/storybook/src/stories/helpers/goodDataWidgetStories.tsx:131–133 sums streamed wei across the entire fixture window using BigInt.
  • /home/runner/work/GoodWidget/GoodWidget/tests/widgets/gooddata-widget/states.spec.ts:112–116 scopes both axis-title assertions to the chart’s svg.

Rechecked: targeted build passed (4 tasks), widget lint passed, and all 6 GoodData Playwright tests passed. Explicit lint of the two files reports an existing unused index parameter in the Storybook helper at line 110; left unchanged per scope.

Files changed this round: none. Generated screenshots were restored; working tree is clean. No new commit, push, or PR was necessary.

@thalescb

Copy link
Copy Markdown
Collaborator

@L03TJ3 ready for review. The two review comments were already fixed in 1b1e078 (Sep 1), threads are resolved now. The PR's checks are green. The two failures from the earlier local run fail on main too: the live Celo RPC test (#268, fix in #269) and root lint (#270, fix in #271)

@thalescb
thalescb removed their request for review October 26, 2026 13:58
@L03TJ3

L03TJ3 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

@sirpy just for the record that it was explicitely requested that any pre-existing failing tests are resolved separately
only tests failing due to changes from the current PR should be resolved within the same PR

This branch was successfully deployed

4 active (2 outdated) and 1 inactive deployments
preview-gooddata — 24ba2adf Deployed Oct 25, 2026 by Copilot via gooddata-web-preview #136
preview-storybook — 24ba2adf Deployed Oct 25, 2026 by Copilot via preview #475
internal — 24ba2adf Deployed Oct 25, 2026 by Copilot via authorize-preview #475
preview-superfluid-campaign — 0f3f5a74 Deployed Sep 1, 2026 by goodbounties-nanoclaw-agent[bot] via preview #158
preview-ai-credits — 0f3f5a74 Deployed Sep 1, 2026 by goodbounties-nanoclaw-agent[bot] via preview #301
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] AI Credits dashboard: display, labeling, and scale fixes

5 participants