fix(weather): match prep behavior — serve cached weather regardless of age
The /api/journal/weather route was filtering out cache rows older than 24 hours via parse_weather_card_data, while journal_prep.py read the same rows raw without freshness checking. Result: the daily prep referenced "home" and "work" temperatures while the right-rail UI showed nothing — two surfaces, same backing data, inconsistent visibility. Two changes: 1. parse_weather_card_data no longer returns None for stale data. WeatherCard already exposes fetched_at and gracefully hides today_high / forecast fields when they're absent, so old data renders with whatever fields the cached forecast still covers. 2. The /weather route opportunistically schedules a background refresh for any cache row older than 4 hours. If the user's journal_config has lat/lon for that location_key, the refresh runs and the next page load gets fresh data; if no usable config, the refresh is a silent no-op and the stale cache is still served. This makes prep and UI consistent. It also self-heals over time — once locations are configured, stale caches get refreshed on the next page load instead of waiting indefinitely. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -156,15 +156,13 @@ def parse_weather_card_data(
|
||||
) -> dict | None:
|
||||
"""
|
||||
Parse a WeatherCache row into the metadata.weather card schema.
|
||||
Returns None if the cache is stale (older than 24 hours) or unavailable.
|
||||
Returns None if the cache row is missing or unparseable. Stale data is
|
||||
returned as-is — the frontend uses `fetched_at` to convey freshness, and
|
||||
WeatherCard handles missing today/forecast fields gracefully.
|
||||
"""
|
||||
from datetime import date, timedelta
|
||||
|
||||
if cache_row is None or cache_row.fetched_at is None:
|
||||
return None
|
||||
|
||||
age_seconds = (datetime.now(timezone.utc) - cache_row.fetched_at).total_seconds()
|
||||
if age_seconds > 86400:
|
||||
if cache_row is None or cache_row.fetched_at is None or not cache_row.forecast_json:
|
||||
return None
|
||||
|
||||
raw = cache_row.forecast_json or {}
|
||||
|
||||
Reference in New Issue
Block a user