Commit Graph
5 Commits
Author SHA1 Message Date
peter e006cc879f refactor(frontend): satisfy noUncheckedIndexedAccess (S3b)
Enable noUncheckedIndexedAccess and fix all 98 call sites it surfaced across 18
files. Every fix is behaviour-preserving — the flag flagged reads TypeScript
couldn't prove in-bounds, all of which were already guarded by a length/index check,
a findIndex result, or a non-empty invariant:

- read-once so a ternary's narrowing sticks (Feed overrides, linkify mention);
- non-null assertion AFTER an existing guard (PlayerModal/VideoEditor queue+cut-list
  indexing, modules step, useUndoable stacks) with a comment stating the invariant;
- nullish fallback where undefined is a real possibility (GlassTuner slider ?? def,
  ConfigPanel active group ?? [], descriptionLinks id ?? null);
- optional chaining where the entry genuinely can be absent (PlexBrowse IO entry);
- a non-empty tuple type for the RELATIVE_UNITS constant (encodes "always has [0]").

The single highest-leverage fix: PlayerModal's `active` became `queue?.[index] ??
video` (always Video), clearing 34 of the 45 errors in that file at once. Verified:
tsc/eslint/prettier clean, 56 vitest + 34 pytest + 17/17 e2e green (the e2e suite
exercises the feed/player/channel components touched here).
2026-07-21 04:11:19 +02:00
peter 3fe0897fd3 build(frontend): enable the zero-fallout compiler flags (S3a)
Three strictness flags that the codebase already satisfies (0 errors each):
- noFallthroughCasesInSwitch on src + e2e — a missing `break` is now a type error.
- noUnusedLocals + noUnusedParameters on the e2e project, so it matches src and node
  and dead spec scaffolding can't accumulate (it was the one project without them).
- allowJs + checkJs on the node project, pulling tailwind.config.js and
  postcss.config.js under the type checker (the last hole in C-4.5) — a real type
  error in either is now caught (verified: `content: 123` fails; Config stays
  permissive on plugin keys by design).

noUncheckedIndexedAccess is NOT here — it has 98 call-site fixes and lands as its own
reviewable sub-sprint (S3b).
2026-07-21 03:47:55 +02:00
peter 33abf2a4d8 fix(build): stop the host tree leaking into the image, split the tsc lanes
Review round 1 fallout, all of it verified against real builds:

- .dockerignore: `node_modules/` is anchored at the context root and has no
  implicit `**/` (unlike gitignore), so it never matched frontend/node_modules.
  `COPY frontend/ ./` was overlaying the Windows host's node_modules on top of
  what `npm ci` had installed — the image carried @esbuild/win32-x64 and 31 .cmd
  shims, and the new typecheck ran a tsc resolved from that merged tree. Build
  context transfer drops 3.05 GB -> 19 kB. Also excludes e2e/.auth (a live
  Playwright session), the report/result dirs and logs.
- build no longer type-checks the e2e project: a type error in a spec must not
  make the app unbuildable for a self-hoster. The gate still checks it via
  `npm run typecheck` (now three named lanes).
- tsconfig.json references tsconfig.node.json, so editors check vite.config.ts /
  vitest.config.ts under the same config the gate uses instead of an inferred one.
- vitest include accepts .test.tsx: an uncollected test file does not fail, it
  silently never runs.
2026-07-21 01:37:53 +02:00
peter 5c29a383cf chore(hygiene): Phase 4 guardrails — noUnusedLocals/Parameters + dead-code sweep
Enable tsconfig noUnusedLocals + noUnusedParameters (permanent guardrail: every tsc/
build now flags re-accumulated dead code). Fixed the 8 violations that surfaced, all
genuine dead code:
- Sidebar: deleted unused SORT_IDS/SHOW_IDS/rollSeed consts + the dead Toggle component
  (+ its now-unused Switch import).
- PlexBrowse: dropped the unused onClearSearch prop (Props + destructure + App call site).
- VideoEditor: dropped the unused map index; notifications: deleted the dead back-compat
  toast(); storage: deleted the unused non-account usePersistedState (+ readJSON import).
- SavedViewsWidget: deleted the dead loadDefaultViewFilters export (App loads the default
  view inline; resolves the last knip unused-export → knip now clean).

Backend: added backend/ruff.toml (ignore E402 — intentional pre-import setup in main.py)
and fixed the 6 E702/E741 style items (_vtt_s_to_ts semicolons, ambiguous `l` loop vars)
so ruff is green. localdev boots; Feed/Plex/sidebar render; 0 console errors.
2026-07-12 02:15:52 +02:00
peter e56502789f feat: M4 (part 2) — React reader UI with theming
- Vite + React + TS + Tailwind SPA served by FastAPI (multi-stage Docker build)
- Four color schemes (Midnight default, Forest, Slate, YouTube) x dark/light,
  adjustable text size; persisted to user preferences and localStorage
- Header search, grid/list toggle, theme menu; sidebar filters (show state,
  sort, include Shorts/live, language + topic tag chips with any/all matching)
- Infinite-scroll feed of video cards; click opens youtube.com in a new tab;
  per-video watched / saved / hidden actions with optimistic updates
- SPA fallback routing; login screen for unauthenticated users
2026-06-11 02:19:47 +02:00