feat: add campaign templates and recurring schedules
This commit is contained in:
@@ -128,6 +128,60 @@ public sealed class AuthorizedSessionService(ISessionStore sessionStore)
|
||||
return await sessionStore.CloneBatchAsync(batchId, batch.GroupId, interval);
|
||||
}
|
||||
|
||||
public async Task<List<WebCampaignTemplate>?> GetCampaignTemplatesForGmAsync(Guid groupId, long gmId)
|
||||
{
|
||||
if (!await GroupBelongsToGmAsync(groupId, gmId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return await sessionStore.GetCampaignTemplatesAsync(groupId);
|
||||
}
|
||||
|
||||
public async Task<WebCampaignTemplate> CreateCampaignTemplateForGmAsync(
|
||||
Guid groupId,
|
||||
long gmId,
|
||||
CreateCampaignTemplateRequest request)
|
||||
{
|
||||
if (!await GroupBelongsToGmAsync(groupId, gmId))
|
||||
{
|
||||
throw new SessionAccessDeniedException(groupId, gmId);
|
||||
}
|
||||
|
||||
var normalizedRequest = NormalizeCampaignTemplateRequest(request);
|
||||
return await sessionStore.CreateCampaignTemplateAsync(groupId, normalizedRequest);
|
||||
}
|
||||
|
||||
public async Task DeleteCampaignTemplateForGmAsync(Guid templateId, long gmId)
|
||||
{
|
||||
var template = await sessionStore.GetCampaignTemplateAsync(templateId);
|
||||
if (template is null || !await GroupBelongsToGmAsync(template.GroupId, gmId))
|
||||
{
|
||||
throw new SessionAccessDeniedException(templateId, gmId);
|
||||
}
|
||||
|
||||
await sessionStore.DeleteCampaignTemplateAsync(templateId, template.GroupId);
|
||||
}
|
||||
|
||||
public async Task<WebSessionBatch> CreateBatchFromCampaignTemplateForGmAsync(
|
||||
Guid templateId,
|
||||
long gmId,
|
||||
DateTime firstScheduledAt)
|
||||
{
|
||||
if (firstScheduledAt <= DateTime.UtcNow)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(firstScheduledAt), firstScheduledAt, "First scheduled time must be in the future.");
|
||||
}
|
||||
|
||||
var template = await sessionStore.GetCampaignTemplateAsync(templateId);
|
||||
if (template is null || !await GroupBelongsToGmAsync(template.GroupId, gmId))
|
||||
{
|
||||
throw new SessionAccessDeniedException(templateId, gmId);
|
||||
}
|
||||
|
||||
return await sessionStore.CreateBatchFromTemplateAsync(templateId, template.GroupId, firstScheduledAt);
|
||||
}
|
||||
|
||||
public async Task AddCoGmForOwnerAsync(Guid groupId, long ownerTelegramId, long coGmTelegramId, string displayName, string? telegramUsername)
|
||||
{
|
||||
if (coGmTelegramId <= 0)
|
||||
@@ -169,4 +223,48 @@ public sealed class AuthorizedSessionService(ISessionStore sessionStore)
|
||||
{
|
||||
return await sessionStore.IsGroupManagerAsync(groupId, gmId);
|
||||
}
|
||||
|
||||
private static CreateCampaignTemplateRequest NormalizeCampaignTemplateRequest(CreateCampaignTemplateRequest request)
|
||||
{
|
||||
var name = request.Name.Trim();
|
||||
var title = request.Title.Trim();
|
||||
var joinLink = request.JoinLink.Trim();
|
||||
|
||||
if (name.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("Template name must not be empty.", nameof(request));
|
||||
}
|
||||
|
||||
if (title.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("Session title must not be empty.", nameof(request));
|
||||
}
|
||||
|
||||
if (joinLink.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("Join link must not be empty.", nameof(request));
|
||||
}
|
||||
|
||||
if (request.SessionCount is < 1 or > 52)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(request), request.SessionCount, "Session count must be between 1 and 52.");
|
||||
}
|
||||
|
||||
if (request.IntervalDays is < 1 or > 365)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(request), request.IntervalDays, "Interval must be between 1 and 365 days.");
|
||||
}
|
||||
|
||||
if (request.MaxPlayers is <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(request), request.MaxPlayers, "Seat limit must be greater than zero.");
|
||||
}
|
||||
|
||||
return request with
|
||||
{
|
||||
Name = name,
|
||||
Title = title,
|
||||
JoinLink = joinLink
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user