thermograph/tests
Emi Griffith 63ba5ab44e Stop the records strip showing stale readings as "right now" (#185)
A card read "Shanghai · 30°C · Near Record hot · Low temp · 99th pct" while the
Day page for the same cell said 26°C, 66th pct, Above Normal. Both were right
about the climatology — the normals matched exactly — but the strip was grading
a reading from several days earlier and presenting it as current.

Two causes, both mine:

- load_cached_recent_forecast deliberately ignores how stale the file is, and
  _grade_city took the newest row <= today with no age check at all.
- Nothing keeps that cache current for the tracked cities. warm_cities.py skips
  any city whose archive is already cached, so it never re-fetches their forecast
  bundle, and the notifier only touches subscribed cells. So "zero upstream
  calls" was satisfied by reading a cache nothing refreshes.

Fixes:

- Drop readings older than MAX_OBSERVATION_AGE_DAYS (1) instead of ranking them.
  Cities span a day of timezones, so a current observation can still be dated
  yesterday in UTC — hence 1 rather than 0.
- Top up the stalest cells' recent/forecast each pass, oldest first and capped
  (THERMOGRAPH_HOMEPAGE_REFRESH, default 40), the same shape as the notifier's
  archive-fetch budget. This is a real change: the sweep is no longer zero-cost
  upstream, because it cannot be and still say "right now". Documented in
  DEPLOY.md, and refresh(fetch=0) keeps a strictly cache-only rebuild.
- Rank over the top THERMOGRAPH_HOMEPAGE_CITIES (250) rather than all ~1000. The
  strip shows ~12 cards; a smaller genuinely-fresh set beats a large stale one.
- Show the observation date on a card when it isn't today's, so a yesterday
  reading can't silently pass for current.
2026-07-18 08:58:34 +00:00
..
conftest.py Isolate the access log in tests so self-test traffic doesn't pollute the live monitor (#168) 2026-07-17 19:44:30 +00:00
test_api.py Migrate backend dataframe layer from pandas to polars (#90) 2026-07-15 19:07:38 +00:00
test_api_accounts.py Push: surface delivery failures (no longer a silent success) (#157) 2026-07-17 00:12:14 +00:00
test_climate.py Serve stale forecast cache when both Open-Meteo and MET Norway fail (#116) 2026-07-16 05:41:51 +00:00
test_content.py Make the brand lockup a home link on every page (#182) 2026-07-18 08:06:14 +00:00
test_dashboard.py Report the notifier's health by heartbeat, not per-worker threads (#166) 2026-07-17 13:49:30 +00:00
test_digest.py Rebuild the homepage as a distribution landing; add an SMTP seam (#178) 2026-07-18 07:39:47 +00:00
test_grading.py Migrate backend dataframe layer from pandas to polars (#90) 2026-07-15 19:07:38 +00:00
test_grid.py Warm neighbor cells server-side (/cell?neighbors=1) (#51) 2026-07-11 20:47:31 +00:00
test_homepage.py Stop the records strip showing stale readings as "right now" (#185) 2026-07-18 08:58:34 +00:00
test_metrics.py Rebuild the homepage as a distribution landing; add an SMTP seam (#178) 2026-07-18 07:39:47 +00:00
test_notify.py Add PWA + Web Push delivery for weather alerts (#95) 2026-07-15 23:21:06 +00:00
test_places.py Move the suggestion policy into places.py (#45) 2026-07-11 20:00:24 +00:00
test_singleton.py Gate the subscription notifier to one worker (#161) 2026-07-17 12:54:55 +00:00
test_store.py Compare/calendar mobile polish: overflow fix, sheet load button, 6-yr default, country in names (#80) 2026-07-12 06:32:10 +00:00
test_views.py Migrate backend dataframe layer from pandas to polars (#90) 2026-07-15 19:07:38 +00:00