using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Api; using PostFundManagement.Domain.Extensions; using PostFundManagement.Infrastructure.Database; namespace PostFundManagement.Api.Endpoints.Users; [ApiVersionTarget(1)] public class GetUsersEndpoint : IEndpoint { public void Map(IEndpointRouteBuilder builder) { builder.MapGet("api/users", async (IDbContextFactory contextFactory, int page = 1, int pageSize = 10, ActivityStatus? status = null, string? email = null, string? sortBy = null, bool sortDescending = false, CancellationToken cancellationToken = default) => { if (page < 1) page = 1; if (pageSize < 1) pageSize = 10; if (pageSize > 100) pageSize = 100; using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var query = context.Users.AsNoTracking(); if (status.HasValue) query = query.Where(u => u.Status == status.Value); if (!string.IsNullOrWhiteSpace(email)) query = query.Where(u => u.Email != null && u.Email.Contains(email)); if (!string.IsNullOrWhiteSpace(sortBy)) query = sortBy.ToLowerInvariant() switch { "email" => sortDescending ? query.OrderByDescending(u => u.Email) : query.OrderBy(u => u.Email), "lastloginat" => sortDescending ? query.OrderByDescending(u => u.LastLoginAt) : query.OrderBy(u => u.LastLoginAt), "status" => sortDescending ? query.OrderByDescending(u => u.Status) : query.OrderBy(u => u.Status), _ => sortDescending ? query.OrderByDescending(u => u.Id) : query.OrderBy(u => u.Id) }; else query = query.OrderBy(u => u.Id); var totalCount = await query.CountAsync(cancellationToken); var items = await query.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync(cancellationToken); return Results.Ok(new { Items = items, TotalCount = totalCount, Page = page, PageSize = pageSize }); }) .RequireAuthorization() .WithDescription("Paginated, searchable directory of system users. Supports filtering by ActivityStatus, searching by Email, and sorting") .WithName(typeof(GetUsersEndpoint).ToEndpointName()) .MapToApiVersion(new ApiVersion(1)) .Produces(StatusCodes.Status200OK) .Produces(StatusCodes.Status400BadRequest) .Produces(StatusCodes.Status401Unauthorized) .WithTags(EndpointTags.Users); } }