Skip to content

Jalkarna/election-guide

Repository files navigation

ElectionGuide

ElectionGuide is a full-stack civic AI platform for Indian elections. It provides Gemini-powered AI chat, voter readiness scoring, guided voting journeys, an interactive EVM/VVPAT simulator, civic quizzes, scenario-based guides, an India electoral map, and verified official resources — all grounded in ECI data and designed for first-time voters, returning voters, NRIs, senior citizens, and persons with disabilities.

The backend is a FastAPI service with Google Gemini streaming, SQLAlchemy async models, three-tier rate limiting, and a full security middleware layer. The frontend is a Next.js 16 app with Framer Motion animations, WCAG 2.1 AA accessibility, and a dark-first India-themed design system. The app is packaged as a single Docker image for Cloud Run. In production, nginx fronts both the Next.js standalone server and the FastAPI API server on one public port.

Challenge Vertical

Chosen vertical: civic information assistant.

ElectionGuide is designed for Indian voters, first-time citizens, candidates, and election volunteers who need reliable, neutral, and source-grounded election guidance. The assistant makes decisions based on user context: selected response language, conversation history, the type of election question, and whether current facts require tool verification before answering.

Evaluation Scorecard Targets

Category Implementation signals
Code Quality Modular FastAPI services, auth and platform packages, typed schemas, split React chat/platform/auth components, reusable hooks/utilities
Security Secret Manager, bounded inputs, rate limiting, browser hardening headers, safe external links, no committed secrets
Efficiency Streaming WebSocket responses, bounded fetch/PDF extraction, model fallback, deterministic platform tools, Cloud Run scale-to-zero
Testing 172 backend tests across auth, platform, security (audit + enhanced + edge cases), integration, config, tools, and Google services; 12 frontend tests for markdown, accessibility, auth, route breadth, and platform client
Accessibility ARIA labels, keyboard focus, disabled states, responsive sidebar, documented manual checks
Google Services Gemini, Google Identity Services, Cloud Run, Cloud Build, Artifact Registry, Secret Manager, Cloud Logging, Cloud Storage, optional Custom Search and Firestore audit
Problem Alignment Non-partisan Indian election assistant with voter readiness, journey, booth guide, quiz, scenarios, and verified chat

Features

  • Landing-first civic platform surface with a dedicated /assistant chat workspace.
  • AI chat experience focused on Indian elections, voting processes, eligibility, schedules, and civic information.
  • Civic platform APIs for readiness scoring, voting journeys, booth guidance, quizzes, scenario simulation, and engagement insights.
  • Auth pages for login/signup with Google OAuth provider discovery and env-driven credentials. Falls back to a local dev session when OAuth credentials are not configured.
  • Gemini response streaming with reasoning, tool-call events, source annotations, and fallback model handling.
  • Session persistence with SQLite via SQLAlchemy async models.
  • Multilingual response support and UI copy translation for Indian languages.
  • Google Custom Search grounding with fallback search, page fetching, PDF text extraction, and Election Commission schedule lookup tools.
  • Single-container production runtime with Next.js, FastAPI, and nginx.
  • Cloud Run deployment through Cloud Build, Artifact Registry, Secret Manager, Cloud Logging, and a Cloud Storage mounted data volume.

Stack

Area Technology
Frontend Next.js 16, React 19, TypeScript, Tailwind CSS
Backend FastAPI, Uvicorn, Pydantic, SQLAlchemy async
AI Google Gemini / Vertex AI via google-genai
Storage SQLite locally or mounted at /data in Docker/Cloud Run
Runtime Docker, nginx reverse proxy
Cloud Google Cloud Build, Artifact Registry, Cloud Run, Secret Manager, Cloud Logging, Cloud Storage, Google Identity Services, optional Firestore audit

Repository Layout

