fct_weather_hourly
City, time, temperature, humidity, precipitation and wind. Weather-model observations retain their valid time.
Reliable pipelines are only the beginning. The real work is turning fragmented data into something people can understand and use.
A city’s weather, air, and mobility data live in different systems. Each comes with its own schema, clock, geography, and definition of “current”.
Retain the originals. Normalize at the boundary. Model useful questions. Carry provenance and quality all the way to the interface.
Select a stage to understand what it does and why it exists.
Different schemas, timestamps, units and refresh rates. Sources are fetched by server-side adapters; OpenAQ is an optional keyed provider. Casablanca intentionally exposes partial coverage.
City, time, temperature, humidity, precipitation and wind. Weather-model observations retain their valid time.
Location, pollutant, source unit, valid time and modeled/measured context. No automatic unit mixing or health labeling.
Station, collection time, capacity, available bikes and docks. An inventory snapshot is not a trip counter.
Hourly city signals joined at matching UTC boundaries. The API receives bounded, useful aggregates.
Keep the evidence. Original payloads are retained before parsing, so a malformed source response remains available for investigation. A failed live provider stays failed; it never turns into a fixture.
Expect duplicates. The event boundary uses at-least-once delivery. Content IDs and unique observation keys make processing repeatable. Consumer offsets advance after the database commit.
Preserve uncertainty. Missing readings remain null. Freshness thresholds belong to each source. The UI distinguishes unavailable, stale and current signals.
Make time explicit. All observations are stored in UTC. City-local time is presentation only. Replay applies an “at or before” cutoff independently to each signal.
Python · Kafka · Airflow · dbt · PostgreSQL / PostGIS · FastAPI · Next.js · TypeScript