using System.Security.Claims; using api.Data; using api.Features.Auth.Common; using api.Features.Projects.Common; using FastEndpoints; using Microsoft.EntityFrameworkCore; namespace api.Features.Projects.Endpoints; public class ListProjectsRequest { public Guid WorkspaceId { get; set; } } public class ListProjectsEndpoint(AppDbContext db) : Endpoint { public override void Configure() { Get("/workspaces/{WorkspaceId}/projects"); } public override async Task HandleAsync(ListProjectsRequest req, CancellationToken ct) { var userId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!); // Verify workspace ownership var workspaceExists = await db.Workspaces .AnyAsync(w => w.Id == req.WorkspaceId && w.OwnerUserId == userId, ct); if (!workspaceExists) { await HttpContext.Response.SendAsync(new MessageResponse("Workspace not found"), 404, cancellation: ct); return; } var projects = await db.Projects .Where(p => p.WorkspaceId == req.WorkspaceId) .OrderByDescending(p => p.CreatedAt) .Select(p => new ProjectResponse( p.Id, p.WorkspaceId, p.Name, p.CreatedAt )) .ToListAsync(ct); await HttpContext.Response.SendAsync(new ProjectListResponse(projects), 200, cancellation: ct); } }