civicwatch-v4/
├── backend/
│ ├── server.js ← Express API (auth, complaints, AI, analytics)
│ ├── database.js ← SQLite schema (wards, users, complaints, votes)
│ ├── seed.js ← 30 BBMP wards + 25 real Bengaluru complaints + all accounts
│ ├── package.json
│ └── .env.example ← Copy to .env and fill in
└── public/
├── index.html ← Login / Register page
├── api.js ← Shared API client (all pages use this)
└── pages/
├── citizen.html ← File complaints, GPS, AI analysis, city view
├── admin.html ← Assign workers, verify, analytics
└── worker.html ← Task list (role-isolated), resolve with photo
cd backend
npm installcp .env.example .envOpen .env and set:
PORT=3000
JWT_SECRET=any-long-random-string-here
GEMINI_API_KEY=your-gemini-api-key-here
Get a Gemini API key from Google AI Studio.
node seed.jsThis creates civicwatch.db with:
- 30 real BBMP wards (with zone, coordinates)
- 25 realistic Bengaluru complaints at real addresses
- All worker, police, admin and demo citizen accounts
node server.js
# or for auto-reload during development:
npm run devGo to http://localhost:3000
| Role | Password | |
|---|---|---|
| Admin | admin@bbmp.gov.in | Admin@2025 |
| Worker (Garbage) | kiran.babu@bbmp.gov.in | Worker@2025 |
| Worker (Roads) | sunil.kumar@bbmp.gov.in | Worker@2025 |
| Worker (Water) | raju.verma@bbmp.gov.in | Worker@2025 |
| Worker (Parks) | preethi.devi@bbmp.gov.in | Worker@2025 |
| Police (Parking) | mohan.s@ksp.gov.in | Police@2025 |
| Police (Signal) | deepak.nair@ksp.gov.in | Police@2025 |
| Police (Traffic) | kavya.m@ksp.gov.in | Police@2025 |
| Demo Citizen | ramesh.kumar@gmail.com | Citizen@2025 |
- JWT tokens signed server-side (12h expiry)
- Each worker sees only their assigned tasks — not other workers' tasks
- Citizens see only their own complaints (+ optional city-wide view)
- Admin has full access
- Tables:
wards,users,complaints,upvotes - Real BBMP ward data (ward number, name, zone, coordinates)
- Complaints indexed by status, citizen, worker, ward
- Complaint priority auto-scored from category weight + AI severity
- Photo uploaded → sent to Google Gemini Vision from the server
- API key lives in
.env— never exposed to browser - Returns: issue type, category, severity 1-5, confidence %, description, number plate
- Auto-fills the complaint form when confidence ≥ threshold
- Duplicate check uses Haversine formula (200m radius, last 7 days)
Real addresses across HSR Layout, Koramangala, Indiranagar, MG Road, BTM Layout, Whitefield, Electronic City, Marathahalli, Malleswaram, Basavanagudi, Yelahanka etc. Statuses spread across pending/assigned/in-progress/resolved/verified.
| Method | Path | Access | Description |
|---|---|---|---|
| POST | /api/auth/login | Public | Login → JWT token |
| POST | /api/auth/register | Public | Register citizen |
| GET | /api/auth/me | Any auth | Current user profile |
| GET | /api/complaints | Role-filtered | Citizens=own, Worker=assigned, Admin=all |
| GET | /api/complaints/all | Any auth | All complaints (city view) |
| POST | /api/complaints | Citizen | File new complaint |
| PUT | /api/complaints/:id/assign | Admin | Assign to worker |
| PUT | /api/complaints/:id/start | Worker | Mark in-progress |
| PUT | /api/complaints/:id/resolve | Worker | Submit resolution + photo |
| PUT | /api/complaints/:id/verify | Admin | Close complaint |
| PUT | /api/complaints/:id/reject | Admin | Reject complaint |
| POST | /api/complaints/:id/upvote | Citizen | Upvote (once per user) |
| POST | /api/ai/analyze | Any auth | AI image analysis |
| POST | /api/ai/duplicates | Any auth | Nearby duplicate check |
| GET | /api/workers | Admin | All workers + stats |
| GET | /api/wards | Any auth | All BBMP wards |
| GET | /api/analytics | Admin | Summary + charts data |
| GET | /api/health | Public | Server + AI status |