<- Back to portfolio

Case study

Internal Data Request and Catalogue Platform

127 requests tracked end to end over three months, with the catalogue and pipeline health in the same place.

Role
Data platform, employer work at Rey.id
Stack
FastAPI, Postgres, Jinja, Airflow, dbt

Problem and constraints

Teams outside the data function had no way to file or follow a request: it arrived by chat, the catalogue and lineage lived with the data team, and nobody outside data could see whether the previous night's pipelines ran.

Approach

A server-rendered platform that holds no warehouse credentials. Airflow pushes the dbt manifest, run results, catalogue and freshness into it, and the asset graph is reconciled as a snapshot with soft deletes, because a rename and a delete look identical in a manifest. Requests move from intake to triage to a board, with requester email written to an outbox in the same transaction as the status change. Roles are declared per route and enforced by tests, personal-data assets are filtered in SQL, and only metadata is ever displayed.

Measured result

127 requests tracked end to end between July and October 2026, 101 of them delivered, with 854 assets and 1,670 lineage edges kept current and 671 DAG runs monitored every day.

Label Value Note
requests tracked end to end 127 July to October 2026, each one auditable from intake to delivery
assets in the catalogue, with 1,670 lineage edges 854 refreshed from the nightly dbt manifest, which lands at 03:30 WIB
DAG runs monitored in a 24-hour window 671 Airflow pushes run results, so a failed night is visible the same morning
automated tests across the platform 1,053 role checks, personal-data filters and access invariants are pinned by tests
requests in a single month 49 September 2026, 37 of them filed directly in the platform rather than imported from the queue it replaced

Stack

FastAPI Postgres Jinja Airflow dbt