using AutoMapper; using Mws.Application.Common; using Mws.Application.Permissions; using Mws.Domain.Roles; namespace Mws.Application.Roles; public class RoleService(IUnitOfWork uow, IMapper mapper) : IRoleService { public async Task> GetRolesAsync(CancellationToken ct = default) { var roles = await uow.Roles.GetAllWithPermissionsAsync(ct); return mapper.Map>(roles); } public async Task GetRoleAsync(Guid id, CancellationToken ct = default) { var role = await uow.Roles.GetByIdWithPermissionsAsync(id, ct) ?? throw new NotFoundException("Role not found"); return mapper.Map(role); } public async Task CreateRoleAsync(SaveRoleRequest request, CancellationToken ct = default) { var name = request.Name.Trim(); if (string.IsNullOrWhiteSpace(name)) { throw new BadRequestException("Role name is required"); } if (await uow.Roles.ExistsByNameAsync(name, null, ct)) { throw new BadRequestException("Role name already exists"); } var now = DateTime.UtcNow; var role = new Role { Id = Guid.NewGuid(), Name = name, IsSystem = false, CreatedAt = now, UpdatedAt = now, Permissions = BuildPermissions(request.Permissions), }; uow.Roles.Add(role); await uow.SaveChangesAsync(ct); return mapper.Map(role); } public async Task UpdateRoleAsync(Guid id, SaveRoleRequest request, CancellationToken ct = default) { var role = await uow.Roles.GetByIdWithPermissionsAsync(id, ct) ?? throw new NotFoundException("Role not found"); var name = request.Name.Trim(); if (string.IsNullOrWhiteSpace(name)) { throw new BadRequestException("Role name is required"); } if (await uow.Roles.ExistsByNameAsync(name, id, ct)) { throw new BadRequestException("Role name already exists"); } role.Name = name; role.UpdatedAt = DateTime.UtcNow; uow.Roles.RemovePermissions(role.Permissions.ToList()); role.Permissions = BuildPermissions(request.Permissions); foreach (var p in role.Permissions) { p.RoleId = role.Id; } await uow.SaveChangesAsync(ct); return mapper.Map(role); } public async Task DeleteRoleAsync(Guid id, CancellationToken ct = default) { var role = await uow.Roles.GetByIdAsync(id, ct) ?? throw new NotFoundException("Role not found"); if (role.IsSystem) { throw new BadRequestException("Cannot delete a system role"); } if (await uow.Users.ExistsByRoleIdAsync(id, ct)) { throw new BadRequestException("Cannot delete a role that is assigned to accounts"); } uow.Roles.Remove(role); await uow.SaveChangesAsync(ct); } private static List BuildPermissions(List entries) { var byScreen = entries.Where(e => ScreenCatalog.Keys.Contains(e.Screen)).ToDictionary(e => e.Screen); return ScreenCatalog.Keys.Select(key => { byScreen.TryGetValue(key, out var entry); return new RolePermission { Screen = key, CanView = entry?.CanView ?? false, CanCreate = entry?.CanCreate ?? false, CanEdit = entry?.CanEdit ?? false, CanDelete = entry?.CanDelete ?? false, }; }).ToList(); } }