Development Documentation
View as:

AI-Guided Power BI Workflow

This page describes the conversational loop Claude uses to ship Power BI / semantic-model changes through an isolated Fabric feature environment. You drive the loop by talking to Claude — Claude drives the scripts, the deploys, the screenshots, the PR, and finally the teardown.

The loop is implemented as four Claude Code skills under .claude/skills/fabric-feature-*/. Each skill ends with an explicit hand-off message telling you what to check, where to check it, and which natural-language phrase to reply with to advance to the next step.

The flow at a glance

graph TD
  START["/fabric-feature-start <slug>"]
  EDIT["Claude edits TMDL / report.json<br/>in .claude/worktrees/&lt;slug&gt;"]
  DEPLOY["/fabric-feature-deploy &lt;slug&gt;"]
  REVIEW{"You review in Fabric"}
  PR["/fabric-feature-pr &lt;slug&gt;"]
  MERGE{"You approve + Complete<br/>the PR in ADO"}
  TEARDOWN["/fabric-feature-teardown &lt;slug&gt;"]
  CLEAN[Clean slate]

  START -->|"Claude asks: 'which developer UPN(s)?'<br/>then provisions workspaces"| EDIT
  EDIT -->|"You: 'deploy it'"| DEPLOY
  DEPLOY -->|"Claude renders PDF<br/>+ asks you to review"| REVIEW
  REVIEW -->|"'Change X'"| EDIT
  REVIEW -->|"'Looks good — open the PR'"| PR
  REVIEW -->|"'Scrap this'"| TEARDOWN
  PR -->|"Claude opens PR<br/>autocomplete NOT set"| MERGE
  MERGE -->|"main is green"| TEARDOWN
  TEARDOWN -->|"workspaces destroyed,<br/>branch + worktree gone"| CLEAN

When to use this flow

Use it for any change to:

  • A Power BI report under workspaces/reports/
  • A semantic model TMDL under workspaces/semantic/
  • Anything that will eventually deploy through fabric-cicd to DEV / UAT / PROD workspaces

Don't use it for changes to dbt models, pipelines, Terraform, or scripts — those have their own developer workflow (Developer Workflow).

Step 1 — Start

You type:

/fabric-feature-start <slug>

