fix(account-repo): Clone query before Count to prevent state pollution

ListWithFilters reused the Ent query builder across Count() and All(),
so interceptor-appended predicates (SoftDeleteMixin's deleted_at IS NULL)
accumulated on the shared builder — the same pattern already fixed in
group_repo/promo_code_repo/user_repo by commit 2588fa6a (P1-03 audit).

The integration test now asserts pagination.Total matches len(items) on a
single page, guarding the total-vs-items invariant reported in #3601.

Fixes #3601
This commit is contained in:
shaw committed 2026-07-01 14:35:49 +08:00
1 parent 3812e627a8
commit fd004bdd88
2 files changed
+11 -2

No files matched your search

+5 -1
View File
@@ -575,7 +575,11 @@ func (r *accountRepository) ListWithFilters(ctx context.Context, params paginati
}))
}
total, err := q.Count(ctx)
// Clone before Count so interceptor-appended predicates (SoftDeleteMixin's
// deleted_at IS NULL) don't accumulate on the shared builder and pollute the
// subsequent list query. Same pattern used in group_repo/promo_code_repo/user_repo
// (P1-03 audit fix, commit 2588fa6a).
total, err := q.Clone().Count(ctx)
if err != nil {
return nil, nil, err
}
@@ -445,9 +445,14 @@ func (s *AccountRepoSuite) TestListWithFilters() {
tt.setup(client)
accounts, _, err := repo.ListWithFilters(ctx, pagination.PaginationParams{Page: 1, PageSize: 10}, tt.platform, tt.accType, tt.status, tt.search, tt.groupID, tt.privacyMode)
accounts, page, err := repo.ListWithFilters(ctx, pagination.PaginationParams{Page: 1, PageSize: 10}, tt.platform, tt.accType, tt.status, tt.search, tt.groupID, tt.privacyMode)
s.Require().NoError(err)
s.Require().Len(accounts, tt.wantCount)
// Regression guard for issue #3601: when the whole result set fits on a single page,
// pagination.Total must match len(items). A mismatch means the Count query was applied
// against different predicates than the list query — the exact symptom reported.
s.Require().NotNil(page)
s.Require().Equal(int64(tt.wantCount), page.Total, "total must match items on single page")
if tt.validate != nil {
tt.validate(accounts)
}