>>

From raw data
to decisions you can defend.

Client work stays confidential, so we built the evidence instead: realistic data scenarios for four invented Australian businesses, each modelled the whole way, from raw data to a boardroom-ready report. Every figure reconciles to a live model, nothing is mocked up, and the person who built every page is the person you would work with.

Member Operations · command centrelive · interactive
// case study 01 · membership operations

A professional association runs its membership lifecycle.

Twenty-five thousand members, four tiers, a support desk and monthly renewals. The board's question: where are we losing members, and what is it costing us? The reports answer it: retention gaps by channel and cohort, a service-quality dip traceable to one agent's quarter, and a complaints cluster on the Central Coast running at 1.8 times the state rate.

Run a membership organisation? This is your retention, renewals and service desk on one screen.

// the modelling underneath

Members change tier and status over time and the history has to survive (SCD2, for the practitioners). A monthly snapshot sits alongside individual renewal transactions and the two can never disagree. A lapsed member is never counted twice.

Power BISCD2 membersSnapshot + transactionalActive-as-of

Answer deck

Dark · 7 pages · every figure reconciled to the live measure
PDF

Command centre

Dark · 6 pages to explore · cohort heatmap · sankey · Azure map
PDF
// case study 02 · financial reporting

A mid-market services group closes its books.

Three entities and one monthly management pack: actuals against budget against a rolling forecast. The CFO's question: why is support over budget, and can the forecast be trusted? The answer is the interesting part: the overrun is rate, not volume. Cost per head climbed while headcount barely moved. And because a mid-2024 restructure split Operations in two, the same month tells a different story under the old and new structures. The model tells both, honestly.

Close the books each month? This is variance reporting that would survive an audit committee.

// the modelling underneath

A P&L that rolls up through five levels (a parent-child hierarchy). The restructure is kept as slowly changing history (SCD2), so current and as-was views both reconcile. Forecast versions are vintaged so nothing double-counts.

Power BIParent-child P&LSCD2 reorgForecast vintage

Answer deck

Light · 7 pages · every headline drawn as the comparison it names
PDF

Variance workbench

Light · 3 pages to explore · drillable P&L matrix · waterfall · decomposition tree
PDF
// case study 03 · product analytics

A B2B SaaS product measures how accounts activate, retain and churn.

Millions of product events, a signup funnel, an A/B experiment, and accounts that upgrade and downgrade over time. The product question: where do new accounts stall, and which acquisition dollars are wasted? The reports find a cliff at the invite step of onboarding, show the experiment that lifts it by 15 percentage points, and put paid-ads accounts at roughly half the retention of referrals.

Run a software product? This is activation, retention and experiment readout in one instrument.

// the modelling underneath

An event fact of several million rows, each carrying a JSON payload. Plan tier is slowly changing history (SCD2 again), so upgrades and downgrades never rewrite the past. Monthly signup cohorts, and a controlled experiment measured without double-counting.

Power BIEvent fact · JSONSCD2 plan tierA/B experimentCohort retention

Answer deck

Dark · 7 pages · every figure reconciled to the live measure
PDF

Product analytics

Dark · 6 pages to explore · funnel · A/B variant heatmap · plan-tier churn sankey · decomposition tree
PDF
// case study 04 · delivery operations

An online retailer moves every order from click to doorstep.

Half a million orders across three distribution centres, four carriers and four delivery zones, plus the inventory behind them. The operations question: where do orders slow down, and is it us or the carrier? The reports isolate a Sydney pick-to-pack blowout that started in mid-May, show that the carrier and warehouse pairing matters more than either alone, and price the delivery-zone gradient at four to one.

Move physical orders? This is your order lifecycle, carrier performance and inventory cover in one view.

// the modelling underneath

The order lifecycle is one row per order, each milestone timestamped as it happens (an accumulating snapshot, where stages an order has not reached stay blank rather than a fabricated zero). A weekly inventory snapshot at a different grain sits beside it, and two order-grain facts each answer their own questions.

Power BIAccumulating snapshotTwo order-grain factsWeekly inventoryCarrier × zone

Answer deck

Light · 7 pages · every figure reconciled to the live measure
PDF

Operations instrument

Light · 6 pages to explore · funnel · carrier × warehouse SLA matrix · Azure delivery map · drill-through
PDF
// all four, both stacks · Every scenario ships the full Power BI treatment: a semantic model, an answer deck and an Explorer dashboard. SaaS Product and Fulfilment Operations also ship a Metabase build, so the portfolio shows range across both stacks. Every model, finding and dashboard lives in the repo under scenarios/.
// how it's built