.
|-- backend/
|   |-- auth/                # Google OAuth provider metadata, session issue/lookup/logout
|   |-- civic_platform/      # Readiness, journey, quiz, scenario, booth, analytics APIs
|   |-- services/            # Gemini streaming service and protocol helpers
|   |-- main.py              # FastAPI app, streaming chat API, session routes
|   |-- config.py            # Environment-based settings
|   |-- database.py          # SQLAlchemy models and async session setup
|   |-- genai_client.py      # Gemini / Vertex AI client factory
|   |-- google_services.py   # Google service registry, health, logging, secret/audit helpers
|   |-- prompts.py           # ElectionGuide system prompt
|   |-- tools.py             # Search, URL/PDF fetch, election schedule tools
|   |-- tests/               # Backend pytest coverage for auth, platform, config, tools, Google services
|   `-- requirements.txt     # Python dependencies
|-- frontend/
|   |-- src/app/             # Landing, assistant, platform, auth, and info routes
|   |-- src/components/      # Chat, auth, platform, thinking, citation, and UI components
|   |-- src/lib/             # API/auth/platform clients, config, i18n helpers
|   |-- tests/               # Frontend Node tests for markdown, routes, auth, accessibility
|   `-- package.json         # Frontend scripts and dependencies
|-- docs/                    # Google service, testing, and submission notes
|-- scripts/                 # Quality gate and repository size checks
|-- Dockerfile               # Multi-stage production image
|-- docker-compose.yml       # Local single-container deployment
|-- docker-entrypoint.sh     # Starts FastAPI, Next.js, and nginx
|-- nginx.conf               # Routes /api to FastAPI and / to Next.js
|-- cloudbuild.yaml          # Cloud Build + Cloud Run deployment
`-- .env.example             # Required environment variables

Environment Variables

Create backend/.env for local development:

cp .env.example backend/.env

Then set the values needed for your environment.

Variable Required Default Description
GOOGLE_API_KEY Yes, unless using ADC none Gemini or Vertex Express API key. Used as the primary auth path when set.
USE_VERTEX_AI No false Set to true to use Vertex AI Application Default Credentials instead of GOOGLE_API_KEY.
GCP_PROJECT_ID Required for Vertex AI / Cloud Run none Google Cloud project ID.
GCP_LOCATION No us-central1 Vertex AI and Cloud Run region.
GOOGLE_SEARCH_API_KEY No none Enables Google Custom Search JSON API grounding.
GOOGLE_SEARCH_ENGINE_ID No none Programmable Search Engine ID for Google Custom Search.
ENABLE_CLOUD_LOGGING No false Enables Google Cloud Logging setup in Cloud Run.
ENABLE_FIRESTORE_AUDIT No false Enables optional non-sensitive Firestore audit events.
FIRESTORE_AUDIT_COLLECTION No electionguide_audit Firestore collection used for audit events.
GOOGLE_OAUTH_CLIENT_ID No none Google Identity Services OAuth client ID for sign-in.
GOOGLE_OAUTH_CLIENT_SECRET No none Google OAuth secret. Keep this in Secret Manager for production.
GOOGLE_OAUTH_REDIRECT_URI No /api/auth/google/callback OAuth callback URL for Google sign-in.
AUTH_SESSION_TTL_HOURS No 24 Lifetime for issued auth sessions.
DATABASE_URL No sqlite+aiosqlite:///./election_guide.db Async SQLAlchemy database URL. Docker uses /data/election_guide.db.
GEMINI_MODEL No gemini-3-flash-preview Primary Gemini model.
GEMINI_FALLBACK_MODEL No gemini-2.5-flash Fallback model for retryable model errors.
NEXT_PUBLIC_BACKEND_URL No same origin in browser Frontend API base URL. Leave empty for the Docker/nginx deployment.
PORT No 8080 Public container port used by nginx.

Do not commit real secrets. In Cloud Run, GOOGLE_API_KEY is read from Secret Manager.

Local Development

Run the backend and frontend as separate processes while developing.

Backend

cd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reload --host 0.0.0.0 --port 8001

Backend health check:

curl http://localhost:8001/api/health

Frontend

In a separate shell:

cd frontend
npm install
NEXT_PUBLIC_BACKEND_URL=http://localhost:8001 npm run dev

Open http://localhost:3000.

Docker

Build and run the production container locally:

docker compose up --build

The app will be available at http://localhost:8080.

Docker Compose mounts ./data to /data, so the SQLite database persists between container restarts.

API Overview

Method Path Description
GET /api/health Health, configured model candidates, Gemini transport, and grounding tool status.
POST /api/i18n/translate-ui Translate frontend UI copy for a supported language.
GET /api/platform/features Machine-readable civic platform feature catalog.
POST /api/platform/readiness Score voter readiness and return missing next actions.
POST /api/platform/journey Generate persona-aware voting journey steps.
POST /api/platform/booth-guide Return polling booth preparation and accessibility guidance.
GET /api/platform/quiz Return civic literacy quiz questions.
POST /api/platform/quiz/submit Grade quiz answers with explanations.
POST /api/platform/scenario Simulate common election problem paths.
POST /api/platform/analytics/insights Return non-sensitive civic engagement insights.
GET /api/auth/providers Return Google Identity Services provider metadata and required env vars.
GET /api/auth/google/start Return a Google OAuth authorization URL when credentials are configured.
GET /api/auth/google/callback OAuth callback placeholder for production token exchange wiring.
POST /api/auth/google/dev Create a local dev session when OAuth credentials are not configured.
GET /api/auth/session Resolve a bearer token to the current auth session.
POST /api/auth/logout Revoke an auth session token.
POST /api/chat/sessions Create a new chat session.
GET /api/chat/sessions List sessions by most recently updated.
GET /api/chat/sessions/{session_id} Read a session and its messages.
DELETE /api/chat/sessions/{session_id} Delete a session.
POST /api/chat/sessions/{session_id}/stream Stream an assistant response using the Vercel AI SDK data stream protocol.
WS /api/chat/sessions/{session_id}/ws WebSocket streaming alternative for chat responses.

Example request flow:

SESSION_ID=$(curl -fsS -X POST http://localhost:8001/api/chat/sessions | jq -r .id)

curl -N \
  -H 'Content-Type: application/json' \
  -X POST "http://localhost:8001/api/chat/sessions/${SESSION_ID}/stream" \
  -d '{"message":"How do I check my voter registration status?","language":"English"}'

Testing and Quality

Backend:

cd backend
pip install -r requirements-dev.txt
pytest --cov=. --cov-report=term-missing

Frontend:

cd frontend
npm run lint
npm test
npm run build

Full local quality gate:

./scripts/run_quality_checks.sh

Submission size check:

./scripts/check_repo_size.sh

See docs/TESTING.md, docs/GOOGLE_SERVICES.md, docs/PLATFORM_FEATURES.md, docs/AUTHENTICATION.md, docs/ACCESSIBILITY.md, SECURITY.md, and docs/SUBMISSION_CHECKLIST.md.

Cloud Run Deployment

This repo includes a Cloud Build config that:

  1. Builds the Docker image.
  2. Pushes it to Artifact Registry.
  3. Creates a Cloud Storage bucket for the SQLite data volume if needed.
  4. Deploys Cloud Run service election-guide.
  5. Mounts the bucket at /data.
  6. Injects GOOGLE_API_KEY from Secret Manager.

Required Google Cloud resources:

  • Artifact Registry repository: election-guide in us-central1.
  • Secret Manager secret: GOOGLE_API_KEY.
  • Optional Secret Manager secret: GOOGLE_SEARCH_API_KEY if using Google Custom Search.
  • Enabled APIs: Cloud Build, Cloud Run, Artifact Registry, Secret Manager, Cloud Logging, Cloud Storage, Vertex AI / Gemini, and optionally Firestore + Custom Search.
  • Cloud Build service account permissions to push images, deploy Cloud Run, read the secret, and manage/use the storage bucket.

Deploy:

gcloud builds submit --config cloudbuild.yaml --project=<PROJECT_ID> .

After deployment:

gcloud run services describe election-guide \
  --region=us-central1 \
  --project=<PROJECT_ID> \
  --format='value(status.url,status.latestReadyRevisionName)'

The most recent deployment from this workspace targeted project new-bro-493718 and produced:

https://election-guide-vqa72x3qma-uc.a.run.app

Production Runtime

The production image starts three processes:

  • FastAPI on 127.0.0.1:8001.
  • Next.js standalone server on 127.0.0.1:3000.
  • nginx on ${PORT:-8080}.

nginx routes:

  • /api/* to FastAPI with buffering disabled for streaming.
  • / and all frontend routes to Next.js.

Useful Commands

# Frontend quality check
cd frontend && npm run lint

# Frontend production build
cd frontend && npm run build

# Backend health check
curl http://localhost:8001/api/health

# Container health check
curl http://localhost:8080/api/health

# Cloud Run logs
gcloud run services logs read election-guide --region=us-central1 --project=<PROJECT_ID>

Notes

  • backend/.env is the local environment file read by the backend settings loader.
  • NEXT_PUBLIC_BACKEND_URL should be empty for the single-container Docker/Cloud Run setup because nginx serves frontend and API from the same origin.
  • The assistant grounds answers with built-in search, URL fetching, PDF extraction, and election schedule lookup tools.
  • The chat stream uses the Vercel AI SDK data stream protocol and includes text deltas, reasoning deltas, tool call events, source annotations, and finish messages.

About

Full-stack AI assistant for Indian election information, powered by Next.js, FastAPI, Gemini, and Cloud Run.

Topics

Resources

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors