π Smart India Hackathon 2025 Winner - Problem Statement #25066
Development of an AI-driven ChatBot for INGRES as a Virtual Assistant
Ministry of Jal Shakti | Central Ground Water Board (CGWB)
- Overview
- Problem Statement
- Solution Architecture
- Key Features
- Technology Stack
- Quick Start
- System Architecture
- Database Schema
- API Documentation
- Query Patterns
- RAG Implementation
- Visualization System
- Deployment
- Project Structure
- Contributing
- Team
GroundSense Bot is an advanced AI-powered virtual assistant designed to revolutionize access to India's groundwater resource data. Built for the INGRES (India Ground Water Resource Estimation System) portal, it transforms complex groundwater assessment data into conversational, actionable insights.
India's groundwater crisis affects 700+ million people, with over 1,000 blocks classified as over-exploited. The INGRES portal contains critical assessment data for 5,796 blocks across India, but users face significant challenges:
- Complex Navigation: Difficult to retrieve specific data from vast databases
- Historical Data Access: Hard to analyze trends across multiple years
- Technical Barriers: Requires domain expertise to interpret data
- Time-Consuming: Manual queries take hours instead of seconds
A production-ready AI chatbot that:
- β Understands natural language queries in English and Indian languages
- β Provides instant access to 27,000+ groundwater assessments
- β Generates interactive visualizations automatically
- β Offers real-time insights with RAG-powered accuracy
- β Supports complex queries across multiple locations and time periods
Problem Statement ID: 25066
Title: Development of an AI-driven ChatBOT for INGRES as a Virtual Assistant
Organization: Ministry of Jal Shakti, Central Ground Water Board
The Assessment of Dynamic Ground Water Resources of India is conducted annually by CGWB and State/UT Ground Water Departments. The INGRES web application estimates:
- Annual groundwater recharge
- Extractable resources
- Total extraction
- Stage of groundwater extraction
Each assessment unit (Block/Mandal/Taluk) is categorized as:
- Safe (<70% extraction)
- Semi-Critical (70-90%)
- Critical (90-100%)
- Over-Exploited (>100%)
β
Intelligent query handling for groundwater data
β
Real-time access to current and historical assessments
β
Interactive scientific diagrams and visualizations
β
Multilingual support including Indian regional languages
β
Seamless INGRES database integration
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend Layer β
β React + TypeScript + TailwindCSS + Framer Motion β
β - INGRESAssistant (Main Chat Interface) β
β - 16+ Custom Chart Components (ECharts, Recharts) β
β - Real-time WebSocket Connection β
β - MapLibre GL JS Integration β
ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββ
β WebSocket / REST API
ββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββ
β Backend Layer β
β Go (Golang) - High Performance β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Chat Service β β
β β - WebSocket Handler β β
β β - Conversational Flow Management β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β NLP Service β β
β β - Query Intent Classification (17+ patterns) β β
β β - Entity Extraction (states, districts, years) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β LLM Service (Qwen 2.5 Coder via Ollama) β β
β β - Natural Language β SQL Generation β β
β β - Zero API Costs (Local LLM) β β
β β - 200+ lines of hardcoded logic eliminated β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β RAG Service (Retrieval-Augmented Generation) β β
β β - Hybrid Search (Keyword + Semantic) β β
β β - Gemini Embeddings (768 dimensions) β β
β β - pgvector Integration β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Cache Service (Redis) β β
β β - 60% faster repeat queries β β
β β - Persistent caching with AOF β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββ
β Data Layer β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β PostgreSQL 16 + pgvector β β
β β - 27,000+ Assessment Records β β
β β - Vector Embeddings (768D) β β
β β - Full-Text Search (tsvector) β β
β β - Multi-Year Data (2021-2025) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Redis (Persistent Cache) β β
β β - Query Results Cache β β
β β - Session Management β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- User Query β Frontend (INGRESAssistant)
- WebSocket β Backend (Chat Service)
- NLP Analysis β Intent Classification + Entity Extraction
- LLM Generation β Natural Language β SQL Query
- Database Query β PostgreSQL Execution
- Cache Check β Redis (if available)
- Visualization β AI-generated chart configuration
- Response Stream β WebSocket β Frontend Rendering
- Zero API Costs: Runs on local Ollama server
- SQL Generation: Natural language β SQL without hardcoded templates
- 7B Parameters: Optimized for code generation
- Offline Support: No internet dependency for query generation
- Hybrid Search: Combines keyword (BM25) + semantic (cosine similarity)
- 27K+ Embeddings: Gemini text-embedding-004 (768D vectors)
- 95%+ Accuracy: Grounded responses from actual assessment data
- Reranking: Gemini reranker for optimal result ordering
- 17+ Query Patterns: SUMMARY, TREND, COMPARE, TOP_RANKING, etc.
- Entity Extraction: Automatic detection of states, districts, blocks, years
- Intent Classification: Routes to appropriate service handlers
- Multilingual Support: English + Indian languages (future)
- Phonetic Matching: Handles misspellings (e.g., "Ferozepur" β "Firozpur")
- Context Handling: Differentiates between groundwater and general queries ("Who is Virat Kohli?")
- Multi-Key Rotation: Automatically switches API keys to bypass rate limits (429 errors).
- Client-Side Analytics: Performs local ranking/sorting for "Top 5" queries when backend is unavailable.
- Robust Fallback: Seamlessly switches between Backend and Direct-API modes.
- Gradient Area Charts: Extraction trends over time
- Stacked Bar Charts: Multi-metric rankings
- Donut Charts: Recharge composition breakdown
- Radar Charts: Risk factor analysis
- Timeline Charts: Historical comparisons
- Heatmaps: Geospatial analysis
- Rose Charts: Sectoral distribution
- Sparklines: KPI indicators
- AI selects optimal chart type based on data structure
- Automatic color coding (Red: Critical, Orange: High, Green: Safe)
- Interactive tooltips with detailed breakdowns
- Export to PNG/PDF for reports
- MapLibre GL JS Integration: Interactive groundwater maps
- Automated Map Analysis: Playwright-powered screenshot analysis
- Layer Control: Toggle recharge zones, extraction hotspots
- Custom Markers: Block-level status indicators
- Redis Caching: 60% faster repeat queries
- Connection Pooling: Efficient database connections
- WebSocket Streaming: Real-time response delivery
- Lazy Loading: On-demand component loading
- Index Optimization: Sub-second query execution
- SQL Injection Prevention: Parameterized queries
- Rate Limiting: DDoS protection
- Error Handling: Comprehensive logging
- Health Checks: System monitoring endpoints
- Docker Support: One-command deployment
{
"framework": "React 18.3.1 + TypeScript",
"build": "Vite 5.4",
"ui": "shadcn/ui + TailwindCSS + Framer Motion",
"ai": "Google Generative AI SDK (Multi-Key Support)",
"voice": "Web Speech API (Speech-to-Text)",
"charts": "ECharts + Recharts + Chart.js",
"maps": "MapLibre GL JS",
"state": "React Query (TanStack)",
"websocket": "Native WebSocket API",
"animation": "Framer Motion 12.23"
}{
"language": "Go 1.24",
"websocket": "Gorilla WebSocket",
"database": "lib/pq (PostgreSQL driver)",
"cache": "go-redis v8",
"logging": "Logrus",
"env": "godotenv"
}PostgreSQL: 16 + pgvector extension
Redis: 7-alpine with AOF persistence
Ollama: Qwen 2.5 Coder 7B (SQL generation)
Gemini: text-embedding-004 (768D embeddings)Containerization: Docker + Docker Compose
Orchestration: docker-compose.yml
Automation: Shell scripts (start.sh, stop.sh)
CI/CD: Vercel (frontend) + Self-hosted (backend)# System Requirements
- Docker & Docker Compose
- Node.js 18+ (for frontend)
- Go 1.24+ (optional, for local development)
- 8GB RAM minimum (16GB recommended)
- 20GB free disk space
# AI Models
- Ollama installed and running
- Qwen 2.5 Coder model pulled (4.7GB)git clone https://github.com/hxrshxz/ground-sense-bot.git
cd ground-sense-bot# Install Ollama (Linux/Mac)
curl -fsSL https://ollama.com/install.sh | sh
# Pull Qwen 2.5 Coder model
ollama pull qwen2.5-coder:7b
# Verify installation
ollama list | grep qwencd backend
./start.shThis automatically:
- β Starts PostgreSQL with pgvector (port 5433)
- β Starts Redis with persistence
- β Builds and starts Go backend (port 8080)
- β Runs database migrations
- β Initializes RAG system
# In a new terminal
cd ..
npm install
npm run devFrontend runs on: http://localhost:5173
# Check backend health
curl http://localhost:8080/api/v1/health
# Expected response
{
"status": "healthy",
"database": "connected",
"redis": "connected",
"ollama": "available"
}Try these in the chat interface:
1. "What is the status of Punjab?"
2. "Show me over-exploited blocks in Haryana"
3. "Compare Punjab and Rajasthan groundwater trends"
4. "Top 10 critical districts in India"
5. "Show rainfall impact on recharge in Gujarat"
src/
βββ components/
β βββ INGRESAssistant.tsx # Main chat interface (2500+ lines)
β βββ BlockAssessmentCard.tsx # Assessment visualizations
β βββ GroundwaterExtractionViz.tsx # Extraction analysis
β βββ MapLibreGroundwaterMap.tsx # Interactive maps
β βββ AIResponseRenderer.tsx # Dynamic response rendering
β βββ charts/ # 16+ chart components
β β βββ ExtractionTrendLine.tsx
β β βββ RechargeCompositionDonut.tsx
β β βββ SectorUsageStackedBar.tsx
β β βββ RiskRadar.tsx
β β βββ KPIStatGroup.tsx
β βββ ui/ # shadcn/ui components
βββ services/
β βββ geminiApi.ts # AI service integration
β βββ websocketService.ts # WebSocket client
βββ hooks/
β βββ useChatWebSocket.ts # WebSocket hook
β βββ useSpeechRecognition.ts # Voice input
βββ data/
βββ groundWaterData.ts # Mock data
βββ stateGroundwaterData.ts # State profiles
backend/internal/
βββ services/
β βββ chat_service.go # WebSocket handler
β βββ conversational_handler.go # Query orchestration
β βββ llm_service.go # Qwen integration
β βββ nlp_service.go # Intent classification
β βββ rag_service.go # Hybrid search
β βββ cache_service.go # Redis caching
β βββ ollama_client.go # Ollama API client
βββ controllers/
β βββ chat_controller.go # WebSocket endpoint
β βββ rag_controller.go # RAG endpoints
βββ repositories/
β βββ ingres_repository.go # Database queries
βββ models/
βββ chat_models.go # Data structures
-- States Table (37 states)
CREATE TABLE states (
state_uuid UUID PRIMARY KEY,
state_name TEXT NOT NULL
);
-- Districts Table (700+ districts)
CREATE TABLE districts (
district_uuid UUID PRIMARY KEY,
district_name TEXT NOT NULL,
state_uuid UUID REFERENCES states(state_uuid)
);
-- Blocks Table (5,796 blocks)
CREATE TABLE blocks (
block_uuid UUID PRIMARY KEY,
block_name TEXT NOT NULL,
district_uuid UUID REFERENCES districts(district_uuid),
state_uuid UUID REFERENCES states(state_uuid),
geometry JSONB,
embedding vector(768), -- For semantic search
search_vector tsvector -- For keyword search
);
-- Assessments Summary (27,000+ records)
CREATE TABLE assessments_summary (
assessment_id SERIAL PRIMARY KEY,
block_uuid UUID REFERENCES blocks(block_uuid),
year TEXT NOT NULL,
rainfall DOUBLE PRECISION,
total_recharge DOUBLE PRECISION,
total_discharge DOUBLE PRECISION,
total_extractable DOUBLE PRECISION,
total_extraction DOUBLE PRECISION,
category TEXT, -- safe, semi_critical, critical, over_exploited
stage DOUBLE PRECISION, -- Extraction percentage
availability DOUBLE PRECISION,
embedding vector(768), -- Gemini embeddings
text_representation TEXT, -- Human-readable summary
search_vector tsvector, -- Full-text search
raw JSONB, -- Original API response
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(block_uuid, year)
);
-- Breakdown Tables (for detailed analysis)
CREATE TABLE assessments_recharge_breakdown (...);
CREATE TABLE assessments_discharge_breakdown (...);
CREATE TABLE assessments_extraction_breakdown (...);-- Vector similarity search (IVFFlat for large datasets)
CREATE INDEX idx_assessments_embedding
ON assessments_summary USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
-- Full-text keyword search
CREATE INDEX idx_assessments_search_vector
ON assessments_summary USING GIN(search_vector);
-- Common query filters
CREATE INDEX idx_assessments_year ON assessments_summary(year);
CREATE INDEX idx_assessments_category ON assessments_summary(category);
CREATE INDEX idx_assessments_stage ON assessments_summary(stage);
CREATE INDEX idx_blocks_state ON blocks(state_uuid);GET /api/v1/health
Response:
{
"status": "healthy",
"timestamp": "2025-12-14T10:30:00Z",
"database": "connected",
"redis": "connected",
"ollama": "available"
}POST /api/v1/rag/search
Content-Type: application/json
{
"query": "over-exploited blocks in Punjab",
"limit": 10,
"use_keyword": true,
"use_semantic": true,
"min_score": 0.5,
"filter_state": "Punjab",
"filter_year": "2024-2025"
}
Response:
{
"results": [
{
"assessment_id": 12345,
"block_name": "Ludhiana",
"district_name": "Ludhiana",
"state_name": "Punjab",
"year": "2024-2025",
"category": "over_exploited",
"stage": 182.5,
"score": 0.95,
"search_type": "hybrid"
}
],
"total_results": 153,
"query": "over-exploited blocks in Punjab",
"search_types": ["keyword", "semantic"]
}GET /api/v1/rag/assessment/{block_uuid}?year=2024-2025
Response:
{
"block_name": "Ludhiana",
"year": "2024-2025",
"rainfall": 650.5,
"total_recharge": 120.3,
"total_extraction": 220.8,
"category": "over_exploited",
"stage": 183.5,
"recharge_breakdown": [...],
"extraction_breakdown": [...]
}const ws = new WebSocket("ws://localhost:8080/ws");
ws.onopen = () => {
console.log("Connected to GroundSense Bot");
};// Client β Server
{
"type": "user_message",
"content": "Show me Punjab status",
"session_id": "uuid-v4"
}
// Server β Client (streaming)
{
"type": "bot_message",
"content": "Analyzing Punjab groundwater data...",
"timestamp": "2025-12-14T10:30:00Z"
}
// Chart Data Response
{
"type": "chart_data",
"chart_type": "stacked-bar",
"data": {
"xAxis": ["Block1", "Block2", ...],
"series": [...]
},
"insights": "Punjab shows 79% over-exploitation rate..."
}Query: "What is the status of Punjab?"
Intent: SUMMARY
SQL Pattern: Single location + latest year (2024-2025)
Response: Aggregate statistics + category distribution
Visualization: Donut chart + KPI cards
Query: "Show me trend for Punjab over time"
Intent: TREND
SQL Pattern: Multi-year GROUP BY year
Response: Year-over-year changes
Visualization: Gradient area chart with trend lines
Query: "Compare Punjab and Haryana"
Intent: COMPARE
SQL Pattern: Multiple locations + GROUP BY state
Response: Side-by-side metrics
Visualization: Multi-series bar chart
Query: "Top 10 over-exploited blocks"
Intent: TOP_RANKING
SQL Pattern: ORDER BY stage DESC LIMIT 10
Response: Ranked list with metrics
Visualization: Horizontal stacked bar chart
Query: "Show me critical blocks in Rajasthan"
Intent: CATEGORY_FILTER
SQL Pattern: WHERE category = 'critical'
Response: Filtered results with breakdowns
Visualization: Map + table view
Query: "Which districts have highest extraction?"
Intent: METRIC_SPECIFIC
SQL Pattern: ORDER BY total_extraction DESC
Response: Sorted by specific metric
Visualization: Horizontal bar chart
Query: "How does rainfall affect recharge in Gujarat?"
Intent: RAINFALL_CORRELATION
SQL Pattern: JOIN with rainfall data
Response: Correlation analysis
Visualization: Scatter plot with regression line
Query: "Ferozepur groundwater status" (User misspelling)
Logic: Skeleton Match (frzpr == frzpr) -> Finds "Firozpur"
Response: Correct data for Firozpur
Query: "Top 5 blocks in Punjab"
Logic: Client-side Sort & Filter
Response: Instant ranking without backend SQL
// 1. Intent Classification
func ClassifyIntent(query string) QueryIntent {
// Pattern matching + keyword analysis
if containsComparison(query) {
return COMPARE
} else if containsRanking(query) {
return TOP_RANKING
}
// ... 17+ patterns
}
// 2. Entity Extraction
func ExtractEntities(query string) Entities {
return Entities{
States: extractStates(query), // "Punjab", "Haryana"
Districts: extractDistricts(query), // "Ludhiana", "Bathinda"
Years: extractYears(query), // "2024-2025"
Categories: extractCategories(query), // "over_exploited"
Metrics: extractMetrics(query), // "extraction", "recharge"
}
}
// 3. SQL Generation (via LLM)
func GenerateSQL(intent QueryIntent, entities Entities) string {
prompt := buildPrompt(intent, entities, schemaContext)
sql := ollamaClient.Generate(prompt) // Qwen 2.5 Coder
return validateAndSanitize(sql)
}User Query: "water stressed regions in India"
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββ
β Step 1: Dual Search Execution β
ββββββββββββββββββββββββββββββββββββββββββ€
β ββββββββββββββββ βββββββββββββββββ β
β β Keyword β β Semantic β β
β β Search β β Search β β
β β (BM25) β β (Cosine) β β
β ββββββββ¬ββββββββ βββββββββ¬ββββββββ β
β β β β
β βΌ βΌ β
β Full-Text Index Vector Index β
β (tsvector) (pgvector) β
ββββββββββ¬ββββββββββββββββββββ¬ββββββββββββ
β β
βΌ βΌ
10 Results 10 Results
β β
ββββββββββ¬βββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Step 2: Deduplication & Merging β
βββββββββββββββββββββββββββββββββββββββββββ€
β - Remove duplicate blocks β
β - Combine scores (weighted average) β
β - Keep top 30 candidates β
ββββββββββββββββββ¬βββββββββββββββββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Step 3: Gemini Reranking β
βββββββββββββββββββββββββββββββββββββββββββ€
β - Send query + 30 docs to Gemini β
β - Reranker API scores relevance β
β - Sort by reranker scores β
ββββββββββββββββββ¬βββββββββββββββββββββββββ
βΌ
Top 10 Final Results
# Data ingestion pipeline
def ingest_assessment(assessment_data):
# 1. Create text representation
text = f"""
Location: {block_name}, {district_name}, {state_name}
Year: {year}
Category: {category}
Stage of Extraction: {stage}%
Rainfall: {rainfall}mm
Total Recharge: {total_recharge} MCM
Total Extraction: {total_extraction} MCM
Net Availability: {availability} MCM
"""
# 2. Generate Gemini embedding (768D)
embedding = gemini.embed(text, task_type="retrieval_document")
# 3. Store in PostgreSQL
db.execute("""
INSERT INTO assessments_summary
(block_uuid, year, text_representation, embedding, ...)
VALUES ($1, $2, $3, $4, ...)
""", block_uuid, year, text, embedding)
# 4. Update search vector for keyword search
db.execute("""
UPDATE assessments_summary
SET search_vector = to_tsvector('english', $1)
WHERE assessment_id = $2
""", text, assessment_id)// Keyword Search (PostgreSQL Full-Text Search)
func (s *RAGService) keywordSearch(query string) []SearchResult {
sql := `
SELECT a.*, ts_rank(search_vector, query) as score
FROM assessments_summary a,
plainto_tsquery('english', $1) query
WHERE search_vector @@ query
ORDER BY score DESC
LIMIT 10
`
return db.Query(sql, query)
}
// Semantic Search (pgvector Cosine Similarity)
func (s *RAGService) semanticSearch(query string) []SearchResult {
// Generate query embedding
queryEmbedding := gemini.Embed(query, "retrieval_query")
sql := `
SELECT a.*,
1 - (embedding <=> $1::vector) as score
FROM assessments_summary a
ORDER BY embedding <=> $1::vector
LIMIT 10
`
return db.Query(sql, queryEmbedding)
}
// Gemini Reranking
func (s *RAGService) rerank(query string, docs []SearchResult) []SearchResult {
req := GeminiRerankerRequest{
Model: "gemini-pro",
Query: query,
Documents: extractTexts(docs),
TopN: 10,
}
rankings := gemini.Rerank(req)
return reorderByRankings(docs, rankings)
}// Dynamic chart selection based on data structure
interface ChartConfig {
type: 'gradient-area' | 'stacked-bar' | 'donut' | 'radar' | 'heatmap' | ...;
data: any[];
options: {
colors?: string[];
title?: string;
legend?: boolean;
tooltip?: TooltipConfig;
};
}
// AI-generated chart configuration
const chartConfig = llm.generateVisualization(queryResults, intent);
// Render appropriate component
<DynamicChart config={chartConfig} />| Chart Type | Use Case | Example Query |
|---|---|---|
| Gradient Area | Time series trends | "Punjab extraction over time" |
| Stacked Bar | Multi-metric rankings | "Top 10 over-exploited blocks" |
| Donut | Category distribution | "Breakdown of block categories" |
| Radar | Multi-dimensional analysis | "Risk factors for Punjab" |
| Heatmap | Geospatial patterns | "Extraction intensity map" |
| Rose | Sectoral breakdown | "Water usage by sector" |
| Sparkline | Quick KPI indicators | "Stage trend mini-chart" |
| Timeline | Historical comparison | "Compare 2021 vs 2024" |
const CATEGORY_COLORS = {
over_exploited: "#ef4444", // Red
critical: "#f97316", // Orange
semi_critical: "#eab308", // Yellow
safe: "#22c55e", // Green
salinity: "#8b5cf6", // Purple
};
const METRIC_COLORS = {
extraction: "#dc2626", // Red (concern)
recharge: "#10b981", // Green (positive)
rainfall: "#3b82f6", // Blue (neutral)
deficit: "#f59e0b", // Orange (warning)
availability: "#06b6d4", // Cyan (resource)
};# 1. Backend + Database
cd backend
docker-compose up -d
# 2. Frontend (Production Build)
cd ..
npm run build
npm run preview# Server
SERVER_HOST=0.0.0.0
SERVER_PORT=8080
# Database
DB_HOST=postgres
DB_PORT=5432
DB_USER=admin
DB_PASSWORD=admin
DB_NAME=ground_sense_bot
DB_SSLMODE=disable
# Redis
REDIS_HOST=redis
REDIS_PORT=6379
# AI Services
OLLAMA_ENABLED=true
OLLAMA_URL=http://localhost:11434
OLLAMA_MODEL=qwen2.5-coder:7b
GEMINI_API_KEY=your_gemini_api_key_here
# Performance
MAX_DB_CONNECTIONS=25
REDIS_CACHE_TTL=3600VITE_API_URL=http://localhost:8080
VITE_WS_URL=ws://localhost:8080/ws
# Multi-Key Rotation (Recommended: Use keys from different Google Projects)
VITE_GEMINI_API_KEY=key_from_project_A
VITE_GEMINI_API_KEY_2=key_from_project_B
VITE_GEMINI_API_KEY_3=key_from_project_C- Set strong database passwords
- Enable SSL/TLS for production
- Configure CORS properly
- Set up reverse proxy (Nginx)
- Enable rate limiting
- Configure log rotation
- Set up monitoring (Prometheus)
- Configure backups (PostgreSQL dumps)
- Enable Redis persistence (AOF)
- Set up health check endpoints
ground-sense-bot/
βββ backend/ # Go backend
β βββ cmd/
β β βββ server/
β β βββ main.go # Entry point
β βββ internal/
β β βββ chat/ # WebSocket handlers
β β βββ config/ # Configuration
β β βββ controllers/ # HTTP/WS controllers
β β βββ database/ # DB connection & migrations
β β βββ models/ # Data models
β β βββ repositories/ # Data access layer
β β βββ routes/ # API routes
β β βββ services/ # Business logic
β β βββ chat_service.go
β β βββ llm_service.go
β β βββ nlp_service.go
β β βββ rag_service.go
β β βββ cache_service.go
β βββ migrations/ # SQL migrations
β βββ scripts/ # Utility scripts
β βββ docker-compose.yml # Container orchestration
β βββ Dockerfile # Backend image
β βββ go.mod # Go dependencies
β βββ start.sh # Quick start script
βββ src/ # React frontend
β βββ components/
β β βββ INGRESAssistant.tsx # Main chat UI
β β βββ charts/ # Visualization components
β β βββ ai-components/ # AI response renderers
β β βββ cards/ # Data cards
β β βββ ui/ # shadcn/ui components
β βββ services/
β β βββ geminiApi.ts # Gemini integration
β β βββ websocketService.ts # WebSocket client
β βββ hooks/ # React hooks
β βββ data/ # Static data & profiles
β βββ lib/ # Utilities
β βββ pages/ # Route pages
βββ Data/ # Data ingestion
β βββ data/ # JSON assessment files
β β βββ 2021-2022/
β β βββ 2023-2024/
β β βββ 2024-2025/
β βββ load_from_markdown.py # Data loader
β βββ requirements-rag.txt # Python dependencies
βββ public/ # Static assets
βββ scripts/ # Automation scripts
βββ package.json # Frontend dependencies
βββ vite.config.ts # Vite configuration
βββ tailwind.config.ts # TailwindCSS config
βββ tsconfig.json # TypeScript config
βββ docker-compose.yml # Full stack compose
βββ start.sh # One-command start
βββ stop.sh # Graceful shutdown
βββ README.md # This file
cd backend
go test ./... -v# Run test query suite
./backend/test_queries.sh
# Example queries
1. "What is the status of Punjab?"
2. "Show me over-exploited blocks in Haryana"
3. "Compare Punjab and Rajasthan trends"
4. "Top 10 critical districts"
5. "Rainfall impact on Gujarat recharge"# Using Apache Bench
ab -n 1000 -c 10 http://localhost:8080/api/v1/health
# Expected: <100ms average response time# 1. Install dependencies
cd backend && go mod download
cd .. && npm install
# 2. Start services individually
docker-compose up postgres redis # Just DB & cache
cd backend && go run cmd/server/main.go
npm run dev # In another terminal
# 3. Watch logs
docker logs -f ground-sense-postgres
docker logs -f ground-sense-redis- Add pattern to NLP service:
// backend/internal/services/nlp_service.go
const EXAMPLE_NEW_PATTERN = `
EXAMPLE X: NEW_INTENT
Query: "example query"
Intent: NEW_INTENT
SQL: SELECT ...
`- Add handler:
// backend/internal/services/conversational_handler.go
func (ch *ConversationalHandler) handleNewIntent(ctx context.Context, ...) {
// Implementation
}- Update visualization logic:
// backend/internal/services/llm_service.go
// Add new chart type mapping# Check Ollama is running
ollama list
# Check Docker services
docker ps
# View logs
docker logs ground-sense-app# Verify PostgreSQL is running
docker exec ground-sense-postgres pg_isready
# Check connection
psql -h localhost -p 5433 -U admin -d ground_sense_bot# Verify backend is running
curl http://localhost:8080/api/v1/health
# Check CORS configuration
# Ensure VITE_WS_URL is correct in .env# Check Redis cache
docker exec -it ground-sense-redis redis-cli
> KEYS *
> GET "query:your_query_hash"
# Analyze slow queries
docker exec ground-sense-postgres psql -U admin -d ground_sense_bot -c "SELECT * FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10;"We welcome contributions! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Go: Follow
golangci-lintrecommendations - TypeScript: Use ESLint + Prettier
- SQL: Use parameterized queries, never string concatenation
- Comments: Document complex logic and public functions
- Add unit tests for new services
- Test query patterns with real data
- Verify UI components render correctly
- Check WebSocket connections under load
- [Your Name] - Team Leader & Full Stack Developer
- [Team Member 2] - Backend Developer (Go + PostgreSQL)
- [Team Member 3] - Frontend Developer (React + TypeScript)
- [Team Member 4] - AI/ML Engineer (RAG + LLM Integration)
- [Team Member 5] - DevOps Engineer (Docker + Deployment)
- [Team Member 6] - UI/UX Designer (Visualization & Design)
- [Mentor Name] - Technical Mentor
- [Industry Expert] - Domain Expert (Groundwater Management)
This project is licensed under the MIT License - see the LICENSE file for details.
- Ministry of Jal Shakti - For the problem statement
- Central Ground Water Board (CGWB) - For INGRES data
- IIT Hyderabad - For INGRES system development
- Smart India Hackathon 2025 - For the platform
- Google - For Gemini API access
- Ollama Team - For local LLM infrastructure
- Open Source Community - For amazing tools (PostgreSQL, Redis, React, Go)
- GitHub: hxrshxz/ground-sense-bot
- Email: team.mercury.sih@example.com
- Issues: GitHub Issues
- Discussions: GitHub Discussions
If you find this project helpful, please consider giving it a β on GitHub!
- Lines of Code: 50,000+
- Backend: 15,000+ lines (Go)
- Frontend: 35,000+ lines (TypeScript/React)
- Database Records: 27,000+ assessments
- Query Patterns: 17+ supported
- Chart Types: 16+ visualizations
- Development Time: 72 hours (Hackathon)
- Team Size: 6 members
- Multilingual support (Hindi, Tamil, Telugu, etc.)
- Mobile app (React Native)
- Advanced analytics dashboard
- Report generation (PDF/Excel)
- Predictive modeling (groundwater forecasting)
- Integration with IoT sensors (real-time data)
- Public API for third-party access
- WhatsApp chatbot integration
- Blockchain for data integrity
- AI-powered policy recommendations
- Satellite imagery integration
- Farmer portal for block-level insights
Built with β€οΈ by Team Mercury
Making India's groundwater data accessible to all
π Smart India Hackathon 2025 Winner π