namespace CSR.Infrastructure.Persistence.Repositories; using CSR.Domain.Entities; using CSR.Application.Interfaces; using Microsoft.EntityFrameworkCore; public class UserRepository(CSRDbContext context) : IUserRepository { private readonly CSRDbContext _context = context; public async Task GetByIdAsync(int id) { var userEntity = await _context.Users .Include(u => u.Role) .SingleOrDefaultAsync(u => u.Id == id); if (userEntity == null) { return null; // No entity found, return null domain model } var user = User.LoadExisting( userEntity.Id, userEntity.Username, userEntity.Email, userEntity.PasswordHash, userEntity.RoleId, Role.LoadExisting( userEntity.Role.Id, userEntity.Role.Name ) ); return user; } public async Task GetByUsernameAsync(string username) { var userEntity = await _context.Users .Include(u => u.Role) .SingleOrDefaultAsync(u => u.Username == username); if (userEntity == null) { return null; // No entity found, return null domain model } var user = User.LoadExisting( userEntity.Id, userEntity.Username, userEntity.Email, userEntity.PasswordHash, userEntity.RoleId, Role.LoadExisting( userEntity.Role.Id, userEntity.Role.Name ) ); return user; } public async Task?> GetAllByRoleIdAsync(int roleId) { var roleEntity = await _context.Roles .Include(r => r.Users) .FirstOrDefaultAsync(r => r.Id == roleId); if (roleEntity == null) { return null; // No entity found, return null } var users = roleEntity.Users .Select(userEntity => User.LoadExisting( userEntity.Id, userEntity.Username, userEntity.Email, userEntity.PasswordHash, userEntity.RoleId, Role.LoadExisting( userEntity.Role.Id, userEntity.Role.Name ) )); return users; } public async Task AddAsync(User user) { var roleEntity = await _context.Roles .SingleOrDefaultAsync(r => r.Id == user.RoleId) ?? throw new InvalidOperationException($"Role with ID {user.RoleId} does not exist."); var userEntity = new Persistence.User { Username = user.Username, Email = user.Email, PasswordHash = user.PasswordHash, RoleId = user.RoleId, Role = roleEntity }; try { _context.Users.Add(userEntity); } catch (DbUpdateException) { return null; } await _context.SaveChangesAsync(); return User.LoadExisting( userEntity.Id, userEntity.Username, userEntity.Email, userEntity.PasswordHash, userEntity.RoleId, Role.LoadExisting( userEntity.Role.Id, userEntity.Role.Name ) ); } public async Task UpdateAsync(User user) { var userEntity = await _context.Users .Include(u => u.Role) .FirstOrDefaultAsync(u => u.Id == user.Id); if (userEntity == null) { // NOTE should I throw an exception here? return; } userEntity.Id = user.Id; userEntity.Username = user.Username; userEntity.Email = user.Email; userEntity.PasswordHash = user.PasswordHash; userEntity.RoleId = user.RoleId; userEntity.Role = new Persistence.Role { Id = user.Role.Id, Name = user.Role.Name }; // Prevent EF from trying to update the Role entity _context.Entry(userEntity.Role).State = EntityState.Unchanged; _context.Users.Update(userEntity); await _context.SaveChangesAsync(); } public async Task DeleteAsync(int id) { var userEntity = new Persistence.User { Id = id, Username = string.Empty, Email = string.Empty, PasswordHash = string.Empty, RoleId = 0 }; _context.Users.Remove(userEntity); await _context.SaveChangesAsync(); } }