Portfolio Build Runbook — Two Pipelines, One Data Story
Goal: two portfolio dashboards, both end-to-end from a real ERP (Business Central / CRONUS), on two stacks that prove different things:
- Microsoft-native (Fabric): signals Microsoft-stack depth to your agency targets.
- Lean (BigQuery/DuckDB + dbt): proves data-engineering / reproducible workflows.
“Done” is not a running system — it’s reproducible + legible: a public GitHub repo (dbt + extract code), a dbt lineage graph, the Power BI reports (embedded), and a short walkthrough. Everything must outlive the trials.
Two clocks to respect: Business Central trial = 30 days, Fabric trial = 60 days. Pull data out of BC early; the warehouse + models persist after it lapses.
1. Accounts to create (Day 1)
| Account | Why | Cost |
|---|---|---|
| Microsoft 365 tenant (EU region) — via M365 Developer Program or a Business Central trial signup | Your new, non-Russian tenant; host for BC + Fabric | Free (dev program E5 is renewable) |
| Business Central trial (CRONUS preloaded) | The real ERP source, seeded Sales/Supply/Finance | Free, 30 days |
| Fabric trial (F4→F64, 1 TB OneLake) | MS-native pipeline | Free, 60 days, no card |
| BigQuery sandbox | Lean warehouse | Free, no card |
| GitHub repo (AxesAccess) | The portfolio artifact itself | Free |
| Optional: Shopify partner dev store / HubSpot free | 2nd source → multi-source story | Free |
Do the M365 tenant + BC trial first — the 30-day BC clock is the binding constraint.
2. Data foundation — real schema, synthetic depth
Source of truth: Business Central CRONUS, pulled via the BC API v2.0 (OData) endpoints. By domain:
- Sales:
salesInvoices,salesInvoiceLines,customers,items - Supply:
itemLedgerEntries,items,purchaseInvoices,vendors, stock/inventory - Finance:
generalLedgerEntries,accounts(chart of accounts),budgets,dimensions - Shared dims:
customers,vendors,items,dimensions, a date table
Reality check: CRONUS data is small and clustered around a single work-date — great for proving schema + connectivity, too thin for forecasting or trend visuals. So:
Hybrid approach: use CRONUS for the real schema and connectivity proof, then augment with synthetic history (same customers/items/accounts, extended 24–36 months, realistic seasonality + noise) in the warehouse layer. The forecasts and cohorts need depth CRONUS doesn’t have.
I can generate that synthetic augmentation (Python, matched to the CRONUS keys) — see §8.
3. Pipeline A — Microsoft-native (Fabric), inside the 60-day trial
- Start the Fabric trial → create workspace “Frequentist Demo” → create a Lakehouse.
- Ingest BC → Lakehouse (bronze): Dataflow Gen2 against the BC API/OData entities above (or the native Business Central → Fabric link if enabled on your tenant). One table per entity, raw.
- Transform (silver → gold): Fabric notebook (PySpark or Spark SQL) or Dataflow — clean to silver, then build the gold star schema:
dim_customer,dim_item,dim_date,dim_account,fct_sales,fct_inventory,fct_gl. Append the synthetic history here. - Semantic model on gold → Power BI report. Build the Finance dashboard here (best CFO fit, and it shows Fabric end-to-end).
- Capture: screenshot the pipeline + lineage; publish the report.
Keep Fabric to one dashboard. It’s the “range” proof, not the whole estate — don’t burn the clock rebuilding everything twice.
4. Pipeline B — Lean (BigQuery/DuckDB + dbt), no clock pressure
- Extract BC → raw: a small Python script (use
dltor plainrequests) pulls the BC API entities into a BigQueryrawdataset (or local DuckDB). Reuse the same synthetic augmentation. - dbt project (structure in §5): sources → staging → intermediate → marts, with tests and
dbt docs generatefor the lineage graph (portfolio gold — it shows the engineering). - Power BI import from BigQuery (native connector) or DuckDB via ODBC → build the Sales and Supply dashboards.
5. dbt project layout
frequentist_analytics/
├── dbt_project.yml
├── README.md # architecture diagram + how to run
├── profiles.example.yml
├── models/
│ ├── staging/
│ │ ├── _bc__sources.yml # BC raw tables + freshness
│ │ ├── stg_bc__customers.sql
│ │ ├── stg_bc__items.sql
│ │ ├── stg_bc__sales_invoice_lines.sql
│ │ ├── stg_bc__item_ledger_entries.sql
│ │ ├── stg_bc__gl_entries.sql
│ │ ├── stg_bc__accounts.sql
│ │ └── stg_bc__budgets.sql
│ ├── intermediate/
│ │ ├── int_sales_enriched.sql # lines + customer + item + date
│ │ ├── int_inventory_movements.sql # item ledger → on-hand, turns
│ │ └── int_gl_with_dimensions.sql # gl + account + dimension
│ └── marts/
│ ├── core/
│ │ ├── dim_customer.sql
│ │ ├── dim_item.sql
│ │ ├── dim_date.sql
│ │ └── dim_account.sql
│ ├── sales/
│ │ ├── fct_sales.sql
│ │ └── sales_kpis.sql # revenue, margin, RFM inputs
│ ├── supply/
│ │ ├── fct_inventory.sql
│ │ └── supply_kpis.sql # turns, days cover, ABC/XYZ, stockout risk
│ └── finance/
│ ├── fct_gl.sql
│ └── finance_kpis.sql # P&L vs budget, variance, cash
├── tests/ # singular tests (e.g. GL balances to zero)
├── macros/
└── seeds/ # synthetic augmentation CSVs (or generated upstream)
Tests to include (they read as rigor on the repo): unique/not_null on all keys, relationships from facts to dims, accepted_values on status fields, and one singular test that GL debits = credits — a genuine finance-integrity check that signals you think like an analyst, not a chart-builder.
6. Dashboard ↔︎ source mapping
| Dashboard | Source entities | Marts | Signature analytical element |
|---|---|---|---|
| Finance (Fabric) | generalLedgerEntries, accounts, budgets, dimensions |
fct_gl, finance_kpis |
P&L actual-vs-budget variance waterfall + cash forecast with interval |
| Sales (lean) | salesInvoiceLines, customers, items |
fct_sales, sales_kpis, dim_customer |
Revenue forecast (confidence band) + RFM/cohort segmentation |
| Supply (lean) | itemLedgerEntries, items, purchaseInvoices |
fct_inventory, supply_kpis |
ABC/XYZ + safety-stock / stockout-risk model |
7. Persistence / capture checklist (do this AS you build, not after)
8. Timeline (fits the 30/60-day clocks)
- Week 1: M365 tenant + BC trial → pull CRONUS via API → BigQuery
raw+ dbt staging. Generate synthetic augmentation. (BC clock started; data now safely extracted.) - Week 2: dbt intermediate + marts + tests + docs → Sales & Supply in Power BI (lean).
- Week 3: Fabric trial → Finance end-to-end in Fabric → capture everything.
- Week 4: embed on the site, swap the three reference tiles, record the walkthrough.
BC can lapse after Week 1 (data’s out); Fabric after Week 3 (artifacts captured). Total cash cost: €0.
9. What I can generate for you next
- The synthetic augmentation dataset (Python generator: customers, items, 24–36 months of sales + inventory + GL with seasonality, matched to CRONUS keys) — drop-in seeds.
- The dbt scaffold —
dbt_project.yml,sources.yml, and the staging + marts models above as real SQL, ready todbt build. - The BC extract script (Python, BC API v2.0 → BigQuery/DuckDB).
- A README architecture diagram (mermaid).
Say which and I’ll write them into a repo layout you can push straight to GitHub.