A scientific dashboard that turns hourly station data into AQI trends, 48-hour forecasts, anomaly alerts, and cross-city insights — inspired by the KDD Cup 2018 "KDD Cup of Fresh Air" challenge. A React + TypeScript + Vite frontend pairs with a Docker-hosted Python Falcon API and a MongoDB datastore.
Note
Every view is driven by the live /api/v1 surface — there is no mocked runtime data. A
deterministic seed populates 159 stations with hourly history, forecasts, metrics, anomalies,
a wind flow field, and pipeline health.
The platform pairs a React + TypeScript + Vite frontend with a Docker-hosted
Python Falcon API and a MongoDB datastore. A deterministic seed command populates a
realistic monitoring network — 159 stations (35 Beijing air-quality stations, 24 London
LAQN air-quality stations, plus weather and grid stations) using authentic
{city}_meo_## and {city}_grid_### naming — together with hourly history, forecasts, model
metrics, anomalies, a wind flow field, and pipeline health.
Every view is driven by the live /api/v1 surface; there is no mocked runtime data.
Plus a Station Browser with a searchable/filterable network table and a live station detail panel.
- Frontend — React 18, TypeScript 5, Vite 6, TanStack Query, React Router, Recharts, Leaflet / react-leaflet, Radix UI + Tailwind CSS, Storybook, Vitest.
- Backend — Python Falcon API (Docker).
- Data store — MongoDB (Docker).
- Data model — deterministic, seeded hourly environment model for stations, history, forecasts, metrics, anomalies, flow field, and pipeline health.
React / Vite dashboard
→ /api/v1 typed HTTP repositories
→ Falcon API container
→ MongoDB versioned seed collections
← deterministic seed command
The frontend enforces a one-way dependency flow — app → features → shared / data → entities —
with a repository pattern that swaps the live HTTP client for an in-memory implementation in tests.
See docs/architecture.md for the full design.
The entire stack runs with Docker Compose:
docker compose up --buildThis builds and starts MongoDB, the Falcon API, the API docs, the frontend, and a one-shot
seed service that populates the datastore. Then open:
| Service | URL |
|---|---|
| Frontend dashboard | http://localhost:4200 |
| API | http://localhost:8080 |
| API docs | http://localhost:8081 |
MongoDB runs on the internal Docker network only (no host port is published). To reach it directly, use
docker compose exec mongodb mongo air-pollution.
To iterate on the frontend against the running API:
cd airPollution
pnpm install
pnpm dev # http://localhost:4200cd airPollution
pnpm typecheck
pnpm lint
pnpm test
pnpm build
pnpm build-storybookBackend syntax and unit checks:
python3 -m compileall -q server/air_pollution
PYTHONPATH=server python3 -m unittest discover -s server/tests -vair-quality-prediction-platform/
├── airPollution/ React + TypeScript + Vite frontend
│ └── src/
│ ├── app/ App shell, layout, router, providers
│ ├── features/ Feature pages (overview, map, predictions, …)
│ ├── shared/ UI kit, charts, and library helpers
│ ├── data/ Typed repositories + HTTP / memory clients
│ └── entities/ Pure domain models and types
├── server/ Python Falcon API + deterministic seed CLI
├── docs/ Architecture, contributing, and screenshots
└── docker-compose.yml API, frontend, docs, MongoDB, and seed services
Station identifiers and the problem framing are based on the public KDD Cup 2018 “KDD Cup of Fresh Air” challenge. All displayed readings are produced by a deterministic seed model for demonstration purposes. See ATTRIBUTIONS.md for open-source credits.







