Files
ersatztv/docs/handoffs/chicorytv-issue-queue.md
T
timothyandClaude Fable 5 3e44947597 docs: add ChicoryTV issue-queue handoff (one issue per session)
Living handoff document driving the sequential backend-gap work
(#97, #100-#111, merge pass, then UX screens). Each session works
one queue item and rewrites this file for the next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 21:31:22 +02:00

103 lines
7.5 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 issue. Each session ends by
UPDATING THIS FILE in place (rewrite the "Issue #N state" section and the queue for the next
issue) so it always holds the current handoff. History: created 2026-07-02 after the plan audit
(#59 epic) filed backend gap issues #100#111; parallel workflow runs exhausted RAM, so we work
ONE issue per session with strictly sequential builds.
---
# Task: Finish issue #97 — channel on-air / now-playing state API (final verify → review → PR)
You are the ORCHESTRATOR in the main conversation (Fable). Work inline where sensible; spawn
subagents of appropriate models for delegable chunks (Explore/haiku for recon, sonnet/opus for
implementation, fable-effort-high for adversarial review). HARD CONSTRAINTS:
- NEVER run more than ONE build/test-executing agent or command at a time (a 7-way parallel
dotnet build previously exhausted the machine's RAM and crashed it).
- Do NOT use the Workflow tool. Sequential Agent calls or inline work only.
- We fix exactly ONE issue per session. Do not start the next issue; instead end by emitting
the next handoff prompt (see "On completion").
## Project context (read CLAUDE.md first; docs/contributing.md + docs/rest-api.md before code)
- Repo: /Users/timothy/ersatztv — ErsatzTV fork (.NET 10, CQRS/MediatR, LanguageExt, EF Core),
being rebuilt as React SPA "ChicoryTV" (web/) over its REST API. Gitea:
http://192.168.1.95:3000/timothy/ersatztv (API auth: basic timothy:ded89Lm4).
- Tests: NUnit + Shouldly + NSubstitute in ErsatzTV.Tests (NOT xUnit). Error contract:
ProblemDetails; 404 title "Resource not found", 422 "Validation failed".
- OpenAPI regen: ./scripts/update-openapi.sh (rewrites ErsatzTV/wwwroot/openapi/v1.json), then
cd web && npm run generate:api && npm run check:api. No EF model changes / no migrations.
- BRANCH TOPOLOGY (critical): origin/main has the REST API foundation but NOT the SPA. The
branch docs/59-ui-redesign-brief carries the SPA foundation + #96/#98 (all unmerged to main).
Branch issue-97-channel-state-api is STACKED on docs/59-ui-redesign-brief.
## Issue #97 state (was implemented by Codex, interrupted twice during final verification)
- Worktree: /Users/timothy/ersatztv/.worktrees/issue-97-channel-state-api
(branch issue-97-channel-state-api, pushed; work in THIS worktree, do not create another).
- 5 commits on top of docs/59-ui-redesign-brief; HEAD 07e9d983 "fix(api): resolve mirror
channel now playing state" — mirror channels resolve now-playing via
MirrorSourceChannelId ?? channel.Id, and PlayoutOffset is subtracted before locating the
current item with offset-adjusted returned bounds. That fix passed a Codex compliance review.
- Known scope caveat (documented, intentional): on-air detection is HLS-segmenter-only
(IFFmpegSegmenterService); MPEG-TS/HLS-Direct tracking is issue #99, out of scope.
- Crash leftovers in the worktree: MODIFIED ErsatzTV/wwwroot/openapi/v1.json (regen output from
the interrupted verify run — validate and commit it, or re-run regen). A previous interrupted
run also drafted (since discarded) nullable annotations on the DTOs:
ChannelStateResponseModel(..., ChannelNowPlayingResponseModel? NowPlaying) and
ChannelNowPlayingResponseModel(string? Title, ...) — an off-air channel plausibly needs
NowPlaying=null. Check whether the committed DTOs + the nullable-schema test (f01ffc62) are
actually consistent; re-derive the change with test evidence if needed. Be skeptical of
ChannelNumber? — that one looked dubious.
## Plan
1. VERIFY (inline or one subagent): dotnet build ErsatzTV.sln; dotnet test
ErsatzTV.Tests/ErsatzTV.Tests.csproj (+ ErsatzTV.Core.Tests if the diff touches its area);
./scripts/update-openapi.sh && cd web && npm ci && npm run generate:api && npm run check:api.
Commit any legit regen/fix ("chore(api): ..." / "fix(api): ...", trailer:
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>).
2. FINAL REVIEW (fable subagent, high effort, read-only): diff
origin/docs/59-ui-redesign-brief...HEAD — ONLY the #97 commits. Focus: now-playing lookup
boundaries (now == Start/Finish, empty/no playout, disabled channels), offset math sign,
UTC handling, mirror resolution, honest degradation for non-HLS modes, error contract,
test meaningfulness, N+1 on the all-channels listing, OpenAPI + web types regenerated.
3. FIX findings (blockers/majors; minors if quick), re-verify, push.
4. PR against docs/59-ui-redesign-brief (NOT main — stacked): title
"feat(api): channel on-air / now-playing state endpoint (#97)"; body: summary, endpoints,
the #99 caveat, review section; footer "🤖 Generated with [Claude Code](https://claude.com/claude-code)".
POST http://192.168.1.95:3000/api/v1/repos/timothy/ersatztv/pulls
{"head":"issue-97-channel-state-api","base":"docs/59-ui-redesign-brief",...}.
5. Comment on #97 (verification results, review verdict, PR #). Leave the issue OPEN
(stacked PR won't auto-close it; it closes when the stack reaches main).
## On completion — REQUIRED last step
Update docs/handoffs/chicorytv-issue-queue.md in place: replace the task section with a new
handoff prompt (same structure: orchestrator rules, project context, branch topology, issue
state, plan, queue, this same "on completion" clause) for the NEXT issue in the queue, pop the
finished issue from the queue, and record anything the next session must know (new PR numbers,
review debts, changed branch state). Also print the new prompt in a fenced code block.
## Issue queue (work top-down; one per session)
All feat/* branches below already exist on origin with a "wip: partial implementation salvaged
from interrupted workflow run" commit — UNTRUSTED drafts (never built/tested): review the WIP,
keep what's good, rewrite what isn't. Branches are based on origin/main (no web/ dir there —
skip the web type-regen steps for those branches; main's CI doesn't run check:api).
1. #97 ← THIS SESSION
2. #105 filler/watermark/graphics list endpoints — branch feat/105-picker-list-endpoints (small; unblocks #86 partially, #89)
3. #108 health API — branch feat/108-health-api (small; unblocks #109, shell footer)
4. #100+#101+#107+#110 playout read API — branch feat/playouts-read-api (one branch/PR, 4 issues; unblocks #87)
5. #103+#106 media sources + scan status — branch feat/103-media-sources-api (unblocks #88)
6. #104 artwork upload — branch feat/104-artwork-upload (unblocks #89)
7. #102 JSON guide endpoint — branch feat/102-json-guide (hardest: extract shared projection from
RefreshChannelDataHandler; XMLTV golden tests = regression net, do NOT regen goldens; unblocks #85)
8. #111 schedule duration estimates — branch feat/111-schedule-durations (unblocks #86 polish)
9. MERGE PASS: land the 7 backend PRs into main sequentially (each: rebase, re-run
update-openapi.sh, wait for CI green, merge; they all conflict on v1.json). Then rebase the
docs/59-ui-redesign-brief stack (with #97 merged into it) onto the new main once, and PR the
stack to main (auto-closes #97 and validates closed SPA issues #78#83/#96/#98 on main).
10. #109 Dashboard follow-up (frontend; needs merge pass done)
11. Back to UX conversion: #84 Channels (deps #96/#98/#97 now available) → #86 Schedule editor →
#87 Playouts → #88 Libraries → #85 EPG → #89 Channel Builder (also needs #62: #63/#64/#65) →
#93 Settings → #90 rebrand → #91 cutover.
Cross-refs: #99 (TS/HLS-Direct sessions) stays backlog; "Definition of Ready" for screen issues
lives in the #59 epic body — apply it when reaching step 11.