# SPA modularization — App.tsx screen/shell extraction epic (#243) Why the ChicoryTV SPA was decomposed out of a monolithic `App.tsx`, and the conventions the extraction froze (single-file screens, screen-owned route wrappers, explicit primary-action ownership). Pure structural moves — no API/route/CSS/behavior change — so the rationale is about *boundaries*, relocated from the append-only `docs/decisions.md` at the v26.9.0 consolidation. Cross-links: `docs/spa-conventions.md` §2/§6/§10. Issue trail: epic #243 — phase 1 #244 (Channels), phase 2 #245 (Playouts), phase 4 #247 (shell/routing + primary actions). Refs #238 #230. ## Contents --- ## Records formerly in this file Each record below moved to its own file under `records/` (ersatztv#610); the rationale is unchanged. Resolve by **key** — that is the stable identity. A date-based pointer from another doc or an old issue comment should land here and then follow the link. - 2026-07-11 — Channels screen extraction (#244): single-file screen, no sibling helper dir (epic #243 phase 1) — [`spa.channels-screen-extraction`](records/spa/channels-screen-extraction.md) - 2026-07-14 — Playouts screen extraction (#245): screen-owned route wrapper (epic #243 phase 2) — [`spa.playouts-screen-extraction`](records/spa/playouts-screen-extraction.md) - 2026-07-15 — App shell/routing extraction + explicit primary-action ownership (#247) — [`spa.app-shell-extraction`](records/spa/app-shell-extraction.md)