Thermograph monorepo: graded-climate API + SSR frontend + infra, domain-specific containerized deploys
Replace the per-cell parquet cache with TimescaleDB hypertables as the production backend for the raw daily climate record, and drop pg_duckdb. Parquet stays the backend whenever THERMOGRAPH_DATABASE_URL is not a Postgres URL (dev, tests, offline tooling), the same dialect switch the accounts DB and derived store already use, so CI stays Postgres-free. - data/climate_store.py: psycopg + polars bridge over climate_history (a hypertable), climate_recent, and climate_sync (per-cell freshness). Reads via pl.read_database, writes via COPY + ON CONFLICT upsert; fail-soft to a cache miss so a DB hiccup degrades to upstream refetch. - data/climate.py: route every cache/mtime touchpoint through a backend dispatch. recent_stamp becomes int(recent_synced_at) on Postgres; the stale-serve path still avoids bumping it, so derived-payload tokens invalidate on exactly the same events as before. - alembic 0002: CREATE EXTENSION timescaledb plus the hypertable schema (compression policy on year-old chunks), guarded to no-op off Postgres. - migrate_cache_to_pg.py (make migrate-cache): idempotent backfill of the parquet cache into the hypertables, preserving file mtimes as sync timestamps so recent_stamp is unchanged across cutover. - db image -> stock timescale/timescaledb:latest-pg18; drop the custom pg_duckdb Dockerfile, the read-only /parquet mount, and the duckdb tuning GUC. Docs updated for the new backend and cutover. Co-authored-by: Claude <noreply@anthropic.com> |
||
|---|---|---|
| accounts | ||
| alembic | ||
| core | ||
| data | ||
| deploy | ||
| notifications | ||
| templates | ||
| tests | ||
| web | ||
| alembic.ini | ||
| app.py | ||
| cities.json | ||
| cities_flavor.json | ||
| gen_cities.py | ||
| gen_flavor.py | ||
| indexnow.py | ||
| migrate.py | ||
| migrate_accounts_to_pg.py | ||
| migrate_cache_to_pg.py | ||
| paths.py | ||
| requirements-dev.txt | ||
| requirements.txt | ||
| warm_cities.py | ||