…or just say "start a new feature called <slug>". <slug> is kebab-case, lowercase, ≤20 chars (the teardown script's hard limit), e.g. etl-thousands-fmt.

Claude asks you for the developer UPN(s) to grant Contributor on the feature workspaces. This is required every time — Claude won't auto-resolve from git config user.email or environment variables. The reason is that git config user.email in this repo is the SPN identity (geris_fabric_admin@geris.nl), which collides with the workspace admin principal and causes a terraform role-assignment race. Always answer with a real human UPN like daan.aerts@geris.nl.

After you answer, Claude runs:

./scripts/fabric dev start \
  --profile model \
  --feature <slug> \
  --developers <upn-you-gave>

This:

  • Provisions feat-<slug>-Semantic and feat-<slug>-Reports workspaces in Fabric
  • Creates and pushes branch feature/<slug>
  • Deploys the current main baseline TMDL + reports into the feature workspaces
  • Binds DirectLake models to the shared Gold connection and refreshes them
  • Writes deployment/feat-<slug>.yml + deployment/parameter-feat-<slug>.yml

Claude hands off with the two Fabric workspace URLs and asks you what to change next. Example replies:

"Add thousand separators to the Total Runs measure on the dbt Build Quality page."

"Move the SLA Compliance card to the top-right of the Overview page and make it red below 95%."

"Add a new page showing failure counts by pipeline_name over the last 7 days."

Step 2 — Edit ↔ Deploy loop

This is the inner loop. You stay here until the rendered report looks the way you want.

Edit

Claude edits the TMDL or report.json inside .claude/worktrees/<slug>/workspaces/…. Two things to know:

  • The pre-commit hook validates TMDL. Most common gotcha: a multi-line measure body must indent the DAX at ≥3 tabs so property lines (formatString:, lineageTag:) at 2 tabs stay outside the DAX expression. The validator catches this and refuses the commit until it's fixed.
  • Every code change includes its docs-site/ update in the same commit. The pre-commit hook regenerates the affected sections via scripts/docs/scan_system.py (path mapping in scripts/docs/_path_mapping.py).

Deploy

When you say "deploy it" / "push to Fabric" / "let me see it", Claude runs /fabric-feature-deploy <slug> which:

source scripts/_lib_spn.sh
load_platform_spn "$(pwd)" >/dev/null
python scripts/deploy_to_feature.py --feature <slug>

…and then renders the report to PDF via the Power BI REST ExportTo endpoint, rasterizes the pages you care about to PNG, and reads them inline so Claude can sanity-check before handing back to you.

Claude hands off with a three-way prompt:

You say…Claude does…
"Looks good — open the PR" / "ship it" / "PR it"Advance to step 3
"Change X" / "Move the Y" / "Make the font smaller"Another edit ↔ deploy cycle
"Scrap this" / "tear it down" / "abandon"Jump to step 4 (teardown)

You can iterate as many times as you want in this loop. Each deploy adds a commit on feature/<slug> and a new screenshot directory under .dev/screenshots/<sha>/.

Step 3 — PR

When you say "looks good — open the PR" (or any of its synonyms), Claude runs /fabric-feature-pr <slug>. This:

  1. Runs bash scripts/fabric dev pr-check --feature <slug> to confirm workspace and git are in sync (after each deploy, Fabric's git integration round-trips a normalized TMDL form back to origin under the sp-fabric-platform-admin author; Claude will git fetch + reset --hard if needed to absorb those commits before opening the PR)
  2. Opens a pull request from feature/<slug>main via mcp__azure-devops__repo_create_pull_request, with the Fabric workspace URLs and screenshot list in the body
  3. Does NOT set autocomplete. You stay in control of the merge.

Claude hands off with your post-PR checklist:

  1. Open the Fabric Reports workspace one more time — confirm the rendered report still matches what you agreed in the deploy loop.
  2. In ADO, tick the reviewer checklist, click Approve, then Complete.
  3. Wait for the post-merge main build to go green. This is the CLAUDE.md rule 5 ("monitor every deployment end-to-end"). If anything fails, ping Claude.
  4. Once main is green, come back and say "clean up <slug>".

Do not ask for teardown before the merge is in and main is green. Teardown destroys the feature workspaces (the diff source for your rendered review) and deletes the feature/<slug> branch (which ADO still needs to complete the merge).

Step 4 — Teardown

When you say "clean up <slug>" / "tear down <slug>" / "remove the feature env", Claude runs /fabric-feature-teardown <slug>. This:

  1. Verifies via mcp__azure-devops__repo_list_pull_requests_by_repo_or_project that the PR for feature/<slug> is Completed or Abandoned.
  2. (Recommended) Verifies the post-merge main build is green via mcp__azure-devops__pipelines_get_builds.
  3. Runs bash scripts/fabric dev teardown <slug> --force, which dispatches to scripts/teardown_feature_env.sh. This actually destroys the Fabric workspaces — under the hood it runs terraform destroy against the feature's tfstate, removing:
    • The Fabric workspaces feat-<slug>-Semantic, feat-<slug>-Reports (plus Gold / Bronze if the profile created them)
    • The Gold Warehouse + Lakehouse + Bronze shortcuts (full profile)
    • The Function App (functions profile)
    • All git connections and workspace role assignments
  4. Deletes the Terraform state blob feat-<slug>.tfstate from Azure Blob Storage.
  5. Removes deployment/feat-<slug>.yml + deployment/parameter-feat-<slug>.yml and commits that cleanup to main.
  6. Deletes the local + remote feature/<slug> branch.
  7. Removes the .claude/worktrees/<slug> worktree and prunes registrations.

Nothing survives. The change you cared about is on main; everything else is gone.

Claude hands off with a confirmation of what was destroyed and points you at /fabric-feature-start <new-slug> for the next loop.

Reference

SkillTriggers (natural-language)What it wraps
fabric-feature-start"start a new feature called X", "/fabric-feature-start X"scripts/fabric dev start --profile model
fabric-feature-deploy"deploy it", "push to Fabric", "let me see it"scripts/deploy_to_feature.py + Power BI REST ExportTo
fabric-feature-pr"ship it", "PR it", "looks good — open the PR"mcp__azure-devops__repo_create_pull_request (no autocomplete)
fabric-feature-teardown"clean up X", "tear down X", "remove the feature env for X"scripts/fabric dev teardownterraform destroy

Related