Expand userAchievements resolver visibility for namespace awarders
<!--IssueSummary start--> <details> <summary> Everyone can contribute. [Help move this issue forward](https://handbook.gitlab.com/handbook/marketing/developer-relations/contributor-success/community-contributors-workflows/#contributor-links) while earning points, leveling up and collecting rewards. </summary> - [Label this issue](https://contributors.gitlab.com/manage-issue?action=label&projectId=278964&issueIid=598828) </details> <!--IssueSummary end--> ## Summary The `user { userAchievements }` GraphQL query filters out records where `show_on_profile=false` for any caller who is not the profile owner. This is correct for public profile visibility. However it breaks award automation that needs to check whether a user already has a pending (unaccepted) award before deciding to re-award. This is a prerequisite for re-landing !227918 (achievement acceptance flow), which was [reverted](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/234155) while this fix is put in place. Without this fix, any automation using the User path to check existing awards before awarding will be blind to pending records and will re-award on every run. ## Current behavior `UserAchievementsForUserResolver` returns `show_on_profile=false` records only when `current_user == object` (the profile owner). Any other caller, including service accounts and automation tokens with `award_achievement` permission on the namespace, gets the filtered result. ## Proposed fix Expand `UserAchievementsForUserResolver` to also return `show_on_profile=false` records where the achievement belongs to a namespace where `current_user` has `award_achievement` permission. Implementation to avoid N+1: 1. Load all namespace IDs where `current_user` has `award_achievement` in a single query upfront. 2. Return: all `show_on_profile=true` records (existing behavior), UNION `show_on_profile=false` records where the achievement's namespace ID is in the permitted set. 3. One extra query, not one per record. A caller with no `award_achievement` permissions anywhere gets exactly the same result as today. A caller with `award_achievement` on namespace X sees hidden records only for achievements owned by namespace X, not for achievements from other namespaces. ## Authorization scope Hidden records are only exposed where `current_user` has `award_achievement` on the specific namespace that owns the achievement. This is the same permission already required to call the `awardAchievement` mutation. No new permission is introduced. ## Files to change - `app/graphql/resolvers/achievements/user_achievements_for_user_resolver.rb` - `spec/requests/api/graphql/achievements/user_achievements_query_spec.rb` ## Database review required The fix introduces a join from `user_achievements` to `achievements` to `namespaces` to check namespace ownership. This query path needs a database review to verify index coverage and query plan. ## Related - !227918: achievement acceptance flow (reverted) - !234155: revert of !227918 - https://gitlab.com/gitlab-org/developer-relations/contributor-success/contributors-gitlab-com/-/work_items/498: full investigation
issue