Case study / Civic data + AI

MONÉLU

A public interface to French parliamentary activity, built from static archives and designed to show where every answer comes from.

646Deputies tracked
5,404Votes analyzed
797K+Vote positions
3,741Indexed chunks
MonÉlu AI chat interface showing suggested civic questions
AI assistant / Guided questions and evidence-backed answers
MonÉlu deputy profile with parliamentary metrics
Deputy profile / Activity, votes, themes, and traceable records

01 / Constraint

The API did not exist.

The Assemblée Nationale publishes useful open data as static ZIP archives rather than a stable REST API. MonÉlu turns those inconsistent exports into a repeatable product: fetch, parse, validate, upsert, model, serve, and refresh without losing provenance.

02 / Data engine

From archive to trusted answer.

The pipeline separates acquisition, transformation, serving, and interface concerns. Retries and idempotent upserts protect ingestion; dbt tests the analytical layer; FastAPI remains stateless; scheduled GitHub Actions keep production current.

AssembléeStatic ZIP exports
IngestionPython parsing + retries
PostgreSQLSupabase + pgvector
dbt + APITested marts + FastAPI
ProductVercel web interface

03 / AI engine

Route first. Generate second.

MonÉlu does not ask a language model to improvise over every question. Deterministic questions route to SQL. Semantic questions retrieve relevant evidence through pgvector before a French-language response is generated.

SQL path

Counts, rankings, known entities, and structured comparisons use PostgreSQL. The answer is reproducible and its source is explicit.

RAG path

Open-ended questions retrieve indexed evidence, expose the supporting passages when available, and identify RAG as the source.

04 / Engineering view

Governance is part of the interface.

Confidence does not come from polished prose. It comes from observable retrieval, tested models, explicit routing, and a product that distinguishes database facts from generated synthesis. A keyword evaluation score above 0.80 provides a measurable baseline for retrieval quality while the architecture leaves room for better evaluations over time.

05 / Ownership

Built across the whole path.

I designed and shipped the ingestion, dbt models, FastAPI layer, SQL/RAG routing, evaluation baseline, and web product. The goal was not a demo chatbot; it was a public system whose data path can be inspected.

My role

Product architecture, data engineering, AI retrieval, API design, deployment, and interface delivery.

Trade-off

Scheduled batch fits the Assembly's ZIP publishing model. Supabase and Railway keep operations lean while preserving clear service boundaries.

Outcome

A live bilingual product with tested marts, explicit answer routing, daily refreshes, and measurable retrieval quality.

Public data becomes useful when its path stays visible.