Query to pbip
Skill bcastelino/powerbi-dashboard-generator/skills/query-to-pbip
Agent Skills toolkit that turns plain-English requests into fully-formed, branded Power BI Desktop Projects (PBIP). Ten composable skills for source-agnostic semantic modeling, visual generation, and theming.
npx -y skills add bcastelino/powerbi-dashboard-generator --skill query-to-pbipAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Orchestrates the end-to-end conversion of a Databricks Genie Query into a Power BI Desktop Project (PBIP) with visuals. Use this skill when transforming a Genie SQL query or YAML metric view into a complete, openable Power BI project containing a semantic model (TMDL) and report visuals (PBIR). It coordinates four sub-skills in sequence — semantic-mapper, visual-selector, visual-generator, and project-packager — to produce a zipped PBIP artifact.
SKILL.md
30.3 KB, ~7.4k tokens by cl100k_base, as published. Nobody here has run it
Query To Pbip
Orchestrate the conversion of a Databricks Genie Query into a complete Power BI Desktop Project (PBIP). This skill acts as a pipeline controller, invoking four sub-skills in sequence to translate query semantics into a TMDL model, select an appropriate visual type, generate the visual JSON, and scaffold the final PBIP package.
When to Use This Skill
- Converting a Genie SQL query or YAML metric view into a Power BI visual
- Generating a complete PBIP project from a natural language query result
- Producing a downloadable
.pbipartifact from Genie output - Automating the end-to-end pipeline from query to Power BI report
Pipeline Overview
The orchestration follows a strict four-stage pipeline. Each stage produces an artifact consumed by the next:
┌─────────────────┐ ┌──────────────────┐ ┌───────────────────┐ ┌───────────────────┐
│ semantic-mapper │────▶│ visual-selector │────▶│ visual-generator │────▶│ project-packager │
│ │ │ │ │ │ │ │
│ Genie YAML ──▶ │ │ TMDL + SQL ──▶ │ │ Visual Type ──▶ │ │ All artifacts ──▶ │
│ TMDL Model │ │ Visual Type │ │ visual.json │ │ Zipped PBIP │
└─────────────────┘ └──────────────────┘ └───────────────────┘ └───────────────────┘
Input: A Genie Query — either as raw SQL, a YAML metric view snippet, or the full genie-metric-view.yaml file.
Output: A zipped PBIP directory ready to open in Power BI Desktop.
Stage 1: Semantic Mapper
Purpose: Translate the Genie SQL (YAML) into a Power BI TMDL semantic model.
Sub-skill: semantic-mapper
Convert the Databricks Genie YAML metric view (or a subset relevant to the query) into TMDL format, applying the same conversion patterns defined in the yaml-to-tmdl-converter skill.
Inputs
- Genie YAML metric view (full file or relevant subset)
- Query context: which measures and dimensions the query references
- SQL aliases from the query output that are not native semantic-model fields (derived fields)
Process
- Parse the Genie Query — Identify the measures and dimensions referenced in the query.
- Extract relevant YAML — From the full
genie-metric-view.yaml, extract only the source, joins, dimensions, and measures that the query touches. - Build a Derived Field Registry — For any
SELECT ... AS <alias>field not already in the model, capture alias name, SQL expression, source tables, inferred kind (dimension/measure), and target materialization (calculatedColumn/measure). - Convert to TMDL — Apply the YAML-to-TMDL conversion workflow:
- Extract source table as the fact table
- Convert joins to table definitions and relationships
- Choose the correct role-playing date strategy: separate active date tables when multiple date roles must filter visuals simultaneously, otherwise inactive alternate relationships with
USERELATIONSHIP - Convert SQL measures to DAX measures
- Materialize derived aliases as calculated columns or measures before visual generation
- Materialize data-anchored rolling-window helper measures when the request is for the latest N periods in the data
- Convert format objects to TMDL format strings
- Generate M-Code partitions for Databricks connectivity
- Add lineage tags (GUIDs) to every object
Outputs
model.tmdl— Model-level configurationdatabase.tmdl— Database name and compatibility levelrelationships.tmdl— All table relationshipstables/<TableName>.tmdl— One file per table (fact + dimensions)
Conversion Quick Reference
| YAML Element | TMDL Output |
|---|---|
source: | Fact table with partition |
joins: with using: | Table + relationship (same key) |
joins: with on: | Table + relationship (different keys) |
measures: with SUM(col) | measure = SUM(table[col]) |
measures: with COUNT(DISTINCT col) | measure = DISTINCTCOUNT(table[col]) |
measures: with a / NULLIF(b, 0) | measure = DIVIDE(a, b) |
format: { type: currency } | formatString: $#,0.00 + annotation |
format: { type: percentage } | formatString: 0.0% |
window: (rolling) | CALCULATE with DATESINPERIOD |
For complete conversion patterns, refer to references/conversion-patterns.md.
Example
Input (YAML subset):
source: wl_internal.olist_ecommerce.fact_sales
joins:
- name: dim_customer
source: wl_internal.olist_ecommerce.dim_customer
using:
- customer_key
measures:
- name: Total Revenue (GMV)
expr: SUM(total_value)
format:
type: currency
currency_code: USD
Output (fact_sales.tmdl excerpt):
table fact_sales
lineageTag: <generated-guid>
measure 'Total Revenue (GMV)' = SUM(fact_sales[total_value])
formatString: $#,0.00
lineageTag: <generated-guid>
partition fact_sales = m
mode: directQuery
source =
let
Source = DatabricksMultiCloud.Catalogs(...),
...
in
fact_sales_Table
Stage 2: Visual Selector
Purpose: Determine the best Power BI visual type based on the query's data profile.
Sub-skill: visual-selector
Analyze the measures and dimensions extracted in Stage 1 to recommend the most appropriate visual type.
Inputs
- List of measures from Stage 1 (names, data types, format types)
- List of dimensions from Stage 1 (names, data types, cardinality hints)
- Original query intent (e.g., "show revenue by state", "compare monthly trends")
Selection Rules
Apply the following decision tree to select the visual type:
START
|
+-- Single measure, no dimensions ------------------> cardVisual
|
+-- Single measure, 1 categorical dimension
| +-- Dimension is temporal (date/month/year) ----> lineChart
| +-- Dimension is nominal (state/category) ------> columnChart
|
+-- Single measure, 1 geographic dimension ----------> map
|
+-- Multiple measures, no dimensions ----------------> cardVisual (multi-card)
|
+-- Multiple measures, 1+ dimensions
| +-- Dimension is temporal -----------------------> lineChart
| +-- Comparison intent ---------------------------> clusteredBarChart
| +-- Default -------------------------------------> tableEx
|
+-- 1 measure, 2+ dimensions
| +-- Both categorical ----------------------------> matrix
| +-- One temporal, one categorical ---------------> lineChart (with series)
|
+-- Fallback ----------------------------------------> tableEx
Dimension Classification
| Indicator | Classification | Examples |
|---|---|---|
Column name contains date, month, year, quarter, time | Temporal | order_date, Month, Year |
Column name contains state, city, country, region, zip | Geographic | customer_state, Region |
Column references dim_date, dim_date_delivery, or another role-playing date table | Temporal | Any date-role column |
| All other columns | Nominal/Categorical | category_name, seller_id |
Outputs
- Selected
visualTypestring (e.g.,cardVisual,clusteredColumnChart,lineChart,tableEx,pivotTable,slicer) - Query bucket mapping (which fields go into which buckets like Category, Y, Values, Series)
- Recommended page layout position
Query Bucket Mapping by Visual Type
| Visual Type | Buckets | What Goes Where |
|---|---|---|
cardVisual | Data | Single measure |
clusteredColumnChart | Category, Y, Series | Dimension -> Category, Measure -> Y, Derived categorical grouping -> Series |
lineChart | Category, Y, Series | Time -> Category, Measure -> Y, Optional grouping -> Series |
tableEx | Values | All dimensions and measures |
pivotTable | Rows, Columns, Values | Dim1 -> Rows, Dim2 -> Columns, Measures -> Values |
slicer | Values | Single dimension column |
clusteredBarChart | Category, Y, Series | Dimension -> Category, Measures -> Y, Derived categorical grouping -> Series |
filledMap | Category, Size | Geo dimension -> Category, Measure -> Size |
If a derived categorical alias exists (for example Top Flag), default to placing it in Series for supported chart visuals so Power BI legend/color segmentation is preserved.
Stage 3: Visual Generator
Purpose: Build individual visual.json files in PBIR format, where each visual is a separate file in its own directory.
Sub-skill: visual-generator
Take the selected visual type and field mappings from Stage 2 and produce all report definition files in PBIR format.
Inputs
visualTypefrom Stage 2 (e.g.,cardVisual,clusteredColumnChart,lineChart)- Query bucket mapping from Stage 2
- Table and measure names from Stage 1
- Page layout preferences (defaults: 1280x720, FitToPage)
Process
- Load the visual template — Select the appropriate template from
assets/visual-templates/based on the visual type. - Populate field references — Replace template placeholders with actual table names, column names, and measure names using the semantic query format. Include
nativeQueryRef(column/measure name without table prefix). - Set positioning — Calculate the visual position within the page layout. For single visuals, center on the page. For dashboards with multiple visuals, apply the layout grid from
references/layout-patterns.md. - Write each visual as a separate file — Each visual gets its own directory:
definition/pages/<pageId>/visuals/<visualId>/visual.json - Assemble page.json — Page definition (no embedded visuals — visuals are separate files in PBIR format).
- Generate report definition files —
definition/report.json,definition/version.json,definition/pages/pages.json
Semantic Query Field Format
Column reference:
{
"field": {
"Column": {
"Expression": { "SourceRef": { "Entity": "<TableName>" } },
"Property": "<ColumnName>"
}
},
"queryRef": "<TableName>.<ColumnName>",
"nativeQueryRef": "<ColumnName>",
"active": true
}
Measure reference:
{
"field": {
"Measure": {
"Expression": { "SourceRef": { "Entity": "<FactTableName>" } },
"Property": "<MeasureName>"
}
},
"queryRef": "<FactTableName>.<MeasureName>",
"nativeQueryRef": "<MeasureName>"
}
Outputs
| File | Location | Schema Version |
|---|---|---|
visual.json (per visual) | definition/pages/<pageId>/visuals/<visualId>/ | visualContainer/2.5.0 |
page.json | definition/pages/<pageId>/ | page/2.0.0 |
pages.json | definition/pages/ | pagesMetadata/1.0.0 |
report.json | definition/ | report/3.1.0 |
version.json | definition/ | versionMetadata/1.0.0 |
definition.pbir | <ProjectName>.Report/ | definitionProperties/2.0.0 |
Visual Template Usage
Templates are stored in assets/visual-templates/. Each template uses schema version 2.5.0 with {{placeholder}} markers:
| Template | PBIR Visual Type | Placeholders |
|---|---|---|
cardVisual.json | cardVisual | {{VisualName}}, {{MeasureTable}}, {{MeasureName}} |
clusteredColumnChart.json | clusteredColumnChart | {{VisualName}}, {{CategoryTable}}, {{CategoryColumn}}, {{MeasureTable}}, {{MeasureName}}, {{SeriesTable}}, {{SeriesColumn}} |
clusteredBarChart.json | clusteredBarChart | {{VisualName}}, {{CategoryTable}}, {{CategoryColumn}}, {{MeasureTable}}, {{MeasureName}}, {{SeriesTable}}, {{SeriesColumn}} |
lineChart.json | lineChart | {{VisualName}}, {{CategoryTable}}, {{CategoryColumn}}, {{MeasureTable}}, {{MeasureName}} |
tableEx.json | tableEx | {{VisualName}}, {{Columns}} |
slicer.json | slicer | {{VisualName}}, {{SlicerTable}}, {{SlicerColumn}} |
To use a template:
- Read the template file from
assets/visual-templates/ - Replace all
{{placeholder}}values with actual field names from Stage 1 and Stage 2 - Generate a unique 20-char hex identifier for
{{VisualName}}(e.g.,uuid.uuid4().hex[:20]) - Set the position coordinates based on the layout
- Write each visual to its own directory:
visuals/<visualId>/visual.json
Stage 4: Project Packager
Purpose: Scaffold the complete PBIP directory structure per the official Microsoft PBIP format and prepare it for use.
Sub-skill: project-packager
Assemble all artifacts from the previous stages into a valid PBIP directory structure with TMDL semantic model and PBIR report format.
Inputs
- TMDL files from Stage 1 (model, database, relationships, tables)
- Report files from Stage 3 (visual.json files, page.json, report.json, pages.json, version.json, definition.pbir)
- Project name (derived from the query or specified by the user)
- Repository root path (optional — used to discover existing
.pbipprojects) - Explicit SemanticModel path (optional — used when multiple exist)
Process
-
Check for existing PBIP projects — Always search the repository for existing
.pbipprojects and*.SemanticModelfolders before creating files from scratch. If an existing<Name>.SemanticModelfolder is found, copy its entire contents (includingTMDLScripts/,definition/,definition.pbism,diagramLayout.json,.platform, etc.) into the output. If multipleSemanticModelfolders are found, prompt the user to confirm which one to use. You must always pass--repo-rootwhen runningscaffold_pbip.pyso that existing SemanticModel content is discovered and copied. Use--semantic-model <path>when you need to target a specific folder.Critical: Do NOT remove any tables, models, relationships, or definition files from the copied SemanticModel — even if they are not directly referenced by the current visual or query. The complete SemanticModel must remain intact. Removing unused tables breaks
ref tabledeclarations inmodel.tmdl, removing relationships breaks foreign key integrity, and Power BI Desktop validates the entire model on load. Only add new report files — never delete or modify existing SemanticModel content. -
Create directory structure — Scaffold the PBIP folder hierarchy:
<ProjectName>/ ├── <ProjectName>.pbip # Project entry point ├── .gitignore # Excludes local settings and cache ├── <ProjectName>.SemanticModel/ │ ├── .platform # Fabric Git integration (type: SemanticModel) │ ├── definition.pbism # Semantic model pointer (version 4.2 for TMDL) │ ├── TMDLScripts/ # Consolidated TMDL (generated or copied) │ │ ├── power-bi-semantic-model.tmdl # Single-file createOrReplace TMDL │ │ └── .pbi/ │ │ └── tmdlScripts.json # TMDLScripts metadata │ ├── diagramLayout.json # Diagram layout (copied from existing project if available) │ ├── .pbi/ │ │ └── editorSettings.json # Editor configuration │ └── definition/ │ ├── database.tmdl │ ├── model.tmdl │ ├── relationships.tmdl │ ├── cultures/ │ │ └── en-US.tmdl # Culture/locale definition │ └── tables/ │ ├── fact_sales.tmdl │ ├── dim_customer.tmdl │ └── ... └── <ProjectName>.Report/ ├── .platform # Fabric Git integration (type: Report) ├── definition.pbir # Report pointer (version 4.0, PBIR format) ├── StaticResources/ │ └── SharedResources/ │ └── BaseThemes/ │ └── CY25SU11.json # Default Power BI theme └── definition/ ├── report.json # Report config (schema 3.1.0) ├── version.json # Report format version └── pages/ ├── pages.json # Page ordering and active page └── <pageId>/ # 20-char hex page identifier ├── page.json # Page definition (schema 2.0.0) └── visuals/ ├── <visualId>/ │ └── visual.json # Visual definition (schema 2.5.0) └── <visualId>/ └── visual.json -
Generate pointer files with correct schemas:
<ProjectName>.pbip— Schema:pbipProperties/1.0.0, version1.0definition.pbism— Schema:semanticModel/definitionProperties/1.0.0, version4.2(TMDL)definition.pbir— Schema:report/definitionProperties/2.0.0, version4.0(PBIR)
-
Generate .platform files — Fabric Git integration metadata for both SemanticModel and Report
-
Write TMDL files — Place all semantic model files from Stage 1
-
Write report files — Place all report files from Stage 3 (individual visual.json files in their directories)
-
Validate structure — Verify all required files exist and references are consistent
-
Package — Create a zip archive of the PBIP directory (excluding
.pbi/localSettings.jsonand.pbi/cache.abf)
Pointer File Templates
<ProjectName>.pbip:
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/pbip/pbipProperties/1.0.0/schema.json",
"version": "1.0",
"artifacts": [
{
"report": {
"path": "<ProjectName>.Report"
}
}
],
"settings": {
"enableAutoRecovery": true
}
}
definition.pbism (version 4.2 = TMDL format in definition/ folder):
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/semanticModel/definitionProperties/1.0.0/schema.json",
"version": "4.2",
"settings": {}
}
definition.pbir (version 4.0 = PBIR format in definition/ folder):
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definitionProperties/2.0.0/schema.json",
"version": "4.0",
"datasetReference": {
"byPath": {
"path": "../<ProjectName>.SemanticModel"
}
}
}
.platform (one in each item folder):
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json",
"metadata": {
"type": "SemanticModel",
"displayName": "<ProjectName>"
},
"config": {
"version": "2.0",
"logicalId": "<generated-guid>"
}
}
Outputs
- Complete PBIP directory structure
- Zipped PBIP archive (
.zip)
File Format Requirements
- All text files: UTF-8 without BOM
- JSON files: 2-space indentation
- TMDL files: Tab indentation
- Line endings: LF (Unix-style)
End-to-End Execution Workflow
To execute the full pipeline for a given Genie query:
Step 1: Receive and Parse the Query
Identify what the user is asking for. The input can be:
- A natural language question (e.g., "Show me revenue by state")
- A Genie SQL query
- A YAML metric view file or snippet
Extract the referenced measures and dimensions from the input.
Step 2: Run the Semantic Mapper (Stage 1)
- Load the Genie YAML metric view (from
databricks-genie-metric-view/genie-metric-view.yamlor a provided file) - Filter to only the measures, dimensions, and joins relevant to the query
- Build a Derived Field Registry for SQL aliases not present in the model
- Materialize derived aliases into TMDL as calculated columns or measures
- Apply the YAML-to-TMDL conversion following the patterns in
references/conversion-patterns.md - Generate all TMDL files (model, database, relationships, tables)
Step 3: Run the Visual Selector (Stage 2)
- Analyze the measures and dimensions from Step 2
- Classify each dimension (temporal, geographic, nominal)
- Apply the visual selection decision tree
- Produce the visual type and query bucket mapping
If a derived categorical alias is available from Stage 1, map it to Series for chart visuals by default to render legend-based color splits.
Step 4: Run the Visual Generator (Stage 3)
- Load the appropriate visual template from
assets/visual-templates/ - Replace placeholders with actual table/column/measure names (include
nativeQueryRef) - Populate date range filter placeholders — If the Genie query contains date-level filters:
- For absolute date ranges (e.g.,
FROM '2017-01-01' TO '2017-12-31'): use the literal dates directly. - For current-date-relative ranges (e.g., "last 12 months", "past 6 months", "last 90 days"): emit a native PBIR
RelativeDatefilter usingNow/DateAdd, following the same shape as the referencegenerated-reports/DeliveryDaysTrends/.../visual.json. - For data-anchored ranges (e.g., "latest 12 months in the data", or historical datasets where the latest row is older than today): do not use native
RelativeDate; instead, bind a Stage 1 helper measure/flag and add a standard visual filter requiring that helper to evaluate to1. - Set the date entity/property to the correct semantic timeline (
dim_date.datefor purchase/order trends,dim_date_delivery.datefor delivery trends).
- For absolute date ranges (e.g.,
- Write each visual as a separate
visual.jsonfile indefinition/pages/<pageId>/visuals/<visualId>/ - Generate
page.json(page container without embedded visuals — PBIR format) - Generate
pages.json,report.json,version.json, anddefinition.pbir
Step 5: Run the Project Packager (Stage 4)
-
Check for existing
.pbipprojects in the repository (search for*.SemanticModelfolders) -
Scaffold the PBIP directory — always pass the repo root:
python scripts/scaffold_pbip.py <ProjectName> --repo-root <repo-root-path>- This automatically discovers and copies existing SemanticModel contents (including
TMDLScripts/,definition/,diagramLayout.json, etc.) into the output - If multiple SemanticModel folders exist, use
--semantic-model <path>to specify which one - Never omit
--repo-root— without it, the existing SemanticModel will not be copied
- This automatically discovers and copies existing SemanticModel contents (including
-
Write all TMDL files from Step 2 into
<ProjectName>.SemanticModel/definition/- Do NOT remove any existing tables, models, relationships, or definition files from the copied SemanticModel
-
Write all report files from Step 4 into
<ProjectName>.Report/definition/ -
Generate pointer files (
.pbip,.pbismv4.2,.pbirv4.0) and.platformfiles -
Generate consolidated TMDLScripts — After all TMDL files are written to
definition/, run:python scripts/generate_tmdl_scripts.py <ProjectName>/<ProjectName>.SemanticModelThis reads the split files from
definition/(model.tmdl, tables/.tmdl, relationships.tmdl, cultures/.tmdl) and produces a singleTMDLScripts/power-bi-semantic-model.tmdlin thecreateOrReplaceformat. TheTMDLScripts/.pbi/tmdlScripts.jsonmetadata file is created during scaffolding. -
Validate the structure (using
scripts/package_pbip.py --validate-only) -
Zip the project directory (excluding
.pbi/localSettings.jsonand.pbi/cache.abf)
Step 6: Deliver the Result
Provide the user with:
- The zipped PBIP file
- A summary of what was generated (tables, measures, visual type)
- Instructions to open in Power BI Desktop
Error Handling
| Stage | Common Error | Resolution |
|---|---|---|
| Semantic Mapper | Unknown DAX conversion for SQL function | Fall back to inline SQL comment with TODO marker |
| Semantic Mapper | Missing join definition | Skip the dimension, warn the user |
| Visual Selector | Ambiguous query intent | Default to tableEx (table visual) |
| Visual Generator | Template placeholder not found | Use generic field reference |
| Project Packager | Invalid directory structure | Re-scaffold from template |
| Project Packager | Missing required files | Report which files are missing |
Validation Checklist
Before delivering the final PBIP, verify:
- Semantic Model Completeness — All referenced tables, columns, and measures exist in TMDL files
1b. Measure Syntax — Every measure uses inline expression syntax (
measure 'Name' = <DAX>). Measures must NOT containdisplayName,dataType,sourceColumn, orexpression =as separate properties — these are either column-only or invalid TMDL keywords 1c. Calculated Column Syntax — Every derived calculated column uses inline DAX expression syntax (column 'Name' = <DAX expression>). Calculated columns must NOT containsourceColumn:orsourceProviderType:— these are source column properties only and are invalid on calculated columns. The keywordcalculatedColumnmust never appear as a TMDL property name. DirectQuery restriction: calculated column DAX must NOT use iterator functions (RANKX,SUMX,AVERAGEX,COUNTX,MAXX,MINX,FILTER,ADDCOLUMNS,SELECTCOLUMNS). Reference pre-existing source columns instead (e.g., usetable[volume_rank]notRANKX(...)). If no source column exists, convert to a measure. 1d. Column Properties — Every source column MUST includesourceProviderTypeandannotation SummarizationSetBy = Automatic.int64columns must haveformatString: 0.doublecolumns must haveannotation PBI_FormatHint = {"isGeneralNumber":true}.dateTimecolumns must have appropriateformatString(Long DateorGeneral Date) 1e. Model Format —model.tmdlmust includedataAccessOptionsblock (withlegacyRedirectsandreturnErrorValuesAsNull) andannotation __PBI_TimeIntelligenceEnabled = 1. Must NOT includediscourageImplicitMeasures1f. Table Annotations — Every table must end withannotation PBI_ResultType = Table - Relationship Integrity— All joins from YAML are converted to relationships; relationships use the GUID as name (NOT as
lineageTag); each hasannotation PBI_IsFromSource = FS2b. Role-Playing Date Strategy — Multiple simultaneously active date roles use separate role-playing date tables; inactive alternate relationships are used only when the alternate role is measure-only - Visual Binding — The visual's query references match actual table/measure names in the TMDL
3b. Timeline Alignment — Temporal visuals and date filters use the correct date role (
dim_date,dim_date_delivery, etc.) for the requested trend - Pointer Consistency —
.pbip->.Report,.pbir->.SemanticModelpaths are correct - Schema Versions —
.pbismversion 4.2 (TMDL),.pbirversion 4.0 (PBIR), visual schema 2.5.0 - Platform Files —
.platformexists in both SemanticModel and Report folders - Report Definition —
definition/report.json,definition/version.json,definition/pages/pages.jsonall present - File Format — UTF-8 encoding, correct indentation (tabs for TMDL, 2-space for JSON)
- GUID Uniqueness — All lineage tags are unique across the project
- Relationship Format — Relationships do NOT contain
lineageTag(causesUnknownKeyworderror); the GUID is the relationship name - SemanticModel Copy — If an existing SemanticModel was found, verify
TMDLScripts/and other contents are present in the output 11b. TMDLScripts —TMDLScripts/power-bi-semantic-model.tmdlmust exist and contain the consolidatedcreateOrReplaceTMDL combining all tables, relationships, and culture info.TMDLScripts/.pbi/tmdlScripts.jsonmust exist with version, tabOrder, and defaultTab - SemanticModel Integrity — No tables, models, relationships, or definition files were removed from the copied SemanticModel
- sortDefinition — Every visual.json includes a
sortDefinitionin thevisual->queryblock for proper default sorting - Last-N-Month Filter Mode — Current-date rolling windows use native PBIR
RelativeDate; data-anchored rolling windows use helper measures/flags rather thanNow
Resources
references/
conversion-patterns.md— Complete YAML-to-TMDL and DAX-to-SQL conversion referencelayout-patterns.md— Page layout grid patterns for multi-visual dashboardsvisual-selection-rules.md— Detailed visual selection decision tree with examples
assets/visual-templates/
cardVisual.json— Card visual (cardVisual, schema 2.5.0)columnChart.json— Column chart (columnChart, schema 2.5.0)clusteredColumnChart.json— Clustered column chart (clusteredColumnChart, schema 2.5.0)clusteredBarChart.json— Clustered bar chart (clusteredBarChart, schema 2.5.0)lineChart.json— Line chart (lineChart, schema 2.5.0)tableEx.json— Table visual (tableEx, schema 2.5.0)slicer.json— Slicer visual (slicer, schema 2.5.0)page-template.json— Base page container (schema 2.0.0)pages-json.json— Page ordering template (schema 1.0.0)report-json.json— Report configuration template (schema 3.1.0)version-json.json— Report format version template
scripts/
scaffold_pbip.py— Creates the PBIP directory structure and pointer filesgenerate_tmdl_scripts.py— Generates consolidatedTMDLScripts/power-bi-semantic-model.tmdlfrom splitdefinition/filespackage_pbip.py— Validates and zips the PBIP directory