feat(api): REST endpoints for decos, deco groups, playout default deco (#144 S3 (#162))

Adds DecoController (groups + decos CRUD + full-state PUT), playlist and
artist/multi-collection search picker wrappers, a PlaylistController for the
break-content playlist cascade, and PUT /api/playouts/{id}/deco. Fixes the
CreateDecoHandler missing deco-group existence check (FK 500 -> 422), matching
the CreateBlock/CreateTemplate precedent. ReplaceDecoRequest.ToCommand rejects
Merge on the non-mergeable sections (422).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 19:22:39 +02:00
co-authored by Claude Fable 5
parent d48e48f1be
commit 57bb320af8
19 changed files with 2402 additions and 2 deletions
@@ -0,0 +1,4 @@
#nullable enable
namespace ErsatzTV.Core.Api.MediaCollections;
public record PlaylistGroupResponseModel(int Id, string Name, int PlaylistCount, bool IsSystem);
@@ -0,0 +1,4 @@
#nullable enable
namespace ErsatzTV.Core.Api.MediaCollections;
public record PlaylistResponseModel(int Id, int PlaylistGroupId, string Name, bool IsSystem);
@@ -0,0 +1,17 @@
#nullable enable
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Domain.Scheduling;
namespace ErsatzTV.Core.Api.Scheduling;
public record DecoBreakContentResponseModel(
int Id,
CollectionType CollectionType,
int? CollectionId,
int? MediaItemId,
int? MultiCollectionId,
int? SmartCollectionId,
int? PlaylistId,
int? PlaylistGroupId,
string? SelectionName,
DecoBreakPlacement Placement);
@@ -0,0 +1,4 @@
#nullable enable
namespace ErsatzTV.Core.Api.Scheduling;
public record DecoGroupResponseModel(int Id, string Name, int DecoCount);
@@ -0,0 +1,4 @@
#nullable enable
namespace ErsatzTV.Core.Api.Scheduling;
public record DecoListItemResponseModel(int Id, int DecoGroupId, string DecoGroupName, string Name);
@@ -0,0 +1,34 @@
#nullable enable
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Domain.Scheduling;
namespace ErsatzTV.Core.Api.Scheduling;
public record DecoResponseModel(
int Id,
int DecoGroupId,
string DecoGroupName,
string Name,
DecoMode WatermarkMode,
List<int> WatermarkIds,
bool UseWatermarkDuringFiller,
DecoMode GraphicsElementsMode,
List<int> GraphicsElementIds,
bool UseGraphicsElementsDuringFiller,
DecoMode BreakContentMode,
List<DecoBreakContentResponseModel> BreakContent,
DecoMode DefaultFillerMode,
CollectionType DefaultFillerCollectionType,
int? DefaultFillerCollectionId,
int? DefaultFillerMediaItemId,
int? DefaultFillerMultiCollectionId,
int? DefaultFillerSmartCollectionId,
string? DefaultFillerSelectionName,
bool DefaultFillerTrimToFit,
DecoMode DeadAirFallbackMode,
CollectionType DeadAirFallbackCollectionType,
int? DeadAirFallbackCollectionId,
int? DeadAirFallbackMediaItemId,
int? DeadAirFallbackMultiCollectionId,
int? DeadAirFallbackSmartCollectionId,
string? DeadAirFallbackSelectionName);