All checks were successful
Deploy / deploy (push) Successful in 27s
- 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
137 lines
6.4 KiB
Markdown
137 lines
6.4 KiB
Markdown
# Product
|
|
|
|
<!-- impeccable:product-schema 1 -->
|
|
|
|
## 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.
|