From f06bc064a06a7f6c3c511d6d4d790975944a3b55 Mon Sep 17 00:00:00 2001 From: Timothy Date: Tue, 7 Jul 2026 17:30:38 +0200 Subject: [PATCH] fix(api): apply schedule-file update before daily rebuild time in PUT /api/playouts/{id} (#170 review) A rejected scripted schedule file no longer leaves DailyRebuildTime half-applied; the file update is the only fallible step post-pre-check. Co-Authored-By: Claude Fable 5 --- ErsatzTV/Controllers/Api/PlayoutController.cs | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/ErsatzTV/Controllers/Api/PlayoutController.cs b/ErsatzTV/Controllers/Api/PlayoutController.cs index 27b9f8f99..eeb29ff4c 100644 --- a/ErsatzTV/Controllers/Api/PlayoutController.cs +++ b/ErsatzTV/Controllers/Api/PlayoutController.cs @@ -148,25 +148,28 @@ public class PlayoutController(IMediator mediator) : ControllerBase } } + // the schedule-file update is the only step that can fail after the pre-checks, + // so it goes first — a rejected file must not leave DailyRebuildTime applied + if (hasScheduleFile) + { + foreach (PlayoutNameViewModel playout in maybePlayout) + { + Either scheduleFileResult = + await UpdateScheduleFile(playout, request.ScheduleFile, cancellationToken); + foreach (BaseError error in scheduleFileResult.LeftToSeq()) + { + return error.ToErrorResult(); + } + } + } + Option dailyRebuildTime = request.DailyRebuildTime is { } t ? Some(t) : Option.None; Either result = await mediator.Send(new UpdatePlayout(id, dailyRebuildTime), cancellationToken); - return await result.Match( - Left: error => Task.FromResult(error.ToErrorResult()), - Right: async playout => - { - if (!hasScheduleFile) - { - return (IActionResult)new OkObjectResult(ToResponse(playout)); - } - - Either scheduleFileResult = - await UpdateScheduleFile(playout, request.ScheduleFile, cancellationToken); - return scheduleFileResult.Match( - Left: error => error.ToErrorResult(), - Right: updated => (IActionResult)new OkObjectResult(ToResponse(updated))); - }); + return result.Match( + Left: error => error.ToErrorResult(), + Right: playout => (IActionResult)new OkObjectResult(ToResponse(playout))); } private async Task> UpdateScheduleFile(