using Application.Auth.DTOs; using Domain.Entities; using Domain.Ports.Repositories; using Domain.ValueObjects; using MediatR; namespace Application.Auth.Commands; public record RegisterCommand( string Username, string Password, string? Name = null, string? Email = null ) : IRequest; public class RegisterCommandHandler( IUserRepository userRepository, IStudentRepository studentRepository, IPasswordService passwordService, IJwtService jwtService, IUnitOfWork unitOfWork ) : IRequestHandler { public async Task Handle(RegisterCommand request, CancellationToken ct) { // Check if username already exists if (await userRepository.ExistsAsync(request.Username, ct)) return new AuthResponse(false, Error: "El nombre de usuario ya existe"); // Validate password strength if (request.Password.Length < 6) return new AuthResponse(false, Error: "La contrasena debe tener al menos 6 caracteres"); // Create student if name and email are provided Student? student = null; if (!string.IsNullOrWhiteSpace(request.Name) && !string.IsNullOrWhiteSpace(request.Email)) { try { var email = Email.Create(request.Email); student = new Student(request.Name, email); studentRepository.Add(student); await unitOfWork.SaveChangesAsync(ct); // Save to get the student ID } catch (Exception ex) { return new AuthResponse(false, Error: ex.Message); } } // Create user var passwordHash = passwordService.HashPassword(request.Password); var user = User.Create( request.Username, passwordHash, UserRoles.Student, student?.Id ); await userRepository.AddAsync(user, ct); await unitOfWork.SaveChangesAsync(ct); // Generate token var token = jwtService.GenerateToken(user); return new AuthResponse( Success: true, Token: token, User: new UserInfo( user.Id, user.Username, user.Role, user.StudentId, student?.Name ) ); } }