← Work

Case study · 2026

Nordic Sustainability Index

A sustainability intelligence platform that transforms unstructured Nordic food company reports into structured, comparable ESG data — backed by evidence and source references.

Data product · Next.js 15 · Supabase · TypeScript · PostgreSQL

Nordic Sustainability Index — KPI comparison table showing climate, circularity and people indicators across Nordic food companies

The problem

Sustainability reporting is built for compliance, not comparison.

Companies like Carlsberg, Danish Crown and Lantmännen publish annual sustainability reports running hundreds of pages. They use different frameworks — GRI, ESRS, SASB — different baseline years, and different definitions of the same metric. Comparing disclosure quality across Nordic food companies requires months of manual work. No centralised, evidence-backed layer exists.

This matters now. The EU's CSRD and ESRS directives are rolling out mandatory structured disclosure requirements from 2024 onwards, with supply chain obligations following. Retailers, investors and procurement teams need structured data — not PDFs.

What I built

From unstructured PDFs to a structured intelligence layer.

01

Data extraction

Read and manually extracted indicators from 40+ company reports — annual reports, sustainability reports, and integrated disclosures. Every extracted value is linked to a page reference and the original company quote, creating a fully auditable chain from raw PDF to structured data.

02

Relational schema

Designed a 4-table PostgreSQL schema in Supabase: companies → sustainability reports → KPI values → KPI definitions. Normalised so adding a new KPI requires one row in kpi_definitions — not a schema migration. Adding a new company requires inserting its data without touching the structure.

03

KPI comparison table

A searchable comparison table showing 8 indicators across Climate, Circularity, and People for all tracked companies.

Technical approach

Architecture decisions that matter.

Data fetching runs entirely on the server via Next.js 15 App Router. The Supabase service role key is scoped to API routes and never reaches the client — a deliberate security boundary, not a default.

The relational schema was designed for extensibility from the start. A normalised 4-table structure means adding a new KPI requires one row in a definitions table, not a schema migration. Adding a new company requires only inserting its data — the structure stays unchanged.

Search is decoupled from the render cycle. Queries are debounced so the database is only hit when input stabilises, and the company record and its KPI values are fetched concurrently rather than in sequence — keeping the interaction responsive without overloading the backend.

Next.js 15 App Router · React 19 · TypeScript · Supabase PostgreSQL · Custom CSS

Outcomes

A production-ready data product.

40+

Nordic food companies mapped

350+

Sustainability indicators extracted

8

KPI categories across climate, circularity and people

Every indicator is linked to a report title, page number, and original company quote — making the data auditable rather than opaque. The index reveals patterns invisible from individual reports: which companies set near-term Scope 3 targets versus net-zero-only commitments, which disclose LTIFR versus which omit safety data entirely.

This is a disclosure index, not a performance index — transparency is what is measured, not actual environmental impact. That distinction is explicit in the framework.