Convert Accounts module to MediatR commands/queries

Replaces IAccountService/AccountService with one command/query per
operation, following the pattern set in the Auth module.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-14 08:38:31 +07:00
co-authored by Claude Sonnet 5
parent ae03208f79
commit 50faf9052c
9 changed files with 183 additions and 134 deletions
@@ -0,0 +1,54 @@
using AutoMapper;
using MediatR;
using Mws.Application.Auth;
using Mws.Application.Common;
using Mws.Application.Permissions;
using Mws.Domain.Users;
namespace Mws.Application.Accounts;
public record CreateAccountCommand(Guid ActorUserId, CreateAccountRequest Request) : IRequest<AccountDto>;
public class CreateAccountHandler(IUnitOfWork uow, IPasswordHasher passwordHasher, IPermissionService permissions, IMapper mapper)
: IRequestHandler<CreateAccountCommand, AccountDto>
{
private const string Screen = "accounts";
public async Task<AccountDto> Handle(CreateAccountCommand command, CancellationToken ct)
{
await permissions.EnsureAsync(command.ActorUserId, Screen, PermissionAction.Create, ct);
var request = command.Request;
var username = request.Username.Trim();
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(request.Password))
{
throw new BadRequestException("Username and password are required");
}
if (await uow.Users.ExistsByUsernameAsync(username, ct))
{
throw new BadRequestException("Username already exists");
}
var role = await uow.Roles.GetByIdAsync(request.RoleId, ct)
?? throw new BadRequestException("Role not found");
var now = DateTime.UtcNow;
var user = new User
{
Id = Guid.NewGuid(),
Username = username,
PasswordHash = passwordHasher.Hash(request.Password),
DisplayName = request.DisplayName.Trim(),
RoleId = role.Id,
IsActive = true,
CreatedAt = now,
UpdatedAt = now,
};
uow.Users.Add(user);
await uow.SaveChangesAsync(ct);
user.Role = role;
return mapper.Map<AccountDto>(user);
}
}