diff --git a/SeaHaven.DataServices/Implementation/TeamPermissionOverrideDataService.cs b/SeaHaven.DataServices/Implementation/TeamPermissionOverrideDataService.cs index 954e8a4..b968a8b 100644 --- a/SeaHaven.DataServices/Implementation/TeamPermissionOverrideDataService.cs +++ b/SeaHaven.DataServices/Implementation/TeamPermissionOverrideDataService.cs @@ -63,22 +63,39 @@ public sealed class TeamPermissionOverrideDataService : ITeamPermissionOverrideD && permission.PermissionKey == permissionKey, cancellationToken); - if (existing is null) - { - await _context.UserPermissionOverrides.AddAsync( - new UserPermissionOverride - { - UserId = userId, - PermissionKey = permissionKey, - State = state - }, - cancellationToken); - } - else + if (existing is not null) { existing.State = state; + await _context.SaveChangesAsync(cancellationToken); + return; } - await _context.SaveChangesAsync(cancellationToken); + var addition = new UserPermissionOverride + { + UserId = userId, + PermissionKey = permissionKey, + State = state + }; + await _context.UserPermissionOverrides.AddAsync(addition, cancellationToken); + + try + { + await _context.SaveChangesAsync(cancellationToken); + } + catch (DbUpdateException) + { + // A concurrent PUT inserted the same (UserId, PermissionKey) between our + // existence check and this save, violating PK_UserPermissionOverrides. + // Converge on the caller's intent by updating the persisted row. + _context.Entry(addition).State = EntityState.Detached; + + var winner = await _context.UserPermissionOverrides + .SingleAsync( + permission => permission.UserId == userId + && permission.PermissionKey == permissionKey, + cancellationToken); + winner.State = state; + await _context.SaveChangesAsync(cancellationToken); + } } } diff --git a/SeaHaven.DataServices/Implementation/UserDataService.cs b/SeaHaven.DataServices/Implementation/UserDataService.cs index 055f870..f5dbb70 100644 --- a/SeaHaven.DataServices/Implementation/UserDataService.cs +++ b/SeaHaven.DataServices/Implementation/UserDataService.cs @@ -135,6 +135,10 @@ namespace SeaHaven.DataServices.Implementation .Where(role => role.UserId == id) .ExecuteDeleteAsync(cancellationToken); + await _context.UserPermissionOverrides + .Where(permissionOverride => permissionOverride.UserId == id) + .ExecuteDeleteAsync(cancellationToken); + await _context.Users .Where(existingUser => existingUser.Id == id) .ExecuteDeleteAsync(cancellationToken);