Repository navigation
fix(api): dedupe per-cell variants in by_service savings to stop ~6x over-report - #1102
Conversation
…over-report summarizeRecommendationsWithCoverage summed scaledSavings for every recommendation into byService[svc].PotentialSavings and the headline total. After PR #195's per-(term, payment) fan-out, one physical-resource cell yields up to 6 mutually-exclusive variant recs (2 terms x 3 payments). Those variants are alternatives, not additions, so summing them inflated the per-service and headline figures by up to ~6x. The frontend already deduped per cell for the headline KPI (recommendations.ts cellKey / groupRecsByCell); the backend reducer did not. Dedupe to one representative variant per physical-resource cell before summing, keyed by (provider, cloud_account_id, service, region, resource_type, engine) to mirror the frontend cellKey. The representative is the variant with the maximum coverage-scaled savings (the best realistic single purchase for that resource). New private helpers bestVariantPerCell and recCellKey carry a cross-reference comment to the frontend cellKey per the cross-language duplication rule. Adds TestSummarizeRecommendationsWithCoverage_DedupesVariantsPerCell, which fails against the sum-all-variants code and passes after. Updates the TestHandler_getDashboardSummary fixture to give its two rds recs distinct resource_type values so they remain additive (distinct cells) under the new dedupe. Closes #1100
|
Warning Review limit reached
More reviews will be available in 55 minutes and 12 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai full review Generated by Claude Code |
|
🧠 Learnings used✅ Action performedFull review finished. |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
Root cause
internal/api/handler_dashboard.go->summarizeRecommendationsWithCoveragesummedscaledSavingsfor EVERY recommendation intobyService[rec.Service].PotentialSavingsand the headlinetotal. After PR #195's per-(term, payment) fan-out, a single physical-resource cell produces up to 6 variant recs (2 terms x 3 payments) that are mutually-exclusive ALTERNATIVES (one commitment per resource), not additive entries. Summing them inflated the per-service breakdown and the headline by up to ~6x.The headline KPI already avoids this on the frontend by grouping per cell (
groupRecsByCell/cellKeyinfrontend/src/recommendations.ts:588, see thedashboard.ts:139-142comment about "~6x inflation of summing every variant"). The backend reducer never deduped.Fix
(provider, cloud_account_id, service, region, resource_type, engine)to mirror the frontendcellKey.scaledSavings/resolveCoverageByAccountKey) is applied to the chosen variant.bestVariantPerCellandrecCellKeylive in theapipackage with a cross-reference comment to the frontendcellKeyper the project's cross-language-duplication rule. No existing backend cell-grouping helper existed.totalandby_servicenow dedupe identically, keepingtotal == sum(by_service)and fixing the documented backendpotential_monthly_savingsinflation in lockstep.Verification
TestSummarizeRecommendationsWithCoverage_DedupesVariantsPerCell(new regression): feeds three term/payment variants of one cell (savings 100/200/300) plus a distinct second cell (50). Assertsby_serviceandtotalequal the sum of per-cell MAX (300 + 50 = 350), NOT the sum of all variants (650). Confirmed it FAILS against the pre-fix code (returned 650) and PASSES after.TestHandler_getDashboardSummaryfixture to give its twordsrecs distinctresource_typevalues so they stay additive (distinct cells) under the new dedupe; the test's aggregation intent is preserved.go build ./...OK,go vet ./internal/api/...clean,go test ./internal/api/...1512 passed (mock/pgxmock; no live Postgres required for this package).Closes #1100
Related: #1031 (current_savings always 0, out of scope here), #908 (per-service chart redesign)