Skip to content

refactor(config): introduce ExternalIDsByProvider map for multi-provider external-ID scoping #960

Closed

Description

@cristim

Summary

The current PurchaseHistoryFilter.ExternalIDs []string treats all external account numbers (e.g. AWS account IDs, Azure subscription IDs) as a flat list with no provider context. This means a filter for account number 123456789012 could in principle match rows from any provider that happens to share that number, rather than only matching the intended provider's rows.

Proposed change

Replace ExternalIDs []string with ExternalIDsByProvider map[string][]string (provider key -> list of external IDs). The predicate builder would then emit:

(cloud_account_id = ANY($u)
   OR (provider = $p1 AND account_id = ANY($ids_for_p1))
   OR (provider = $p2 AND account_id = ANY($ids_for_p2))
   ...)

This ensures a filter for aws/123456789012 never pulls azure/123456789012 rows.

Scope

  • internal/config/types.go: PurchaseHistoryFilter.ExternalIDs -> ExternalIDsByProvider map[string][]string
  • internal/config/store_postgres.go: appendAccountPredicate gains provider grouping
  • internal/api/analytics_postgres.go: accountFilterClause gains provider grouping (the full version reverted in PR fix(api): filter purchases by account UUID AND external id (closes #701, #498, #866) #956 is the target shape)
  • internal/api/scoping.go: resolveAccountFilterIDs / resolveSingleAccountFilterIDs return map[string][]string instead of []string
  • internal/api/handler_dashboard.go, handler_history.go, handler_analytics.go: update callers

Notes

Activity

  1. cristim commented on Jul 27, 2026

    @cristim
    MemberAuthor

    Verification sweep against main (101f099fb) on 2026-07-27 finds this already resolved.
    The ExternalIDsByProvider map landed with per-provider grouping in appendAccountPredicate.
    Evidence: commit 5885697 (PR #956).
    Recommending close.

  2. cristim commented on Sep 2, 2026

    @cristim
    MemberAuthor

    Verified resolved at 3c0f8ac: PurchaseHistoryFilter carries ExternalIDsByProvider (internal/config/types.go:747) and appendAccountPredicate emits a per-provider (provider = $p AND account_id = ANY($ids)) clause so an aws-scoped external id never matches an azure row. Evidence: internal/config/store_postgres.go:2107-2120 (#956, commit 5885697). Residual axes checked: analytics path (internal/api/analytics_postgres.go:104 accountFilterClause takes the same map), GetActivePurchaseHistory (store_postgres.go:2057 uses appendAccountPredicate), cross-provider regression test present at store_postgres_pgxmock_test.go:1031-1045. Closing as completed; reopen if the behaviour recurs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions