Filter out banned users in Contribution Analytics
What does this MR do and why?
This MR filters out banned users from the stats and from the user list on the contribution analytics page. It also optimizes loading the users in batches from the PostgreSQL DB. It only loads user records which are required for the current page. For example, instead of selecting 2000 users from the DB and then array-paginate it, we only select 100 since we need 100 records for the current page.
Previously the GraphQL endpoint was array paginated. To optimize the record loading, we now use the external pagination utility methods where we deal with the cursor (single integer value).
How:
- The query for loading the stats includes all user ids from the
events
table (ClickHouse or PostgreSQL). - When loading users, we load
PAGE_SIZE
user records from the database via theids
. - If we don't get exactly
PAGE_SIZE
users, that means we might have filtered out banned users, make another query for the next batch ofids
.
Example query (no functional change):
{
group(fullPath:"gitlab-org") {
contributions(from: "2024-01-01", to: "2024-02-01", first: 15, after: "MTAx") {
nodes {
user {
id
}
}
pageInfo {
endCursor
startCursor
hasNextPage
}
}
}
}
How to set up and validate locally
- Ensure that you're on premium or ultimate plan.
- Seed GDK
- Find a group that has some events:
Event.joins(project: :group).group(Arel.sql('namespaces.traversal_ids[1]'), Arel.sql('namespaces.path')).order('1 desc').limit(3).pluck(Arel.sql('count(*)'), Arel.sql('namespaces.traversal_ids[1]'), Arel.sql('namespaces.path'))
- Navigate to the first group and check contribution analytics: Analyze > Contribution Analytics
- Find a user in the list and mark the user as banned.
User.find_by_name("full name").ban!
- After refreshing the contribution analytics page, the user should not show up.
Related to #431545 (closed)
Edited by Adam Hegyi