From 95b7ce7c03a9a3ff33a49428173f3634cc897fda Mon Sep 17 00:00:00 2001 From: Barely Removable Date: Thu, 27 Aug 2026 07:46:29 -0700 Subject: [PATCH] Bump to v1.4.0 and document the local all-offline baseline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The footer version is the honest check that a deploy landed, so cut 1.4.0 for the Storage table. Also record something that has now cost two sessions: the dev machine isn't on the media stack's network, so every service is offline and the live-poll endpoints 500 on a timer. That's the normal local baseline, not a regression. Notes the monkey-patch pattern for exercising a card's real rendering, plus the two traps that go with it — Jinja's auto_reload follows app.debug (off), so template edits need a restart rather than a browser reload, and LOGIN_PASSWORD has to be set explicitly. Co-Authored-By: Claude Opus 5 --- CLAUDE.md | 29 +++++++++++++++++++++++++++++ app.py | 4 ++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index d3e8212..5d56a8f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -114,6 +114,35 @@ env vars (see `.env.example`) to reach real services — without them, dashboard cards degrade to "error" status individually rather than crashing the page. +**Expect every service to be offline on the dev machine, and expect +`/api/*` polls to 500.** The dev laptop is not on the network with the +media stack, so Sonarr/Radarr/SABnzbd/Tautulli/Prowlarr/Ombi all refuse +the connection: every card renders its `service_error()` state, the +header pills all read "offline", and the browser console fills with +`500` responses from the live-poll endpoints (`/api/sabnzbd` and +`/api/tautulli` poll on a timer, so they repeat every few seconds). +**This is the normal local baseline, not a regression** — don't go +debugging it, and don't "fix" it. If you need to check whether a 500 is +genuinely yours, stash the working tree and confirm the same response on +a clean checkout. + +Because of that, the only reliable way to exercise a card's real +(non-error) rendering locally is to monkey-patch its fetcher and run the +app on a spare port, e.g.: + +```bash +LOGIN_PASSWORD=test python3 -c " +import app as a +a.get_unraid_stats = lambda: {'status': 'ok', 'source': 'api', ...} +a.app.run(host='127.0.0.1', port=5099)" +``` + +Two gotchas when doing this: Jinja's `auto_reload` follows `app.debug`, +which is off, so **template edits need a server restart** — a browser +reload alone will silently serve the cached template. And the login +password comes from `LOGIN_PASSWORD`, so set it explicitly rather than +hunting for the real one. + ## Deployment **Target:** Unraid server, container path `/mnt/user/appdata/greendale` diff --git a/app.py b/app.py index 949ed06..3dbc230 100644 --- a/app.py +++ b/app.py @@ -20,8 +20,8 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # Docker tab caches stale container IDs, so the footer is the reliable way # to confirm a `docker compose up -d --build` actually took effect. # Both are env-overridable if the deploy pipeline ever injects them. -APP_VERSION = os.environ.get("APP_VERSION", "1.3.0") -APP_VERSION_DATE = os.environ.get("APP_VERSION_DATE", "2026-08-26") +APP_VERSION = os.environ.get("APP_VERSION", "1.4.0") +APP_VERSION_DATE = os.environ.get("APP_VERSION_DATE", "2026-08-27") # Must point at a path that survives `docker compose up --build` — the # container filesystem does not. See the data volume in docker-compose.yml.