ref: project structure

This commit is contained in:
2026-08-19 23:25:08 +07:00
parent 05a93cfc09
commit a1fe31cf70
155 changed files with 3339 additions and 1007 deletions
+34
View File
@@ -0,0 +1,34 @@
using AutoMapper;
using MediatR;
using mws.backend.dotnet.application.Common;
using mws.backend.dotnet.application.Users;
namespace mws.backend.dotnet.application.Auth;
public record LoginCommand(LoginRequest Request) : IRequest<LoginResponse>;
public class LoginHandler(IUnitOfWork uow, IPasswordHasher passwordHasher, ITokenService tokenService, IMapper mapper)
: IRequestHandler<LoginCommand, LoginResponse>
{
public async Task<LoginResponse> Handle(LoginCommand command, CancellationToken ct)
{
var username = command.Request.Username.Trim();
var user = await uow.Users.GetByUsernameWithRoleAsync(username, ct);
if (user is null || !passwordHasher.Verify(command.Request.Password, user.PasswordHash))
{
throw new UnauthorizedException("Invalid username or password");
}
if (!user.IsActive)
{
throw new ForbiddenException("Account disabled");
}
return new LoginResponse
{
Token = tokenService.CreateToken(user.Id, user.Username),
User = mapper.Map<UserDto>(user),
};
}
}
+26
View File
@@ -0,0 +1,26 @@
using mws.backend.dotnet.application.Users;
namespace mws.backend.dotnet.application.Auth;
public class LoginRequest
{
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
public class LoginResponse
{
public string Token { get; set; } = string.Empty;
public UserDto User { get; set; } = null!;
}
public interface IPasswordHasher
{
string Hash(string password);
bool Verify(string password, string hash);
}
public interface ITokenService
{
string CreateToken(Guid userId, string username);
}
+23
View File
@@ -0,0 +1,23 @@
using AutoMapper;
using MediatR;
using mws.backend.dotnet.application.Common;
using mws.backend.dotnet.application.Users;
namespace mws.backend.dotnet.application.Auth;
public record GetProfileQuery(Guid UserId) : IRequest<UserDto>;
public class GetProfileHandler(IUnitOfWork uow, IMapper mapper)
: IRequestHandler<GetProfileQuery, UserDto>
{
public async Task<UserDto> Handle(GetProfileQuery request, CancellationToken ct)
{
var user = await uow.Users.GetByIdWithRoleAsync(request.UserId, ct);
if (user is null)
{
throw new NotFoundException("User not found");
}
return mapper.Map<UserDto>(user);
}
}