A full-stack web application that provides water quality scores for NYC ZIP codes using official NYC Open Data.
- Real NYC Data: Uses official NYC Open Data from distribution monitoring sites
- 178 NYC ZIP Codes: Covers all 5 boroughs (Manhattan, Brooklyn, Queens, Bronx, Staten Island)
- 0-100 Quality Score: Easy-to-understand score based on 5 key water quality metrics
- Detailed Metrics: Turbidity, chlorine, fluoride, coliform, and E. coli measurements
- Filter Recommendations: Personalized filtration suggestions based on your water quality
- Confidence Indicators: Know how recent and reliable the data is
| Dataset | Source | Description |
|---|---|---|
| Water Quality | NYC Open Data bkwf-xfky | Distribution monitoring measurements |
| ZIP Boundaries | NYC Open Data pri4-ifjk | NYC MODZCTA boundaries |
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β β β β β β
β Next.js 16 β ββββΊ β FastAPI β ββββΊ β SQLite β
β Frontend β β Backend β β Database β
β (Port 3000) β β (Port 8000) β β β
β β β β β β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β β
β βΌ
β βββββββββββββββββββ
β β NYC Open Data β
β β (Socrata API) β
β βββββββββββββββββββ
β
βΌ
βββββββββββββββββββ
β User Browser β
βββββββββββββββββββ
- Node.js 18+ and npm
- Python 3.10+
- Git
git clone https://github.com/ghostkush/Hackathon_02_27.git
cd Hackathon_02_27cd backend
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Run data pipeline (downloads NYC data and builds database)
python -m data_pipeline.ingest_sites
python -m data_pipeline.ingest_zips
python -m data_pipeline.ingest_water
python -m data_pipeline.build_zip_site_map
python -m data_pipeline.build_zip_summary
# Start backend server
uvicorn app.main:app --reload --port 8000cd Hackathon_02_27
# Install dependencies
npm install
# Start development server
npm run dev- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- API Docs: http://localhost:8000/docs
# Build and start both services
docker-compose up --build
# Or run in detached mode
docker-compose up -d --buildAccess the app at http://localhost:3000
Hackathon_02_27/
βββ app/ # Next.js app directory
β βββ api/
β β βββ water-quality/ # API route (proxies to backend)
β βββ layout.tsx
β βββ page.tsx # Main page
βββ components/ # React components
β βββ water-results.tsx # Results display
β βββ zip-search.tsx # ZIP search input
β βββ score-ring.tsx # Score visualization
β βββ contaminant-card.tsx # Metric cards
β βββ ui/ # UI primitives
βββ backend/ # Python FastAPI backend
β βββ app/
β β βββ main.py # FastAPI application
β β βββ config.py # Configuration
β β βββ db.py # Database helpers
β β βββ models.py # Pydantic models
β β βββ parsing.py # Value parsing
β β βββ mapping.py # ZIP-site mapping
β β βββ scoring.py # Scoring engine
β βββ data_pipeline/ # Data ingestion scripts
β β βββ ingest_sites.py
β β βββ ingest_zips.py
β β βββ ingest_water.py
β β βββ build_zip_site_map.py
β β βββ build_zip_summary.py
β βββ water.db # SQLite database (generated)
β βββ requirements.txt
β βββ Dockerfile
β βββ README.md
βββ docker-compose.yml # Docker orchestration
βββ Dockerfile # Frontend Docker image
βββ package.json
βββ .env.local.example # Environment template
βββ README.md # This file
Get water quality score for an NYC ZIP code.
Request:
curl "http://localhost:8000/score?zip=10001"Response:
{
"zip": "10001",
"score": 62,
"confidence": "medium",
"window": {
"preferred_days": 30,
"used_days": 180,
"min_samples_30d": 10
},
"as_of": {
"start": "2025-09-07",
"end": "2025-12-28"
},
"sites_used": [
{"sample_site": "33100", "distance_km": 3.12, "weight": 0.31}
],
"metrics": {
"turbidity": {"mean": 0.64, "min": 0.11, "max": 0.97, "n": 25},
"residual_free_chlorine": {"mean": 0.70, "min": 0.45, "max": 0.87, "n": 25},
"fluoride": {"mean": null, "min": null, "max": null, "n": 0},
"coliform_mpn": {"mean": 0.5, "max": 0.5, "n": 25},
"e_coli_mpn": {"mean": 0.5, "max": 0.5, "n": 25},
"sample_count_total": 25
},
"recommendations": [
"This score uses NYC distribution monitoring sites, not building plumbing."
],
"notes": []
}| Endpoint | Description |
|---|---|
GET /health |
Health check with database stats |
GET /stats |
Overall data statistics |
GET /zips |
List all valid NYC ZIP codes |
GET /docs |
Interactive Swagger UI |
BACKEND_URL=http://localhost:8000| Variable | Default | Description |
|---|---|---|
HOST |
0.0.0.0 |
Server host |
PORT |
8000 |
Server port |
CORS_ORIGINS |
http://localhost:3000 |
Allowed CORS origins (comma-separated) |
SOCRATA_APP_TOKEN |
`` | NYC Open Data API token (optional, increases rate limits) |
Penalties are applied based on water quality metrics:
| Condition | Penalty |
|---|---|
| E. coli max β₯ 1 MPN/100mL | -50 |
| E. coli mean β₯ 0.5 MPN/100mL | -25 |
| Coliform max β₯ 10 MPN/100mL | -20 |
| Coliform mean β₯ 1 MPN/100mL | -10 |
| Turbidity max β₯ 1.0 NTU | -15 |
| Turbidity mean β₯ 0.5 NTU | -8 |
| Chlorine mean < 0.2 mg/L | -8 |
| Medium confidence (stale data) | -5 |
| Low confidence (very stale data) | -12 |
Final score: 0-100 (clamped)
- High: Data within 30 days, β₯30 samples
- Medium: Data within 180 days, β₯10 samples
- Low: Older data or fewer samples
-
Frontend (Vercel):
- Connect GitHub repo to Vercel
- Set
BACKEND_URLenvironment variable to your backend URL
-
Backend (Railway/Render):
# Railway railway init railway up # Or Render # Connect repo and set build command: pip install -r requirements.txt # Start command: uvicorn app.main:app --host 0.0.0.0 --port $PORT
# Build images
docker-compose build
# Run with custom environment
CORS_ORIGINS=https://your-domain.com docker-compose up -dTo refresh the water quality data:
cd backend
source venv/bin/activate
python -m data_pipeline.ingest_water
python -m data_pipeline.build_zip_summaryThis fetches the latest data from NYC Open Data and recomputes all scores.
cd backend
source venv/bin/activate
# Test API endpoints
curl http://localhost:8000/health
curl http://localhost:8000/score?zip=10001npm run build
npm run lintMIT License - see LICENSE for details.
- NYC Open Data for providing water quality monitoring data
- NYC DEP (Department of Environmental Protection)
- Hackathon_02_27 team
Built with β€οΈ for NYC