Commit Graph
2398 Commits
Author SHA1 Message Date
timothy dfa561a97e feat(api): logs and troubleshooting-info endpoints for SPA parity (#145, #158)
Add GET /api/logs (thin wrapper over GetRecentLogEntries; paged, filtered,
clamped pageSize like LibraryBrowseController) and GET /api/troubleshoot/info
(wraps GetTroubleshootingInfo; General section serialized to the same JSON
shape the legacy Blazor Troubleshooting page renders, plus per-platform
capability dumps). Also adds [EndpointGroupName("general")] to the existing
troubleshoot playback endpoints so they surface in the OpenAPI spec (#158
item 3).
2026-07-07 13:34:47 +02:00
timothyandClaude Fable 5 6e091c98ae ci: retrigger main build (flaky Libraries scan-polling test, see #157)
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m15s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m43s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 4m38s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:05:56 +02:00
timothyandClaude Fable 5 22fa3ecb08 docs: advance ChicoryTV queue past parity #140/#146/#147 (PRs #150/#154/#156); gaps #151-#153/#155 filed; next prompt = parity #141-#145
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m33s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m55s
Build ErsatzTV Image / Build & push image (amd64) (push) Failing after 43s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:57:51 +02:00
timothy d58deddc48 Merge pull request 'feat(web): collections management screen — manual + smart collections (#140)' (#156) from feat/140-collections-screen into main
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 / Build & test (.NET) (push) Has been cancelled
2026-07-07 10:54:19 +00:00
timothyandClaude Fable 5 5995707c84 feat(web): collections management screen for manual + smart collections (#140)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m37s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 3m30s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Replaces the PlaceholderScreen at /app/collections with a real screen that
covers manual and smart collections, matching the SPA's extracted-screen
pattern (screens/CollectionsScreen.tsx; App.tsx gets only the route branch +
import).

Manual collections: list, create, rename, delete, and a per-row toggle for
UseCustomPlaybackOrder (PUT). Item management: an add-items picker that searches
the library (library/browse) and buckets results into the typed
AddItemsToCollectionRequest, plus per-item remove.

Smart collections: list, create, edit (name + query), delete, with a live
result preview that runs the query through library/browse.

API layer: new api/collections.ts owns the typed CRUD (getCollections/
getSmartCollections moved here from schedules.ts; schedules imports them). Unit
tests cover the client, the add-items bucket mapping, and the screen.

Honest gap: no API endpoint lists a manual collection's items by id. The items
view uses a best-effort collection:"name" Lucene search (movies/shows/seasons/
artists only) behind a prominent note. Multi/rerun/playlist collections are out
of scope (no API) and pointed to the Classic UI. Follow-ups #151/#152/#153.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:44:51 +02:00
timothy fcdecd16c0 Merge pull request 'feat(web): dedicated channel edit screen (#146)' (#154) from feat/146-channel-edit into main
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m30s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m50s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 5m52s
2026-07-07 10:40:17 +00:00
timothy 2b09bffab8 Merge pull request 'feat(web): Classic UI link in Settings + ChicoryTV cue on redirecting Blazor nav links (#147)' (#150) from feat/147-classic-ui-link into main
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
2026-07-07 10:40:09 +00:00
timothyandClaude Fable 5 1f3385a2ff fix(web): review fixes — EPG switch gating, edit route key, stronger PUT assertion (#146)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m17s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m41s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:32:29 +02:00
timothyandClaude Fable 5 c21827667a feat(web): dedicated channel edit screen for SPA parity (#146)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m2s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m25s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Add a full ChannelEditScreen so the SPA can edit an existing channel
(the list/builder could only create). Mirrors the Blazor ChannelEditor
field set via hydrate-then-PUT against GET/PUT /api/channels/{id}.

- api/channels.ts: getChannelById + updateChannel (typed from generated
  ChannelViewModel / UpdateChannelRequest).
- screens/ChannelEditScreen.tsx: section-rail form (General, Playout,
  Streaming, Stream selection, Music video, Branding) following the
  SettingsScreen draft/saved dirtiness + floating save bar pattern. Logo
  upload reuses uploadArtwork; option data via existing pickers clients.
- App.tsx: /app/edit-channel/{id} route (allowSubPaths, screen parses the
  id); repoint the channel-table edit pencil at it.
- Tests: API-client GET/PUT + screen hydrate/edit-save/404 coverage.

Deferred per scope: ExternalLogoUrl (backend contract gap), and the
/channels/numbers bulk renumber (existing Renumber toolbar = parity).
Language codes / stream selector / credits template are free-text inputs
(no enumeration endpoints exist); mirror-source list can't filter to
Generated-only (ChannelResponseModel omits playoutSource).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:22:30 +02:00
timothyandClaude Fable 5 39455a96ed feat(web): Classic UI link in Settings → System (#147)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 3m25s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 3m23s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Add a discoverable "Open Classic UI" link in the SPA's Settings → System
About card, pointing at /system/health (a real full-page navigation, not
the SPA's pushState router), so un-migrated Blazor-only admin screens
stay reachable now that root / redirects to the SPA.

Also add a lightweight "Opens in ChicoryTV" tooltip cue (small icon) on
the Blazor sidebar's redirecting MudNavLink entries (per
LegacyUiRedirects.Map), so it's clear before clicking which sidebar
entries leave the Blazor UI vs. stay in it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:11:11 +02:00
timothyandClaude Fable 5 2362850559 docs: post-cutover housekeeping — dep PRs #61/#132 merged, #21/#48/#49/#131 closed, #76 rebased, prod v26.5.0 verified; next prompt = parity #147/#146/#140
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m12s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m41s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 5m4s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:01:07 +02:00
timothy 7e5a6b75ce Merge pull request 'chore(deps): update dependency entityframeworkprofiler.appender to 6.0.6053' (#132) from renovate/entityframeworkprofiler.appender-6.x into main
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
2026-07-07 09:58:02 +00:00
timothy fbb659b19f Merge pull request 'chore(deps): apply open Renovate patch updates' (#61) from issue22-renovate-dashboard into main
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
2026-07-07 09:57:24 +00:00
renovateandtimothy 7319e31fa1 chore(deps): update dependency entityframeworkprofiler.appender to 6.0.6053
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 3m52s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m37s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
2026-07-07 11:44:15 +02:00
timothy d3f71faf66 chore(deps): apply open Renovate patch updates refs #22
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m26s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m55s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
2026-07-07 11:42:56 +02:00
timothyandClaude Fable 5 1cf4a7a90c docs: v26.5.0 tagged + deployed to prod (Komodo GitOps pin); deployment section reflects pinned-tag releases
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m21s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m41s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 4m30s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:39:02 +02:00
timothyandClaude Fable 5 21ede49253 docs: advance ChicoryTV issue queue past #91 phase (a) (PR #148); CLAUDE.md reflects SPA-default UI; next prompt = post-cutover housekeeping + parity kickoff
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m11s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m34s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 4m33s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
v26.5.0
2026-07-07 11:21:35 +02:00
timothy d04769ccdb Merge pull request 'feat(web): SPA cutover — root route (#91)' (#148) from feat/91-cutover into main
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m14s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m42s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 3m23s
2026-07-07 09:12:50 +00:00
timothyandClaude Fable 5 439272b405 feat(web): SPA cutover — root route + legacy redirects (#91)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m11s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m31s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Make the ChicoryTV SPA the default UI: GET/HEAD requests to / and to
legacy Blazor routes with SPA equivalents (channels, schedules,
playouts, libraries, all settings pages, channel add) now 302 to their
/app counterparts, preserving query strings and the ETV_BASE_URL path
base. 302 not 301: the map will grow as parity lands and permanent-
redirect caching would make rollback painful.

Blazor-only functionality (collections, media browse/search, trakt,
filler presets, watermarks, ffmpeg profiles, blocks/decos/templates,
playout detail editors, logs, troubleshooting, channel edit) keeps
serving Blazor; the Blazor home stays reachable at /system/health.
Parity gaps are tracked in #140-#146; Blazor removal is phase (b).

Also adds an /app smoke assertion to the docker build workflow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:07:01 +02:00
timothyandClaude Fable 5 b564545ff7 docs: advance ChicoryTV issue queue past #90 (PR #139, tagged v26.4.0); next prompt = #91 cutover
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 3m55s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m36s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 3m54s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:20:36 +02:00
timothy 65b1a5e38c Merge pull request 'feat(web): ChicoryTV rebrand (#90)' (#139) from feat/90-rebrand into main
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m9s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m39s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 4m6s
v26.4.0
2026-07-07 08:11:34 +00:00
timothyandClaude Fable 5 ef88e93256 feat(web): ChicoryTV rebrand (#90)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m27s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m45s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Complete the SPA-surface rebrand: SVG favicon (chicorytv-icon) served
from web/public, description + theme-color meta, sidebar brand mark
switched to the canonical transparent chicory-mark.svg per the design
system lockup, and the Channel Builder default group ErsatzTV->ChicoryTV
(tests updated). Legacy Blazor UI and backend strings intentionally
untouched (product-wide rebrand = epic #59).

closes #90

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:05:39 +02:00
timothyandClaude Fable 5 9497df0d53 docs: advance ChicoryTV issue queue past #93 (PR #138); document design-sync workflow (#92); next prompt = #90 rebrand
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m7s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m34s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 4m54s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:39:27 +02:00
timothy 17f49304e5 Merge pull request 'feat(web): Settings screen (#93)' (#138) from feat/93-settings into main
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m12s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m34s
Build ErsatzTV Image / Build & push image (amd64) (push) Has been cancelled
2026-07-07 07:34:47 +00:00
timothyandClaude Fable 5 540def7f17 fix: address #93 adversarial review findings
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m51s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m21s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Backend: 401 documented on all mutating settings/resolution routes;
resolution delete distinguishes 404 (unknown) from 422 (not custom);
XMLTV enum bridging via exhaustive switch instead of int casts;
field-level Arg.Is assertions incl. non-null watermark/filler flow.

Frontend: resolution add/delete failures surfaced inline (were
silent); partial saves merge succeeded groups via allSettled; empty
numeric fields invalid + tunerCount min 1; HLS Direct select shows
out-of-list wire values; media-source rows show derived last-scan.

ErsatzTV.Tests 495; web suite 145.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:22:51 +02:00
timothyandClaude Fable 5 ab9d21326b fix(web): settings screen degrades gracefully on partial API failure
Reference data (profiles, watermarks, fillers, media sources, version,
health) now loads via allSettled with per-resource failure notes; only
the settings groups themselves gate the screen. Error state renders
before the loading guard (was unreachable). +2 tests (136 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:22:51 +02:00
timothyandClaude Fable 5 6938cbab40 fix(api): media-sources 500 on fresh database
GET /api/media-sources threw on any empty database: with zero result
rows, Microsoft.Data.Sqlite reports the COUNT(*) column as BLOB, so
Dapper generated a (long, byte[]) deserializer that cannot match
LibraryItemCount(long, long). Replaced the Dapper query with EF LINQ
GroupBy (provider-agnostic, no schema inference) and added an
empty-database regression test.

Also carries the Scriban.Signed 6.5.2 -> 7.2.5 bump (GHSA-5wr9-m6jw-xx44,
PR #137) so this branch builds; redundant once #137 lands on main.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:22:50 +02:00
timothyandClaude Fable 5 c85177071e feat(web): Settings screen (#93)
SettingsScreen with linkable sub-sections (/app/settings/<section>),
settings API module + useSettingsScreenQuery, floating save bar that
PUTs only changed groups, custom resolution add/delete, legacy-UI
callouts for read-only resources. mockDashboardApi extended; 23 new
tests (suite 112 -> 134).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:22:50 +02:00
timothyandClaude Fable 5 5f1d3e4d96 design: Settings screen prototype + handoff bundle (#93)
templates/chicorytv-admin/Settings.jsx wired into app.html;
design_handoff_settings/ carries the implementation spec + API mapping.
Synced to the Claude Design project via DesignSync.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:22:50 +02:00
timothyandClaude Fable 5 57905bc0f4 feat(api): settings read/write endpoints (#93)
GET/PUT /api/settings/{ffmpeg,playout,xmltv,scanner,logging,ui,hdhr}
wrapping the existing MediatR settings handlers, plus custom resolution
list/create/delete under /api/settings/resolutions. String-enum OpenAPI
schemas extended to OutputFormatKind + LogEventLevel.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:22:50 +02:00
timothy 82a93ea3be Merge pull request 'fix(deps): bump Scriban.Signed 6.5.2 → 7.2.5 (GHSA-5wr9-m6jw-xx44)' (#137) from fix/scriban-ghsa-5wr9 into main
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m24s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m54s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 4m54s
2026-07-07 07:09:56 +00:00
timothyandClaude Fable 5 47c3c3b5e2 fix(deps): bump Scriban.Signed 6.5.2 -> 7.2.5 (GHSA-5wr9-m6jw-xx44)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m59s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m20s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
The advisory published against Scriban < 7.0.0 (sandbox escape) turns
NuGetAudit's NU1904 into a restore failure for every build, blocking all
CI. Full solution builds and both test suites pass on 7.2.5 (XMLTV
goldens unchanged).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 08:59:13 +02:00
timothyandClaude Fable 5 8a323f98bf docs: advance ChicoryTV issue queue past #89 (PR #136); next prompt = #93 Settings
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m34s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 5m1s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 4m13s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 23:43:42 +02:00
timothy e1860785cc Merge pull request 'feat(web): Channel Builder (#89)' (#136) from feat/89-channel-builder into main
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 / Build & test (.NET) (push) Has been cancelled
2026-07-06 21:40:44 +00:00
timothyandClaude Fable 5 7d37e554d3 test(web): Channel Builder coverage — collections fan-out, paging, save-as-template, 413, zero-templates, lineup item shape (refs #89)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m38s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m5s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 23:30:22 +02:00
timothyandClaude Fable 5 54a0760fcd fix(web): Channel Builder review fixes (refs #89)
- Dialog: focus only on open transition (was stealing focus from its own
  inputs every parent re-render); Escape listener via latest-ref
- Advanced overrides: honest 'Inherit from template' semantics - the
  handler coalesces null with the template value so 'None' could never
  clear anything (clear-to-none follow-up: #135); save-as-template now
  composes from the same effective-value helper
- toggle rows: label->div (label activation forwarding double-fired in
  real browsers); clear stale 422 row highlight on lineup mutations
- port .ctv-lift/.ctv-press motion utilities + apply per prototype;
  Advanced expand scroll-into-view; Info glyph on advanced info line
- fixture fidelity: real 'Validation failed' title, verbatim handler
  detail message, omit null keys, collectionKind on rerun fixture
- cache successful artwork upload across create retries

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 23:22:52 +02:00
timothyandClaude Fable 5 579b30d489 feat(web): Channel Builder screen (refs #89)
3-column library-to-lineup builder replacing the four-editor chain:
library browser (search/filter/poster grid, double-click or drag to add,
collections via 5 typed browse calls) · drag-to-reorder lineup with
add-time constraint surfacing (Rerun/Playlist only-valid-alone,
MultiCollection requires shuffle, server lineup[i] 422 mapping) ·
settings rail (AUTO number, channel image w/ guide-logo + bug preview,
shuffle/always-playing toggles with overrides-template tags, template
picker + save-as-template, advanced override/view-defaults accordion).
Creates channel atomically via POST /api/channels/from-lineup, artwork
uploaded at create time. navigateToPath extracted to routing.ts to
avoid an App<->builder import cycle. 16 new tests (106 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 22:34:55 +02:00
timothyandClaude Fable 5 8e11362360 feat(web): Dialog primitive + Channel Builder API modules (refs #89)
- components/overlay.tsx: first Dialog/ConfirmDialog (portal, esc/backdrop
  close, scroll lock, aria wiring, reduced-motion aware) + 7 tests
- api: libraryBrowse, channelTemplates (default 404->null), artwork upload
  (multipart /api/artwork/uploads), pickers (client-sorted lists incl.
  /api/ffmpeg/profiles), createChannelFromLineup in channels.ts
- schedules.ts now sources filler/watermark fetchers from pickers.ts
  (avoids duplicate barrel exports)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 22:07:36 +02:00
timothyandClaude Fable 5 2596a433a8 docs: advance ChicoryTV issue queue past #63 (PR #134); Claude-only process; next prompt = #89 Channel Builder
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 3m48s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 3m38s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 5m0s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 21:33:04 +02:00
timothy a126970dcd Merge pull request 'feat(api): composite create-channel endpoint (#63)' (#134) from feat/63-composite-create into main
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m20s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m53s
Build ErsatzTV Image / Build & push image (amd64) (push) Has been cancelled
2026-07-06 19:28:01 +00:00
timothyandClaude Fable 5 cf36c30997 fix(api): rework from-lineup to generated playlist design + review fixes (#63)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m23s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m54s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Adversarial review found the previous multi-flood design non-viable:
PlayoutModeSchedulerFlood never yields to a following Dynamic-start
schedule item, so only the first item ever played, and grouping
media items into a Collection silently dropped the requested order.

Redesign:
- Single-item lineup: one ProgramScheduleItemFlood referencing the
  target directly (media item / collection / smart / multi / rerun /
  playlist); no generated collection or playlist. Response PlaylistId
  is null.
- Multi-item lineup (>= 2): one generated IsSystem Playlist in a
  get-or-created IsSystem PlaylistGroup ("Channel Lineups"), one
  PlaylistItem per entry in lineup order with PlayAll=true, referenced
  by a single Flood schedule item. Rerun collections and playlists are
  rejected (422) in multi lineups (PlaylistItem/CollectionKey lack the
  fields to enumerate them).

Review fixes:
- Normalize + strict-validate MediaType<->CollectionType pairs once up
  front (422 on mismatch / wrong id / not exactly one id).
- Reject MultiCollection with non-Shuffle order (mirrors
  PlayoutModeMustBeValid), Mirror playout source, all via 422.
- OnDemand parity: queue TimeShiftOnDemandPlayout post-commit.
- De-collide generated ProgramSchedule and Playlist names against their
  unique indexes instead of leaking a UNIQUE-constraint DbUpdateException.
- Generic 422 on save failure + ILogger; AnyAsync existence checks;
  Either/Validation unwrap via Match; XML doc on request DTO + endpoint.
- Response model: ChannelId, PlaylistId (nullable), ProgramScheduleId,
  PlayoutId (CollectionId removed). Regenerated OpenAPI v1.json + v1.d.ts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 21:09:00 +02:00
timothy 6857a0d191 feat(api): composite create-channel endpoint (#63)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m58s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m42s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
2026-07-06 20:27:02 +02:00
timothyandClaude Fable 5 16674ba80e docs: advance ChicoryTV issue queue past #64 (PR #133); next prompt = #63 composite create-channel
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m43s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 5m22s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 3m32s
Also: record prod cutover as done in CLAUDE.md (fork :prod live since
2026-06-27) and add standing v26.4.0 release-checkpoint note to the handoff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 19:45:08 +02:00
timothy 4854c45a89 Merge pull request 'feat(api): channel templates entity + CRUD (#64)' (#133) from feat/64-channel-templates into main
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m23s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 4m46s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 5m0s
2026-07-06 17:33:31 +00:00
timothy 1a61b89f04 fix(api): address channel template review
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m22s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m57s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
2026-07-06 19:22:42 +02:00
timothy 7858ac002a feat(api): add channel templates
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 5m34s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m58s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
2026-07-06 18:43:39 +02:00
timothyandClaude Fable 5 836087da09 docs: advance ChicoryTV issue queue past #65 (PR #130); next prompt = #64 Channel Templates
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m30s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 5m11s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 3m28s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 07:58:57 +02:00
timothy c4007293bf Merge pull request 'feat(api): library browse + search endpoints (#65)' (#130) from feat/65-library-browse into main
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m26s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 5m0s
Dependency vulnerability scan / NuGet vulnerable packages (push) Failing after 53s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 5m23s
2026-07-06 05:53:39 +00:00
timothy 630119f382 fix(api): address library browse review findings
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m3s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m36s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
refs #65

refs PR #130
2026-07-06 07:45:39 +02:00
timothy 127a130737 feat(api): add library browse endpoint
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 4m10s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m47s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
refs #65
2026-07-06 00:01:06 +02:00