using FluentValidation; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using SIGCM2.Application.Abstractions; using SIGCM2.Application.Usuarios.Create; namespace SIGCM2.Api.Controllers; [ApiController] [Route("api/v1/users")] [Authorize(Roles = "admin")] public sealed class UsuariosController : ControllerBase { private readonly IDispatcher _dispatcher; private readonly IValidator _validator; public UsuariosController(IDispatcher dispatcher, IValidator validator) { _dispatcher = dispatcher; _validator = validator; } /// Creates a new user. Requires admin role. [HttpPost] [ProducesResponseType(typeof(UsuarioCreatedDto), StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task CreateUsuario([FromBody] CreateUsuarioRequest request) { var command = new CreateUsuarioCommand( Username: request.Username ?? string.Empty, Password: request.Password ?? string.Empty, Nombre: request.Nombre ?? string.Empty, Apellido: request.Apellido ?? string.Empty, Email: request.Email, Rol: request.Rol ?? string.Empty); var validation = await _validator.ValidateAsync(command); if (!validation.IsValid) { var errors = validation.Errors .GroupBy(e => e.PropertyName) .ToDictionary(g => g.Key, g => g.Select(e => e.ErrorMessage).ToArray()); return BadRequest(new { errors }); } var result = await _dispatcher.Send(command); return CreatedAtAction(nameof(CreateUsuario), new { id = result.Id }, result); } } /// Create user request body — nullable to catch missing field scenarios. public sealed record CreateUsuarioRequest( string? Username, string? Password, string? Nombre, string? Apellido, string? Email, string? Rol);