using Backend.Data; using Backend.Gateway; using Microsoft.AspNetCore.Mvc; namespace Backend.Controllers; [ApiController] [Route(ApiRoutes.V1 + "/[controller]")] public sealed class UsersController : ControllerBase { private readonly IUserRepository _userRepository; public UsersController(IUserRepository userRepository) { _userRepository = userRepository; } [HttpGet] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task GetAll(CancellationToken cancellationToken) => Ok(await _userRepository.GetAllAsync(cancellationToken)); [HttpGet("{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetById(Guid id, CancellationToken cancellationToken) { var user = await _userRepository.GetByIdAsync(id, cancellationToken); return user is null ? NotFound() : Ok(user); } [HttpPost] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task Create( CreateUserRequest request, CancellationToken cancellationToken) { if (await _userRepository.GetByEmailAsync(request.Email, cancellationToken) is not null) { return Conflict(new ProblemDetails { Title = "Email already in use", Status = StatusCodes.Status409Conflict, }); } var user = await _userRepository.AddAsync( new User { Email = request.Email, DisplayName = request.DisplayName }, cancellationToken); return CreatedAtAction(nameof(GetById), new { id = user.Id }, user); } [HttpPut("{id:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task Update( Guid id, UpdateUserRequest request, CancellationToken cancellationToken) { var existing = await _userRepository.GetByIdAsync(id, cancellationToken); if (existing is null) { return NotFound(); } var emailOwner = await _userRepository.GetByEmailAsync(request.Email, cancellationToken); if (emailOwner is not null && emailOwner.Id != id) { return Conflict(new ProblemDetails { Title = "Email already in use", Status = StatusCodes.Status409Conflict, }); } existing.Email = request.Email; existing.DisplayName = request.DisplayName; var updated = await _userRepository.UpdateAsync(existing, cancellationToken); return updated is null ? NotFound() : Ok(updated); } [HttpDelete("{id:guid}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task Delete(Guid id, CancellationToken cancellationToken) => await _userRepository.DeleteAsync(id, cancellationToken) ? NoContent() : NotFound(); }