# Offline-first data and caching

The app **must never require the API to launch**. It ships with metro-specific defaults for bootstrap, areas and home, plus a bundled fallback image. At startup, it displays local data immediately, then attempts a network refresh asynchronously.

## Refresh sequence

1. Load the most recent validated cached bootstrap, otherwise bundled bootstrap.
2. Load cached areas/home data, otherwise bundled datasets.
3. Request `/bootstrap` when network and refresh policy allow.
4. Compare `resources.areas.version` and `resources.home.version` with versions stored alongside each validated local resource. Treat versions as **opaque equality tokens**, not sortable dates.
5. For changed resources, download and validate the entire response. Write data and corresponding version **atomically**; preserve previous valid data on failure.
6. Download scheduled images independently and store them by stable photo ID. A changed image requires a new ID or an explicit future revision scheme.

Feature flags and metro metadata update with bootstrap itself. Cache freshness is a client policy; suggested bootstrap revalidation is 5–15 minutes while online. HTTP ETag / If-None-Match and 304 may be used in addition to explicit resource versions. Do not discard stale local data solely because a cache lifetime elapsed.

## First-run outage

Bundled bootstrap, areas and home responses make a fresh install usable without a network connection. If no remote image has ever been downloaded, display the bundled fallback image. If a scheduled cached image exists, prefer it. If none is active, choose the latest cached photo only if permitted usage rights allow it; otherwise use the bundled fallback.

## Data integrity

Do not activate a partially downloaded or invalid JSON/GeoJSON response. Keep the previous validated copy and its version. Store photo bytes separately from metadata; do not display an image URL without cached bytes when offline.
