Case study · № 072025Gov-tech · Solo

MGNREGA Portal

A full-stack government-data portal that ingests district-level MGNREGA statistics from India's data.gov.in Open API, caches them in Postgres, and surfaces them through interactive charts, side-by-side comparisons, and a bilingual AI assistant — built to make rural-employment data readable even for low-literacy users.

RoleSolo
Sourcedata.gov.in
Metrics~29 / district
AIGemini Flash
mgnrega · district dashboard
ClientCoreSource & dataReactRecharts · EN/HIGemini assistantexplains · navigatesExpress API/data · /sync · /chatbotScraperpaginated + backoffnode-crondaily / weeklyPostgreSQLPrisma cache · ~29 metricsdata.gov.inOpen APIschedulepull
Fig. 1 · Gov-data portal — cron-scheduled ingest from data.gov.in cached in Postgres, Recharts dashboards, and a bilingual Gemini assistant.
01

Context

MGNREGA — India’s rural employment guarantee scheme — publishes a lot of performance data: employment, wages, works completed, social-inclusion metrics by district. It’s technically public and practically unusable: scattered, rate-limited, and shaped for machines, not citizens.

The portal aggregates and caches that data locally, then presents district-level insight with visualizations, comparisons, and plain-language explanations — so a non-technical rural user or a local official can actually read it.

trends · employment
02

Getting the data in

The government Open API is rate-limited and paginated, so I couldn’t hit it live per request. A batched scraper service (batch size 100, retry with backoff) pulls the district resource and persists it to Postgres via Prisma — a local caching layer that both dodges the rate limit and keeps the site up when the source API isn’t.

node-cron jobs keep it fresh: a daily incremental sync and a weekly full historical pass, with every run recorded in a SyncLog table so you can see exactly what landed and when.

sync · data.gov.in
03

Making it readable

The front end is a React + Recharts dashboard: historical trend charts, a comparison page for up to four districts side by side with CSV/Excel export, and rankings by a selectable metric. Everything is bilingual (English / Hindi) with short “how to read this chart” notes for low-literacy users.

A Gemini 2.5-flashassistant sits on top — it explains MGNREGA, analyses a district’s numbers in plain language, and detects navigation intent so “show me Rajkot” actually routes there. Geolocation auto-detects the visitor’s district to skip the search entirely.

compare · four districts
04

Decisions & tradeoffs

  • Cache locally, don’t proxy. Mirroring the data into Postgres was the only way to get interactive charts on a rate-limited source without the whole UI stalling.
  • Gemini for language, not numbers. The assistant explains and navigates; the figures it quotes come from the cached dataset, not from the model.
  • Bilingual from the start. The audience is rural and often Hindi-first — English-only would have defeated the point of making the data accessible.
05

What I would change

The sync is state-scoped and defaults narrow; I’d generalise the ingestion to cover all states out of the box and add a proper freshness indicator per district. And the assistant’s navigation intent is rule-plus-model today — I’d ground it against the actual district list so it can never route somewhere that isn’t in the cache.

Built with
React 19ViteRechartsNodeExpressPostgreSQLPrismaGemini 2.5 Flashnode-cronTailwind
← PreviousExpencifyNext →Kidnex
You found the trick.
Thanks for
looking closely.
↑ ↑ ↓ ↓ ← → ← → B A · konami