Server Architecture
Router structure
The Axum server has two route groups:
Page routes (server/routes/)
GET /– index page (SVG map, chart, data table)GET /region/:slug– region detail pageGET /compare– regional comparison page
API routes (server/api/)
GET /api/chart/*– Chart.js JSON data endpointsPOST /api/mortgage-calc– HTMX mortgage calculatorPOST /api/recalc-savings– HTMX savings recalculatorPOST /api/scenario/*– personalized scenario endpointsGET /api/status– refresh status
AppState
Shared state contains:
pool: SqlitePool– database connectionrefreshing: AtomicBool– whether a background fetch is runninglast_refresh: RwLock<Option<String>>– timestamp of last successful refresh
Templates
Askama templates with a custom HtmlTemplate<T> wrapper that implements IntoResponse. Display helpers (fmt_thousands, severity_color, slug_to_display_name) are in templates.rs.
Background scheduler
On startup, the server triggers an immediate fetch+compute, then schedules a cron job every 6 hours via tokio-cron-scheduler. The server starts serving immediately with whatever data exists in SQLite.