using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using ProposalSystem.Application.DTOs; using ProposalSystem.Application.Interfaces; using ProposalSystem.Domain.Entities; using ProposalSystem.Infrastructure.Data; namespace ProposalSystem.Api.Controllers; [ApiController] [Route("api/users")] [Authorize] public class UsersController : ControllerBase { private readonly ProposalDbContext _db; private readonly ICurrentUserService _currentUser; private readonly IAuditService _audit; public UsersController(ProposalDbContext db, ICurrentUserService currentUser, IAuditService audit) { _db = db; _currentUser = currentUser; _audit = audit; } [HttpGet("me")] public async Task> GetMe(CancellationToken ct) { var user = await _db.Users .FirstOrDefaultAsync(u => u.Id == _currentUser.UserId, ct); if (user == null) return NotFound(); return Ok(new UserProfileResponse(user.Id, user.Email, user.DisplayName, user.Role)); } [HttpGet] [Authorize(Roles = "sysadmins")] public async Task>> GetAll(CancellationToken ct) { var users = await _db.Users .OrderBy(u => u.DisplayName) .Select(u => new UserResponse(u.Id, u.Email, u.DisplayName, u.Role, u.IsActive, u.CreatedAt)) .ToListAsync(ct); return Ok(users); } [HttpPut("{id:guid}/role")] [Authorize(Roles = "sysadmins")] public async Task UpdateRole(Guid id, [FromBody] UpdateUserRoleRequest request, CancellationToken ct) { var user = await _db.Users.FindAsync(new object[] { id }, ct); if (user == null) return NotFound(); user.Role = request.Role; user.UpdatedAt = DateTime.UtcNow; await _db.SaveChangesAsync(ct); await _audit.LogAsync(AuditAction.UpdateRole, null, $"User {user.Email} role changed to {request.Role}", ct); return NoContent(); } }