Skip to content

fix(dashboard): call the Active Commitments figure estimated savings - #1716

Merged
cristim merged 1 commit into
mainfrom
fix/issue-1709-committed-label
Nov 4, 2026
Merged

cristim merged 1 commit into
mainfrom
fix/issue-1709-committed-label

Conversation

@cristim

@cristim cristim commented Nov 4, 2026

Copy link
Copy Markdown
Member

Summary

The Home Active Commitments card read "$X/mo committed". committed_monthly is built in calculateCommitmentMetrics (internal/api/handler_dashboard.go) from aggregateActiveCommitmentsPerService, which sums each active purchase's EstimatedSavings. That is monthly savings, not the monthly cost of the commitments.

  • The card detail now reads "$X/mo estimated savings" (frontend/src/dashboard.ts).
  • The committed_monthly field keeps its name, because renaming it would break existing API clients. Its Go doc comment (internal/api/types.go) and its OpenAPI description (internal/api/openapi.yaml) now say what it holds.

The issue's other option, showing actual committed spend (amortized upfront plus recurring), would need a new backend figure. I left it out because no caller needs it yet.

This sits next to #1707's YTD caption change in the same tile list, so whichever merges second needs a one-line rebase.

Tests

  • New jest test: the Active Commitments tile shows "$500/mo estimated savings" and not "committed". It fails on main (received "$500/mo committed").
  • Locally: npm test (4715 passed, 1 skipped), npm run lint (0 errors), npm run build, and go test ./internal/api/ -run "OpenAPI|Openapi|Dashboard" pass.

Closes #1709

🤖 Generated with Claude Code

The Active Commitments card showed "$X/mo committed", but
committed_monthly is the sum of the active commitments' EstimatedSavings
(calculateCommitmentMetrics in handler_dashboard.go): monthly savings, not
what the commitments cost. The card now says "$X/mo estimated savings".

The API field keeps its name so existing API clients don't break; its Go
doc comment and OpenAPI description now say what it holds.

Closes #1709

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cristim cristim added priority/p2 Backlog-worthy severity/medium Moderate harm urgency/this-quarter Within the quarter impact/many Affects most users effort/s Hours type/bug Defect triaged Item has been triaged labels Nov 4, 2026
@cristim

cristim commented Nov 4, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 25 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between b3a6b30 and 96c7659.

Files selected for processing: 4
  • frontend/src/__tests__/dashboard.test.ts
  • frontend/src/dashboard.ts
  • internal/api/openapi.yaml
  • internal/api/types.go
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor
Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim

cristim commented Nov 4, 2026

Copy link
Copy Markdown
Member Author

Independent review (claude-qa-ui-4, cold): APPROVED 96c7659

The label matches what the field holds. Trace from storage to the card:

  • A purchase writes purchase_history.estimated_savings from the recommendation's Savings (internal/purchase/execution.go:1025-1040, EstimatedSavings: rec.Savings). The column is in monthly units (internal/api/handler_dashboard.go:707).
  • fetchCommitmentPurchases loads those rows; aggregateActiveCommitmentsPerService sums EstimatedSavings per service over active commitments (handler_dashboard.go:640-650); calculateCommitmentMetrics sums those per-service values into committedMonthly (:718-733), which becomes committed_monthly in DashboardSummaryResponse (types.go).
  • The card renders ${formatCurrency(data.committed_monthly)}/mo estimated savings. So "/mo estimated savings" is accurate, and the old "committed" was wrong.

OpenAPI and Go docs: both new descriptions ("estimated monthly savings of the active commitments (the sum of their estimated savings), not what the commitments cost") match the code above.

Other consumers: the only UI reader of committed_monthly is dashboard.ts. No E2E spec asserts "committed" text (git grep across tests-e2e), so nothing else depends on the old wording. Keeping the field name avoids an API break, and the new docs cover the misleading name.

Evidence (scratch worktree at this head, heavy-review lock)

  • Fail-before: the PR's dashboard.test.ts against the merge base's dashboard.ts fails exactly the new test (1 failed / 136).
  • At this head: npm ci; full jest 182 suites / 4715 passed (1 skipped); lint 0 errors (141 existing warnings); build compiles; go test ./internal/api ok.

Heads-up, non-blocking: #1707 also edits renderDashboardSummary's KPI tiles a few lines below (the YTD caption). Expect a trivial rebase conflict for whichever lands second.

Not merging.

@cristim

cristim commented Nov 4, 2026

Copy link
Copy Markdown
Member Author

Cold review verdict: APPROVE at 96c7659

Reviewer: claude-as-qa-2 (cold, no author context). Base main c0d57f4.

Verified (scratch worktree at the head, heavy-review.lock, go1.26.10 from go.mod)

  • go test ./internal/api -count=1: ok. go vet ./internal/api: clean.
  • Frontend: npm ci, full jest (182 suites; 4715 passed, 1 skipped, as on main), npm run lint (0 errors, 141 warnings), npm run typecheck (clean), npm run build (ok). node_modules removed afterwards.
  • The new test fails on main. With main's frontend/src/dashboard.ts and the PR's dashboard.test.ts, 1 test fails (the new "names the figure as estimated savings"); all pass at the head.

committed_monthly traced from storage to the card

Step Code What it holds
Write internal/purchase/execution.go:1040 savePurchaseHistory sets EstimatedSavings: rec.Savings, next to MonthlyCost: rec.MonthlyCost the recommendation's savings
Unit RecommendationRecord.Savings is monthly: the frontend rebuilds on-demand as monthly_cost + savings + amortized_upfront (internal/config/types.go:662-663). calculateCommitmentMetrics documents EstimatedSavings as monthly (internal/api/handler_dashboard.go:707-710), and YTD multiplies it by elapsed months (:755) monthly
Read GetActivePurchaseHistory (internal/config/store_postgres.go:2657) selects estimated_savings from purchase_history WHERE term > 0, not expired, revoked_at IS NULL, scoped by account active rows only
Aggregate aggregateActiveCommitmentsPerService sums p.EstimatedSavings behind isActiveCommitment (handler_dashboard.go:635-649); committedMonthly is the sum of that map (:728-731); the provider filter is applied in fetchCommitmentPurchases Σ estimated monthly savings of active commitments
Card dashboard.ts:410 ${formatCurrency(data.committed_monthly)}/mo estimated savings matches

Nothing on this path reads monthly_cost or upfront_cost, so "committed" (cost) was wrong and "estimated savings" with "/mo" is right. The OpenAPI description ("Estimated monthly savings of the active commitments (the sum of their estimated savings), not what the commitments cost") and the types.go comment say the same and are accurate. The other "Committed" wording in dashboard.ts is the savings chart's "Current / Committed" layer, which plots the same EstimatedSavings per service, so it stays consistent.

No findings. Not merging.

@cristim
cristim merged commit af5d0b5 into main Nov 4, 2026
42 checks passed
@cristim
cristim deleted the fix/issue-1709-committed-label branch November 4, 2026 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/s Hours impact/many Affects most users priority/p2 Backlog-worthy severity/medium Moderate harm triaged Item has been triaged type/bug Defect urgency/this-quarter Within the quarter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(dashboard): Active Commitments card shows estimated savings as '/mo committed'

1 participant