From powerbi
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.
How this skill is triggered — by the user, by Claude, or both
Slash command
/powerbi:query-to-pbipThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
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.
assets/visual-templates/cardVisual.jsonassets/visual-templates/clusteredBarChart.jsonassets/visual-templates/clusteredColumnChart.jsonassets/visual-templates/columnChart.jsonassets/visual-templates/donutChart.jsonassets/visual-templates/hundredPercentStackedColumnChart.jsonassets/visual-templates/lineChart.jsonassets/visual-templates/lineClusteredColumnComboChart.jsonassets/visual-templates/page-template.jsonassets/visual-templates/pages-json.jsonassets/visual-templates/pieChart.jsonassets/visual-templates/pivotTable.jsonassets/visual-templates/report-json.jsonassets/visual-templates/scatterChart.jsonassets/visual-templates/slicer.jsonassets/visual-templates/tableEx.jsonassets/visual-templates/version-json.jsonreferences/conversion-patterns.mdreferences/layout-patterns.mdreferences/visual-selection-rules.mdOrchestrate 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.
.pbip artifact from Genie outputThe 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.
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.
genie-metric-view.yaml, extract only the source, joins, dimensions, and measures that the query touches.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).USERELATIONSHIPmodel.tmdl — Model-level configurationdatabase.tmdl — Database name and compatibility levelrelationships.tmdl — All table relationshipstables/<TableName>.tmdl — One file per table (fact + dimensions)| 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.
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
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.
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
| 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 |
visualType string (e.g., cardVisual, clusteredColumnChart, lineChart, tableEx, pivotTable, slicer)| 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.
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.
visualType from Stage 2 (e.g., cardVisual, clusteredColumnChart, lineChart)assets/visual-templates/ based on the visual type.nativeQueryRef (column/measure name without table prefix).references/layout-patterns.md.definition/pages/<pageId>/visuals/<visualId>/visual.jsondefinition/report.json, definition/version.json, definition/pages/pages.jsonColumn 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>"
}
| 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 |
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:
assets/visual-templates/{{placeholder}} values with actual field names from Stage 1 and Stage 2{{VisualName}} (e.g., uuid.uuid4().hex[:20])visuals/<visualId>/visual.jsonPurpose: 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.
.pbip projects)Check for existing PBIP projects — Always search the repository for existing .pbip projects and *.SemanticModel folders before creating files from scratch. If an existing <Name>.SemanticModel folder is found, copy its entire contents (including TMDLScripts/, definition/, definition.pbism, diagramLayout.json, .platform, etc.) into the output. If multiple SemanticModel folders are found, prompt the user to confirm which one to use. You must always pass --repo-root when running scaffold_pbip.py so 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 table declarations in model.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, version 1.0definition.pbism — Schema: semanticModel/definitionProperties/1.0.0, version 4.2 (TMDL)definition.pbir — Schema: report/definitionProperties/2.0.0, version 4.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.json and .pbi/cache.abf)
<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>"
}
}
.zip)To execute the full pipeline for a given Genie query:
Identify what the user is asking for. The input can be:
Extract the referenced measures and dimensions from the input.
databricks-genie-metric-view/genie-metric-view.yaml or a provided file)references/conversion-patterns.mdIf a derived categorical alias is available from Stage 1, map it to Series for chart visuals by default to render legend-based color splits.
assets/visual-templates/nativeQueryRef)FROM '2017-01-01' TO '2017-12-31'): use the literal dates directly.RelativeDate filter using Now / DateAdd, following the same shape as the reference generated-reports/DeliveryDaysTrends/.../visual.json.RelativeDate; instead, bind a Stage 1 helper measure/flag and add a standard visual filter requiring that helper to evaluate to 1.dim_date.date for purchase/order trends, dim_date_delivery.date for delivery trends).visual.json file in definition/pages/<pageId>/visuals/<visualId>/page.json (page container without embedded visuals — PBIR format)pages.json, report.json, version.json, and definition.pbirCheck for existing .pbip projects in the repository (search for *.SemanticModel folders)
Scaffold the PBIP directory — always pass the repo root:
python scripts/scaffold_pbip.py <ProjectName> --repo-root <repo-root-path>
TMDLScripts/, definition/, diagramLayout.json, etc.) into the output--semantic-model <path> to specify which one--repo-root — without it, the existing SemanticModel will not be copiedWrite all TMDL files from Step 2 into <ProjectName>.SemanticModel/definition/
Write all report files from Step 4 into <ProjectName>.Report/definition/
Generate pointer files (.pbip, .pbism v4.2, .pbir v4.0) and .platform files
Generate consolidated TMDLScripts — After all TMDL files are written to definition/, run:
python scripts/generate_tmdl_scripts.py <ProjectName>/<ProjectName>.SemanticModel
This reads the split files from definition/ (model.tmdl, tables/.tmdl, relationships.tmdl, cultures/.tmdl) and produces a single TMDLScripts/power-bi-semantic-model.tmdl in the createOrReplace format. The TMDLScripts/.pbi/tmdlScripts.json metadata file is created during scaffolding.
Validate the structure (using scripts/package_pbip.py --validate-only)
Zip the project directory (excluding .pbi/localSettings.json and .pbi/cache.abf)
Provide the user with:
| 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 |
Before delivering the final PBIP, verify:
measure 'Name' = <DAX>). Measures must NOT contain displayName, dataType, sourceColumn, or expression = 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 contain sourceColumn: or sourceProviderType: — these are source column properties only and are invalid on calculated columns. The keyword calculatedColumn must 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., use table[volume_rank] not RANKX(...)). If no source column exists, convert to a measure.
1d. Column Properties — Every source column MUST include sourceProviderType and annotation SummarizationSetBy = Automatic. int64 columns must have formatString: 0. double columns must have annotation PBI_FormatHint = {"isGeneralNumber":true}. dateTime columns must have appropriate formatString (Long Date or General Date)
1e. Model Format — model.tmdl must include dataAccessOptions block (with legacyRedirects and returnErrorValuesAsNull) and annotation __PBI_TimeIntelligenceEnabled = 1. Must NOT include discourageImplicitMeasures
1f. Table Annotations — Every table must end with annotation PBI_ResultType = TablelineageTag); each has annotation PBI_IsFromSource = FS
2b. 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-onlydim_date, dim_date_delivery, etc.) for the requested trend.pbip -> .Report, .pbir -> .SemanticModel paths are correct.pbism version 4.2 (TMDL), .pbir version 4.0 (PBIR), visual schema 2.5.0.platform exists in both SemanticModel and Report foldersdefinition/report.json, definition/version.json, definition/pages/pages.json all presentlineageTag (causes UnknownKeyword error); the GUID is the relationship nameTMDLScripts/ and other contents are present in the output
11b. TMDLScripts — TMDLScripts/power-bi-semantic-model.tmdl must exist and contain the consolidated createOrReplace TMDL combining all tables, relationships, and culture info. TMDLScripts/.pbi/tmdlScripts.json must exist with version, tabOrder, and defaultTabsortDefinition in the visual->query block for proper default sortingRelativeDate; data-anchored rolling windows use helper measures/flags rather than Nowconversion-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 examplescardVisual.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 templatescaffold_pbip.py — Creates the PBIP directory structure and pointer filesgenerate_tmdl_scripts.py — Generates consolidated TMDLScripts/power-bi-semantic-model.tmdl from split definition/ filespackage_pbip.py — Validates and zips the PBIP directorynpx claudepluginhub bcastelino/powerbi-dashboard-generator --plugin powerbi-dashboard-generatorSearches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Implements vector databases with Pinecone, Weaviate, Qdrant, Milvus, pgvector for semantic search, RAG, recommendations, and similarity systems. Optimizes embeddings, indexing, and hybrid search.