Describe the bug
PR #5850 fixed an incorrect total count in the project identity membership list endpoint -- the count was summing role assignments instead of unique identities because of a window function running over JOINed membership_roles rows.
The same bug exists in two sibling files that weren't covered by that fix:
membership-user-dal.ts (findUsers, line ~228)
membership-group-dal.ts (findGroups, line ~214)
Both use the same pattern:
.select(
db.raw(
`count(${TableName.Membership}."actorUserId") OVER(PARTITION BY ${TableName.Membership}."scopeOrgId") as total`
)
)
The query JOINs membership_roles (one-to-many), so a user with 3 roles produces 3 rows. The window function counts all rows in the partition, returning 8 instead of 5 for an org with 5 users.
identity-org-dal.ts (searchIdentities, line ~432) has the same issue.
To reproduce
Given 5 users in an org, where 2 users have multiple roles:
| User |
Roles |
| alice |
admin, developer, reviewer |
| bob |
member, developer |
| charlie |
member |
| diana |
member |
| eve |
viewer |
Buggy query result: total_count = 8 (3+2+1+1+1)
Expected result: total_count = 5
Tested on PostgreSQL 14 with the same table structure.
Expected behavior
Total count should reflect the number of unique users/groups/identities, not the number of role assignments.
Fix
The same approach from #5850 works here -- replace the window function with a subquery count over the distinct membership set:
const countQuery = await (tx || db.replicaNode())
.count("* as total")
.from(paginatedUsers.clone().as("distinctMemberships"));
Happy to open a PR for this if it makes sense to fix all three in one go.
Describe the bug
PR #5850 fixed an incorrect total count in the project identity membership list endpoint -- the count was summing role assignments instead of unique identities because of a window function running over JOINed
membership_rolesrows.The same bug exists in two sibling files that weren't covered by that fix:
membership-user-dal.ts(findUsers, line ~228)membership-group-dal.ts(findGroups, line ~214)Both use the same pattern:
The query JOINs
membership_roles(one-to-many), so a user with 3 roles produces 3 rows. The window function counts all rows in the partition, returning 8 instead of 5 for an org with 5 users.identity-org-dal.ts(searchIdentities, line ~432) has the same issue.To reproduce
Given 5 users in an org, where 2 users have multiple roles:
Buggy query result:
total_count = 8(3+2+1+1+1)Expected result:
total_count = 5Tested on PostgreSQL 14 with the same table structure.
Expected behavior
Total count should reflect the number of unique users/groups/identities, not the number of role assignments.
Fix
The same approach from #5850 works here -- replace the window function with a subquery count over the distinct membership set:
Happy to open a PR for this if it makes sense to fix all three in one go.