Commit Graph
3319 Commits
Author SHA1 Message Date
timothyandClaude Opus 4.8 b4ae0bde18 feat(434): distinct-values search endpoint (text fields, Lucene term enumeration)
Adds GET /api/v1/search/fields/{name}/values?q=&limit= — the backend slice of the
visual rule builder's facet-value typeahead (#434). Enumerates distinct Lucene term
values for a text field via MultiFields.GetTerms + TermsEnum, filtered by a
case-insensitive prefix, limit clamped to [1,50]. 404s when the field is absent from
SearchFieldCatalog or is not type "text". ElasticSearchIndex (the optional external
backend) throws NotSupportedException for this method — its text fields are analyzed,
not keyword-mapped, so a terms aggregation isn't safe to guess at without verifying
against a live cluster.

Regenerated OpenAPI trio (v1.json, v1.d.ts, endpoint-index.md).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:43:27 +02:00
timothyandClaude Opus 4.8 b66a3400ae feat(438,435): RuleBuilder UI — validation surface, relative-date inputs, single-child toggle
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:43:26 +02:00
timothyandClaude Opus 4.8 30a8a5752c feat(435): parse relative-date macros; round-trip against normalizeGroup
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:43:26 +02:00
timothyandClaude Opus 4.8 d487ce3601 fix(438): drop empty nested subgroups instead of emitting "()" in compiled Lucene
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:43:26 +02:00
timothyandClaude Opus 4.8 575f652760 feat(438,435): compile relative-date macros; drop invalid rules instead of malformed Lucene
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:43:26 +02:00
timothyandClaude Opus 4.8 000a987a48 test(435): cover all relative-date combos, invalid-input rejection, composed round-trip
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:43:26 +02:00
timothyandClaude Opus 4.8 e91891a453 feat(435): dateMacro compile/parse mapping for relative-date operators
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:43:26 +02:00
timothyandClaude Opus 4.8 c301db10c4 feat(438,435): extend rule types; validation + single-child normalization helpers
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:43:26 +02:00
timothyandClaude Opus 4.8 5618ad12ea plan(434,435,438): RuleBuilder bundle implementation plan
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:43:26 +02:00
timothyandClaude Opus 4.8 4e2183d9a3 design(434,435,438): RuleBuilder bundle spec — validation, relative-date operators, facet typeahead
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:43:26 +02:00
timothyandtimothy 8b9a7ed541 feat(414): stamp immutable Channel.Origin (auto-tuned vs user-created) and surface it (#575)
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 6m23s
Build ErsatzTV Image / Functional E2E (curl contracts) (push) Successful in 14m21s
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 19m9s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 12m1s
Co-authored-by: Timothy <timothy.look@gmail.com>
Co-committed-by: Timothy <timothy.look@gmail.com>
2026-07-23 18:12:25 +00:00
timothyandtimothy 7a7c611267 fix(458): reject duplicate names on playlist &amp; playlist-group rename (#576)
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / Build & push image (amd64) (push) Has been cancelled
Build ErsatzTV Image / Build & test (.NET) (push) Has been cancelled
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Has been cancelled
Build ErsatzTV Image / Functional E2E (curl contracts) (push) Has been cancelled
Co-authored-by: Timothy <timothy.look@gmail.com>
Co-committed-by: Timothy <timothy.look@gmail.com>
2026-07-23 18:07:43 +00:00
timothyandtimothy 0c063c23fb harden(421,559): percent-encode access_token in IPTV URLs, redact from logs, no-store on tokened manifests (#574)
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 7m45s
Build ErsatzTV Image / Functional E2E (curl contracts) (push) Successful in 14m19s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 18m27s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 4m10s
Co-authored-by: Timothy <timothy.look@gmail.com>
Co-committed-by: Timothy <timothy.look@gmail.com>
2026-07-23 16:30:59 +00:00
timothy 41291b3686 Merge pull request #573 (feat/392): per-schedule clock-boundary padding toggle + 60-min increment
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / Functional E2E (curl contracts) (push) Successful in 32s
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 33s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 33s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 5m40s
2026-07-23 07:10:29 +00:00
timothy bb3e245b3c docs(392): drop predecessor cross-ref line (append-only decisions diff)
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 11s
PR Gates / Docs update reminder (pull_request) Successful in 12s
PR Gates / decisions lifecycle (pull_request) Successful in 21s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m53s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 4m44s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 8s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 14m58s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 19m45s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
2026-07-23 08:27:02 +02:00
timothyandClaude Opus 4.8 60fecd18b7 chore(392): regenerate migration + OpenAPI + decisions catalog after rebase onto main
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 27s
PR Gates / Docs update reminder (pull_request) Successful in 38s
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 34s
PR Gates / decisions lifecycle (pull_request) Failing after 43s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 14m55s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 18m23s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 22m58s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 23m49s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
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>
2026-07-23 08:18:15 +02:00
timothy 767f96802e fix(392): apply schedule-level pad to Fill-With-Group items (reverse nav lost in DeepCopy) 2026-07-23 08:03:31 +02:00
timothyandClaude Opus 4.8 6a05363e2a design(392): mirror 60-min pad option into FillerPresets prototype
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>
2026-07-23 08:03:31 +02:00
timothy e99e72ee71 docs(392): record per-schedule clock-padding decision + domain-model field 2026-07-23 08:03:31 +02:00
timothy f4ba219000 feat(392): add pad-to-clock-boundary control to the schedule editor 2026-07-23 08:03:31 +02:00
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
timothy 7efe38dd04 feat(392): honor ProgramSchedule.PadToNearestMinute in the Classic builder 2026-07-23 08:03:31 +02:00
timothy 9ea2750cbf feat(392): expose ProgramSchedule.padToNearestMinute on the REST API 2026-07-23 08:03:31 +02:00
timothy 75d5c385b2 feat(392): add ProgramSchedule.PadToNearestMinute column (dual-provider migration) 2026-07-23 08:03:31 +02:00
timothy 2f1ede6030 feat(392): add 60-minute option to filler-preset pad increment 2026-07-23 08:03:31 +02:00
timothy 0b814abf41 docs(392): extract shared ComputePadBoundary helper in plan (DRY) 2026-07-23 08:03:31 +02:00
timothyandClaude Opus 4.8 9385bc8acd docs(392): implementation plan for per-schedule clock-boundary padding
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 08:03:31 +02:00
timothyandClaude Opus 4.8 425b4b65f9 docs(392): design spec for per-schedule clock-boundary padding toggle
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 08:03:31 +02:00
timothy 5a7a4ed7e0 Merge pull request 'fix(570): On Now/Next overlay YAML renders (font_family + format_datetime)' (#571) from fix/74-overlay-render into main
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 15s
Build ErsatzTV Image / Functional E2E (curl contracts) (push) Successful in 28s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 29s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 9m39s
Merge pull request '#571 fix(570): On Now/Next overlay YAML renders (font_family + format_datetime)' (#571) from fix/74-overlay-render into main

fixes #570
2026-07-22 21:39:32 +00:00
timothyandClaude Opus 4.8 892f4e354b fix(570): On Now/Next overlay YAML renders — font_family + format_datetime
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 13s
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 16s
PR Gates / Docs update reminder (pull_request) Successful in 17s
PR Gates / decisions lifecycle (pull_request) Successful in 21s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 1m28s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 15m46s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 15m50s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 20m18s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
The #74 seeded on-now-next.yml never rendered at transcode time:
- format_datetime was called with 2 args; it needs 3 (DateTimeOffset, timeZoneId,
  format) and does the tz conversion itself, so the Scriban render threw. Drop the
  NEXT start-time (avoids hardcoding a timezone in a shipped default).
- styles had no font_family; CustomFontMapper.TypefaceFromStyle crashes on a null
  family before its default-font fallback. Add font_family: Noto Sans.
Verified live on ersatztv-test via frame capture. Adds a seeder test that
deserializes the YAML and asserts base_style resolves + every style sets a font.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 23:10:35 +02:00
timothy 7080f63ebe Merge pull request 'feat(74): per-channel On Now/Next transient overlay' (#569) from feat/74-on-now-next-overlay into main
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 15s
Build ErsatzTV Image / Functional E2E (curl contracts) (push) Successful in 28s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 29s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 5m45s
Merge pull request '#569 feat(74): per-channel On Now/Next transient overlay' (#569) from feat/74-on-now-next-overlay into main

fixes #74
2026-07-22 20:36:41 +00:00
timothyandClaude Opus 4.8 b7d58bbf32 docs(74): tighten overlay suppression rule (Merge-during-filler also clears)
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 15s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 17s
PR Gates / Docs update reminder (pull_request) Successful in 20s
PR Gates / decisions lifecycle (pull_request) Successful in 22s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 14m25s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 16m45s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 16m51s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 21m18s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Folds whole-branch review finding #2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 22:11:46 +02:00
timothy c80839b338 docs(74): channel-level graphics attachment + On Now/Next overlay 2026-07-22 22:11:46 +02:00
timothy b139921691 feat(74): channel Branding-tab On Now/Next overlay toggle 2026-07-22 22:11:46 +02:00
timothy 7757814766 feat(74): channel graphicsElementIds + graphics builtIn; regen OpenAPI 2026-07-22 22:11:46 +02:00
timothy d6652dbe13 feat(74): selector emits channel-level graphics elements as a base layer 2026-07-22 22:11:46 +02:00
timothyandClaude Opus 4.8 fe0a273aad feat(74): add ChannelGraphicsElement join + dual-provider migration
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 22:11:45 +02:00
timothy 9c6b524aed feat(74): seed built-in on-now-next.yml text element (file + marker) 2026-07-22 22:11:45 +02:00
timothy ed3acb931c docs(74): fix Task 3 test to Testably MockFileSystem API 2026-07-22 22:11:45 +02:00
timothyandClaude Opus 4.8 6ad2f83ea6 docs(74): implementation plan for On Now/Next overlay
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 22:11:45 +02:00
timothyandClaude Opus 4.8 2901b5293a docs(74): design spec for per-channel On Now/Next transient overlay
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 22:11:45 +02:00
timothy d759a9fc83 Merge pull request 'refactor(395): dedup Scripted≡YAML enumerator construction into ContentEnumeratorBuilder' (#566) from issue-395-dedup-enumerator into main
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Functional E2E (curl contracts) (push) Successful in 31s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 31s
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 32s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 9m37s
2026-07-22 18:52:23 +00:00
timothyandClaude Opus 4.8 7b77a37f0f docs(395): keep the decision record's original heading (fix decisions-lifecycle)
PR Gates / decisions lifecycle (pull_request) Successful in 18s
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 21s
PR Gates / Docs update reminder (pull_request) Successful in 24s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 5m22s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 9s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 7s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 19m22s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 19m58s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
The lifecycle validator matches records by their `##` heading for removal
detection (gone = base_headings - head_headings), ungated by [decisions-edit].
Renaming the heading read as an unlogged record removal. Restore the exact
original heading -- which stays literally true ("excluded from the golden net":
#395 adds a unit test, not a golden) -- and keep the rationale correction in the
Rule/Signals/body, which is what [decisions-edit] authorizes.

[decisions-edit]

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 20:28:58 +02:00
timothyandClaude Opus 4.8 f54c9ae195 refactor(395): dedup Scripted≡YAML enumerator construction into ContentEnumeratorBuilder
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 9s
PR Gates / Docs update reminder (pull_request) Successful in 13s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 1m25s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 1m21s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 7m36s
PR Gates / decisions lifecycle (pull_request) Failing after 14s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been cancelled
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Has been cancelled
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Has been cancelled
Extract the byte-identical PlaybackOrder -> IMediaCollectionEnumerator switch
shared by SchedulingEngine.EnumeratorForContent (Scripted) and
EnumeratorCache.GetEnumeratorForContent (Sequential/YAML) into one static
per-family seam, mirroring #380's ShuffleSourceBuilder. Each engine keeps its own
"not supported" warning on the None branch, so the per-engine message is unchanged.
Adds ContentEnumeratorBuilderTests pinning the block-shuffle-not-classic trap and
the unsupported-order -> None (#70) contract across all 8 unsupported orders.

Corrects the testing.scripted-playout-golden-deferred decision record: Scripted's
external-process + HTTP pipeline is integration-only (deferred to #563), but the
in-process SchedulingEngine it drives IS unit-testable (ScriptedScheduleController
is a 1:1 pass-through) -- the earlier "un-golden-able by construction" framing
conflated transport with engine. docs/testing.md reframed to match.

[decisions-edit]

fixes #395

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 20:21:52 +02:00
timothy 5c20a98468 Merge pull request 'test(381): Sequential (YAML) playout golden; document Scripted deferral' (#564) from feat/381-scheduler-goldens into main
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / Functional E2E (curl contracts) (push) Successful in 5m47s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 18m56s
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 19m8s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 6m14s
2026-07-22 17:40:31 +00:00
timothy 04ca7ae981 Merge pull request 'feat(297): add channelId to PlayoutListItemResponseModel; SPA reset keys directly' (#562) from issue-297-playout-channelid into main
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / Build & test (.NET) (push) Has started running
Build ErsatzTV Image / Build & push image (amd64) (push) Has been cancelled
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Has been cancelled
Build ErsatzTV Image / Functional E2E (curl contracts) (push) Has been cancelled
2026-07-22 17:30:24 +00:00
timothy 5c73c7a4bd Merge pull request 'fix(248): focus-trap the shared modal overlay so Tab can't escape a dialog' (#561) from issue-248-overlay-focus-trap into main
Build ErsatzTV Image / Build & test (.NET) (push) Has started running
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Has started running
Build ErsatzTV Image / Functional E2E (curl contracts) (push) Has been cancelled
Build ErsatzTV Image / Build & push image (amd64) (push) Has been cancelled
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been cancelled
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been cancelled
2026-07-22 17:30:13 +00:00
timothyandClaude Opus 4.8 80a9824a4e test(381): golden coverage for Sequential (YAML) playout builder; document Scripted deferral
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 28s
PR Gates / Docs update reminder (pull_request) Successful in 46s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 7m53s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 17s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 18s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 5m29s
PR Gates / decisions lifecycle (pull_request) Successful in 18s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 21m0s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Extends the #163 PlayoutBuildGoldenTests in-memory net to the Sequential (YAML)
builder: a committed fixture (Goldens/Fixtures/sequential-schedule.yml) with two
`count: 2` instructions over one chronological collection, built via
SequentialPlayoutBuilder over the pinned window. The count/all/duration handlers
do UTC-only arithmetic off the caller-supplied start, so the case is
TZ-independent (passes, not skips, under a non-UTC TZ) and needs no Assume guard.
Non-vacuity: a fixture count tweak flips the golden + the contiguity assertion.

Scripted is deliberately excluded from the golden net — ScriptedPlayoutBuilder
shells out via Cli.Wrap to an external process that drives SchedulingEngine over
HTTP, which no in-memory golden can characterize. Recorded as the Done-when
"documented decision" arm in docs/decisions.md
(testing.scripted-playout-golden-deferred) + docs/testing.md; the scripted
integration harness is tracked as follow-up #563.

fixes #381

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 19:18:12 +02:00
timothyandClaude Opus 4.8 1a3c8e277f feat(297): add channelId to PlayoutListItemResponseModel; SPA reset keys directly
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 11s
PR Gates / Docs update reminder (pull_request) Successful in 12s
PR Gates / decisions lifecycle (pull_request) Successful in 20s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 7m37s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 21s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 4m54s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 19m41s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 16m43s
Added ChannelId to PlayoutNameViewModel and all 6 construction sites
(Mapper, GetPlayoutByIdHandler, and the Update{,Scripted,ExternalJson,Sequential}
PlayoutHandler commands), plus the list DTO PlayoutListItemResponseModel and the
PlayoutController list projection. Regenerated OpenAPI (v1.json) and the TS client
(v1.d.ts); endpoint-index.md unchanged (no endpoint/operation delta). Simplified
PlayoutsScreen resetSelectedChannel to key directly on selectedSummary.channelId
instead of resolving via channelStates. Updated controller + SPA tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 18:57:54 +02:00
timothyandClaude Opus 4.8 ae4408c6b2 fix(248): focus-trap the shared modal overlay so Tab can't escape a dialog
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 11s
PR Gates / Docs update reminder (pull_request) Successful in 12s
PR Gates / decisions lifecycle (pull_request) Successful in 21s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 5m42s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 8s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 7s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 20m21s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 20m28s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
focus trap added to shared useOverlayBehavior (covers Dialog + SlideOver);
Tab/Shift+Tab now cycle within the panel; test added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 18:55:26 +02:00