1# frozen_string_literal: true
2
3module HasUserType
4  extend ActiveSupport::Concern
5
6  USER_TYPES = {
7    human: nil,
8    support_bot: 1,
9    alert_bot: 2,
10    visual_review_bot: 3,
11    service_user: 4,
12    ghost: 5,
13    project_bot: 6,
14    migration_bot: 7,
15    security_bot: 8,
16    automation_bot: 9
17  }.with_indifferent_access.freeze
18
19  BOT_USER_TYPES = %w[alert_bot project_bot support_bot visual_review_bot migration_bot security_bot automation_bot].freeze
20  NON_INTERNAL_USER_TYPES = %w[human project_bot service_user].freeze
21  INTERNAL_USER_TYPES = (USER_TYPES.keys - NON_INTERNAL_USER_TYPES).freeze
22
23  included do
24    scope :humans, -> { where(user_type: :human) }
25    scope :bots, -> { where(user_type: BOT_USER_TYPES) }
26    scope :without_bots, -> { humans.or(where.not(user_type: BOT_USER_TYPES)) }
27    scope :bots_without_project_bot, -> { where(user_type: BOT_USER_TYPES - ['project_bot']) }
28    scope :non_internal, -> { humans.or(where(user_type: NON_INTERNAL_USER_TYPES)) }
29    scope :without_ghosts, -> { humans.or(where.not(user_type: :ghost)) }
30    scope :without_project_bot, -> { humans.or(where.not(user_type: :project_bot)) }
31    scope :human_or_service_user, -> { humans.or(where(user_type: :service_user)) }
32
33    enum user_type: USER_TYPES
34
35    def human?
36      super || user_type.nil?
37    end
38  end
39
40  def bot?
41    BOT_USER_TYPES.include?(user_type)
42  end
43
44  # The explicit check for project_bot will be removed with Bot Categorization
45  # Ref: https://gitlab.com/gitlab-org/gitlab/-/issues/213945
46  def internal?
47    ghost? || (bot? && !project_bot?)
48  end
49end
50