Skip to content

Add option to query awaiting users for billable members

Nicolas Dular requested to merge nd/awaiting-users-for-billable-members into master

What does this MR do and why?

This adds the possibility to also query awaiting members for groups via the billable_member API.

Why is this required? https://gitlab.com/gitlab-org/gitlab/-/issues/352638+ is part of the free user cap work and should show members on the usage quota page for the free namespaces. However, members could also be in the state awaiting, which the current API does not provide yet.

Migration of the index

bin/rails db:migrate
bin/rails db:migrate
== 20220404170446 AddIndexForNonRequestedNonInvitedAwaitingMembers: migrating =
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:members, :source_id, {:where=>"((requested_at IS NULL) AND (invite_token IS NULL) AND (access_level > 5) AND (state = 1))", :name=>"index_members_on_non_requested_non_invited_and_state_awaiting", :algorithm=>:concurrently})
   -> 0.0031s
-- execute("SET statement_timeout TO 0")
   -> 0.0002s
-- add_index(:members, :source_id, {:where=>"((requested_at IS NULL) AND (invite_token IS NULL) AND (access_level > 5) AND (state = 1))", :name=>"index_members_on_non_requested_non_invited_and_state_awaiting", :algorithm=>:concurrently})
   -> 0.0020s
-- execute("RESET statement_timeout")
   -> 0.0004s
== 20220404170446 AddIndexForNonRequestedNonInvitedAwaitingMembers: migrated (0.0103s)
bin/rails db:rollback
bin/rails db:rollback
== 20220404170446 AddIndexForNonRequestedNonInvitedAwaitingMembers: reverting =
-- transaction_open?()
   -> 0.0000s
-- indexes(:members)
   -> 0.0025s
-- execute("SET statement_timeout TO 0")
   -> 0.0002s
-- remove_index(:members, {:algorithm=>:concurrently, :name=>"index_members_on_non_requested_non_invited_and_state_awaiting"})
   -> 0.0015s
-- execute("RESET statement_timeout")
   -> 0.0003s
== 20220404170446 AddIndexForNonRequestedNonInvitedAwaitingMembers: reverted (0.0084s)

Queries

The BilledUserFinder already existed and got introduced with !49357 (merged). The new functionality is only to query awaiting members from Member and the other queries haven't changed. I am also re-using the existing methods like self_and_descendants, invited_group_in_groups, invited_groups_in_projects to get the right project/group relationships.

GroupMember.awaiting_without_invites_and_requests

Using gitlab-org as Namespace:

users_without_project_bots(::GroupMember.awaiting_without_invites_and_requests.where(source_id: sources)).distinct
SELECT DISTINCT "users".*
FROM   "users"
WHERE  "users"."id" IN (SELECT DISTINCT "members"."user_id"
                        FROM   "members"
                               LEFT OUTER JOIN "users"
                                            ON "users"."id" =
                                               "members"."user_id"
                        WHERE  ( ( "members"."user_id" IS NULL
                                   AND "members"."invite_token" IS NOT NULL )
                                  OR "users"."state" = 'active' )
                               AND "members"."requested_at" IS NULL
                               AND ( members.access_level > 5 )
                               AND "members"."state" = 1
                               AND "members"."invite_token" IS NULL
                               AND "members"."source_id" IN (9970))
       AND ( "users"."user_type" IS NULL
              OR "users"."user_type" != 6 ) 

Screenshots or screen recordings

These are strongly recommended to assist reviewers and reduce the time to merge your change.

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Nicolas Dular

Merge request reports