The short version
Kleva works in collections, where the questions are more established than in many product analytics projects: how many calls connected, how many people were reached, how many promises were made, and what did each outcome cost? That gave us a useful starting point. We could model the KPI framework as a shared contract in dbt MetricFlow, then build an operational view for the questions Kleva's team actually needs to answer each day.
The result is a data platform with two complementary pieces: reusable metric definitions in the warehouse project and a custom operations dashboard for day-to-day monitoring. The dashboard reads curated BigQuery marts directly, rather than querying MetricFlow. Keeping that distinction visible matters.
A more defined measurement problem
Kleva's data starts in its operational Postgres database. Calls, campaigns, contacts, debts, and agents each describe a part of the collections process. Looking at any one table can produce a number; producing a defensible contact rate or promise amount requires agreeing on the population, time period, identity, and denominator first.
Collections has a relatively stable vocabulary of KPIs compared with a product team that is still inventing its funnel. But stable vocabulary does not mean automatic agreement. Does “contact” mean an answered call or a unique person? Is a promise counted per call or per debt? Can amounts in different currencies be combined? Those decisions belong in the model, not in a copied dashboard query.
What we built
We set up scheduled ingestion from Postgres with Meltano, landed the data in BigQuery, and used dbt to move from source-shaped staging tables to enriched facts and daily marts. GitHub Actions coordinates the extraction and transformation workflows.
On top of those marts, we defined semantic models and metrics in dbt MetricFlow. Calls, contact rates, reach, promises, costs, and revenue have named definitions and documented grains. For example, a daily rate is not silently promoted into a unique-person monthly rate. The semantic layer exposes eligible-day counts alongside weighted rates so a number can be read with its coverage, not just its percentage.
Then we built a custom operations dashboard. It brings together the views that matter to Kleva's operating cadence: a summary, telephony and contactability, the collections funnel, activity by company, costs, and alerts. Filters and visualizations reflect the way this team reviews performance. The business has a well-understood operating cycle, so a purpose-built dashboard made more sense than forcing every question through an open-ended self-service interface.
The dashboard queries the curated BigQuery tables and views with SQL. It does not execute those queries through MetricFlow. The semantic definitions provide an explicit, reusable contract in the dbt project; dashboard-specific SQL still needs to be checked against that contract for matching filters, units, and denominators.
The hard part was defining what a number can mean
A reliable KPI model includes the cases where a number should not appear. Some contact rates depend on a confirmed base and complete call coverage. Promise amounts can be missing even when a promise event exists. Call costs are recorded in USD, while promised amounts can be in local currency. Summing the latter across currencies would produce a neat-looking but meaningless total.
We kept those boundaries visible in the modeling and documentation rather than filling gaps with a convenient zero. Other indicators, including actual recovery and payment-based ROI, need external payment data before they can be presented as verified outcomes. This is part of making metrics useful: knowing which ones are ready to use and which ones still need a source.
Why this approach fits Kleva
With a defined set of industry measures, the valuable work is not inventing a new KPI every week. It is making existing measures consistent, traceable, and easy to use in context. MetricFlow gives the team a place to maintain those definitions. The tailored dashboard puts the right operational questions in front of the people making decisions.
That combination leaves room to extend the model as new data becomes available, without turning daily reporting into a collection of disconnected calculations.
