Inspiration
Pune is the 4th slowest city in the world for traffic — average 10km travel time: 33 minutes 22 seconds (TomTom Traffic Index 2024). ~300 fatal road accidents happen in Pune every year, with 42 accident black spots identified in the district — work started on only 15 (Pune District Collector, March 2026). Officers are managing dozens of junctions with zero live data. Citizens spot broken signals, congestion, or accidents — but they have nowhere to formally report it. They post to WhatsApp groups, call helplines that log nothing, or just move on.
I wanted to build something that closes this loop: a system where a citizen can report a junction problem in seconds, an officer can see it in real time, act on it, and the citizen gets notified when it's actually resolved — with a verification mechanism so the system doesn't just mark things "done" and forget them.
The name ChowkChakra captures the idea. Chowk is "intersection" in Marathi/Hindi. Chakra means "cycle." It's the cycle from report → officer action → citizen verification → resolution.
What It Does
ChowkChakra is a two-interface system: a mobile-first Citizen PWA and a desktop Officer Command Center.
Citizen PWA
Citizens open the app and land on a live Mapbox map of Pune's junctions, color-coded by Gridlock Risk Score. They can:
- Report in 2 modes: Commute Mode (wake-word activated hands-free mode — say "Chakra" to open a 15-second voice session via Gemini Live API, GPS detects the junction automatically) or Manual Report (upload a photo or video — Gemini Vision classifies the issue type, auto-fills a description).
- Search existing junctions: Find a junction by name or ward, see active incident tags, upvote confirmed problems, and view citizen evidence gallery. A 200-meter proximity check prevents duplicate junction entries from being created for the same physical location.
- Get notified: When an officer resolves a tag, the citizen receives a push notification and a verification card in the Alerts tab — they vote "Fixed" or "Still Broken." If more than 50% of at least 3 responses say "Still Broken," the tag automatically reopens.
Officer Command Center
Officers use a dark-mode web dashboard with five sections:
- Live Heatmap — Mapbox GL map showing junctions with active incident reports. Click any marker to see the junction's name, ward, risk score, active tags, and a button to view detailed reports.
- Reports Review — Two-panel workspace. Left: junction list filtered by ward, tag type, and status. Right: selected junction's details including dominant issue, live traffic congestion (Google Maps Routes API), weather penalty (Open-Meteo API), historical accident count, and active incident tags. Officers can generate a PDF dispatch report, refresh live data, view past analysis & history, open an AI powered analysis, assign the tag to a specific ward officer (emailed via Resend), or mark "Approve & Resolve" to push verification notifications to contributors.
- Analytics Dashboard — Daily report volume chart (30 days / 7 days / today), ward-level congestion grades (A–F), root cause breakdown donut chart, top 5 recurring junctions, chronic problem junctions (resolved and reopened 2+ times), and a live traffic alerts feed scanned from Google News, Pune Mirror, and X.
- Chakra AI Assistant — Natural language chat backed by Gemini 2.5 Flash with function calling on DynamoDB tables, and RAG semantic search over citizen incident reports and web evidence powered by pgvector on Amazon Aurora PostgreSQL.
- Social Bot Controls — Risk score threshold slider for automated X (Twitter) posts, manual post editor, and activity feed.
How We Built It
Stack:
- Next.js 16 (App Router), deployed on Vercel
- Amazon DynamoDB — single primary data store (10 tables), AWS SDK v3
- AWS S3 for media uploads (photos, videos)
- Google Gemini 2.5 Flash (text + vision classification via REST API)
- Mapbox GL JS for junction maps
- Google Maps Routes API (live jam factor per junction)
- Open-Meteo API (weather-based risk penalties)
- Resend (email dispatch to assigned officers)
- Web Push API / VAPID (push notifications to citizens)
Why DynamoDB, and how we actually used it:
We didn't just wire DynamoDB as a key-value store. Every table and index decision came from a specific access pattern we knew we'd hit:
- 10 tables, each with a clear job. Citizen profiles, active reports, junction metrics, incident tags, and resolved history are in separate tables — not one giant table with filter expressions. Hot write paths (
cc-tags,cc-reports) stay small. Cold archive (cc-tags-history) never slows down live queries. - SLA penalties computed at read time, not stored. We didn't want a cron job updating every overdue tag every minute. Instead, we check
currentTime > slaDeadlinewhen a junction is queried, and add a flat +15 penalty to thechainRiskScoreon the fly. No background writes, no drift. - Officer resolves and citizen vote confirmations run inside
TransactWriteCommand. When an officer marks something resolved, the tag status and the junction risk score update atomically. When citizen consensus confirms a fix, the tag moves from the livecc-tagstable tocc-tags-historyin a single transaction — or it rolls back toREOPENEDif the majority says it's still broken. - Ward-level lookups use a GSI, not a scan. The
cc-junctionstable has award-score-indexGSI withwardas the partition key andchainRiskScoreas the sort key. Officer dashboard ward filters areQuerycalls, notScancalls. - Native TTL handles all cleanup. Sessions expire in 24 hours, reports and push subscriptions in 90 days, media queue entries in 7 days. No external scripts.
Challenges We Ran Into
Keeping Commute Mode stable on mobile: PCM audio streams over WebSocket to a Python FastAPI relay → Gemini Live API. Mobile connections drop constantly. The relay uses exponential backoff, Gemini's native session_resumption handle, and context re-injection after each reconnect so the conversation doesn't restart.
The citizen verification state machine: Getting TransactWriteCommand to atomically archive a tag to cc-tags-history on majority-Fixed, or reopen it on majority-Still-Broken, without race conditions when simultaneous votes arrive — required careful DynamoDB key design.
Accomplishments That We're Proud Of
- The citizen verification loop actually works end-to-end: report → officer resolve → push notification → citizen votes → auto-reopen if majority says "Still Broken." This is a real governance mechanism, not a demo feature.
- The voice-activated Commute Mode is genuinely hands-free — a citizen driving can say "There's a water-logging issue at Kothrud junction" and the report is logged via Gemini without touching the phone.
- Designing the DynamoDB schema around query access patterns paid off: we isolated hot active paths from cold historical logs to prevent partition bottlenecks, successfully utilized GSIs to avoid table scans on ward-level lookups, and offloaded database maintenance entirely to native TTL.
What We Learned
The thing that surprised me most: the hard problems weren't frontend. They were "what happens when an officer resolves something but two citizens vote 'Still Broken' simultaneously?" or "what do we do when the same junction gets 15 reports in 5 minutes from different people?"
Every one of those edge cases became a database decision. DynamoDB forces you to think about access patterns before you write a single line of schema. The first time I tried to add a ward filter to the officer dashboard using a Scan, I saw exactly why that's wrong at scale. The GSI rewrite was 30 minutes of work, but understanding why it was necessary took the better part of a day.
What's Next for ChowkChakra
- Multi-city support: The junction registry and ward system are parameterized by city. Adding Nashik, Nagpur, or Mumbai would require importing that city's junction data — the rest of the system is already city-agnostic.
- Predictive risk scoring: Right now the Gridlock Risk Score is calculated from active tag counts and types. Adding historical pattern analysis (e.g., "FC Road always congests on Monday mornings") would allow predictive alerts before the reports start coming in.
- Integration with PMC SCOOT/ATCS: Pune's Smart City project has signal controller data. Integrating that feed would make the risk score more precise and reduce dependence on citizen reports alone.
Built With
- amazon-aurora-postgresql
- amazon-dynamodb
- amazon-web-services
- drizzle-orm
- google-gemini
- mapbox
- next.js
- open-meteo
- resend
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.