Inspiration
Every day, people in Lahore run into the same urban problems: potholes that damage vehicles, streets that flood after rain, uncollected waste, and streetlights that stay dark for weeks. Residents often don't know where to report them, and when reports do reach the city, they arrive as scattered, duplicated complaints with no way to tell which ones matter most. We wanted to fix both sides of the problem: make reporting as simple as taking a photo, and give city staff a clear, data-driven view of what to fix first.
What it does
CivicAI is a Lahore urban intelligence platform that turns citizen reports into prioritized action.
- Easy reporting: citizens submit a problem with a photo and GPS location from the web app or the Android app.
- AI classification: an LLM reads each report and assigns a category, a severity level and the responsible city department.
- Duplicate merging: reports are grouped into incidents by distance (80 m for the same category, 150 m across categories), so many reports of one problem become a single incident.
- Impact scoring (0-100): each incident is scored on severity (35%), number of reports (20%), proximity to major roads (20%), proximity to critical facilities such as hospitals and schools (15%) and recurrence (10%). Active rainfall adds a flood multiplier.
- Command Center: city staff get a live dashboard and map of incidents ranked by real-world impact.
- Status updates: citizens are notified when their report is assigned and when the issue is fixed.
- Recurring problem detection: report history is used to identify areas where problems keep returning, such as flood-prone streets.
- Ask CivicAI: a chat assistant answers questions about city incidents, with citations.
- Adaptable to other cities: local map data and departments can be swapped in, so the platform isn't limited to Lahore.
How I built it
- Backend: FastAPI with async SQLAlchemy and PostgreSQL. The AI pipeline is built with LangChain and LangGraph and uses Groq-hosted LLMs. The chat assistant works in three steps: a supervisor routes the question, retrieval runs through MCP tools, and a final step writes the answer with citations.
- Geospatial logic: Haversine distance for duplicate detection, and OpenStreetMap road and facility data synced into the database to power the impact engine.
- Weather: OpenWeatherMap rainfall data drives the flood multiplier.
- Web app: Next.js 16, React 19 and Tailwind CSS v4, with Leaflet and OpenStreetMap for maps and role-based sign-in for citizens and staff.
- Android app: Kotlin and Jetpack Compose, with Retrofit, OSMDroid and DataStore. Screens include an incident feed, a nearby map, report submission, my reports, alerts, the chat assistant and a staff-only Command Center.
- Infrastructure: Docker Compose for local development, deployed on Vercel (frontend), Render (backend) and Neon (PostgreSQL).
Challenges I ran into
- Deciding what counts as the same problem. A pothole and a nearby broken drain shouldn't always merge, but two reports of one pothole should. Using different distance thresholds for same-category and cross-category reports was our answer.
- Making the score reflect real harm. Counting complaints isn't enough. We had to combine severity, nearby roads and facilities, repeat history and weather into one explainable score.
- Keeping three surfaces consistent. The web app, the Android app and the API all had to behave the same way around one backend.
- Making LLM output dependable. We needed structured, predictable classifications to drive a real workflow, not free-form text.
- Building on a free-tier budget. We deployed on free services and had to work around their limits.
Accomplishments that I am proud of
- A complete, working pipeline: photo and GPS in, then AI classification, duplicate merging, impact score and a ranked staff dashboard.
- An impact score that is transparent and explainable, not a black box.
- Closing the loop with citizens, who are notified when their report is assigned and fixed.
- Going beyond single reports by using history to surface areas where problems keep recurring.
- Three working surfaces (web, Android and a documented REST API) running on one shared backend.
- A live deployment anyone can open and try.
What I learned
- How to pair LLM reasoning with deterministic geospatial logic, using each for what it does best.
- How to build multi-step AI workflows with LangGraph and tool-based retrieval.
- How to design for the people who act on the data, not just the people who submit it.
- How valuable open data like OpenStreetMap is for civic technology.
- How to ship one product across web, mobile and backend with a small team.
What's next for CivicAI: Lahore Urban Intelligence Platform
- Run a pilot with a real Lahore city department or local civic group.
- Add Urdu support so more residents can report and chat in their own language.
- Publish a public transparency view showing how quickly each department resolves issues.
- Launch in a second city to prove how easily the platform adapts.
- Add offline reporting for areas with weak internet, syncing once the phone reconnects.
Built With
- docker
- fastapi
- groq
- jetpack-compose
- jwt
- kotlin
- langchain
- langgraph
- leaflet.js
- mcp
- neon
- next.js
- openstreetmap
- openweathermap
- osmdroid
- postgresql
- python
- react
- render
- rest
- retrofit
- sqlalchemy
- tailwind-css
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.