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/<slug>"]
DEPLOY["/fabric-feature-deploy <slug>"]
REVIEW{"You review in Fabric"}
PR["/fabric-feature-pr <slug>"]
MERGE{"You approve + Complete<br/>the PR in ADO"}
TEARDOWN["/fabric-feature-teardown <slug>"]
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-cicdto 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>-Semanticandfeat-<slug>-Reportsworkspaces in Fabric - Creates and pushes branch
feature/<slug> - Deploys the current
mainbaseline 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_nameover 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 viascripts/docs/scan_system.py(path mapping inscripts/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:
- 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 thesp-fabric-platform-adminauthor; Claude willgit fetch + reset --hardif needed to absorb those commits before opening the PR) - Opens a pull request from
feature/<slug>→mainviamcp__azure-devops__repo_create_pull_request, with the Fabric workspace URLs and screenshot list in the body - Does NOT set autocomplete. You stay in control of the merge.
Claude hands off with your post-PR checklist:
- Open the Fabric Reports workspace one more time — confirm the rendered report still matches what you agreed in the deploy loop.
- In ADO, tick the reviewer checklist, click Approve, then Complete.
- Wait for the post-merge
mainbuild to go green. This is the CLAUDE.md rule 5 ("monitor every deployment end-to-end"). If anything fails, ping Claude. - Once
mainis 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:
- Verifies via
mcp__azure-devops__repo_list_pull_requests_by_repo_or_projectthat the PR forfeature/<slug>is Completed or Abandoned. - (Recommended) Verifies the post-merge
mainbuild is green viamcp__azure-devops__pipelines_get_builds. - Runs
bash scripts/fabric dev teardown <slug> --force, which dispatches toscripts/teardown_feature_env.sh. This actually destroys the Fabric workspaces — under the hood it runsterraform destroyagainst the feature's tfstate, removing:- The Fabric workspaces
feat-<slug>-Semantic,feat-<slug>-Reports(plusGold/Bronzeif the profile created them) - The Gold Warehouse + Lakehouse + Bronze shortcuts (full profile)
- The Function App (functions profile)
- All git connections and workspace role assignments
- The Fabric workspaces
- Deletes the Terraform state blob
feat-<slug>.tfstatefrom Azure Blob Storage. - Removes
deployment/feat-<slug>.yml+deployment/parameter-feat-<slug>.ymland commits that cleanup tomain. - Deletes the local + remote
feature/<slug>branch. - 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
| Skill | Triggers (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 teardown → terraform destroy |
Related
- Developer Workflow — the general flow for dbt / pipelines / infra changes
- Feature Provisioning Profiles — what each
--profilevalue provisions - Developer Dashboard — the web UI alternative to the CLI for the same commands
- AI Knowledge Base — the
.mex/scaffold that backs AI sessions