feat(api): BATCH 5 - PermisosController + tests HTTP [UDT-005]

This commit is contained in:
2026-04-15 15:42:03 -03:00
parent be2257a9bf
commit 4913a35d06
3 changed files with 511 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
using FluentValidation;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SIGCM2.Application.Abstractions;
using SIGCM2.Application.Permisos.Assign;
using SIGCM2.Application.Permisos.Dtos;
using SIGCM2.Application.Permisos.GetByRol;
using SIGCM2.Application.Permisos.List;
namespace SIGCM2.Api.Controllers;
[ApiController]
[Route("api/v1")]
[Authorize(Roles = "admin")]
public sealed class PermisosController : ControllerBase
{
private readonly IDispatcher _dispatcher;
private readonly IValidator<AssignPermisosToRolCommand> _assignValidator;
public PermisosController(
IDispatcher dispatcher,
IValidator<AssignPermisosToRolCommand> assignValidator)
{
_dispatcher = dispatcher;
_assignValidator = assignValidator;
}
/// <summary>Lists all permisos in the canonical catalog. Requires admin role.</summary>
[HttpGet("permisos")]
[ProducesResponseType(typeof(IReadOnlyList<PermisoDto>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<IActionResult> ListPermisos()
{
var result = await _dispatcher.Send<ListPermisosQuery, IReadOnlyList<PermisoDto>>(new ListPermisosQuery());
return Ok(result);
}
/// <summary>Gets all permisos assigned to a rol. Requires admin role.</summary>
[HttpGet("roles/{codigo}/permisos")]
[ProducesResponseType(typeof(IReadOnlyList<PermisoDto>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetRolPermisos(string codigo)
{
var result = await _dispatcher.Send<GetRolPermisosQuery, IReadOnlyList<PermisoDto>>(
new GetRolPermisosQuery(codigo));
return Ok(result);
}
/// <summary>
/// Replace-set: replaces the full permiso assignment for a rol.
/// Returns the updated permiso set (200). Requires admin role.
/// </summary>
[HttpPut("roles/{codigo}/permisos")]
[ProducesResponseType(typeof(IReadOnlyList<PermisoDto>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> AssignPermisos(string codigo, [FromBody] AssignPermisosRequest request)
{
var codigos = request.Codigos ?? [];
var command = new AssignPermisosToRolCommand(
RolCodigo: codigo,
Codigos: codigos);
var validation = await _assignValidator.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<AssignPermisosToRolCommand, IReadOnlyList<PermisoDto>>(command);
return Ok(result);
}
}
public sealed record AssignPermisosRequest(IReadOnlyList<string>? Codigos);