Smart. Transparent. Impactful.
Bridging the gap between Nagpur's citizens and municipal departments through intelligent complaint routing, real-time tracking, and AI-driven prioritization.
- Overview
- Live Architecture
- Key Features
- Tech Stack
- Getting Started
- Environment Variables
- Database Schema
- API Reference
- Future ML Roadmap
- Project Structure
- Contributing
- License
CitySync is a full-stack, AI-augmented civic platform built specifically for Nagpur, India, enabling citizens to report municipal issues (roads, water, electricity) and track their resolution in real time. The platform connects three actor types โ Citizens, Zonal Officers, and City Administrators โ through role-based dashboards backed by a shared PostgreSQL database.
Every pothole, broken streetlight, and burst pipe reported via CitySync is automatically scored for urgency and routed to the correct department โ no manuals, no middlemen.
| Traditional System | CitySync |
|---|---|
| Paper/phone complaints | Real-time multi-channel (Web + WhatsApp) |
| Manual priority assessment | AI-powered Gemini 2.5 scoring |
| No duplicate detection | Geo-clustering deduplicates within 50 m |
| Status via phone calls | Live ticket tracking with short IDs |
| No spatial analytics | Interactive city-wide heatmap |
| Department chosen by clerk | Auto-corrected by AI |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CITIZENS โ
โ Web Dashboard โโโโบ WhatsApp Bot (Baileys) โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ HTTPS / REST
โโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Next.js 16 App Router (Edge-ready) โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโโ โ
โ โ /reports โ โ/priority โ โ/heatmap โ โ/escalation โ โ
โ โ API โ โ Engine โ โ API โ โ API โ โ
โ โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ โโโโโโโฌโโโโโโ โโโโโโโโฌโโโโโโ โ
โโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโ
โ โ โ โ
โผ โผ โ โ
โโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ โ
โ Supabase DB โ โ Gemini 2.5 โ โ โ
โ (PostgreSQL) โ โ Flash (AI) โ โ โ
โ + RLS + RPC โ โ โ โ โ
โโโโโโโโโฌโโโโโโโโ โโโโโโโโโโโโโโโโ โ โ
โ โ โ
โผ โผ โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Role-Based Dashboards โ
โ Civilian Portal โ Admin Overview โ Zonal Officer Panel โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The citizen-facing interface allows residents to submit, track, and upvote civic complaints with zero bureaucratic friction.
Complaint Submission
- Multi-step form selecting Department โ Issue Type โ Description โ Photo โ Location
- GPS-aware address resolution with manual fallback
- Ghost Mode โ privacy-preserving anonymous reporting (user ID is SHA-256 hashed before storage)
- Image evidence mandatory โ uploaded to Supabase Storage with public CDN URL
- Immediate ticket ID (
CS-XXXX-YYYYformat) returned after submission
Real-Time Tracking
- Live status dashboard:
Pending โ In Progress โ Resolved - Upvote mechanism to signal complaint importance to officers
- Visual status badges with color-coded state indicators
City Pulse Heatmap
- Interactive Leaflet.js map embedded in the civilian dashboard
- Heat intensity reflects density of active (non-resolved) issues in each area
- Zoomable, pannable โ built on OpenStreetMap tiles
QR-Based WhatsApp Access
- Scannable QR code on the civilian dashboard for instant WhatsApp bot onboarding
The city-level administrator has oversight over all complaints across all zones and departments.
System Overview
- Total complaints, resolution rate, and AI-processing statistics at a glance
- Department-wise breakdown: PWD, Electricity, Water
- Escalation feed: all tickets with
priority_score โฅ 9surfaced automatically
Escalation Management
- Mark tickets as
High PriorityorEscalate(forces priority to max) - Add administrative remarks visible to zonal officers
- Filter by status: Pending / In Progress / Resolved / Rejected
City Pulse (Admin)
- Admin-level heatmap showing the full spatial distribution of unresolved complaints
- Zone-level breakdown (North / Central / East / West / South Nagpur)
AI Audit Trail
- View Gemini's
verification,urgencyscores, andreasoningper complaint - See when the AI corrected a citizen's department selection
Each of Nagpur's five zones (North, Central, East, West, South) gets a dedicated officer who sees only their zone's complaints.
Priority Queue
- Complaints sorted by
priority_score(0โ9 scale) โ highest urgency at top - Visual evidence display: citizen-uploaded images rendered inline
- One-click status transitions:
Pending โ In Progress โ Resolved
Assignments Done
- Archive of completed work with before/after imagery
- Resolution reports with officer notes and time taken
Zone-Aware Audit Map
- Heatmap scoped to the officer's assigned zone only
- Filters out resolved complaints automatically โ shows only active workload
Ticket ID Search
- Look up any complaint by short ticket ID across the zone
The heart of CitySync's intelligence โ a multi-signal scoring engine that runs every time a complaint is submitted.
Formula:
Priority = min(9, (P ร I) + (V ร U) / 10)
P = similar complaints in a 500m radius in the last 15 days / 24
I = (upvotes + 1) ร 8 [impact/community weight]
V = AI verification score (0โ10) [Gemini: is this a real issue?]
U = AI urgency score (0โ10) [Gemini: how dangerous/urgent?]
How It Works:
-
Similarity Clustering โ When a complaint is submitted, the system checks for existing complaints of the same category within a 50-metre radius. Duplicates are batched into an existing cluster, incrementing its count.
-
Gemini 2.5 Flash Scoring โ The description, category, department, and attached image (converted to base64) are sent to Google Gemini. The model returns:
verification(0โ10): Is this a genuine civic issue? Does the image match the claim?urgency(0โ10): How dangerous or time-sensitive is it?corrected_department: If the citizen filed under the wrong department (e.g., a burst pipe reported to Electricity), Gemini reassigns it automatically.reasoning: A one-sentence explanation stored for audit.
-
Score Computation โ All signals are combined and capped at 9.
-
Persistent Write โ The score and AI metadata are written back to the
reportstable. The parent cluster'savg_priorityis recomputed via a Supabase RPC function. -
Department Auto-Correction โ If Gemini detects a department mismatch, the report is re-routed to the correct department dashboard without any human intervention.
Key Design Choices:
- Scoring is fire-and-forget (runs in the background post-insertion) so the citizen's POST request returns immediately.
- If Gemini is unavailable, the score defaults gracefully to 0 (community signals alone drive ranking).
- Priority = 9 triggers automatic surfacing in the Admin escalation feed.
A standalone Node.js service (in /bot) using Baileys (WhatsApp Web multi-device library) that allows citizens to file complaints via WhatsApp without installing any app.
Conversation Flow (State Machine):
Start / Hi / Menu
โโโบ [1] File Complaint
โโโบ Select Department (PWD / Electricity / Water)
โโโบ Select Issue Type
โโโบ Describe the problem (โฅ10 chars)
โโโบ ๐ท Send photo (mandatory)
โโโบ ๐ Share live location (mandatory)
โโโบ Confirm (Y/N)
โโโบ โ
Ticket Created (Short ID returned)
โโโบ [2] Track Complaint โ Enter Short ID โ Status Card
โโโบ [3] Privacy Policy
Technical Details:
- Sessions stored in-memory per WhatsApp JID (
jid โ {state, data}) - Images uploaded to Supabase Storage before the complaint is submitted
- Complaints POSTed to the same
/api/reportsendpoint as the web dashboard โ single source of truth - Short IDs (
CS-XXXX-9999) generated with Nano ID for shareable tracking - Full privacy policy served as plain text on request
Built with Leaflet.js + leaflet.heat and rendered via react-leaflet:
- Civilian view: Aggregated heatmap of all active issues across Nagpur
- Admin view: Full city view with zone labels and complaint density
- Zonal Officer view: Zone-scoped view filtered to their jurisdiction
- Heatmap points use complaint coordinates with intensity proportional to
priority_score - Automatically excludes resolved/completed complaints
- Data served via
/api/heatmapโ a dedicated endpoint with RLS bypass viasupabaseAdmin
| Layer | Technology |
|---|---|
| Framework | Next.js 16.2 (App Router, React 19) |
| Language | TypeScript 5 |
| Styling | TailwindCSS 4 + Framer Motion |
| Database | Supabase (PostgreSQL + RLS + RPCs) |
| Storage | Supabase Storage (CDN-backed image hosting) |
| AI / LLM | Google Gemini 2.5 Flash (@google/generative-ai) |
| Maps | Leaflet.js + react-leaflet + leaflet.heat |
| Baileys (multi-device WA Web API) | |
| Icons | Lucide React |
| Animations | Framer Motion |
| Bot Runtime | Node.js (ES Modules) |
- Node.js 20+
- A Supabase project
- A Google AI Studio API key (Gemini)
- A WhatsApp account for the bot (scan QR on first run)
# Clone the repo
git clone https://github.com/singhalgauri/CitySync.git
cd CitySync
# Install dependencies
npm install
# Set up environment (see below)
cp .env.example .env.local
# Run migrations against your Supabase project
# (apply files in supabase/migrations/ via Supabase dashboard SQL editor)
# Start development server
npm run devThe app will be available at http://localhost:3000.
cd bot
npm install
# Copy and configure bot env
cp .env.example .env
# Start the bot (scan QR code shown in terminal on first run)
node src/index.js# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
# Google Gemini AI
GEMINI_API_KEY=your_gemini_api_keySUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key-- Geo-spatial complaint clusters (deduplication unit)
clusters (
id UUID PRIMARY KEY,
lat FLOAT8,
lng FLOAT8,
category TEXT,
zone TEXT, -- 'north' | 'central' | 'east' | 'west' | 'south'
report_count INT,
avg_priority FLOAT8
)
-- Individual complaint reports
reports (
id UUID PRIMARY KEY,
cluster_id UUID REFERENCES clusters(id),
description TEXT,
category TEXT,
department TEXT, -- 'PWD' | 'Electricity' | 'Water'
lat FLOAT8,
lng FLOAT8,
zone TEXT,
image_url TEXT,
status TEXT, -- 'pending' | 'in_progress' | 'resolved' | 'rejected'
upvotes INT DEFAULT 0,
hashed_user_id TEXT, -- SHA-256, NULL if ghost mode
is_ghost BOOLEAN DEFAULT FALSE,
priority_score INT DEFAULT 0, -- 0โ9
ai_verification INT DEFAULT 0, -- Gemini output
ai_urgency INT DEFAULT 0, -- Gemini output
ai_processed BOOLEAN DEFAULT FALSE,
remarks TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
)
-- Zonal officer resolution reports
officer_reports (
id UUID PRIMARY KEY,
report_id UUID REFERENCES reports(id),
officer_id UUID,
report_text TEXT,
image_url TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
)| Function | Description |
|---|---|
find_nearby_cluster(lat, lng, category, radius_m) |
Returns the nearest matching cluster within radius_m metres |
update_cluster_avg_priority(cluster_id) |
Recomputes avg_priority for a cluster after a report is scored |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/reports |
Submit a new complaint (with AI scoring) |
GET |
/api/heatmap |
Get active complaint coordinates for heatmap |
GET |
/api/priority/recalculate |
Recalculate scores for unprocessed reports |
GET |
/api/escalation |
Fetch escalated complaints (score โฅ 9) |
PATCH |
/api/escalation |
Escalate, flag, or remark on a complaint |
GET |
/api/system-overview |
Admin stats: total, resolved, pending counts |
GET |
/api/reports |
Fetch reports (scoped by zone/department) |
POST |
/api/force-emergency |
Force a complaint to maximum priority |
POST |
/api/chat |
Gemini-powered contextual Q&A for admin |
CitySync's current AI integration uses prompt-based LLM scoring (Gemini Flash). The following roadmap outlines the transition to specialized, trainable ML models that will dramatically improve accuracy, speed, and operational insight.
Current State: Gemini Flash performs multimodal analysis โ it receives the complaint image as base64 alongside the text description and returns a verification score.
Problem: General-purpose LLMs are not optimized for detecting subtle infrastructure defects (hairline cracks in roads, partial waterlogging, sagging power lines). They can be fooled by irrelevant but city-themed images.
Planned Implementation:
Phase 1 โ Dataset Collection:
โโโ Label historical complaint images by category
โ (Pothole, Waterlogging, Broken Light, Garbage, etc.)
โโโ Augment with public civic datasets (COCO, India-specific municipal datasets)
โโโ Build annotation pipeline for zonal officers to label resolved cases
Phase 2 โ Model Training:
โโโ Fine-tune EfficientNet-B3 or MobileNetV4 for:
โ (a) Multi-class issue classification (10+ categories)
โ (b) Severity scoring (0โ5 scale for road damage, water damage)
โ (c) Binary validity detection (is this a real civic issue?)
โโโ Training infra: Google Vertex AI / HuggingFace Spaces
โโโ Model versioning via MLflow
Phase 3 โ Integration:
โโโ Replace Gemini verification call in getAiScores() with
โ dedicated vision model endpoint
โโโ Gemini retained only for department correction and NLP reasoning
โโโ Confidence threshold โ auto-reject spam below 0.3 confidence
Expected Outcome:
โ 40% reduction in false-positive complaints
โ Sub-200ms classification latency (vs. 2-4s Gemini calls)
โ Category auto-fill from image alone (no citizen selection needed)
Current State: No time estimate is given to citizens. Status changes from "Pending" to "In Progress" to "Resolved" with no predicted timeline.
Problem: Citizens have no expectation of when their complaint will be resolved, leading to distrust and repeat submissions.
Planned Implementation:
Feature Engineering from Historical Data:
โโโ department ร category ร zone combinations
โโโ day-of-week / season / weather patterns
โโโ officer workload (pending assignments per officer)
โโโ priority_score of the complaint
โโโ complaint cluster size (number of similar nearby reports)
Model Architecture:
โโโ Gradient Boosted Regressor (XGBoost / LightGBM) for:
โ โ Predicted hours to "In Progress" transition
โ โ Predicted hours to "Resolved" transition
โโโ Calibration layer for 80th-percentile confidence intervals
(display range, not point estimate, to citizens)
Integration Points:
โโโ POST /api/reports: ETA computed and stored as eta_hours field
โโโ Civilian dashboard: "Expected resolution by: [date]" badge
โโโ Admin dashboard: Overdue complaint alerts when ETA breached
โโโ Weekly ETA accuracy report for admin (RMSE per zone/department)
Data Requirements:
โ Minimum 500 resolved complaints with timestamps per department
โ 3-month historical baseline before model is reliable
Current State: Zonal officers manually mark complaints as "Resolved" by uploading a completion report with an after-image. There is no automated check that the issue was actually fixed.
Problem: Officers may upload irrelevant images or mark issues resolved prematurely without actual fieldwork. Citizens cannot verify the fix.
Planned Implementation:
Before/After Change Detection:
โโโ Compare citizen's evidence image (before) with officer's
โ completion image (after) using siamese network or
โ contrastive learning model
โโโ Classify pairs as: Fixed / Partially Fixed / Unchanged
โโโ Score: "Work Completion Confidence" (0โ100%)
GPS Timestamp Verification:
โโโ Require officer app to embed EXIF GPS + timestamp in
โ completion photo
โโโ Validate that completion photo was taken within:
โ (a) 50m of the original complaint coordinates
โ (b) After the "In Progress" status was set
โโโ Flag suspicious submissions (same image hash, wrong GPS)
Citizen Feedback Loop:
โโโ Push WhatsApp notification when complaint is marked resolved
โโโ Citizen rates actuality: โ
Fixed / โ ๏ธ Partially Fixed / โ Not Fixed
โโโ Negative feedback auto-reopens the complaint
โโโ Officer reliability score updated based on citizen feedback
Integration:
โโโ POST /api/reports/{id}/verify (officer submits completion proof)
โโโ Background vision model validates before/after pair
โโโ If confidence < 60%, flag for admin review (don't auto-approve)
โโโ Admin dashboard: "Pending Verification" queue
Long-term:
โ Officer performance scorecards based on verification acceptance rate
โ Gamification: top-rated officers get highlighted in admin dashboard
Current State: CitySync is entirely reactive โ issues are reported by citizens after they occur.
Planned Implementation:
Spatial-Temporal Pattern Mining:
โโโ Identify recurring hotspots: areas with 3+ complaints of
โ same type in rolling 30-day window โ "Chronic Issue Zone"
โโโ Correlate with city infrastructure age data (if available from NMC)
โโโ Generate pre-emptive work orders for chronic zones
Seasonal Predictive Alerts:
โโโ Before monsoon: flag low-lying zones historically prone to waterlogging
โโโ Before summer: flag transformers/lines with past fault history
โโโ Alerts sent to relevant department heads via admin dashboard
Anomaly Detection:
โโโ LSTM / Isolation Forest on daily complaint volume per zone
โโโ Sudden spike in a zone โ early warning of infrastructure failure
โโโ Admin notified via dashboard banner + email
Infrastructure:
โโโ Scheduled cron job (Supabase Edge Functions)
โโโ Pattern analysis runs nightly on resolved complaint history
โโโ Output: "Predicted Risk Zone" overlay on admin heatmap
Current State: Citizens pick their department manually; Gemini corrects obvious errors but requires a full LLM call.
Planned Implementation:
Lightweight NLP Classifier:
โโโ Fine-tune DistilBERT / MobileBERT on complaint descriptions
โโโ Output: department + category + severity label
โโโ Runs client-side (ONNX.js) for zero-latency pre-fill
Multilingual Support:
โโโ Support Marathi (primary local language in Nagpur) and Hindi
โโโ Integrate IndicBERT or similar multilingual fine-tuned model
โโโ WhatsApp bot accepts complaints in Marathi/Hindi/English
Auto-Routing Pipeline:
โโโ NLP classifier runs on description text at form fill time
โโโ Suggests Department + Category to citizen (editable)
โโโ If citizen accepts suggestion, skip Gemini department-correction step
โโโ Reduces Gemini API usage by ~60%, cutting costs
Complaint Submitted
โ
โผ
โโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ
โ NLP Classifier โโโโโโโบโ Department + Categoryโ
โ (DistilBERT/ONNX) โ โ Auto-filled โ
โโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโฌโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโ
โ Vision Classifier โ
โ (EfficientNet B3) โ
โ โ Validity Score โ
โ โ Severity Score โ
โโโโโโโโโโโโฌโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโ
โ Priority Engine โ
โ (ML scores + P + I) โ
โ โ Final Score 0โ9 โ
โโโโโโโโโโโโฌโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโ
โ ETA Estimator โ
โ (XGBoost Regressor) โ
โ โ Resolution Date โ
โโโโโโโโโโโโฌโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโ
โ Work Verifier โ
โ (Siamese Net) โ
โ โ Completion % โ
โโโโโโโโโโโโโโโโโโโโโโโ
CitySync/
โโโ src/
โ โโโ app/
โ โ โโโ api/
โ โ โ โโโ reports/ # POST: Submit complaint, trigger AI scoring
โ โ โ โโโ heatmap/ # GET: Active complaint coordinates
โ โ โ โโโ priority/ # Priority recalculation endpoints
โ โ โ โโโ escalation/ # Admin escalation management
โ โ โ โโโ system-overview/ # Admin stats aggregation
โ โ โ โโโ force-emergency/ # Override-to-max-priority
โ โ โ โโโ chat/ # Gemini chat for admin Q&A
โ โ โโโ dashboard/
โ โ โ โโโ civilian/ # Citizen portal
โ โ โ โโโ admin/ # City administrator panel
โ โ โ โโโ zonal-officer/ # Zone-scoped officer view
โ โ โโโ login/ # Role-based authentication
โ โ โโโ register/ # New user registration
โ โโโ lib/
โ โ โโโ priority.ts # AI priority scoring engine (Gemini + formula)
โ โ โโโ zones.ts # Nagpur zone definitions + geo-utilities
โ โ โโโ auth-context.tsx # React auth state provider
โ โ โโโ supabase/ # Supabase client (anon + admin)
โ โโโ components/ # Shared UI components
โโโ bot/
โ โโโ src/
โ โ โโโ index.js # Baileys WhatsApp client entrypoint
โ โ โโโ handler.js # State-machine message router
โ โ โโโ store.js # Supabase complaint storage
โ โ โโโ sessions.js # In-memory session management
โ โ โโโ messages.js # Message templates
โ โโโ data/
โ โโโ privacy.txt # Privacy policy text
โโโ supabase/
โ โโโ migrations/ # SQL schema migrations
โ โโโ add_priority_columns.sql
โ โโโ add_priority_rpc.sql
โ โโโ add_zone_column.sql
โ โโโ fix_priority_column_types.sql
โโโ public/ # Static assets (logo, QR code)
โโโ .env.example # Environment variable template
โโโ package.json
We welcome contributions! CitySync is being built as a reference implementation for AI-assisted civic tech in Indian municipalities.
- Fork the repo and create a feature branch:
git checkout -b feat/your-feature - Follow the existing code style (TypeScript strict, ESLint configured)
- Add a migration file if you modify the database schema
- Submit a PR with a clear description of changes and screenshots where relevant
Good first issues:
- Add support for more Nagpur departments (e.g., Solid Waste, Garden)
- Implement complaint search by address text
- Add Marathi language support in the WhatsApp bot
- Build officer mobile PWA for field use
This project is licensed under the MIT License. See LICENSE for details.
Built with โค๏ธ for smarter cities, starting with Nagpur.
CitySync โ Because every complaint deserves an answer.