Repository navigation
fix(analytics): Savings History chart ignores the global Provider filter (only account honored) #25
Description
The Savings-over-time analytics chart (getSavingsAnalytics -> /history/analytics, and getSavingsBreakdown -> /history/breakdown) accepts only account_id + date range + interval. getHistoryAnalytics/getHistoryBreakdown read NO provider param, and QueryHistory/QueryBreakdown WHERE is timestamp >= $1 AND timestamp <= $2 [+ account dual-column clause] (they GROUP BY provider but never restrict to one). So selecting a single Provider in the global top-bar filter does NOT filter the Savings History chart.
QA row 305 (LeanerCloud/cloud-commitments-cli#701) expects a Provider selection to filter Approval Queue + Savings History + Purchase History. The Approval Queue and Purchase History lists DO honor the provider filter; the Savings History chart does not. Account filtering of the chart works (fixed by LeanerCloud/cloud-commitments-cli#956). This gap is pre-existing - the analytics path never took a provider param; LeanerCloud/cloud-commitments-cli#956's scope was the account-id (UUID vs external) representation bug.
Fix
Plumb provider into getHistoryAnalytics/getHistoryBreakdown -> QueryHistory/QueryBreakdown WHERE (AND provider = $n when set), and have the FE getSavingsAnalytics/getSavingsBreakdown forward the global provider chip. Add a test asserting a provider-only selection restricts the chart. If an all-providers trend is the intended UX, close as wontfix with a note.
Found during adversarial verification of LeanerCloud/cloud-commitments-cli#956 (zero-ambiguity confirm of the analytics provider-only case).
Findings from the 2026-09-02 codebase audit
Added by an automated audit of 3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd (tip of origin/main). Each item below was reported by one reviewer and independently confirmed by a second that did not write it. Full report: docs/audits/codebase-audit-2026-09-02.md.
A11-014 (medium)
The account dimension has the same shape as the provider gap described here, and the fix should probably land together. getSavingsAnalytics (frontend/src/api/history.ts:43-45) sends both account_ids=a,b,c and account_id=a, but the analytics handlers read only the singular param (accountID := params["account_id"] at internal/api/handler_analytics.go:40, :131, :197, then resolveSingleAccountFilterIDs) and account_ids is parsed nowhere for these routes. So with three accounts selected the chart silently renders only account A's savings while the chip row advertises three, an under-reported figure with no indication that two were dropped. The sibling getHistory (history.ts:22) sends only the plural form, which internal/api/handler_history.go:678 does honour, so the two panels on the same page disagree for the same filter. Either plumb account_ids through the analytics path alongside provider, or have the caller disable/annotate the chart when more than one account is selected. Audit finding A11-014.
Activity
cristim commentedon Jul 27, 2026
Verification sweep against
main(101f099fb) on 2026-07-27 finds this already resolved.The savings-history chart now takes a provider param, with handler and query tests covering it.
Evidence: commit 61788c118 (PR LeanerCloud/cloud-commitments-cli#1122).
Recommending close.
fix(secrets): use shared metadata guard for Key Vault (#482)