Files
ersatztv/ErsatzTV/Controllers/Api/Requests/CreatePlayoutRequest.cs
T
timothy 5f202a2175 feat(api): REST endpoints to create playouts of all kinds + update details (#144 S5 (#162))
- CreatePlayoutRequest now carries a PlayoutScheduleKind discriminator, a
  nullable ProgramScheduleId, and a ScheduleFile so POST /api/playouts can
  create Classic, Block, Sequential, Scripted, or ExternalJson playouts (not
  just Classic). ToCommand() validates per-kind requirements and returns
  Either<BaseError, CreatePlayout>, surfacing 422 on mismatched fields via the
  existing ToErrorResult() mapping.
- Add PUT /api/playouts/{id} (UpdatePlayoutDetailsRequest): DailyRebuildTime is
  always applied (null clears the daily reset, matching the Blazor
  SchedulePlayoutReset "Do not automatically reset" semantics); ScheduleFile is
  only valid for Sequential/Scripted/ExternalJson playouts (422 otherwise) and
  dispatches the matching Update*Playout command.
- Playout existence is checked via GetPlayoutById (real 404) before dispatching
  UpdatePlayout, since the command's own "Playout does not exist." validation
  produces a plain BaseError (422), not NotFoundError -- an existing quirk in
  UpdatePlayoutHandler left as-is (out of scope for this slice).
- Extend ApiErrorResponseMetadataTests + PlayoutControllerTests for the new
  Update action and the widened Create action (block/sequential/file-kind
  validation paths).
- Regenerate ErsatzTV/wwwroot/openapi/v1.json via update-openapi.sh.
2026-07-07 17:08:43 +02:00

32 lines
1.5 KiB
C#

using ErsatzTV.Application.Playouts;
using ErsatzTV.Core;
using ErsatzTV.Core.Domain;
namespace ErsatzTV.Controllers.Api.Requests;
public record CreatePlayoutRequest(
int ChannelId,
PlayoutScheduleKind ScheduleKind,
int? ProgramScheduleId,
string ScheduleFile)
{
public Either<BaseError, CreatePlayout> ToCommand() =>
ScheduleKind switch
{
PlayoutScheduleKind.Classic => ProgramScheduleId is { } programScheduleId
? new CreateClassicPlayout(ChannelId, programScheduleId)
: BaseError.New("[ProgramScheduleId] is required for Classic playouts"),
PlayoutScheduleKind.Block => new CreateBlockPlayout(ChannelId),
PlayoutScheduleKind.Sequential => !string.IsNullOrWhiteSpace(ScheduleFile)
? new CreateSequentialPlayout(ChannelId, ScheduleFile)
: BaseError.New("[ScheduleFile] is required for Sequential playouts"),
PlayoutScheduleKind.Scripted => !string.IsNullOrWhiteSpace(ScheduleFile)
? new CreateScriptedPlayout(ChannelId, ScheduleFile)
: BaseError.New("[ScheduleFile] is required for Scripted playouts"),
PlayoutScheduleKind.ExternalJson => !string.IsNullOrWhiteSpace(ScheduleFile)
? new CreateExternalJsonPlayout(ChannelId, ScheduleFile)
: BaseError.New("[ScheduleFile] is required for ExternalJson playouts"),
_ => BaseError.New("[ScheduleKind] must be one of Classic, Block, Sequential, Scripted, ExternalJson")
};
}