Business intelligence, end to end.

Every page traces back through one pipeline: synthetic data engineered from scratch, modelled with intent, then reported. No black boxes, no sample datasets.

Every layer is code, not clicks: the schema, the SQL views, the semantic model, even the report pages themselves. One command rebuilds the lot from a single seed, and anyone who clones the repo gets the same 10.8 million rows, byte for byte.

build.log
$uv run python -m scenarios.*.generator --seed 20260101
[ ✓ ]generate · 36 tables · 10,784,652 rows
[ ✓ ]load · postgres · 8 schemas · 28 marts views
[ ✓ ]model · tmdl · 143 measures · 3 scd2 dimensions
[ ✓ ]report · 8 reports · 49 pages · 4 dashboards
$uv run pytest
[ ✓ ]975 passed · byte-identical across runs
01python

Generate

A Python generator invents ~10.8M rows of realistic business history, with the insights designed in, so the reports have something real to find. One seed, and every run rebuilds the data byte for byte.

> 36 tables · 10,784,652 rows

02postgres · supabase

Load

Everything lands in Postgres on Supabase, one schema per business, with proper keys and indexes. Hand-written SQL views then shape the raw tables into reporting-ready marts.

> 8 schemas · 28 hand-written views

03tmdl

Model

Where the value lives: a semantic model with real measure definitions. SCD2 history, parent-child P&L rollups, snapshot and transactional grain side by side, forecast vintages that behave.

> 143 DAX measures · 3 SCD2 dimensions

04power bi

Report

Answer decks that state a claim and draw it, and Explorer dashboards for the follow-up questions. Every number on the page comes from the live measure, never a mock-up.

> 8 reports · 49 pages · 4 dashboards

Code, not clicks

The schema, the marts views, the semantic model and the report definitions are all version-controlled text. If it can't be diffed, reviewed and rebuilt, it doesn't ship.

Determinism is the floor

One seed drives every random draw. The test suite generates the data twice and fails if a single byte differs, and CI does the same on every push.

Insights by design

The data isn't random noise. All 22 findings are engineered in, each with a documented drill path and a test that proves it's really there.

Reconciled before shipped

A page that looks right but shows a wrong figure is worse than no page. Checking every number against the live model caught real defects before launch, including a rate that read 100% on empty data.

// ai, with discipline

Built with AI in the loop.

This portfolio was engineered with AI agents in the loop: report layouts judged from rendered output, every change gated by 975 automated tests, every figure reconciled against the live model before it shipped. That is our wider view of AI too. It multiplies what a small team can build, and it earns trust only when something rigorous is checking the work. We bring both halves to client engagements.

More on our AI work
// proof, not promises · for the technical reader

The modelling, shown.

This section is for the technical reader in the room: the data lead, the analyst who inherits the handover, the hiring manager checking depth. “Reconciles to a live model” is easy to claim, so here are real fragments from the shipped models, and the script output that holds every page to them. If you don't read TMDL or DAX, this is simply what your team inherits: definitions in writing, and numbers that are checked.

dim_member_as_was.tmdl
column valid_from
dataType: dateTime
sourceColumn: valid_from
formatString: "yyyy-mm-dd"
 
column valid_to
dataType: dateTime
sourceColumn: valid_to
formatString: "yyyy-mm-dd"
 
column is_current
dataType: boolean
sourceColumn: is_current
The member dimension keeps every version of every member: a tier change closes one row and opens the next, so any month can be replayed exactly as it was. The same pattern carries the finance restructure and the SaaS plan tiers.
// working together

How an engagement runs.

No discovery theatre, no landgrab. Three steps, each with something concrete at the end of it.

[01]30 min · no charge

A data review

You bring the questions your current reporting can't answer. We tell you honestly whether the problem is the data, the model or the presentation, and what fixing it involves.

[02]fixed scope

A scoped first build

One agreed slice of your data, modelled and reported to the standard on this page. Privately, on your infrastructure, with the measure definitions written down and agreed.

[03]yours to keep

A handover that sticks

Documentation, training and the source. Your team runs it without us, and knows why every number is what it is.

>>

Want reporting built to this standard?

The same discipline behind this portfolio, applied to your data. Thirty minutes with the person who built every page above.