Files
social-media/backend/src/Socialize.Api/Modules/CalendarIntegrations/Handlers/CalendarSourceDtos.cs
Jonathan Bourdon b66c10b681
Some checks failed
Backend CI/CD / build_and_deploy (push) Has been cancelled
Frontend CI/CD / build_and_deploy (push) Has been cancelled
Add calendar integrations and collaboration updates
2026-05-05 15:25:53 -04:00

113 lines
4.1 KiB
C#

using Socialize.Api.Modules.CalendarIntegrations.Data;
using Socialize.Api.Modules.CalendarIntegrations.Services;
namespace Socialize.Api.Modules.CalendarIntegrations.Handlers;
public record CalendarSourceDto(
Guid Id,
string Scope,
Guid? OrganizationId,
Guid? WorkspaceId,
Guid? UserId,
string? SourceUrl,
string? CatalogSourceReference,
string DisplayTitle,
string Color,
string Category,
bool IsEnabled,
string? InheritanceMode,
bool IsReadOnly,
DateTimeOffset? LastSuccessfulSyncAt,
DateTimeOffset? LastAttemptedSyncAt,
string? LastSyncError,
DateTimeOffset CreatedAt,
DateTimeOffset UpdatedAt)
{
public static CalendarSourceDto FromSource(CalendarSource source, bool isReadOnly)
{
return new CalendarSourceDto(
source.Id,
source.Scope,
source.OrganizationId,
source.WorkspaceId,
source.UserId,
source.SourceUrl,
source.CatalogSourceReference,
source.DisplayTitle,
source.Color,
source.Category,
source.IsEnabled,
source.InheritanceMode,
isReadOnly,
source.LastSuccessfulSyncAt,
source.LastAttemptedSyncAt,
source.LastSyncError,
source.CreatedAt,
source.UpdatedAt);
}
}
public record UpsertCalendarSourceRequest(
string Scope,
Guid? OrganizationId,
Guid? WorkspaceId,
string? SourceUrl,
string? CatalogSourceReference,
string DisplayTitle,
string Color,
string Category,
bool IsEnabled,
string? InheritanceMode);
public class UpsertCalendarSourceRequestValidator
: FastEndpoints.Validator<UpsertCalendarSourceRequest>
{
public UpsertCalendarSourceRequestValidator()
{
RuleFor(x => x.Scope)
.NotEmpty()
.Must(CalendarSourceRules.IsSupportedScope)
.WithMessage("A valid calendar source scope should be specified.");
RuleFor(x => x.DisplayTitle).NotEmpty().MaximumLength(256);
RuleFor(x => x.Category).NotEmpty().MaximumLength(64);
RuleFor(x => x.Color)
.NotEmpty()
.Matches("^#[0-9A-Fa-f]{6}$")
.WithMessage("Color should be a six digit hex color, for example #2F80ED.");
RuleFor(x => x.SourceUrl)
.MaximumLength(2048)
.Must(value => string.IsNullOrWhiteSpace(value) || Uri.TryCreate(value, UriKind.Absolute, out Uri? uri) &&
(uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
.WithMessage("Source URL should be an absolute HTTP or HTTPS URL.");
RuleFor(x => x.CatalogSourceReference).MaximumLength(256);
RuleFor(x => x)
.Must(x => !string.IsNullOrWhiteSpace(x.SourceUrl) || !string.IsNullOrWhiteSpace(x.CatalogSourceReference))
.WithMessage("A source URL or catalog source reference should be specified.");
RuleFor(x => x)
.Must(x => x.Scope != CalendarSourceScopes.Organization || x.OrganizationId.HasValue)
.WithMessage("Organization calendar sources require an organization id.");
RuleFor(x => x)
.Must(x => x.Scope != CalendarSourceScopes.Workspace || x.WorkspaceId.HasValue)
.WithMessage("Workspace calendar sources require a workspace id.");
RuleFor(x => x)
.Must(x => x.Scope != CalendarSourceScopes.User || (!x.OrganizationId.HasValue && !x.WorkspaceId.HasValue))
.WithMessage("User calendar sources should not include organization or workspace ids.");
RuleFor(x => x)
.Must(x => x.Scope == CalendarSourceScopes.Organization ||
(!x.OrganizationId.HasValue && string.IsNullOrWhiteSpace(x.InheritanceMode)))
.WithMessage("Only organization calendar sources can set organization ids or inheritance modes.");
RuleFor(x => x.InheritanceMode)
.Must(value => string.IsNullOrWhiteSpace(value) || CalendarSourceRules.IsSupportedInheritanceMode(value))
.WithMessage("A valid inheritance mode should be specified.");
}
}