# Weather Widget Architecture Note

## Components and Ownership

- **HTTP entrypoint (`server.js`)**
  - Owns request parsing and response writing in `createServer()`.
  - Reads query params (`city`, `units`, `view`) and delegates to `renderPage()`.

- **Live weather integration (`server.js`)**
  - `fetchLiveWeather(cityInput, units)` owns end-to-end live lookup.
  - `cityInputToLookup()` normalizes quick-pick slugs (e.g. `nyc` -> `New York`).
  - `fetchJson()` performs upstream HTTP requests.
  - Uses Open-Meteo geocoding + current weather endpoints.
  - `WEATHER_CODES` maps provider weather codes into human-readable conditions.

- **Caching layer (`server.js`)**
  - `readCache()`, `writeCache()`, `cacheKey()` own in-memory caching.
  - Reduces repeated upstream calls for identical city/unit requests (5-minute TTL).

- **UI rendering layer (`server.js`)**
  - `layout()`, `baseStyles()` provide shared shell/style.
  - `searchForm()` owns searchable city input and units selector.
  - `renderCard()` owns current-weather card rendering from **live data**.
  - `renderUnknown()` owns polite failure state (`cannot find that city`).
  - `cityNav()` owns quick-pick control generation.

- **Forecast table module (`server.js`)**
  - `FORECAST_BY_CITY` and `renderForecast()` own the 3-day table view.
  - This table is retained for forecast flow UX and scenario continuity.

## Data Flow

1. Browser requests `/?city=<value>&units=<c|f>&view=<card|forecast>`.
2. `createServer()` parses inputs and calls `renderPage()`.
3. `renderPage()` decision:
   - `view=forecast` + known quick-pick city -> `renderForecast()` (table data path).
   - otherwise -> `fetchLiveWeather()` (live service path).
4. `fetchLiveWeather()` checks cache, then:
   - geocodes city name via Open-Meteo geocoding API,
   - fetches current weather by lat/lon,
   - maps code -> condition text,
   - returns normalized card model.
5. Renderer (`renderCard()` / `renderUnknown()` / `renderForecast()`) returns HTML.
6. Server writes HTML response.

## Relationship: Live Current Weather vs Retained Forecast Tables

- **Current city card values are live-only** (temperature, condition, wind come from Open-Meteo now).
- **Forecast view remains table-backed** (`FORECAST_BY_CITY`) to preserve earlier forecast navigation behavior and deterministic 3-day rows (including Rome day 2 = 26 cloudy).
- Quick picks participate in both paths:
  - on card view: quick-pick slug resolves to a live city lookup,
  - on forecast view: quick-pick slug indexes the retained local 3-day table.

This split keeps live correctness for present conditions while preserving stable forecast-flow UX required by earlier interactions.