Scaffolding
0 0 About
Scaffolding · Lesson 2 of 7

Specs before
files

Before anyone pours concrete, the plans are drawn. Here the plans are two files. Every table and every tile was decided in them before a single project file existed.
Have the report open. The lessons point at real pages and tiles. The .pbix opens in Power BI Desktop; the PDF works on any device, but things like View as and the i buttons need Desktop.
00

Two files that decide everything

The kit has two s, both in . The brief calls each one a : the project is built from them, and checked against them.

model_spec.json32 tables, 53 relationships, 4 roles, format strings and sort orders.
pages_spec.json8 pages and 55 visuals: title, visual type, fields, grid position, basis measure, data tier.
Open model_spec.json on GitHub Open pages_spec.json on GitHub

Predict first: Why write the specs before any project file?

01

A table, written down first

Here is the smallest table in the model spec, slightly shortened. It's a with three columns.

{ "name": "DimCommodityGroup", "kind": "dimension", "rows": 3, "grain": "one row per commodity group", "columns": [ { "name": "GroupKey", "dataType": "int64", "isHidden": true }, { "name": "GroupCode", "dataType": "string" }, { "name": "CommodityGroup", "dataType": "string" } ] }

Two lines matter more than they look. The says what one row stands for. rows: 3 says how many there should be: base metals, battery metals and magnet metals.

Predict first: After a refresh in Desktop, the table has 4 rows. What should happen?

02

Relationships and roles

Each is one line in the spec. This one joins every commodity to its group:

{ "from": "DimCommodity.GroupKey", "to": "DimCommodityGroup.GroupKey", "cardinality": "many-to-one", "crossFilter": "single" }

That's : many commodities, one group. All 53 relationships are written the same way. How they work is covered in The model layer.

The spec also defines four s for . Each filters one column of the datasets table:

Internal no filter Core partner [DataTier] <> "Restricted-use" Associate partner [DataTier] = "Derived" Project partner [DataTier] = "Derived" && [ExportAllowed] = "Yes"

A note on the cobalt price tile says its is restricted-use, because it comes from a licensed feed.

Check it in the report: open Commodity: world with Cobalt selected, then Modeling > View as and tick Associate partner. Watch the four cards at the top. Click Stop viewing when you're done. Needs Power BI Desktop, not the PDF.

Predict first: Viewed as Associate partner, the cobalt production figure shows, but the price is blank. Why?

03

A tile, written down first

Here is one tile from the pages spec: the Production growth card on the Commodity: world page.

{ "id": "s-c2", "title": "Production growth", "visual": "card", "grid": { "col": 4, "row": 1, "colSpan": 3, "rowSpan": 1 }, "basisMeasure": "Basis s-growth", "tier": "proprietary: KPI", "fields": { "value": "[Production growth 5y %]", "categoryLabel": "[Production growth period]" }, "notes": "The period is part of the card. Never show the rate without it." }

Everything about the tile is decided here: what it's called, what kind of visual it is, where it sits, which s it shows, and its tier. The note is a rule for this one tile.

Check it in the report: on Commodity: world, find the Production growth card. Its title, its tier in brackets and its grey Basis line all come from this entry.

Predict first: Which part of the spec decides what the tile's grey Basis line says?

04

Positions from a formula

No tile was placed by eye. The pages spec sets out a and a 12-column grid, and a formula turns a tile's grid cell into pixels:

width 1280 · margin 16 · gutter 10 · 12 columns colWidth = (width − 2 × margin − 11 × gutter) / 12 w = colSpan × colWidth + (colSpan − 1) × gutter Round to whole pixels.

Predict first: The Production growth card spans 3 columns. How wide is it?

05

One name, in one place

The pages spec opens with one rule: every name in square brackets is a measure that exists in one of the two DAX files. A tile never invents a name. It points at a measure that's already written.

That's what makes the specs checkable. The reads every field a tile names and looks for it in the model: 264 checks on their own. How it does that is in The validator.

Predict first: A tile in the spec names [Production growth 5y] but the DAX file calls it [Production growth 5y %]. When is that caught?

06

When two sources disagree

The specs weren't written from nothing. They were checked against the original , and the model spec says so in its first line:

Relationships for the original tables were checked against section 1 of the build guide and agree with it.

The brief has a rule for when they don't agree: if the guide and a spec differ, say so before changing either.

Predict first: While building, the agent finds that the guide and the spec give a measure different format strings. What should it do?

07

Plans before building

The plans are drawn. Next lesson: the workbook, where every number in those tables actually comes from.

Decide on paper first. Give every name one home. Build from the spec, and check against it.

When two sources disagree, stop and say so. Don't quietly pick one.