arr-summary/PRODUCT.md
Barely Removable 08491c0c9b
All checks were successful
Deploy / deploy (push) Successful in 27s
Fix System page crash, retire "held" copy, and slim CLAUDE.md
- system.html crashed with a 500 whenever SABnzbd history loaded: the
  trend() macro compared the formatted "avg_speed" string (e.g. "900
  KB/s") against a number. Added a real numeric avg_speed_kbps field
  and pointed the macro at that instead.
- Replaced "held"/"not held" wording with "in library"/"not in
  library" on Home and Discover.
- Moved CLAUDE.md's Deployment/reverse-proxy and account-management
  sections into two on-demand skills (deploy-arr-summary,
  manage-accounts) so they only load when actually relevant, with a
  one-line pointer left in their place.
- Updated PRODUCT.md's restructure note now that meridian-marquee has
  merged to main.
- Dropped two stale/broken entries from settings.local.json's
  permission allowlist (a rule from a different machine/path, and one
  with a corrupted token).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NBw1QodG8ZMYHrGeQfqyDS
2026-08-30 08:05:49 -07:00

6.4 KiB

Product

Platform

web

Users

Single primary user: the self-hoster who administers the Sonarr/Radarr/ SABnzbd/Tautulli/Prowlarr/Ombi stack and the Unraid server it runs on. They are both the audience and the operator — checking on the stack is also how they'd notice something needs fixing. Multi-user login support (manage_users.py) exists for credential hygiene / future-proofing, not because other people actively use the dashboard day to day.

Used mostly on a desktop/tablet-class screen at home, not primarily on a phone over cellular — though the 5-second parallel-fetch deadline and per-service error degradation mean it still has to stay usable and fast on a phone away from home when needed.

Product Purpose

A single glanceable page (well, now a small set of focused pages) that answers "is my media stack healthy and what's new" without opening six different service UIs. It exists because Sonarr/Radarr/SABnzbd/Tautulli/ Prowlarr/Ombi each have their own web UI with their own login, and none of them show "what's playing right now + what just finished downloading + is the array full" in one glance.

Success is a page that loads fast (parallel fetch, 5s wall-clock cap), degrades gracefully per-card when a service is offline rather than failing the whole page, and surfaces the handful of numbers that actually change day to day (active streams, queue, disk usage, new library adds, what's popular that isn't owned yet).

Positioning

Not a general-purpose *arr dashboard project (like Organizr or Homarr) — this is a bespoke, single-tenant tool built around exactly this user's stack, their Unraid box, and their own judgment calls about what's worth surfacing (e.g. Rotten Tomatoes "popular but not owned yet" filtered against the actual library, not just a generic trending feed). It trades general configurability for being exactly right for one specific setup.

Operating Context

Runs as a single Docker container (arr-summary) on the user's Unraid home server, deployed via Forgejo push-to-deploy. Fronted by Nginx Proxy Manager over HTTPS (DNS-01/Porkbun certs — port 80 is blocked by the ISP, so this is not optional). Session-based login (single shared password or per-user accounts) gates the whole app; there's no public/unauthenticated view.

Multi-page restructure (shipped 2026-08-29, meridian-marquee merged to main): the app split from one long single-page dashboard into focused pages — Home/P100, Watch, Library, Discover, Requests, System, Activity — each answering one question well rather than one long scroll trying to show everything. This also resolved cases where a content-heavy section (e.g. the per-disk storage list) would otherwise force awkward row heights on a shared "Right now" strip. _shell.html and _macros.html are the shared-layout scaffolding; dashboard.html (the old single-page template) was deleted, superseded by home.html + the per-page templates. Landed together with the visual redesign in Brand Commitments below — see DESIGN.md and static/css/base.css's header comment for the visual system's own invariants.

Each page fetches only the services it needs (e.g. /watch fetches only Tautulli) rather than the old single route's all-services-at-once fetch — narrower per-page payloads, same parallel-fetch/caching discipline described in CLAUDE.md.

Capabilities and Constraints

  • Aggregates: Sonarr, Radarr, SABnzbd, Tautulli, Prowlarr, Ombi, Unraid array stats, and scraped Rotten Tomatoes/IMDB "popular, not yet owned" data.
  • Per-service REST clients with independent, tuned cache TTLs; active streams and the SABnzbd queue are always live, never cached.
  • Every dev-machine service call fails by design (dev laptop isn't on the home network) — per-card error states are the expected local baseline, not a bug.
  • Can add missing titles directly to Radarr/Sonarr from the Discover flow (/add-to-radarr, /add-to-sonarr, lookup endpoints).
  • RT/IMDB data comes from HTML scraping, not an official API — brittle to upstream markup changes by nature; this is a known, accepted tradeoff, not a defect to "fix" by finding an API.
  • Reverse-proxy-subpath capable (SCRIPT_NAME) though currently deployed at domain root.

Brand Commitments

Branded "Media Centre". One committed visual identity, never a themeable shell — that has held across two redesigns and the five original novelty themes before them.

As of the 2026-08-29 redesign (v2.0.0) that identity is a broadcast information service in the teletext tradition. The visual system is DESIGN.md's business, not this file's; what belongs here is that pages are now numbered and reachable by typing their number, which makes the page-number model part of how the product is navigated, not merely how it looks — and that the earlier neutral card-based dark theme was deliberately replaced rather than refined.

Server-side project directory is greendale; container/repo are arr-summary — internal naming detail, not user-facing.

Evidence on Hand

No real service data is reachable from the dev environment (see Operating Context / CLAUDE.md's "expect every service to be offline on the dev machine" note) — every card's real, non-error rendering must be checked either on the deployed Unraid box or by monkey-patching a fetcher locally per the CLAUDE.md recipe. Do not fabricate sample Sonarr/Radarr/Tautulli/etc. data as if it were representative; use realistic-shaped placeholders only when a card must be visually evaluated offline, and say so.

Product Principles

  1. Never let one slow/offline service take down the page. Parallel fetch with a hard deadline and per-card service_error() degradation is non-negotiable — a single point of failure defeats the purpose.
  2. Show what changes, cache what doesn't. Cache TTLs are tuned per service to how often that data actually moves; live-only data (active streams, download queue) stays live.
  3. One focused question per page, not one page trying to answer all of them. The meridian-marquee split exists to keep each page's "quietest state" reasonable, not to add navigation for its own sake.
  4. Built for this one stack, not a general product. Configurability that would matter for other people's setups is explicitly out of scope.
  5. A committed visual identity, not a themeable shell. "Media Centre"'s dark theme is the one look; don't reintroduce per-user or per-page theme switching.