The rebase onto origin/main (which merged #74's ChannelGraphicsElement
migration) left the PadToNearestMinute migration's embedded Designer.cs
model snapshot stale — it still reflected the pre-#74 model, so EF's
diff against it produced an empty Up()/Down() when naively regenerated.
Reset TvContextModelSnapshot.cs to origin/main's true post-#74 state,
then re-ran scripts/add-migration.sh so the migration's Designer.cs
correctly folds in ChannelGraphicsElement and the migration's Up() adds
only the PadToNearestMinute column. Verified has-pending-model-changes
is clean for both providers.
OpenAPI (v1.json/v1.d.ts/endpoint-index.md) and docs/decisions/README.md
regenerated identically to the auto-merged state, so nothing to commit
there — confirmed both padToNearestMinute and #74's graphics-elements
endpoints/decision key are present.
Stripped a UTF-8 BOM this dotnet-ef/dotnet-format toolchain wrote into
the regenerated migration + snapshot files (known BOM trap, ersatztv#311).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Schedule-level pad control has no prototype counterpart (the schedule-level
scalar form is not modeled in Schedules.jsx); nothing to mirror there.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>