Building an AI-Powered Civic Grievance System with FastAPI and PostGIS
How we architected JanSamadhan to ingest WhatsApp webhooks, route tickets dynamically to city departments, and suppress duplicate complaints using location-aware queries.
Scale, accuracy, and geo-deduplication: key system design lessons from deploying a municipal pilot in Delhi.
Introduction to Civic Engineering
Building software for local government is completely different from building typical SaaS. In civic tech, your users aren't tech-savvy developers; they are everyday citizens reporting open potholes, water leaks, or electrical failures. The primary interface needs to be as friction-free as possible, which is why we turned to messaging interfaces like WhatsApp for ingestion.
However, behind that simple interface lies a complex routing problem. How do you take unstructured, multilingual complaints, identify where they are, figure out which of the 10+ government departments is responsible, and prevent queue flooding from duplicate reports?
This post details the system design of JanSamadhan, an automated civic routing system deployed as a ward pilot in Delhi.
---
High-Throughput Ingest with FastAPI
Our entry point is the WhatsApp Cloud API webhook. During local civic crises (such as heavy rainfall causing road flooding), webhook callbacks spike to thousands per minute. If the ingest server takes too long to respond, WhatsApp retries the callback, creating a webhook storm.
To solve this, we decoupled ingest from processing:
---
Geospatial Deduplication with PostGIS
The biggest administrative problem in civic reporting is duplicate reports. If a water main bursts in a market square, fifty people might report it within an hour. Creating fifty separate work tickets wastes civic resources and clogs agency dashboards.
We solved this using PostGIS:
SELECT id, category
FROM grievances
WHERE status = 'open'
AND category = :new_category
AND ST_DWithin(geom, ST_SetSRID(ST_Point(:lng, :lat), 436), :radius_meters);By querying coordinates using the `ST_DWithin` spatial query inside a strict radius (usually 50 meters), the system automatically links new submissions to the master ticket. The user is instantly registered as a subscriber to the existing issue, receiving updates without creating database overhead.
---
Multilingual Classification with Gemini
To route issues to correct departments without manual oversight, we structured our prompts to parse messy inputs into strict JSON models.
We defined a schema using Gemini structured output:
{
"category": "drainage_overflow",
"urgency": "high",
"summary": "Overflowing sewer line causing road block at Ward 12."
}The parsed JSON matches our internal database schema. Because Gemini returns standard format fields, the backend routes the grievance straight to the correct department's queue automatically.
---
Conclusion
Civic tech doesn't need over-engineered frameworks; it needs high-availability API endpoints, intelligent spatial caching, and structured routing models. JanSamadhan demonstrates how open APIs and simple open-source tools can dramatically improve urban living standards.