Implement BumperEndpoints and remove deprecated bumper-related functionality
ci / build-backend (push) Successful in 1m39s
ci / build-frontend (push) Failing after 26s
ci / tests (push) Skipped
ci / sonar (push) Skipped

Added new BumperEndpoints to the API for managing bumper templates and variants, enhancing the channel management capabilities. Removed outdated bumper-related commands and handlers from the application, streamlining the codebase and improving maintainability. Updated ChannelEndpoints to reflect these changes and ensure proper routing for the new endpoints.
This commit is contained in:
Leonid Pershin
2026-07-27 22:01:56 +03:00
parent ee0b4d2d01
commit ba3721eb92
140 changed files with 7326 additions and 3609 deletions
@@ -85,11 +85,19 @@ public sealed record PlanningSlot(
public DateTimeOffset TargetEndUtc => TargetStartUtc.AddMinutes(TargetDurationMinutes);
}
/// <summary>Окно времени суток в часах канала; допускает переход через полночь (22:00 → 06:00).</summary>
public sealed record PlanningTimeWindow(TimeOnly From, TimeOnly To)
{
public bool Contains(TimeOnly moment) =>
From <= To ? moment >= From && moment < To : moment >= From || moment < To;
}
/// <summary>
/// Врезка стыка, развёрнутая для планировщика: единицы уже подобраны оркестратором, домену остаётся
/// решить, сколько их поставить и влезают ли они.
/// </summary>
public sealed record PlanningJunctionElement(
Guid ElementId,
JunctionElementKind Kind,
IReadOnlyList<PlanningUnit> Units,
JunctionAmountMode AmountMode,
@@ -99,8 +107,17 @@ public sealed record PlanningJunctionElement(
bool OnlyOnElementChange = false,
/// <summary>Не ставить чаще, чем раз в N минут (0 — без ограничения).</summary>
int MinMinutesBetween = 0,
/// <summary>Вероятность показа в процентах (100 — всегда).</summary>
int Chance = 100,
/// <summary>Окно времени суток, вне которого врезка не ставится (null — всегда).</summary>
PlanningTimeWindow? TimeWindow = null,
/// <summary>Метка развилки: из врезок с одной меткой ставится одна, выбранная по весам.</summary>
string? ChoiceKey = null,
int ChoiceWeight = 1,
/// <summary>Блок заставки — ассет рендерится позже, планировщик резервирует длительность.</summary>
Guid? BumperTemplateId = null,
/// <summary>Конкретный подблок заставки; null — выберет резолвер по триггеру и весам.</summary>
Guid? BumperVariantId = null,
/// <summary>Длительность резерва под заставку.</summary>
TimeSpan BumperDuration = default
);
@@ -108,7 +125,9 @@ public sealed record PlanningJunctionElement(
/// <summary>Стык: последовательность врезок между программами.</summary>
public sealed record PlanningJunction(
Guid JunctionId,
IReadOnlyList<PlanningJunctionElement> Elements
IReadOnlyList<PlanningJunctionElement> Elements,
/// <summary>Потолок длины стыка целиком (null — ограничен только якорем).</summary>
TimeSpan? MaxTotal = null
);
/// <summary>Полный вход одного прогона генератора.</summary>
@@ -119,7 +138,9 @@ public sealed record PlanningInput(
IReadOnlyList<PlanningSlot> Slots,
/// <summary>Чем закрывать место, не покрытое слотами и не заполненное контентом.</summary>
IReadOnlyList<PlanningUnit> FallbackUnits,
int SegmentSeconds
int SegmentSeconds,
/// <summary>Смещение времени канала от UTC — по нему считаются окна суток у врезок стыка.</summary>
int UtcOffsetMinutes = 0
);
/// <summary>Одна запись будущей ленты. Трейс пишется здесь же — восстановить его потом невозможно.</summary>
@@ -136,6 +157,8 @@ public sealed record PlannedItem(
Guid? BumperTemplateId = null,
Guid? FromShowId = null,
Guid? ToShowId = null,
/// <summary>Подблок заставки, если врезка задала его жёстко; null — выберет резолвер.</summary>
Guid? BumperVariantId = null,
/// <summary>Коллекция, частью которой шла единица (null — шоу играло само по себе).</summary>
Guid? CollectionId = null
);