Skip to content

Add occupies_seat column to member_roles table

What does this MR do and why?

  • This MR follows from discussion, #437719 (comment 1737274716)
  • We are trying to improve the query which calculates non-Guest users.
  • This calculation gets tricky when users are assigned a custom role, because we have some custom abilities such as read_code which have skip_seat_consumption = true i.e. if a user is assigned to a custom role which only allows read_code as the permission, the user should only be counted as a Guest user. But if the user is assigned to a custom role which allows read_code + read_dependency then they should be counted as a non-Guest user.
  • This MR is sub-task 1 of #437719 (closed), it introduces a occupies_seat column in the member_roles table which is set to true if the user is assigned to any one of the non-Guest abilities.

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Database

Output of db:migrate
Running: `bundle exec rake db:migrate:main`
main: == [advisory_lock_connection] object_id: 107840, pg_backend_pid: 184
main: == 20240206075104 AddOccupiesSeatToMemberRole: migrating ======================
main: -- add_column(:member_roles, :occupies_seat, :boolean, {:default=>false, :null=>false})
main:    -> 0.0032s
main: == 20240206075104 AddOccupiesSeatToMemberRole: migrated (0.0108s) =============
main: == 20240206080928 AddIndexToOccupiesSeatOnMemberRole: migrating ===============
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main:    -> 0.0048s
main: -- index_exists?(:member_roles, :occupies_seat, {:name=>"index_member_roles_on_occupies_seat", :algorithm=>:concurrently})
main:    -> 0.0037s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0005s
main: -- add_index(:member_roles, :occupies_seat, {:name=>"index_member_roles_on_occupies_seat", :algorithm=>:concurrently})
main:    -> 0.0018s
main: -- execute("RESET statement_timeout")
main:    -> 0.0004s
main: == 20240206080928 AddIndexToOccupiesSeatOnMemberRole: migrated (0.0310s) ======
main: == [advisory_lock_connection] object_id: 107840, pg_backend_pid: 184
Output of db:rollback
Running: `bundle exec rake db:migrate:down:main VERSION=20240206080928`
main: == [advisory_lock_connection] object_id: 108600, pg_backend_pid: 124
main: == 20240206080928 AddIndexToOccupiesSeatOnMemberRole: reverting ===============
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main:    -> 0.0146s
main: -- indexes(:member_roles)
main:    -> 0.0047s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0005s
main: -- remove_index(:member_roles, {:algorithm=>:concurrently, :name=>"index_member_roles_on_occupies_seat"})
main:    -> 0.0015s
main: -- execute("RESET statement_timeout")
main:    -> 0.0005s
main: == 20240206080928 AddIndexToOccupiesSeatOnMemberRole: reverted (0.0443s) ======
main: == [advisory_lock_connection] object_id: 108600, pg_backend_pid: 124

Running: `bundle exec rake db:migrate:down:main VERSION=20240206075104`
main: == [advisory_lock_connection] object_id: 108060, pg_backend_pid: 152
main: == 20240206075104 AddOccupiesSeatToMemberRole: reverting ======================
main: -- remove_column(:member_roles, :occupies_seat, :boolean, {:default=>false, :null=>false})
main:    -> 0.0023s
main: == 20240206075104 AddOccupiesSeatToMemberRole: reverted (0.0122s) =============
main: == [advisory_lock_connection] object_id: 108060, pg_backend_pid: 152

How to set up and validate locally

  1. In the rails console, create two member roles
# has occupies_seat = false
MemberRole.create(base_access_level: 10, read_code: true) 

# has occupies_seat = true
MemberRole.create(base_access_level: 10, read_vulnerability: true)

Related to #437719 (closed)

Edited by Hinam Mehra

Merge request reports