Vigía
Interactive map of Peruvian open-government data: budget, services, payroll and public-works risk
🏆 2nd Place — Hackathon DSC PUCP · Vibecoding 2026 (organized by @dsc.pucp and @gdgopen).
The Peruvian State manages more than S/ 220 billion a year. Vigía integrates four open-data sources from the State into a single interactive map and answers a question that today has no accessible answer: how is the State performing in your region?
Four layers, one platform
- 💰 Budget — MEF Consulta Amigable: which regions and ministries fail to execute their allocation?
- 🏥 Services — MINSA (RENIPRESS) + MINEDU: which districts lack clinics, schools and hospitals?
- 👥 Payroll — SERVIR / open data: where is public employment concentrated, and which regimes dominate?
- 🏗️ Public works — OCDS + INFOBRAS + OECE: which projects show risk signals? (explainable 0–100 score)
The user isn’t only the auditor hunting for fraud — it’s the citizen, the NGO, the journalist and the regional planner who need to understand how the State performs as a whole.
Architecture
A medallion lakehouse + analytical Postgres, layered: ingestion decoupled from serving, business logic centralized in the database, a thin API, and a clear server/client boundary in the front end.
Bronze (raw) → Silver (normalized) → Gold (crossed + aggregated) → API → 4-layer map
- Ingestion (Bronze): Python · requests · BeautifulSoup · pandas · psycopg2 — one adapter per state source
- Database: PostgreSQL (Supabase) · pg_trgm · materialized views · a SQL scoring function
- API: Next.js 14 Route Handlers · pg (direct SQL, no ORM)
- Frontend: Next.js App Router · React 18 · MapLibre GL · Tailwind CSS
- Deploy: Vercel + Supabase
Learnings
- Keeping the red-flag scoring in SQL (a compute_red_flag_scores() function plus materialized Gold views) instead of app code lets the Next.js API stay a thin pass-through and makes the scoring auditable in one place
- A natural-language "Agente Vigía" chat can answer questions over real data with zero LLM cost — intent matching against pre-aggregated Gold views is deterministic, free, and fast enough to feel conversational
- A Bronze → Silver → Gold medallion layout with one Python adapter per state data source decouples messy scraping/ingestion from a clean analytical serving layer
- Querying Postgres directly with pg (no ORM) from Next.js route handlers over the Supabase pooler keeps the API trivial when the heavy lifting already lives in materialized views