Files
ersatztv/ErsatzTV.Core/Scheduling/PlayoutSchedulerResult.cs
T
timothyandClaude Opus 4.8 beab219a90 test(392): cover schedule pad through Flood/Duration/Multiple; make day-seam clamp precise
Adds parameterized invariant tests (Schedule_clock_padded_offline_multimode)
exercising schedule-level clock pad + offline advance across a 2-day window
(two midnight crossings) through Flood, Duration, and Multiple — previously
only PlayoutModeSchedulerOne had any coverage. Fixture uses sub-15-min content
so each padded item occupies one :15 slot and Duration's fill-the-block
contract tiles exactly (no off-boundary packing).

Part 2 (precision): replaces the day-boundary anchor-clamp magnitude heuristic
(overrun <= one pad interval on a padded schedule) with a precise signal — the
last scheduler now reports the exact offline-pad target it advanced CurrentTime
to (transient PlayoutSchedulerResult.ClockPadOfflineTarget, never persisted),
and the clamp exempts only when CurrentTime equals that target exactly. A
non-offline overrun (Duration/Flood/Multiple ending short of its natural end, a
hard-stop, a tail advance) changes CurrentTime away from the target and still
clamps, so persisted NextStart no longer shifts by up to an interval. No
persisted-schema/migration change. Output byte-identical for all existing
goldens.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 08:03:31 +02:00

16 lines
692 B
C#

using ErsatzTV.Core.Domain;
namespace ErsatzTV.Core.Scheduling;
public record PlayoutSchedulerResult(
PlayoutBuilderState State,
List<PlayoutItem> PlayoutItems,
PlayoutBuildWarnings Warnings)
{
// #392: the exact clock-boundary target the last scheduled item advanced CurrentTime to when a
// schedule-level pad left an OFFLINE gap (no filler emitted). Non-null ONLY for such an advance; the
// day-boundary anchor clamp in PlayoutBuilder reads it (by exact CurrentTime equality) so an offline
// pad advance survives the seam. Transient/in-memory only — never serialized to the PlayoutAnchor.
public DateTimeOffset? ClockPadOfflineTarget { get; init; }
}