AirQ Web GIS is a production-minded environmental engineering portfolio project that brings together air quality monitoring, QA/QC, ISPU calculation, compliance-oriented screening, meteorological analytics, and simplified atmospheric dispersion visualization in a single system. It is designed to demonstrate how scientific logic, geospatial interfaces, and operational governance features can be integrated into a practical air quality workflow, while remaining explicit that the repository is a prototype for demonstration and screening rather than a certified regulatory platform.
- Purpose: showcase an environmental engineering workflow that combines monitoring, screening compliance, QA/QC, geospatial visualization, and operational governance.
- Best first experience: run locally with the built-in deterministic
syntheticdataset. - Deployment paths: local Windows run, Docker stack, or Vercel quick deployment.
- Engineering posture: tested, documented, secret-scanned, and explicit about scientific and regulatory boundaries.
- Recommended OS for the easiest first run: Windows with Python 3.11+.
- The backend auto-loads
.envfor local runs andrun_dashboard.bat. - The default demo mode is
synthetic, so you do not need a WAQI token to try the app.
Local demo: best option for portfolio review, screenshots, and first-time testing.Docker stack: best option if you want Prometheus, Grafana, Alertmanager, Redis, and PostGIS together.Vercel: best option for a lightweight public demo of the dashboard and API.
- Open PowerShell in the repo root.
- Create a local env file:
Copy-Item .env.example .env - Create the backend virtual environment and install dependencies:
cd backend python -m venv .venv .\.venv\Scripts\python.exe -m pip install -r requirements.txt
- Go back to the repo root and start the app:
cd .. .\run_dashboard.bat - Open:
Optional real-data mode:
- add
WAQI_TOKENto.env - open the UI with
?source=waqior setDATA_SOURCE=waqi
- Monitoring dashboard with ISPU and per-station air quality summaries.
- OpenAir-style wind rose, polar plot, and pollutant time series.
- Air quality forecasting for upcoming 24-72 hours.
- Automated report generation (Summary & Historical CSV exports).
- AERMOD-style near-field plume visualization.
- CALPUFF-style long-range transport view.
- Metrics, alerts, audit trail, retention, and backup endpoints.
The screenshots below show the dashboard, analytical modules, and operational features included in this portfolio project.
- Domain-focused engineering: ISPU computation, ambient standard checks, and dispersion mapping in one product.
- Modern Python Standards: Refactored for Python 3.12+ compatibility with 100% timezone-aware datetime handling.
- Full-stack implementation: FastAPI backend + spatial front-end visualization.
- Security-aware delivery: environment-based secrets and configurable CORS policy.
- Robust Testing: 34 automated tests covering core logic, API endpoints, and new features with 0 warnings.
- ISPU engine (PermenLHK No. 14/2020 style breakpoint interpolation).
- Compliance checks against:
- Indonesia PP No. 22/2021 (ambient limits used in this prototype).
- WHO 2021 Air Quality Guidelines (reference comparison layer).
- Monitoring dashboard data feed with selectable source:
synthetic(local deterministic demo dataset)waqi(real-time WAQI snapshots, token-based)auto(attempt real data, fallback to synthetic)
- QA/QC pipeline per station:
- range checks
- missing/non-numeric checks
- spike suspicion checks
- output split into
measurements_rawand cleanedmeasurements
- Operational governance controls:
- append-only audit events (
/api/audit-events) - data quality SLA summary (
/api/data-quality) - simple runtime metrics (
/api/metrics) - Prometheus scrape endpoint (
/metrics) - historical measurement query (
/api/history/station) - operational alerts (
/api/alerts) - automatic retention execution (
/api/history/retention/run) - history backup/restore endpoints (
/api/history/backup,/api/history/restore) - configurable rate limiting
- optional JWT auth + RBAC (
admin/viewer)
- append-only audit events (
- OpenAir-style analytics:
- Wind rose
- Polar plot
- Pollutant time series
- Air Quality Forecasting:
- 24-72 hour predictive trends for all pollutants and ISPU.
- Combines future meteorological projections with diurnal industrial activity profiles.
- Interactive Reporting & Data Export:
- Automated CSV/JSON summary reports of current quality state.
- Historical trend CSV exports for specific stations and parameters.
- AERMOD-style and CALPUFF-style visualization simulators for plume behavior insights.
- Backend: FastAPI, NumPy/SciPy, SQLAlchemy/PostGIS-ready models.
- Frontend: HTML/CSS/JavaScript with map + chart modules.
- Infra: Docker Compose with PostGIS, Redis, optional Celery worker.
backend/: FastAPI app, scientific logic (AERMOD, CALPUFF, ISPU), QA/QC, Forecasting, Reporting, auth, governance, and history store.frontend/: static dashboard UI with Leaflet and Chart.js.api/: Vercel serverless entrypoint.monitoring/: Prometheus, Alertmanager, and Grafana provisioning.docs/: scientific, compliance, privacy, auth rotation, and runbook notes..github/workflows/: CI, dependency audit, and secret scanning.
flowchart LR
U["User (Browser)"] --> FE["Frontend UI (Leaflet + Chart.js)\nfrontend/index.html + app.js"]
FE -->|GET /api/health| API["FastAPI Backend\nbackend/main.py"]
FE -->|GET /api/dashboard-data?source=synthetic| API
FE -->|GET /api/openair/*| API
FE -->|GET /api/aermod/dispersion| API
FE -->|GET /api/calpuff/plume| API
FE -->|GET /api/forecast| API
FE -->|GET /api/reports/*| API
FE -->|GET /api/emission-sources| API
API --> DF["Data Fetcher\nbackend/data_fetcher.py\nsources: synthetic | waqi | auto"]
DF --> WAQI["WAQI API (optional, token-based)"]
DF --> SYN["Synthetic NTB Generator"]
API --> QA["QA/QC Engine\nbackend/qa_qc.py\nmissing, range, spike checks"]
API --> ISPU["ISPU Calculator\nbackend/ispu_calculator.py"]
API --> CMP["Compliance Checker\nbackend/compliance.py\nPP 22/2021 + WHO 2021"]
API --> OA["OpenAir-style Analytics\nbackend/met_data.py"]
API --> FC["Forecast Engine\nbackend/forecast_engine.py"]
API --> RG["Report Generator\nbackend/report_generator.py"]
API --> AER["AERMOD-style Simulator\nbackend/aermod_simulator.py"]
API --> CAL["CALPUFF-style Simulator\nbackend/calpuff_simulator.py"]
API --> SRC["Emission Source Registry\nbackend/emission_sources.py"]
API --> RESP["JSON Response\n(raw + cleaned + qa_qc + ispu + compliance)"]
RESP --> FE
subgraph Deploy["Vercel Deployment"]
FE
API
VCFG["vercel.json\nroutes static + /api/*"]
end
This repository is an engineering portfolio prototype.
- It uses a local synthetic telemetry generator for repeatable demos.
- AERMOD/CALPUFF modules are simplified educational simulators, not replacement for certified regulatory modeling workflows.
- Compliance outputs are screening indicators and must be validated in formal EIA/AMDAL or permitting processes.
See:
docs/SCIENTIFIC_BOUNDARIES.mddocs/COMPLIANCE_SCOPE.mddocs/SECURITY_AND_PRIVACY.md
This repository is designed as an environmental engineering portfolio prototype.
- The system combines monitoring, QA/QC, ISPU calculation, meteorological analysis, and simplified dispersion visualization.
- It uses deterministic synthetic data by default to provide a reproducible demo path.
- The AERMOD-style and CALPUFF-style modules in this repository are simplified simulators for educational, screening, and workflow demonstration use.
- The outputs should be interpreted as engineering screening indicators, not as certified regulatory modeling results.
- Compliance checks in this project are intended as screening support against reference ambient air quality limits used in the prototype.
- The repository is informed by the Indonesian ambient air quality context, including
PP No. 22 Tahun 2021. - ISPU-related functionality is included to reflect common Indonesian air quality communication practice.
- This repository should not be presented as a substitute for formal AMDAL, permitting, or regulator-approved assessment workflows.
- The project includes comparison against WHO 2021 air quality guideline references for health-oriented benchmarking.
- The software design also includes governance-oriented controls such as auth, audit trail, retention, backup/restore, and observability.
- These controls improve engineering maturity, but they do not by themselves make the system legally compliant across all jurisdictions.
- an environmental engineering prototype
- a compliance-oriented screening tool
- a production-minded portfolio project
- a demonstration of monitoring, analytics, and governance integration
- a certified regulatory modeling platform
- an official implementation of AERMOD or CALPUFF
- a formal legal compliance system
- a replacement for field validation, regulator review, or external legal sign-off
If the Fastest Local Demo section already works for you, you can skip this section.
- Create env file:
- Copy
.env.exampleto.env - For the easiest portfolio demo, set
DATA_SOURCE=synthetic - The sample env defaults to SQLite for local-first setup
- Replace placeholder secrets before enabling auth or public deployment
- For public deployment, set
AUTH_ENABLED=true
- Copy
- Install backend dependencies:
cd backend python -m venv .venv .\.venv\Scripts\python.exe -m pip install -r requirements.txt
- Run the app:
Or start manually:
cd .. run_dashboard.batcd backend .\.venv\Scripts\python.exe -m uvicorn main:app --reload --host 127.0.0.1 --port 8000
- Open dashboard:
- Validate key endpoints:
- Run tests:
cd backend .\.venv\Scripts\python.exe -m pytest -q
docker compose --env-file .env up --buildMonitoring stack included in Docker:
- Prometheus:
http://localhost:9090 - Grafana:
http://localhost:3000usingGRAFANA_ADMIN_USERandGRAFANA_ADMIN_PASSWORDfrom.env - Alertmanager:
http://localhost:9093 - Grafana auto-loads
monitoring/grafana/dashboards/airq-overview.json - Docker Compose automatically connects the app container to PostGIS even though the sample
.envstays SQLite-first for local runs. - Before using Docker beyond local testing, replace placeholder secrets in
.env.
- Push repository to GitHub.
- Import project in Vercel from that GitHub repo.
- Set environment variables in Vercel Project Settings:
DATA_SOURCE=synthetic(recommended for first test)APP_NAMEAPP_VERSIONAUTH_ENABLED=trueif you want protected operational endpoints available
- Deploy.
Notes:
vercel.jsonservesfrontend/as static site and routes/api/*to FastAPI serverless entrypointapi/index.py.- Frontend API calls use same-origin paths, so no API URL rewrite is required.
AUTH_ENABLED=falseis acceptable for local/private demo use.- If you expose the app publicly, set
AUTH_ENABLED=trueand replace all placeholder credentials and secrets. ADMIN_API_KEYcan add another layer of protection for sensitive operational endpoints.ALERT_DISPATCH_KEYis optional and is mainly useful for non-private callers to the internal dispatch endpoint.
- No production secrets should ever be committed. Use
.envlocally and repository or platform secrets in deployment. - The default local path is intentionally easy to run for reviewers and recruiters.
- This repo is optimized for reproducible demo behavior first, then optional real-data experimentation second.
- When auth is disabled, protected operational endpoints are intended for local/private use only.
- GitHub Actions
CIworkflow:rufflint checkpytestwith coverage gate (>=70%)- backup/restore verification drill
pip-auditvulnerability check
- GitHub Actions
Secret Scanworkflow:gitleakson push/pull request
These pipelines enforce baseline code quality and security checks on every change.
Operational policy docs:
docs/AUTH_AND_SECRET_ROTATION_POLICY.mddocs/BACKUP_AND_RETENTION_RUNBOOK.md
- Contribution guide: CONTRIBUTING.md
- Security reporting: SECURITY.md
- Changelog: CHANGELOG.md
- License: LICENSE
GET /api/healthGET /api/data-qualityGET /api/metricsGET /metrics(Prometheus format)GET /api/audit-events(optionally protected viax-api-keywhenADMIN_API_KEYis set)GET /api/alertsGET /api/forecast?hours=24GET /api/reports/summary?format=csvGET /api/reports/historical?station_id=ntb-01&pollutant=pm10GET /api/auth/postureGET /api/history/station?station_id=<id>&pollutant=pm25POST /api/auth/token(whenAUTH_ENABLED=true)POST /api/alerts/dispatchPOST /api/history/retention/run?keep_days=30POST /api/history/backupPOST /api/history/restore?backup_file=<path>
- Prioritizes practical environmental analytics with clear system boundaries.
- Demonstrates ability to connect scientific logic, data services, and geospatial visualization.
- Includes baseline secure configuration practices expected in real deployments.
- Includes an optional SQLAlchemy/PostGIS schema scaffold in
backend/models.pyfor future persistence expansion.







