feat: add campaign templates and recurring schedules
Deploy Telegram Bot / build-and-push (push) Successful in 3m49s
Deploy Telegram Bot / deploy (push) Successful in 10s

This commit is contained in:
2026-04-28 10:01:18 +03:00
parent a1ec688ec8
commit 0218890a7a
17 changed files with 1075 additions and 14 deletions
@@ -18,8 +18,33 @@ public sealed record WebSessionBatch(
int SessionCount,
string NotificationMode = SessionNotificationModeExtensions.GroupAndDirectValue);
public sealed record WebCampaignTemplate(
Guid Id,
Guid GroupId,
string Name,
string Title,
string JoinLink,
int SessionCount,
int IntervalDays,
int? MaxPlayers,
string NotificationMode,
DateTime CreatedAt,
DateTime UpdatedAt);
public sealed record CreateCampaignTemplateRequest(
string Name,
string Title,
string JoinLink,
int SessionCount,
int IntervalDays,
int? MaxPlayers,
SessionNotificationMode NotificationMode);
public static class BatchSchedulePlanner
{
private const int MaxTemplateSessionCount = 52;
private const int MaxTemplateIntervalDays = 365;
public static IReadOnlyList<DateTime> BuildFixedIntervalSchedule(
IEnumerable<DateTime> currentSchedule,
DateTime firstScheduledAt,
@@ -36,6 +61,26 @@ public static class BatchSchedulePlanner
.ToList();
}
public static IReadOnlyList<DateTime> BuildRecurringSchedule(
DateTime firstScheduledAt,
int sessionCount,
int intervalDays)
{
if (sessionCount is < 1 or > MaxTemplateSessionCount)
{
throw new ArgumentOutOfRangeException(nameof(sessionCount), sessionCount, "Session count must be between 1 and 52.");
}
if (intervalDays is < 1 or > MaxTemplateIntervalDays)
{
throw new ArgumentOutOfRangeException(nameof(intervalDays), intervalDays, "Interval must be between 1 and 365 days.");
}
return Enumerable.Range(0, sessionCount)
.Select(index => firstScheduledAt.AddDays(intervalDays * index))
.ToList();
}
public static DateTime ShiftForClone(DateTime scheduledAt, BatchCloneInterval interval) =>
interval switch
{