Case Study: Automating Power BI Report Localisation on a Live Mining Programme
Client and context
The client is a global engineering group delivering the electrical, control and instrumentation (EC&I) scope on a Southern African mining programme. FaolanIQ supports the account's project controls and reporting function, including a suite of Power BI reports used for financial and programme reporting. Part of the client's group reporting structure required the same report suite to serve a Swedish-language stakeholder audience, without maintaining two parallel report builds.
Problem
Power BI's built-in locale mechanism (captions) only covers object names in the semantic model, and only displays when a user's device locale matches the target culture. It does not touch the report layer at all. A Power BI report carries English in two independent places that must both be fixed: the semantic model (table, column and measure names, hardcoded data values, DAX expressions) and the report definition (visual titles, field labels, text boxes, slicer headers, page and bookmark names). The report layer has its own trap: every visual field label is driven by an internal nativeQueryRef identifier that Power BI shows verbatim whenever no explicit displayName override is set, and captions do not override it. A caption-only pass leaves most on-screen labels in English. Manual translation is also fragile: changing an English data value without checking every measure that compares against it silently breaks SWITCH and IF statements and conditional formatting, returning blanks or wrong colours with no error. A spot-check scan of "the obvious pages" reliably misses most of the English in a report of any real size.
Approach
FaolanIQ's Dynamo account agent designed and built a repeatable, tooled localisation pipeline rather than translating by hand. The core of it is a purpose-built MCP server (a small local tool server that plugs new, specific capabilities into an AI coding assistant, so it can call exact functions instead of guessing at text in a file). This translation-audit server exposes three tools: scan_english_remaining, scan_missing_displaynames and validate_translation_coverage, giving a machine-checkable PASS or FAIL verdict on translation completeness rather than relying on a human eyeballing every page. Its language detection is not hard-coded to one locale: it ships character-set rules for ten target languages, making the tooling reusable on future localisation work.
Around that audit server, Dynamo built two automated fix scripts: pbip_translate_display_names.py, which bulk-injects the correct displayName override onto every field carrying an English nativeQueryRef, and pbip_fix_visual_titles.py, which repairs auto-generated visual titles and slicer headers that Power BI silently regenerates in English when no explicit title text is set. Both draw on a domain-specific dictionary built for this engagement: 109 mapped financial-reporting terms plus a 60-entry skip list of values that must never be touched (abbreviations such as FC, BU, ACT and PY, internal formatting measures, proper nouns), so the automation cannot silently break a calculation or colour rule while translating a label. The method is a written playbook: a pre-flight inventory step plus ten execution phases, nine for the semantic model layer, one for the report-definition layer. The result is a scan-fix-verify loop: scan finds the gaps, the scripts fix them in bulk against the dictionary, the audit server verifies, and the loop repeats until PASS.
Outcome
The engagement produced a reusable toolchain, not a single-use fix: a 457-line audit server with three MCP tools and ten-language detection, two fix scripts totalling 567 lines, a 109-term/60-exception domain dictionary, and a ten-phase playbook. The build was disciplined enough to generate 47 documented lessons learned (20 semantic-model, 13 report-layer, 14 field-label and scripting), each folded back into the scripts and dictionary so the same mistake is caught automatically next time rather than rediscovered by hand. Every translation pass now has an objective acceptance gate: validate_translation_coverage only returns PASS when zero suspected-English strings and zero unresolved missing-label gaps remain, replacing subjective "looks done" sign-off with a machine-checked one.
What this demonstrates
This is FaolanIQ's operating model in miniature: an account agent (Dynamo) that builds durable, auditable tooling around a real client problem instead of a one-off report, encodes the domain knowledge (which terms translate, which must never be touched) into a reusable asset, and replaces manual quality checks with an automated verification gate. The same pattern, purpose-built MCP tooling plus a scan-fix-verify loop plus a lessons-learned register, transfers directly to other reporting, data-quality and localisation problems across the FaolanIQ client portfolio.
