Files
ersatztv/docs/handoffs/chicorytv-issue-queue.md
T
timothyandClaude Fable 5 2362850559
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
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
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:01:07 +02:00

115 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ChicoryTV issue-queue handoff (living document)
Paste the prompt below into a fresh session to work the next item. Each session ends by
UPDATING THIS FILE in place (rewrite the state section and the queue for the next item) so it
always holds the current handoff. History: created 2026-07-02 after the plan audit (#59 epic);
all backend gap issues (#100#111) and all SPA screens (#84#89, #93, #109), the rebrand (#90)
and the cutover root-flip (#91 phase a, PR #148) are MERGED. v26.5.0 tagged + DEPLOYED to prod
2026-07-07 (verified live: image :26.5.0, / 302→/app, ChicoryTV title, /api/version 26.5.0,
M3U serving). Blazor removal (#91 phase b) is blocked on parity issues #140#147.
**Session state (2026-07-07, post-housekeeping)**: main = 7e5a6b75 (+ this doc commit).
Housekeeping session did:
- Dep batch: PR #61 (BlazorSortable 6.0.2 + CliWrap 3.10.2 + Dapper 2.1.79, rebased) and
PR #132 (EFProfiler.Appender 6.0.6053, rebased) MERGED; #21/#48/#49 closed as superseded by
#61; #131 (Scriban 7.2.0) closed obsolete — main already has Scriban 7.2.5 (47c3c3b5).
- MCP PR #76 (#58): rebased onto main (clean, purely additive ErsatzTV.Mcp project), 12 tests
green locally, pushed (head d1c04030). Still OPEN — needs a content refresh against the full
API surface before merge, plus review.
- Filed #149: CI flake — migrations job MySQL service publishes fixed host port 3306:3306, so
two concurrent runs collide ("port is already allocated"). Fix = drop the `ports:` mapping
(job connects via `Server=mysql` service name); verify MySql drift/apply still passes.
- Worktrees: removed issue-91-cutover; .worktrees/deps was this session's scratch (remove it).
**.worktrees/parity-147 exists** (branch feat/147-classic-ui-link off 1cf4a7a9, web/ npm ci
already done) — rebase onto current main and use it for #147.
- PARITY NOT STARTED — recon done though; facts baked into the prompt below.
**Lessons for all remaining prompts** (accumulated):
- The main checkout (/Users/timothy/ersatztv) sits on the STALE docs/59-ui-redesign-brief
branch. NEVER recon/edit there — point subagents at a worktree pinned to origin/main, or
they report placeholders that no longer exist (this bit a recon agent on 2026-07-07).
- Gitea 1.24 has no rerun-run API; retrigger CI with an empty commit. Runs on the single
runner queue mostly sequentially; concurrent migration jobs collide on port 3306 until #149
lands.
- DTO records in ErsatzTV.Core/Api MUST get file-scoped `#nullable enable` (else OpenAPI emits
`["null","string"]` and SPA typegen degrades). ErsatzTV.Application has NO nullable context —
`string?` there trips CS8632.
- NSubstitute + ConfigElementKey: keys are fresh instances per access — stub with
`Arg.Any<ConfigElementKey>()` disambiguated by the generic `<T>`.
- `Option<T>.ToNullable()` doesn't exist; use `MatchUnsafe(v => (T?)v, () => null)`.
- ./scripts/update-openapi.sh needs a prior normal `dotnet build ErsatzTV/ErsatzTV.csproj`.
- Id-taking child-collection GETs 404 on unknown parent via pre-check + ApiResults + an
OpenApiErrorResponseContractTests [TestCase] entry.
- Backlog nits: pageSize unclamped on paged endpoints; artwork content-type trusted (#66);
GET /api/guide runs the full 21-include eager-load per channel per request; `fillerKind`
almost always `None` in JSON guide (merged into adjacent programmes).
---
# PROMPT — Parity kickoff: #147 escape hatch → #146 channel edit → #140 collections
You are Fable, the ORCHESTRATOR in the main Claude Code session (Claude Code only). Fable is
EXPENSIVE: delegate (recon → Explore/haiku; mechanical → sonnet; judgment-heavy code → opus;
fable forks for review). Read CLAUDE.md + the Lessons above first.
HARD CONSTRAINTS:
- Work in worktrees off origin/main; NEVER touch /Users/timothy/ersatztv (stale branch).
.worktrees/parity-147 exists (npm ci done) — rebase feat/147-classic-ui-link onto
origin/main first. `cd web && npm ci` in any NEW worktree.
- Max 23 concurrent builds; ONE dotnet build at a time. NEVER set ETV_UPDATE_GOLDENS.
- Merge consent in-conversation per PR. CI reruns = empty commit (no rerun API).
- Live-E2E new screens per the #93 recipe (curl `localhost`, NOT 127.0.0.1 — host guard;
wait for "Done migrating search index").
## Recon facts (2026-07-07, verified against main)
- Routing: web/src/App.tsx (~150252). /app/collections renders PlaceholderScreen
(App.tsx ~2776). Manual pushState routing, no router lib.
- #147: web/src/screens/SettingsScreen.tsx, System pane About card (~852) is the natural home
for a "Classic UI" link to /system/health; reuse the existing `LegacyCallout` component
(ExternalLink icon + "Legacy UI" badge, used by the Media sources card ~840). Remove again
in #91 phase (b).
- #146: Channels screen edit pencil already navigates
navigateToPath(`/app/new-channel?edit=${channel.id}`) (App.tsx ~1216) but
web/src/builder/ChannelBuilder.tsx never reads query params → dead-end. Backend ready:
GET /api/channels/{id} → full ChannelViewModel; PUT /api/channels/{id} takes
UpdateChannelRequest (ChannelController.cs). Issue #146 also covers /channels/numbers bulk
renumbering — bulkRenumberChannels already exists in web/src/api/channels.ts (check what UI
exposes it). Decide: hydrate the builder for edit vs a dedicated edit view — the builder's
lineup model (from-lineup composite create) does NOT map 1:1 onto editing an existing
channel's 30+ settings; a form-style edit view calling PUT may be the honest shape.
- #140: manual + smart collections have FULL API CRUD (CollectionController incl. items
add/remove; SmartCollectionController). NO API exists for multi-collections, playlists,
rerun collections → those need backend gap issues/endpoints for full Blazor parity
(/media/multi-collections, /media/playlists, /media/rerun-collections). SPA has
getCollections()/getSmartCollections() in web/src/api/schedules.ts (no collections.ts yet).
Tests: Vitest + testing-library; App.test.tsx mocks fetch by path (mockDashboardApi).
## Task (in order)
1. #147 [small, sonnet]: Classic UI link in Settings → System About card (+ optional
"opens in ChicoryTV" cue on migrated Blazor sidebar links, per the issue). Vitest
coverage. PR, CI, consent, merge.
2. #146 [opus]: channel edit path. Scope call first (builder hydration vs edit form —
recommend and confirm in an issue comment), then implement + tests + live E2E. Include or
explicitly defer /channels/numbers with an issue comment. PR, consent, merge.
3. #140 [opus, biggest]: collections screen for manual + smart collections (list/create/
edit/delete/items). File follow-up issues for multi/playlist/rerun API gaps and cover
those types read-only if feasible (they surface in GET /api/collections by CollectionType).
PR, consent, merge.
4. Adversarial review fork over each PR diff before asking merge consent.
5. Update THIS handoff: merged PRs + main SHA, pop done items, next prompt = remaining parity
(#141#145). Commit to main. Print the next prompt in a fenced block.
---
## Issue queue (work top-down)
1. #147 SPA escape-hatch link (tiny) ← PROMPT above
2. #146 channel edit + /channels/numbers (blocker for #91b)
3. #140 collections management (biggest gap; spawns multi/playlist/rerun API follow-ups)
4. #141#145 remaining parity gaps (media browse/search, trakt, filler, watermarks, ffmpeg
profiles, blocks/decos/templates, playout editors, logs, troubleshooting — see each issue)
5. #91 phase (b): remove Blazor once #140#147 close; also remove the #147 link then.
6. MCP PR #76 (#58): refresh tool catalog against the full API surface, review, merge.
7. #149 CI flake (migrations job host-port collision) — small, slot into any session.
Cross-refs: #99 (TS/HLS-Direct sessions) stays backlog. Done this pass: dep PRs #61/#132
merged; #21/#48/#49/#131 closed; prod verified on v26.5.0.