AnalyticsEngineering
Bridging the gap between Data and Decisions. Building the Semantic Layer that powers enterprise reporting and self-service BI.
01 — The Core
The Semantic Layer
The Warehouse contains data, but the Semantic Layer contains meaning. I implement a centralized "Source of Truth" model that standardizes KPIs across the organization, preventing the "spreadsheets everywhere" chaos.
02 — Technologies
Data Modeling
- SchemaStar Schema (Kimball)
- LanguageDAX / M
- ToolsTabular Editor 3
- ModeDirect Lake / Import
Visualisation
- PlatformPower BI Service
- Custom VizDeneb (Vega-Lite)
- DesignFigma Prototypes
- DeliveryPower BI Apps
Automation
- DeploymentDeployment Pipelines
- TestingPBI Inspector
- RefreshPower Automate
- Version CtrlGit Integration (PBIP)
03 — Philosophy
Reports are products.
Treat them like software.
Too often, BI is treated as "make it look pretty". I treat Analytics as a strict engineering discipline.
Every measure is code. Every report is a product release. I enforce Version Control, CI/CD, and Automated Testing on all Power BI artifacts.
- 01. Calculation Groups for DRY Code
- 02. OLS/RLS for Security
- 03. Incremental Refresh for Scale
Direct Lake
Fabric Speed
Bypassing the import engine. Directly querying Delta Parquet files from OneLake for near-instantaneous performance on massive datasets.
Self Service
Empowerment
Enable business analysts to connect via "Analyze in Excel" or Composite Models. They build their own calculations; IT manages the core model.
04 — Security
Row-Level Security (RLS)
Security is not a filter; it's a fundamental property of the data model. I implement Dynamic RLS to allow a single report to serve thousands of users, each seeing only their own data.
Instead of creating 50 different "Regional Sales" reports, I build one report. The Semantic Layer intercepts the query, checks the user's identity via Azure Entra ID (Active Directory), and automatically injects security predicates into the SQL/DAX query.
U.P.N. Extraction
System identifies john.doe@company.com.
Bridge Table Filtering
Security table filters the RegionBridge based on user assignment.
Fact Propagation
Filter propagates to 100M+ row Fact table via relationship.
VAR CurrentUser = UserPrincipalName() VAR AccessLevel = LOOKUPVALUE( 'Security'[AccessType], 'Security'[Email], CurrentUser ) RETURN IF( AccessLevel = "Admin", TRUE(), 'Region'[RegionKey] IN CALCULATETABLE( VALUES('Security'[RegionKey]), 'Security'[Email] = CurrentUser ) )