Deleted users that awarded achievements cause invalid UserAchievements
Problem
We observed that the awardedByUser
field on the UserAchievement
type can error out because of null
values on this non-nullable field.
"errors": [
{
"message": "Cannot return null for non-nullable field UserAchievement.awardedByUser"
}
]
The relation on the UserAchievement
model is defined as optional: false
(which effectively makes it required)
belongs_to :awarded_by_user,
class_name: 'User',
inverse_of: :awarded_user_achievements,
optional: false
The problem is that the foreign key is defined with on_delete: :nullify
(https://gitlab.com/gitlab-org/gitlab/-/blob/a31062c8a87c6299b3a14a3d8e2174935c85b162/db/migrate/20221214204247_user_achievements_foreign_keys.rb#L8)
This causes the field to be set to null when the user that awarded the achievement is deleted.
But a awarded_by_user
of null
is invalid and causes errors when queried with GraphQL. The record probably can't be updated as well because of the model validations.
(Initial investigation happened in the community discord: https://canary.discord.com/channels/778180511088640070/1151947235081334835/1151957658509779004)
Proposed solution
Migrate this field to the Ghost user (@ghost1 on gitlab.com) by adding it to Users::MigrateRecordsToGhostUserService
(https://gitlab.com/gitlab-org/gitlab/-/blob/a31062c8a87c6299b3a14a3d8e2174935c85b162/app/services/users/migrate_records_to_ghost_user_service.rb)
We probably also need a migration that will back-fill all null values in awarded_by_user
with the Ghost user to fix already broken records.