diff --git a/app/graphql/types/achievements/achievement_type.rb b/app/graphql/types/achievements/achievement_type.rb
index 99f50966cbe45e4d5cda41a3f89edb1e16e53a23..e6b27129f72ba21ca67b9f61f977fdbb43335c54 100644
--- a/app/graphql/types/achievements/achievement_type.rb
+++ b/app/graphql/types/achievements/achievement_type.rb
@@ -51,6 +51,11 @@ class AchievementType < BaseObject
extras: [:lookahead],
resolver: ::Resolvers::Achievements::UserAchievementsResolver
+ field :unique_users, Types::UserType.connection_type,
+ null: false,
+ experiment: { milestone: '18.6' },
+ description: "Unique users who have received the achievement."
+
def avatar_url
object.avatar_url(only_path: false)
end
diff --git a/app/models/achievements/achievement.rb b/app/models/achievements/achievement.rb
index d47868c4b669d9e4a5b1582790809485c4e54854..97bd13293678cfbc3b27a7b2d0b091aa13c422b4 100644
--- a/app/models/achievements/achievement.rb
+++ b/app/models/achievements/achievement.rb
@@ -18,6 +18,10 @@ class Achievement < ApplicationRecord
uniqueness: { case_sensitive: false, scope: [:namespace_id] }
validates :description, length: { maximum: 1024 }
+ def unique_users
+ users.distinct
+ end
+
def uploads_sharding_key
{ namespace_id: namespace_id }
end
diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md
index 013fd60e8381cb20a88ea3cfa54db580fee870ba..3bb5e851e6dc675436bf9cef8361814ac9cfe8ac 100644
--- a/doc/api/graphql/reference/_index.md
+++ b/doc/api/graphql/reference/_index.md
@@ -23143,6 +23143,7 @@ Representation of a GitLab user.
| `id` | [`AchievementsAchievementID!`](#achievementsachievementid) | ID of the achievement. |
| `name` | [`String!`](#string) | Name of the achievement. |
| `namespace` | [`Namespace`](#namespace) | Namespace of the achievement. |
+| `uniqueUsers` {{< icon name="warning-solid" >}} | [`UserCoreConnection!`](#usercoreconnection) | **Introduced** in GitLab 18.6. **Status**: Experiment. Unique users who have received the achievement. |
| `updatedAt` | [`Time!`](#time) | Timestamp the achievement was last updated. |
| `userAchievements` {{< icon name="warning-solid" >}} | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in GitLab 15.10. **Status**: Experiment. Recipients for the achievement. |
diff --git a/spec/graphql/types/achievements/achievement_type_spec.rb b/spec/graphql/types/achievements/achievement_type_spec.rb
index 08fadcdff229fca850e908209049b6e38172c62b..5e0eb1f69754a31a94920d3a8cd18f087a71247f 100644
--- a/spec/graphql/types/achievements/achievement_type_spec.rb
+++ b/spec/graphql/types/achievements/achievement_type_spec.rb
@@ -15,6 +15,7 @@
created_at
updated_at
user_achievements
+ unique_users
]
end
diff --git a/spec/models/achievements/achievement_spec.rb b/spec/models/achievements/achievement_spec.rb
index 5d8d0e90bb0d5826a8c99530b8a986ea090430a2..bd25b6d21ad966d7fb09f201cc7f5d33bbd384b0 100644
--- a/spec/models/achievements/achievement_spec.rb
+++ b/spec/models/achievements/achievement_spec.rb
@@ -41,4 +41,25 @@
expect(achievement.uploads_sharding_key).to eq(namespace_id: namespace.id)
end
end
+
+ describe '#unique_users' do
+ let_it_be(:achievement) { create(:achievement) }
+
+ subject(:unique_users) { achievement.unique_users }
+
+ it 'returns unique users even when a user has multiple awards' do
+ user1 = create(:user)
+ user2 = create(:user)
+
+ create(:user_achievement, achievement: achievement, user: user1)
+ create(:user_achievement, achievement: achievement, user: user1)
+ create(:user_achievement, achievement: achievement, user: user2)
+
+ expect(unique_users).to contain_exactly(user1, user2)
+ end
+
+ it 'returns empty when no users have been awarded' do
+ expect(unique_users).to be_empty
+ end
+ end
end
diff --git a/spec/requests/api/graphql/achievements/user_achievements_query_spec.rb b/spec/requests/api/graphql/achievements/user_achievements_query_spec.rb
index eb6e53442f362194ffd29426e030d40a7de44872..ca0bccddcf67a69249ac4a20423a61734902ba2c 100644
--- a/spec/requests/api/graphql/achievements/user_achievements_query_spec.rb
+++ b/spec/requests/api/graphql/achievements/user_achievements_query_spec.rb
@@ -20,6 +20,12 @@
achievements {
count
nodes {
+ uniqueUsers {
+ count
+ nodes {
+ username
+ }
+ }
userAchievements {
count
nodes {