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>
16 lines
692 B
C#
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; }
|
|
}
|