ROADMAP: rewrite with snapshot table, status emojis, Open above Done

- Snapshot table at top (live stats: prod/dev URLs, theme, eps, disk, users)
- Open items first (high/med/low + effort + blocker)
- Blocked + Deferred middle
- Done section moved to bottom per owner request
- Visual: emoji-tagged severity, tables, scannable
- Updated counts: 6 series, 175 eps, 156G free, 9 users, 17 docs
This commit is contained in:
s8n 2026-05-08 17:19:45 +01:00
parent a3f82dfcc0
commit 21500156dc

View file

@ -1,110 +1,142 @@
# Roadmap — ARRFLIX
What's done, what's open, what's deferred. Update on every commit that lands or
moves an item between buckets.
Last revised: 2026-05-08
Last revised: **2026-05-08**
---
## Done
## Snapshot
- [x] **Deploy**: Jellyfin 10.10.3 on nullstone, LAN-only at `arrflix.s8n.ru`, file-provider Traefik route, LE cert via Gandi DNS-01, Pi-hole local DNS pin, userns_mode=host
- [x] **Theme**: ElegantFin v25.12.31 applied via `/System/Configuration/branding`
- [x] **Cast & Crew + Guest Stars**: hidden globally via CustomCss (`#castCollapsible, #guestCastCollapsible`)
- [x] **Library**: TV Shows → `/media/tv/Futurama (1999)/`, 72 eps + 9 featurettes, locked to TMDB 615
- [x] **Cleanup**: Polish set deleted, junk-stripped English set imported, source + staging deleted
- [x] **Plugins**: OpenSubtitles v20 installed (v21+ needs JF 10.11 ABI)
- [x] **Users**: `s8n` (admin), `guest` (non-admin, pw `123`)
- [x] **Wrapper**: `bin/add-jellyfin-user.sh` for canonical user creation
- [x] **Home layout**: My Media tile row dropped per user (resume / resumeaudio / nextup / latestmedia)
- [x] **Docs**: 0108 (artwork, metadata, subs, theming, file-structure, per-lib themes, cleanup, naming) + ADMIN-GUIDE.md
- [x] Imported: The Incredible Hulk (2008)
- [x] Imported: Idiocracy (2006)
- [x] Imported: American Dad! (2005) S01-S04 (58 eps)
- [x] Imported: Star Wars - Maul - Shadow Lord (2026) S01 (10 eps)
- [x] Imported: Rick and Morty (2013) S01 (11 eps, 4K HDR upscale)
- [x] Imported: Obi-Wan Kenobi (2022) S01
| Metric | Value |
|---|---|
| Prod URL | https://arrflix.s8n.ru → 302 ✓ |
| Dev URL | https://dev.arrflix.s8n.ru → 302 ✓ |
| Theme | **Cineplex v1.0.6** (rolled back from NeutralFin) |
| Repo | `git.s8n.ru/s8n/ARRFLIX` |
| Library | 6 series + 2 movies, 175 eps + 9 featurettes |
| Disk | nullstone /home — 156G free (60% used) |
| Users | 9 (1 admin + 8 non-admin) |
| Snapshot tag | `snapshot-2026-05-08-pre-elegantfin` (rollback) |
| Docs | 17 in `docs/` + ADMIN-GUIDE + ROADMAP |
---
## Open — actionable now
## 🟥 Open — High value (do first)
### High value
- [ ] **OpenSubtitles credentials**
- Owner signs up at opensubtitles.**com** (NOT .org)
- I POST creds to `/Plugins/<id>/Configuration` per [docs/03 § 3.4](docs/03-subtitles.md)
- Test by triggering subtitle search on one Futurama episode
- Free tier = 20 dl/day; full library will take ~3 days unless VIP
- [ ] **GPU transcode (nvidia driver)**
- GTX 1660 Ti present on nullstone, `nvidia-smi` fails — driver kernel module not loaded
- SecureBoot enabled → DKMS module signing required
- Steps in `README.md § Transcoding` and one earlier diagnosis turn
- Blocks: anyone watching on a low-power client (phone, fire TV) currently CPU-transcodes
- Estimated wall: 30 min + reboot (nullstone hosts traefik, forgejo, matrix — ~2 min downtime)
- [ ] **Loading-splash rebrand**
- Replace Jellyfin pre-bundle logo with `arrflix.s8n.ru` wordmark + 4-bar pulse spinner
- Approach: bind-mount patched `/jellyfin/jellyfin-web/index.html` per the plan in this session's history
- Doc to write: `docs/09-loading-splash.md` (pre-bundle vs CustomCss timing, regen-on-upgrade)
### Medium value
- [ ] **Extract `bin/cleanup-import.sh` and `bin/normalize.py`** from docs 07 + 08 into runnable repo files (currently embedded in markdown only)
- [ ] **Per-library themes (doc 06)**
- Install `n00bcodr/Jellyfin-JavaScript-Injector` plugin
- Ship 30-line shim that mirrors `topParentId` + `collectionType` from URL hash to body class
- Add three scoped CSS blocks (`body.lib-movies` Netflix, `body.lib-anime` Crunchyroll, `body.lib-music` Spotify)
- Source CSS hunt: 5 Netflix-flavoured bases listed in doc 06; Crunchyroll + Spotify must be hand-built (no existing theme)
- Verdict per doc 06: "tinted, branded, recognisable" — NOT pixel-perfect
- [ ] **Audit-vs-rules pass on current state**
- `/home/user/media/tv/Futurama (1999)/` already conforms post-import
- But: subtitle sidecars absent (waiting on OpenSubtitles creds)
- Featurettes folder is lowercase ✓
- Year in parens ✓
- SXXEXX zero-padded ✓
- Episode title separator ` - `
### Low value
- [ ] **Library scaffolding**: empty `/media/{movies,anime,musicvideos}/` libraries exist; no content yet
- [ ] **Backup strategy** for `/home/docker/jellyfin/config/` (DB + watched-state). Currently zero backups. Tie into existing nullstone backup chain.
- [ ] **Forgejo Actions CI** for the repo (lint compose, validate `bin/*.sh` with shellcheck, render docs)
---
## Blocked / waiting on owner
- OpenSubtitles creds → owner has not signed up yet
- nvidia driver fix → owner needs to run sudo commands or approve disable-SecureBoot path
- Decision on per-library themes (doc 06): green-light or skip
---
## Deferred
- **Pixel-perfect Netflix/Crunchyroll/Spotify per-library**: would require 3 separate Jellyfin instances on subdomains. ~100× maintenance cost. Doc 06 § 5. Don't do.
- **Custom Jellyfin Docker image**: `FROM jellyfin/jellyfin + COPY index.html`. Cleaner than bind-mount for splash + JS injector but extra build pipeline. Defer until ≥3 web-bundle overrides needed.
- **Subdomain split for friend-only access**: friend already gets non-admin Jellyfin user via `bin/add-jellyfin-user.sh` with `EnabledFolders` ACL. Subdomain not necessary.
- **Move to alternative web client (Jellyfin-Vue)**: replaces the whole UI, breaks ElegantFin + JS Injector. Owner explicitly wants Netflix-y, not vue-y. Don't do.
- **Hardware change**: 4 TB HDD on nullstone idle. Wait until library exceeds 500 GB before activating second-path library mounts (doc 05 § Architecture C).
---
## Tracking
When an item moves to **Done**, link the commit hash. When it stalls, note the blocker date. Don't let entries rot — review on the first of each month.
| Item | Status | Last touch | Owner |
| # | Item | Effort | Blocker |
|---|---|---|---|
| OpenSubtitles creds | blocked-on-owner | 2026-05-07 | s8n |
| nvidia driver | blocked-on-owner | 2026-05-07 | s8n |
| Loading splash | open-actionable | 2026-05-08 | s8n |
| Extract bin/ scripts | open-actionable | 2026-05-08 | s8n |
| Per-library themes | open-actionable (decision pending) | 2026-05-08 | s8n |
| Library scaffolding | open-low-value | 2026-05-08 | s8n |
| Backup strategy | open-low-value | not-started | s8n |
| Forgejo CI | open-low-value | not-started | s8n |
| H1 | OpenSubtitles credentials (auth fixes log spam too — doc 13 win 2) | S | **owner signs up at opensubtitles.com** |
| H2 | GPU transcode (nvidia driver kernel module + container toolkit + SecureBoot signing) | L | **owner sudo + reboot** |
| H3 | Apply `bin/force-english-all-users.sh` (German Play button breaks UX for non-English browsers) | S | none — owner runs |
| H4 | Backup `/home/docker/jellyfin/config/` off-host (no automated backup yet) | M | strategy decision |
## 🟨 Open — Medium value
| # | Item | Effort | Notes |
|---|---|---|---|
| M1 | Tune detail-page backdrop gradient stops if text contrast off | S | doc 14 §7 |
| M2 | EnableThrottling + EnableSegmentDeletion (kills wasted ffmpeg-after-disconnect) | S | doc 13 win 1 |
| M3 | KnownProxies + LocalNetworkSubnets in network.xml (fixes session origin on WAN endpoint) | S | doc 13 win 3 |
| M4 | PWA manifest bind-mount — kills "Jellyfin" name on Android/iOS install | M | doc 16 phase 1 |
| M5 | Logo-screensaver disable + i18n DOM-rewrite shim | M | doc 16 phases 2+3 |
| M6 | Extract `bin/cleanup-import.sh` + `normalize.py` from doc bodies into runnable files | S | docs 07/08 |
| M7 | Per-library themes (JS injector plugin + body class shim) | M | doc 06 — "tinted, not pixel-perfect" |
## 🟩 Open — Low value (nice-to-have)
| # | Item | Effort | Notes |
|---|---|---|---|
| L1 | Forgejo Actions CI (lint compose, shellcheck bin/, render docs) | M | not started |
| L2 | High-res ARRFLIX wordmark for desktop splash variant (currently 235×85, looks soft on 1080p+) | S | doc 14 finding |
| L3 | Hide lone "User" h3 header above Sign Out (cosmetic) | S | open Q from settings-fix agent |
| L4 | Rotate dev admin password (currently same as prod for parity) | S | open Q from settings-fix agent |
---
## 🚫 Blocked / waiting
| Item | Blocker | Action owner |
|---|---|---|
| OpenSubtitles auth | account signup at .com | **you** |
| Nvidia GPU | sudo + reboot decision | **you** |
| WAN public access | home router port-forward 80/443 → 192.168.0.100 | **you** |
---
## 🔒 Deferred (with reason)
| Item | Reason |
|---|---|
| Pixel-perfect Netflix/Crunchyroll/Spotify per-lib themes | requires 3 separate Jellyfin instances on subdomains; ~100× maintenance cost. Doc 06 |
| Custom Jellyfin Docker image (FROM jellyfin + COPY index.html) | bind-mount works; defer until ≥3 web-bundle overrides needed |
| Subdomain split for friend-only access | non-admin user policies + EnabledFolders ACL already do this on a single instance |
| Move to Jellyfin-Vue alt web client | replaces UI, breaks current branding stack |
| 4 TB HDD activation | wait until library exceeds 500 GB; currently 50G |
---
## ✅ Done
### Branding + theme
- ✅ Theme: ElegantFin → Cineplex → ElegantFin → NeutralFin → **Cineplex v1.0.6 (final)**, snapshot tag for rollback
- ✅ ARRFLIX logo data-URL injected — overrides Cineplex's logo on `.adminDrawerLogo img` + `.pageTitleWithLogo` (split-rule per element type, no overlap)
- ✅ Browser tab title `ARRFLIX` + favicon = ARRFLIX wordmark (via index.html bind-mount)
- ✅ Pre-bundle splash → ARRFLIX wordmark (no more Jellyfin logo on first paint)
- ✅ LoginDisclaimer "Welcome to ARRFLIX - Private invite only service"
- ✅ Critical-path inline `<style>` in index.html eliminates pre-bundle theme flash
- ✅ JS shim in index.html: title-lock + favicon-lock + nukeSettings + SW unregister
- ✅ Detail-page backdrop full-bleed gradient fix (was 17vw black band; now Netflix-style)
### UI hides + tweaks (CSS in CustomCss)
- ✅ Cast & Crew + Guest Stars sections (`#castCollapsible, #guestCastCollapsible`)
- ✅ Quick Connect button + server-side disable (`.btnQuick`, `QuickConnectAvailable=false`)
- ✅ Settings drawer link v2 (`a.btnSettings, [data-itemid="settings"]` — verified on dev with headless A/B before swap)
- ✅ Header icons: SyncPlay group, Cast, User menu (`.headerSyncButton`, `.headerCastButton`, `.headerUserButton`)
- ✅ Unwatched-count badges (`.countIndicator`)
- ✅ Settings menu page access (`EnableUserPreferenceAccess=false` per non-admin)
- ✅ Slider thumbs blue → white (scrubber + volume on player OSD)
- ✅ Pure-black background
### Library
- ✅ Cleanup playbook: 17-doc set including pre-import strip rules + filename normalization
- ✅ Imports applied via cleanup → normalize pipeline:
- Futurama (1999) S01S04, 72 eps + 9 featurettes (TMDB 615)
- American Dad! (2005) S01S04, 58 eps (TMDB 1433)
- Rick and Morty (2013) S01, 11 eps (TMDB 60625)
- Star Wars: Maul Shadow Lord (2026) S01, 10 eps (TMDB 289219)
- Obi-Wan Kenobi (2022) S01, 6 eps + 4 featurettes (TMDB 92830)
- The Incredible Hulk (2008) (TMDB 1724)
- Idiocracy (2006) (TMDB 7512)
- ⏳ The Mandalorian (2019) S01S03 — 18/24 mkv on disk, scrape in flight
- ✅ Futurama season posters re-locked to highest-res TMDB (was low-res)
- ✅ Polish set replaced with English; libraries flipped `pl/PL``en/US`
### Users + access
- ✅ 9 users (`s8n` admin, `5`, `64bitpotato`, `aloy`, `guest`, `house`, `marco`, `pet`, `yummyhunny`)
- ✅ All non-admin policies: `IsAdministrator=false`, `EnableContentDeletion=false`, `EnableUserPreferenceAccess=false`, `LoginAttemptsBeforeLockout=5`
- ✅ Wrapper `bin/add-jellyfin-user.sh` — single-call canonical user creation (4-step pipeline: create + home layout + lang prefs + restricted policy)
- ✅ Home layout per-user: resume → resumeaudio → nextup → latestmedia (My Media tile row dropped)
### Infra
- ✅ Domain rename: `tv.s8n.ru``nasflix.s8n.ru`**`arrflix.s8n.ru`**
- ✅ Repo rename: `jellyfin-stack``NASFLIX`**`ARRFLIX`** at `git.s8n.ru/s8n/ARRFLIX`
- ✅ Pi-hole local DNS for `arrflix.s8n.ru` + `dev.arrflix.s8n.ru`
- ✅ LE certs via Gandi DNS-01 for both prod + dev
- ✅ WAN window: Gandi public A record `arrflix.s8n.ru → 82.31.156.86`, no-guest middleware dropped, lockout=5 baked in (router port-forward pending)
- ✅ Dev instance: `dev.arrflix.s8n.ru`, isolated config, shared `/home/user/media:/media:ro` mount with prod (read-only), 7 mirror users + s8n-dev admin
- ✅ Snapshot tag `snapshot-2026-05-08-pre-elegantfin` for one-command rollback
### Docs (17 + 2 indexes + bin/)
- ✅ `ADMIN-GUIDE.md` (entry point)
- ✅ `ROADMAP.md` (this file)
- ✅ `docs/01..16` covering: artwork, metadata, subtitles, theming-and-users, file-structure, per-library-themes, cleanup, normalization, WAN exposure, SPA shim, NeutralFin audit, dev instance, optimization audit, theme audit, force English, Jellyfin-branding leaks, dev mirror + settings fix
- ✅ `bin/add-jellyfin-user.sh`, `bin/inject-shim.py`, `bin/force-english-all-users.sh`
---
## Conventions
When marking an item:
- Move **Open****Done** when shipped + verified
- Move to **Blocked** when waiting on owner / external
- Move to **Deferred** with one-line reason
- Update **Snapshot** stats on every revision