using FastEndpoints; using Microsoft.EntityFrameworkCore; using Socialize.Api.Data; using Socialize.Api.Infrastructure.Security; using Socialize.Api.Modules.CalendarIntegrations.Data; using Socialize.Api.Modules.CalendarIntegrations.Services; namespace Socialize.Api.Modules.CalendarIntegrations.Handlers; public record ListCalendarSourcesRequest(Guid? WorkspaceId); public class ListCalendarSourcesHandler( AppDbContext dbContext, AccessScopeService accessScopeService) : Endpoint> { public override void Configure() { Get("/api/calendar-integrations/sources"); Options(o => o.WithTags("Calendar Integrations")); } public override async Task HandleAsync(ListCalendarSourcesRequest request, CancellationToken ct) { ArgumentNullException.ThrowIfNull(request); Guid currentUserId = User.GetUserId(); List sources; if (request.WorkspaceId.HasValue) { var workspace = await dbContext.Workspaces .Where(candidate => candidate.Id == request.WorkspaceId.Value) .Select(candidate => new { candidate.Id, candidate.OrganizationId }) .SingleOrDefaultAsync(ct); if (workspace is null) { await SendNotFoundAsync(ct); return; } if (!await accessScopeService.CanAccessWorkspaceAsync(User, workspace.Id, ct)) { await SendForbiddenAsync(ct); return; } sources = await dbContext.CalendarSources .Where(source => source.Scope == CalendarSourceScopes.Organization && source.OrganizationId == workspace.OrganizationId || source.Scope == CalendarSourceScopes.Workspace && source.WorkspaceId == workspace.Id || source.Scope == CalendarSourceScopes.User && source.UserId == currentUserId) .OrderBy(source => source.Scope) .ThenBy(source => source.DisplayTitle) .ToListAsync(ct); await SendOkAsync( sources .Select(source => CalendarSourceDto.FromSource( source, CalendarSourceRules.IsInheritedOrganizationSource(source, workspace.OrganizationId))) .ToArray(), ct); return; } sources = await dbContext.CalendarSources .Where(source => source.Scope == CalendarSourceScopes.User && source.UserId == currentUserId) .OrderBy(source => source.DisplayTitle) .ToListAsync(ct); await SendOkAsync( sources.Select(source => CalendarSourceDto.FromSource(source, isReadOnly: false)).ToArray(), ct); } }