DATATHON 2026 Β· Track 3: Smart City β "Where Should We Fix First?"
A defensible, evidence-grounded decision tool that tells municipal teams which locations to review first, shows transparent score receipts, quantifies rank stability, and converts limited crew and budget capacity into an optimized, variable-cost work plan.
Note
Synthetic Educational Data Notice: Coordinates, timestamps, and outcomes are simulated for educational evaluation. They do not represent a real municipality and must not be used for actual public-safety or emergency decisions.
Municipal operations teams face a recurring challenge: hundreds of reported incidents and public complaints arrive daily across thousands of urban locations, but public works crews and budget are strictly limited.
FixFirst solves this by answering two operational questions:
- Where should we inspect first? β Ranks 1,000 locations using transparent, current-state facts (open incidents, recent injuries, aging complaints, and human exposure) rather than noisy historical forecasts.
- What can our crews actually complete today? β Solves a multi-constraint resource allocation problem (crews, working days, and budget) where each incident is evaluated with dynamic variable costs based on its severity tier, case priority score, injury complexity, and location mobilization.
Before building FixFirst, we rigorously tested whether machine learning models could reliably predict future incident locations on this dataset:
-
208 Association Tests: Tested every outcome against every location attribute, hour, weekday, and month. Zero (0) passed the Bonferroni threshold (
$p < 2.4 \times 10^{-4}$ ). -
9 Gradient-Boosting Probes: Evaluated under time-based train/test splits (Train: JanβAug, Test: SepβDec). All probes matched naive majority-class baselines (AUC
$\approx 0.50$ ,$R^2 \approx 0.0$ ). -
Poisson Dispersion Test: Pearson ratio
$1.058$ ($p = 0.099$ ). Location-level incident distributions do not differ significantly from random Poisson noise. - Historical Count Trap: Ranking locations purely by raw past incident counts produces a Poisson deviance of 2.52, which is substantially worse than a global mean baseline (1.09).
The Architectural Choice: Instead of offering an unreliable predictive forecast, FixFirst prioritizes based on active backlog, verified harm, and vulnerable exposure, while reporting rank stability intervals honestly.
-
Incident-Specific Variable Costing:
- Base Severity Tier: Low (βΉ3,000, 0.25 crew-days), Medium (βΉ6,000, 0.50 crew-days), High (βΉ12,000, 0.75 crew-days), Critical (βΉ20,000, 1.00 crew-days).
-
Priority Multiplier: Scaled from
0.85xto1.20xdepending on the case priority score. -
Harm Complexity: Adds
+βΉ2,000and+0.10crew-days per reported injury. -
Mobilization Overhead: Adds
+βΉ2,000and+0.25crew-days each time a crew relocates to a new site.
-
Multi-Constraint Optimization:
- Dynamically evaluates crew capacity (
$\text{crews} \times \text{days}$ ) and budget limits. - Automatically identifies and displays the active system bottleneck:
Budget,Crew capacity, orBoth.
- Dynamically evaluates crew capacity (
-
Dual Schedule Views:
- By Priority: Sequential dispatch ordered by urgent case priority.
- By Crew: Partitioned itineraries showing each crew's assigned locations, days used, and budget allocation.
-
One-Click Re-Planning:
- Computes the exact monetary and crew-day shortfall for the top 10 deferred high-priority cases.
- One-click button applies the recommended capacity and updates the plan in real-time.
Municipalities can tailor triage to their policy priorities:
- Safety-first: Prioritizes severe incidents, recent injuries, and school/hospital exposure.
- Backlog-first: Focuses on clearing open complaints and long-standing unattended tickets.
- Vulnerable-areas-first: Emphasizes high pedestrian activity and high-density zones.
- Custom: Full control to specify custom normalized weight vectors across all 6 core components.
- Score Receipts: Breaks down priority scores into 6 clear components (Open incident load, Injury severity, Open complaint load, Complaint age, Exposure, and Shrunk history).
- Perturbation Testing (500 runs): Measures rank robustness against policy weight shifts, classifying stability as High, Medium, or Low.
- Evidence Gap Detection: Flags when historical data is tied, when a complaint is aging past 90 days, or when an area has high incidents but zero complaints (suspected under-reporting).
- Built with Next.js (React 19, TypeScript) and a companion Streamlit application.
- Live queue map with OSM coordinates and rank-colored markers.
- Inspection drawer with location-level monthly histories, open ticket tables, and generated work-order briefs.
- In-memory mutation support: CSV upload (
incidents.csv,public_complaints.csv), single ticket entry form, simulated demo bursts, and one-click data reset.
graph TD
subgraph Frontend ["Next.js Frontend (Port 3000)"]
UI[App UI: Tabs, Map, Controls]
APIClient["lib/api.ts (REST Fetch Client)"]
UI <--> APIClient
end
subgraph Backend ["FastAPI Backend (Port 8000)"]
API[FastAPI Server: backend.py]
PriorityEngine["src/priority.py (Triage & Receipts)"]
WorkPlanner["src/planner.py (Capacity & Variable Cost Solver)"]
EBModels["src/eb_models.py (Empirical-Bayes & Poisson GLM)"]
API <--> PriorityEngine
API <--> WorkPlanner
API <--> EBModels
end
subgraph Storage ["Data & Model Artifacts"]
CSV[Data CSVs: locations, incidents, complaints]
ModelFiles[outputs/models/*.json & *.csv]
PriorityEngine <--> CSV
EBModels <--> ModelFiles
end
APIClient <-->|REST API / JSON| API
| Layer | Technologies |
|---|---|
| Frontend | Next.js 16 (App Router), React 19, TypeScript 5.7, Lucide Icons, CSS Design System |
| Backend API | FastAPI, Uvicorn, Pydantic, Python-Multipart, HTTPX |
| Modeling & Analytics | Python 3.10+, NumPy, Pandas, Scikit-learn (KMeans, HistGradientBoosting), SciPy |
| Alternative UI | Streamlit, Plotly, PyDeck |
FirstFix/
βββ backend.py # FastAPI REST server with all triage and planning endpoints
βββ app.py # Streamlit interactive application
βββ requirements.txt # Python backend dependencies
βββ test_api.py # Automated API smoke test suite (FastAPI TestClient)
βββ inspect_data.py # Dataset summary and schema inspection utility
βββ README.md # Project documentation
β
βββ frontend/ # Next.js web application
β βββ app/
β β βββ page.tsx # Main dashboard (Work plan, Queue, Location, Strategy, Evidence)
β β βββ layout.tsx # Root layout & metadata
β β βββ globals.css # Responsive theme & component styles
β βββ lib/
β β βββ api.ts # TypeScript API client & live backend communication
β β βββ utils.ts # Utility helper functions
β βββ package.json # Frontend scripts and dependencies (pnpm)
β βββ tsconfig.json # TypeScript configuration
β
βββ src/ # Core algorithmic and modeling modules
β βββ priority.py # Current-state triage engine, receipts, and rank stability
β βββ planner.py # Crew-days budgeting, route clustering, strategy benchmark
β βββ eb_models.py # Empirical-Bayes Gamma-Poisson and IRLS Poisson GLM from scratch
β βββ signal_scan.py # 208 association tests and ML baseline probes
β βββ power_check.py # Heterogeneity power-simulation verification
β βββ eda.py # Exploratory analysis and visual diagnostic outputs
β
βββ data/ # Input datasets
β βββ locations.csv # Location coordinates, road types, pedestrian density, schools/hospitals
β βββ incidents.csv # Reported incident tickets, timestamps, severity, and injuries
β βββ public_complaints.csv # Civic 311 complaints, categories, priorities, and statuses
β
βββ outputs/ # Precomputed evaluation artifacts
βββ models/ # Empirical-Bayes tables, scan results, and power checks
- Python: Version
3.10or newer - Node.js: Version
18.xor newer (withpnpminstalled:npm install -g pnpm)
Open a terminal in the root directory:
# 1. Install Python dependencies
pip install -r requirements.txt
pip install pandas numpy scikit-learn scipy streamlit
# 2. Start the FastAPI backend with auto-reload
uvicorn backend:app --reload --port 8000The API documentation is interactively available at: http://localhost:8000/docs.
Open a second terminal in the frontend folder:
cd frontend
# 1. Install dependencies
pnpm install
# 2. Start the Next.js development server
pnpm devOpen your browser and navigate to: http://localhost:3000.
If you prefer the standalone Streamlit interface:
streamlit run app.pyStreamlit will launch locally at http://localhost:8501.
To run the full suite of end-to-end API smoke tests:
python test_api.pyExpected output:
summary: 2025-12-31 2903 open inc | 3513 open com ...
top5: [('L0642', 93.32, 'High'), ('L0493', 91.11, 'High'), ...]
plan: 27 locs, 60.0 days, 5 bundles ...
workplan: 11 scheduled | 134 very-high deferred | limiting: budget ...
ALL OK
| Endpoint | Method | Description |
|---|---|---|
/api/health |
GET |
Health check and current dataset record counters |
/api/summary |
GET |
Citywide KPIs, records in use, policy lenses, and zone lists |
/api/queue |
GET |
Ranked location queue with filters (lens, topN, zones, stability) |
/api/location/{id} |
GET |
Full inspection receipt, open items, monthly history, and work brief |
/api/workplan |
POST |
Incident-level schedule solver under crew, days, and budget constraints |
/api/workplan/defaults |
GET |
Default unit costs, currency, overheads, and priority weights |
/api/plan |
POST |
Location-level crew-day budgeting and strategy comparison benchmarks |
/api/gap |
GET |
Voice-record divergence scan (locations with high complaints vs low incidents) |
/api/demo-batch |
POST |
Injects simulated January 2026 incident bursts across 3 locations |
/api/reset |
POST |
Clears all dynamic uploads and resets state to original baseline |
/api/upload |
POST |
Ingests multipart CSV files (incidents.csv or public_complaints.csv) |
/api/report |
POST |
Adds a single new incident or complaint from an operational form |
/api/evidence |
GET |
Model deviance metrics, association scan stats, and probe evaluations |
- Strict Temporal Boundaries:
- As-of date queries strictly purge any ticket recorded after the timestamp.
- An incident is counted as open only if
resolved == 0or its recordedresolution_hoursextends beyond theasofcutoff.
- Leakage-Safe Validation Splits:
- Validation fits exclusively on JanβJun and evaluates on JulβDec.
- 28-day forecast probes maintain a temporal purge gap between train targets and test evaluation cutoffs.
- No External Dependences or Black Boxes:
- Zero external LLM APIs, no proprietary web services, and no pretrained model weights.
- All analytical models (Poisson GLM with Iteratively Reweighted Least Squares and Empirical-Bayes Gamma-Poisson) were developed directly on the provided data.
- Decision Support, Not Automated Enforcement: FixFirst prioritizes the order in which municipal personnel should review locations; it does not replace professional on-site evaluation.
- Backlog Triage vs. Prevention: The planning system optimizes how much existing backlog and recorded harm can be serviced within current resources; it does not claim to prevent unobserved future occurrences.
- Reporting Discrepancies: High-complaint areas may reflect active community civic reporting rather than physical hazard severity. The "Evidence Gaps" flag alerts officers when an area might be under-reported.