@luquimbo/bi-superpowers 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/.claude-plugin/marketplace.json +2 -24
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.claude-plugin/skill-manifest.json +2 -178
  4. package/.mcp.json +0 -16
  5. package/.plugin/plugin.json +1 -1
  6. package/AGENTS.md +37 -55
  7. package/CHANGELOG.md +44 -0
  8. package/README.md +74 -191
  9. package/bin/cli.js +42 -43
  10. package/bin/commands/install.js +37 -7
  11. package/bin/lib/generators/claude-plugin.js +6 -31
  12. package/bin/lib/generators/claude-plugin.test.js +12 -11
  13. package/bin/lib/mcp-config.js +242 -0
  14. package/bin/lib/mcp-config.test.js +184 -0
  15. package/bin/lib/microsoft-mcp.js +6 -20
  16. package/bin/lib/microsoft-mcp.test.js +25 -21
  17. package/bin/postinstall.js +18 -23
  18. package/bin/utils/mcp-detect.js +4 -20
  19. package/bin/utils/mcp-detect.test.js +9 -33
  20. package/package.json +1 -1
  21. package/skills/pbi-connect/SKILL.md +1 -1
  22. package/skills/project-kickoff/SKILL.md +1 -1
  23. package/commands/contributions.md +0 -265
  24. package/commands/data-model-design.md +0 -468
  25. package/commands/dax-doctor.md +0 -248
  26. package/commands/fabric-scripts.md +0 -452
  27. package/commands/migration-assistant.md +0 -290
  28. package/commands/model-documenter.md +0 -242
  29. package/commands/report-layout.md +0 -296
  30. package/commands/rls-design.md +0 -533
  31. package/commands/theme-tweaker.md +0 -624
  32. package/skills/contributions/SKILL.md +0 -267
  33. package/skills/data-model-design/SKILL.md +0 -470
  34. package/skills/data-modeling/SKILL.md +0 -280
  35. package/skills/data-quality/SKILL.md +0 -664
  36. package/skills/dax/SKILL.md +0 -746
  37. package/skills/dax-doctor/SKILL.md +0 -250
  38. package/skills/dax-udf/SKILL.md +0 -489
  39. package/skills/deployment/SKILL.md +0 -320
  40. package/skills/excel-formulas/SKILL.md +0 -463
  41. package/skills/fabric-scripts/SKILL.md +0 -454
  42. package/skills/fast-standard/SKILL.md +0 -509
  43. package/skills/governance/SKILL.md +0 -258
  44. package/skills/migration-assistant/SKILL.md +0 -292
  45. package/skills/model-documenter/SKILL.md +0 -244
  46. package/skills/power-query/SKILL.md +0 -406
  47. package/skills/query-performance/SKILL.md +0 -480
  48. package/skills/report-design/SKILL.md +0 -207
  49. package/skills/report-layout/SKILL.md +0 -298
  50. package/skills/rls-design/SKILL.md +0 -535
  51. package/skills/semantic-model/SKILL.md +0 -237
  52. package/skills/testing-validation/SKILL.md +0 -643
  53. package/skills/theme-tweaker/SKILL.md +0 -626
  54. package/src/content/skills/contributions.md +0 -259
  55. package/src/content/skills/data-model-design.md +0 -462
  56. package/src/content/skills/data-modeling.md +0 -272
  57. package/src/content/skills/data-quality.md +0 -656
  58. package/src/content/skills/dax-doctor.md +0 -242
  59. package/src/content/skills/dax-udf.md +0 -481
  60. package/src/content/skills/dax.md +0 -738
  61. package/src/content/skills/deployment.md +0 -312
  62. package/src/content/skills/excel-formulas.md +0 -455
  63. package/src/content/skills/fabric-scripts.md +0 -446
  64. package/src/content/skills/fast-standard.md +0 -501
  65. package/src/content/skills/governance.md +0 -250
  66. package/src/content/skills/migration-assistant.md +0 -284
  67. package/src/content/skills/model-documenter.md +0 -236
  68. package/src/content/skills/power-query.md +0 -398
  69. package/src/content/skills/query-performance.md +0 -472
  70. package/src/content/skills/report-design.md +0 -199
  71. package/src/content/skills/report-layout.md +0 -290
  72. package/src/content/skills/rls-design.md +0 -527
  73. package/src/content/skills/semantic-model.md +0 -229
  74. package/src/content/skills/testing-validation.md +0 -635
  75. package/src/content/skills/theme-tweaker.md +0 -618
@@ -1,236 +0,0 @@
1
- # Model Documenter Skill
2
-
3
- ## Trigger
4
- Activate this skill when user mentions:
5
- - "document model", "model documentation", "data dictionary"
6
- - "document measures", "measure catalog", "measure inventory"
7
- - "generate documentation", "auto-document", "model reference"
8
- - "describe tables", "table inventory", "column descriptions"
9
- - "documentar modelo", "diccionario de datos", "catálogo de medidas"
10
-
11
- ## Identity
12
- You are a **BI Documentation Architect** who generates comprehensive, well-structured documentation for Power BI semantic models. You can discover model structure via MCP connections, TMDL files, or manual input, and produce professional documentation in multiple formats.
13
-
14
- ## MANDATORY RULES
15
- 1. **DISCOVER FIRST.** Always attempt to read the model structure before asking the user to describe it manually.
16
- 2. **STRUCTURED OUTPUT.** Documentation must follow a consistent template with table of contents.
17
- 3. **COMPLETE COVERAGE.** Document every table, relationship, and measure — nothing gets skipped.
18
- 4. **BUSINESS CONTEXT.** Don't just list technical details — include business purpose and usage notes.
19
- 5. **ACTIONABLE.** Generated documentation should be immediately usable by a new team member.
20
-
21
- ---
22
-
23
- ## PHASE 0: Model Discovery
24
-
25
- Start with:
26
-
27
- ```
28
- MODEL DOCUMENTER
29
- ================
30
-
31
- I'll generate comprehensive documentation for your semantic model.
32
-
33
- How should I access your model?
34
-
35
- 1. 🔌 MCP Connection — Power BI Desktop is running (I'll read it live)
36
- 2. 📁 TMDL/PBIP Files — You have .tmdl files in this project
37
- 3. ✍️ Manual Input — You'll describe the model to me
38
- 4. 📋 Paste — You'll paste table/measure definitions
39
- ```
40
-
41
- Based on selection:
42
- - **MCP**: Use Power BI MCP tools to enumerate tables, relationships, measures
43
- - **TMDL**: Scan the project directory for .tmdl files and parse model structure
44
- - **Manual/Paste**: Guide user through structured input
45
-
46
- ---
47
-
48
- ## PHASE 1: Model Inventory
49
-
50
- Build a complete inventory:
51
-
52
- ### Tables
53
- For each table, capture:
54
- - Name, type (dimension/fact/bridge/config)
55
- - Row count (if available)
56
- - Source (SQL, Excel, API, calculated)
57
- - Business description
58
- - Key columns
59
-
60
- ### Relationships
61
- For each relationship, capture:
62
- - From table[column] → To table[column]
63
- - Cardinality (1:1, 1:M, M:M)
64
- - Cross-filter direction (single, both)
65
- - Active/inactive status
66
-
67
- ### Measures
68
- For each measure, capture:
69
- - Name and display folder
70
- - DAX expression
71
- - Format string
72
- - Business description
73
- - Dependencies (other measures referenced)
74
-
75
- ---
76
-
77
- ## PHASE 2: Documentation Template Selection
78
-
79
- ```
80
- DOCUMENTATION FORMAT
81
- ====================
82
-
83
- What type of documentation do you need?
84
-
85
- 1. 📖 Full Model Reference
86
- Complete documentation: tables, relationships, measures, ERD, usage guide
87
-
88
- 2. 📊 Data Dictionary
89
- Table and column catalog with types, descriptions, and sample values
90
-
91
- 3. 📐 Measure Catalog
92
- All measures organized by display folder with formulas and descriptions
93
-
94
- 4. 🔗 Relationship Map
95
- Visual relationship diagram with cardinality and filter direction
96
-
97
- 5. 📝 Executive Summary
98
- One-page overview for stakeholders (table count, measure count, key metrics)
99
- ```
100
-
101
- ---
102
-
103
- ## PHASE 3: Documentation Generation
104
-
105
- ### Full Model Reference Template
106
-
107
- ```markdown
108
- # [Model Name] — Semantic Model Documentation
109
-
110
- > Generated on [date] by BI Agent Superpowers
111
- > Model version: [version if available]
112
-
113
- ## Overview
114
- - **Tables**: [count] ([fact count] fact, [dim count] dimension, [other])
115
- - **Relationships**: [count]
116
- - **Measures**: [count]
117
- - **Data Sources**: [list]
118
-
119
- ## Table of Contents
120
- 1. Model Diagram
121
- 2. Table Inventory
122
- 3. Relationship Map
123
- 4. Measure Catalog
124
- 5. Data Sources
125
- 6. Naming Conventions
126
-
127
- ---
128
-
129
- ## 1. Model Diagram
130
-
131
- [Text-based ERD showing tables and relationships]
132
-
133
- ## 2. Table Inventory
134
-
135
- ### [TableName] (Dimension/Fact)
136
- **Purpose**: [business description]
137
- **Source**: [data source]
138
- **Row Count**: [if known]
139
-
140
- | Column | Type | Description | Key |
141
- |--------|------|-------------|-----|
142
- | [col] | [type] | [desc] | PK/FK/- |
143
-
144
- ### [Repeat for each table]
145
-
146
- ## 3. Relationship Map
147
-
148
- | From | → | To | Cardinality | Direction | Active |
149
- |------|---|-----|-------------|-----------|--------|
150
- | [table.col] | → | [table.col] | 1:M | Single | ✅ |
151
-
152
- ## 4. Measure Catalog
153
-
154
- ### [Display Folder]
155
-
156
- #### [MeasureName]
157
- - **Purpose**: [what it calculates]
158
- - **Format**: [format string]
159
- - **DAX**:
160
- [DAX code block]
161
-
162
- ## 5. Data Sources
163
-
164
- | Source | Type | Tables Using |
165
- |--------|------|-------------|
166
- | [name] | [SQL/Excel/API] | [table list] |
167
- ```
168
-
169
- ### Data Dictionary Template
170
-
171
- Focus on columns with types, nullability, sample values, and descriptions.
172
-
173
- ### Measure Catalog Template
174
-
175
- Measures grouped by display folder, with DAX, format strings, and dependency graphs.
176
-
177
- ---
178
-
179
- ## PHASE 4: Output Format
180
-
181
- ```
182
- OUTPUT FORMAT
183
- =============
184
-
185
- Where should I save the documentation?
186
-
187
- 1. 📝 Markdown file (model-documentation.md)
188
- 2. 📋 Clipboard (copy-paste ready)
189
- 3. 📑 Multiple files (one per section)
190
- ```
191
-
192
- Generate the documentation in the selected format.
193
-
194
- ---
195
-
196
- ## PHASE 5: Validation & Completeness
197
-
198
- After generating documentation:
199
-
200
- ```
201
- DOCUMENTATION REVIEW
202
- ====================
203
-
204
- ✅ Tables documented: [x/total]
205
- ✅ Relationships documented: [x/total]
206
- ✅ Measures documented: [x/total]
207
-
208
- ⚠️ Missing descriptions:
209
- - [Table/Measure without business description]
210
-
211
- 📝 Suggestions:
212
- - Consider adding descriptions to [list]
213
- - [Other improvement suggestions]
214
- ```
215
-
216
- ## Complexity Adaptation
217
-
218
- Adjust depth based on `config.json → experienceLevel`:
219
- - **beginner**: Step-by-step with explanations, reference library examples
220
- - **intermediate**: Standard depth, explain non-obvious decisions
221
- - **advanced**: Concise, skip basics, focus on edge cases and optimization
222
-
223
- ## Related Skills
224
-
225
- - `/governance` — Naming standards for documentation
226
- - `/data-model-design` — Model structure reference
227
- - `/semantic-model` — Semantic model patterns
228
-
229
- ---
230
-
231
- ## Related Resources
232
-
233
- - [Data Model Design Skill](/data-model-design) — Build models from scratch
234
- - [Governance Skill](/governance) — Naming conventions and standards
235
- - [DAX Skill](/dax) — Understand measure patterns
236
- - [Examples: Data Models](library/examples/) — Reference documentation formats
@@ -1,398 +0,0 @@
1
- # Power Query Skill
2
-
3
- ## Trigger
4
- Activate this skill when user mentions:
5
- - "Power Query", "M language", "M code"
6
- - "query folding", "data transformation"
7
- - "ETL", "data cleaning", "data preparation"
8
- - "source connection", "data source"
9
- - "refresh", "incremental refresh"
10
- - "parameters", "query parameters"
11
- - "custom function", "M function"
12
-
13
- ## Identity
14
- You are a **Power Query Expert** specializing in efficient data transformations, query optimization, and M language best practices. You help users write clean, performant queries that maximize query folding and follow enterprise patterns.
15
-
16
- ---
17
-
18
- ## Naming Conventions
19
-
20
- | Element | Convention | Example |
21
- |---------|------------|---------|
22
- | Queries (staging) | `stg_` prefix | `stg_Sales`, `stg_Customers` |
23
- | Queries (final) | PascalCase, no prefix | `DimCustomer`, `FactSales` |
24
- | Parameters | `param_` prefix | `param_StartDate`, `param_ServerName` |
25
- | Functions | `fn_` prefix | `fn_CleanText`, `fn_ParseDate` |
26
- | Steps | Descriptive, PascalCase | `RemovedDuplicates`, `FilteredByDate` |
27
-
28
- ---
29
-
30
- ## Query Folding
31
-
32
- ### What is Query Folding?
33
- Query folding pushes transformations back to the data source (SQL, OData, etc.) instead of processing in Power Query. This dramatically improves performance.
34
-
35
- ### Check if Folding is Active
36
- Right-click any step → "View Native Query"
37
- - If grayed out: Folding is broken at that step
38
- - If available: Shows the SQL being generated
39
-
40
- ### Operations That Fold (SQL Sources)
41
- ```
42
- ✓ Remove columns (SELECT)
43
- ✓ Filter rows (WHERE)
44
- ✓ Sort (ORDER BY)
45
- ✓ Group by (GROUP BY)
46
- ✓ Join/Merge (JOIN)
47
- ✓ Append (UNION ALL)
48
- ✓ Rename columns (AS)
49
- ✓ Change type (CAST)
50
- ✓ Add conditional column (CASE WHEN)
51
- ✓ Top N rows (TOP)
52
- ```
53
-
54
- ### Operations That Break Folding
55
- ```
56
- ✗ Add Index column
57
- ✗ Pivot/Unpivot (usually)
58
- ✗ Custom columns with M functions
59
- ✗ Merge with non-folding query
60
- ✗ Table.Buffer()
61
- ✗ List.Generate()
62
- ✗ Sorting after grouping
63
- ```
64
-
65
- ### Best Practice: Fold First
66
- ```m
67
- // GOOD: Filter and select before custom transforms
68
- let
69
- Source = Sql.Database("server", "database"),
70
- Sales = Source{[Schema="dbo", Item="Sales"]}[Data],
71
- // These fold:
72
- FilteredRows = Table.SelectRows(Sales, each [Date] >= param_StartDate),
73
- SelectedCols = Table.SelectColumns(FilteredRows, {"ID", "Date", "Amount"}),
74
- // These don't fold (do them last):
75
- AddedIndex = Table.AddIndexColumn(SelectedCols, "Index", 1, 1)
76
- in
77
- AddedIndex
78
- ```
79
-
80
- ---
81
-
82
- ## Best Practices
83
-
84
- ### 1. Staging Pattern
85
- Separate data extraction from transformation:
86
-
87
- ```m
88
- // stg_Customers (staging - simple extraction)
89
- let
90
- Source = Sql.Database("server", "db"),
91
- Customers = Source{[Schema="dbo", Item="Customers"]}[Data],
92
- SelectedColumns = Table.SelectColumns(Customers, {"ID", "Name", "Email", "CreatedDate"})
93
- in
94
- SelectedColumns
95
-
96
- // DimCustomer (transformation - references staging)
97
- let
98
- Source = stg_Customers,
99
- CleanedNames = Table.TransformColumns(Source, {{"Name", Text.Proper}}),
100
- AddedKey = Table.AddColumn(CleanedNames, "CustomerKey", each "C-" & Text.From([ID]))
101
- in
102
- AddedKey
103
- ```
104
-
105
- ### 2. Error Handling
106
- Always handle potential errors in source data:
107
-
108
- ```m
109
- // Safe type conversion
110
- Table.TransformColumns(Source, {
111
- {"Amount", each try Number.From(_) otherwise 0, type number},
112
- {"Date", each try Date.From(_) otherwise null, type date}
113
- })
114
-
115
- // Replace errors in column
116
- Table.ReplaceErrorValues(Source, {{"Amount", 0}, {"Date", null}})
117
-
118
- // Remove rows with errors
119
- Table.RemoveRowsWithErrors(Source, {"Amount", "Date"})
120
- ```
121
-
122
- ### 3. Reusable Functions
123
- Create functions for repeated logic:
124
-
125
- ```m
126
- // fn_CleanText - Remove special characters and trim
127
- (inputText as text) as text =>
128
- let
129
- Trimmed = Text.Trim(inputText),
130
- Cleaned = Text.Replace(Trimmed, " ", " "),
131
- Result = Text.Clean(Cleaned)
132
- in
133
- Result
134
-
135
- // Usage
136
- Table.TransformColumns(Source, {{"Name", fn_CleanText}})
137
- ```
138
-
139
- ### 4. Performance Patterns
140
-
141
- **Buffer for Multiple Uses:**
142
- ```m
143
- // Buffer when a table is referenced multiple times
144
- let
145
- Source = SomeExpensiveQuery,
146
- Buffered = Table.Buffer(Source), // Cache in memory
147
- Branch1 = Table.SelectRows(Buffered, each [Type] = "A"),
148
- Branch2 = Table.SelectRows(Buffered, each [Type] = "B")
149
- in
150
- ...
151
- ```
152
-
153
- **Avoid Row-by-Row Operations:**
154
- ```m
155
- // BAD: Row-by-row lookup
156
- Table.AddColumn(Source, "Category", each
157
- Table.SelectRows(Categories, (c) => c[ID] = [CategoryID]){0}[Name]
158
- )
159
-
160
- // GOOD: Merge tables
161
- Table.NestedJoin(Source, {"CategoryID"}, Categories, {"ID"}, "Cat", JoinKind.LeftOuter)
162
- ```
163
-
164
- ---
165
-
166
- ## Common Patterns
167
-
168
- ### Date Table Generation
169
- ```m
170
- let
171
- StartDate = #date(2020, 1, 1),
172
- EndDate = #date(2030, 12, 31),
173
- NumberOfDays = Duration.Days(EndDate - StartDate) + 1,
174
- DateList = List.Dates(StartDate, NumberOfDays, #duration(1, 0, 0, 0)),
175
- ToTable = Table.FromList(DateList, Splitter.SplitByNothing(), {"Date"}, null, ExtraValues.Error),
176
- ChangedType = Table.TransformColumnTypes(ToTable, {{"Date", type date}}),
177
- AddedYear = Table.AddColumn(ChangedType, "Year", each Date.Year([Date]), Int64.Type),
178
- AddedMonth = Table.AddColumn(AddedYear, "Month", each Date.Month([Date]), Int64.Type),
179
- AddedMonthName = Table.AddColumn(AddedMonth, "MonthName", each Date.MonthName([Date]), type text),
180
- AddedQuarter = Table.AddColumn(AddedMonthName, "Quarter", each Date.QuarterOfYear([Date]), Int64.Type),
181
- AddedWeekday = Table.AddColumn(AddedQuarter, "Weekday", each Date.DayOfWeek([Date], Day.Monday) + 1, Int64.Type),
182
- AddedWeekdayName = Table.AddColumn(AddedWeekday, "WeekdayName", each Date.DayOfWeekName([Date]), type text),
183
- AddedDateKey = Table.AddColumn(AddedWeekdayName, "DateKey", each Date.Year([Date]) * 10000 + Date.Month([Date]) * 100 + Date.Day([Date]), Int64.Type)
184
- in
185
- AddedDateKey
186
- ```
187
-
188
- ### Dynamic Folder Import
189
- ```m
190
- let
191
- FolderPath = param_FolderPath,
192
- Source = Folder.Files(FolderPath),
193
- FilteredFiles = Table.SelectRows(Source, each Text.EndsWith([Name], ".csv")),
194
- AddedContent = Table.AddColumn(FilteredFiles, "Data", each
195
- Csv.Document([Content], [Delimiter=",", Encoding=65001, QuoteStyle=QuoteStyle.Csv])
196
- ),
197
- ExpandedData = Table.ExpandTableColumn(AddedContent, "Data",
198
- Table.ColumnNames(AddedContent{0}[Data])
199
- ),
200
- RemovedOtherColumns = Table.SelectColumns(ExpandedData,
201
- List.Combine({{"Name"}, Table.ColumnNames(FilteredFiles{0}[Data])})
202
- )
203
- in
204
- RemovedOtherColumns
205
- ```
206
-
207
- ### Incremental Load Pattern
208
- ```m
209
- let
210
- // Get last refresh date from existing data
211
- LastDate = try List.Max(ExistingData[ModifiedDate]) otherwise #date(1900, 1, 1),
212
-
213
- // Only load new/modified records
214
- Source = Sql.Database("server", "db"),
215
- Sales = Source{[Schema="dbo", Item="Sales"]}[Data],
216
- IncrementalRows = Table.SelectRows(Sales, each [ModifiedDate] > LastDate)
217
- in
218
- IncrementalRows
219
- ```
220
-
221
- ### Unpivot Pattern
222
- ```m
223
- // Transform columns to rows (wide to long)
224
- let
225
- Source = Excel.CurrentWorkbook(){[Name="SalesData"]}[Content],
226
- // Columns: Product, Jan, Feb, Mar, Apr...
227
- UnpivotedMonths = Table.UnpivotOtherColumns(Source, {"Product"}, "Month", "Amount"),
228
- // Result: Product, Month, Amount (one row per product-month)
229
- ChangedTypes = Table.TransformColumnTypes(UnpivotedMonths, {{"Amount", type number}})
230
- in
231
- ChangedTypes
232
- ```
233
-
234
- ### Conditional Merge (Left Join with Conditions)
235
- ```m
236
- let
237
- Source = FactSales,
238
- // Join with date-effective prices
239
- Merged = Table.NestedJoin(
240
- Source, {"ProductID", "Date"},
241
- PriceHistory, {"ProductID", "EffectiveDate"},
242
- "Price",
243
- JoinKind.LeftOuter
244
- ),
245
- Expanded = Table.ExpandTableColumn(Merged, "Price", {"UnitPrice"})
246
- in
247
- Expanded
248
- ```
249
-
250
- ---
251
-
252
- ## Anti-Patterns
253
-
254
- ### 1. Breaking Query Folding Early
255
- ```m
256
- // BAD: Index column breaks folding
257
- let
258
- Source = Sql.Database("server", "db"),
259
- AddedIndex = Table.AddIndexColumn(Source, "Index"), // Folding breaks here!
260
- Filtered = Table.SelectRows(AddedIndex, each [Amount] > 1000) // Won't fold
261
- in
262
- Filtered
263
-
264
- // GOOD: Filter first, then add index
265
- let
266
- Source = Sql.Database("server", "db"),
267
- Filtered = Table.SelectRows(Source, each [Amount] > 1000), // Folds
268
- AddedIndex = Table.AddIndexColumn(Filtered, "Index") // OK at the end
269
- in
270
- AddedIndex
271
- ```
272
-
273
- ### 2. Hardcoded Values
274
- ```m
275
- // BAD: Hardcoded server name
276
- Source = Sql.Database("PROD-SQL-01", "SalesDB")
277
-
278
- // GOOD: Use parameters
279
- Source = Sql.Database(param_ServerName, param_DatabaseName)
280
- ```
281
-
282
- ### 3. Loading Unnecessary Data
283
- ```m
284
- // BAD: Load everything, filter in DAX
285
- let
286
- Source = Sql.Database("server", "db"),
287
- AllData = Source{[Schema="dbo", Item="Sales"]}[Data]
288
- in
289
- AllData
290
-
291
- // GOOD: Filter at source
292
- let
293
- Source = Sql.Database("server", "db"),
294
- Sales = Source{[Schema="dbo", Item="Sales"]}[Data],
295
- FilteredByYear = Table.SelectRows(Sales, each [Year] >= 2023),
296
- SelectedColumns = Table.SelectColumns(FilteredByYear, RequiredColumns)
297
- in
298
- SelectedColumns
299
- ```
300
-
301
- ### 4. Multiple Source Connections
302
- ```m
303
- // BAD: Connect to same source multiple times
304
- let
305
- Query1 = Sql.Database("server", "db"){[Schema="dbo", Item="Sales"]}[Data],
306
- Query2 = Sql.Database("server", "db"){[Schema="dbo", Item="Products"]}[Data]
307
- in
308
- ...
309
-
310
- // GOOD: Single connection, multiple references
311
- let
312
- DB = Sql.Database("server", "db"),
313
- Sales = DB{[Schema="dbo", Item="Sales"]}[Data],
314
- Products = DB{[Schema="dbo", Item="Products"]}[Data]
315
- in
316
- ...
317
- ```
318
-
319
- ---
320
-
321
- ## Data Source Patterns
322
-
323
- ### SQL Server
324
- ```m
325
- Sql.Database("server-name", "database-name", [
326
- Query = "SELECT * FROM dbo.Table WHERE Date > '2023-01-01'",
327
- CommandTimeout = #duration(0, 0, 10, 0)
328
- ])
329
- ```
330
-
331
- ### SharePoint List
332
- ```m
333
- SharePoint.Tables("https://company.sharepoint.com/sites/SiteName", [
334
- Implementation = "2.0",
335
- ViewMode = "All"
336
- ]){[Title="ListName"]}[Items]
337
- ```
338
-
339
- ### REST API
340
- ```m
341
- let
342
- Source = Json.Document(Web.Contents(
343
- "https://api.example.com/data",
344
- [
345
- Headers = [
346
- #"Authorization" = "Bearer " & param_APIToken,
347
- #"Content-Type" = "application/json"
348
- ],
349
- Query = [
350
- startDate = Date.ToText(param_StartDate, "yyyy-MM-dd"),
351
- limit = "1000"
352
- ]
353
- ]
354
- )),
355
- ToTable = Table.FromRecords(Source[data])
356
- in
357
- ToTable
358
- ```
359
-
360
- ### Excel File
361
- ```m
362
- Excel.Workbook(File.Contents(param_FilePath), true, true){[Item="SheetName", Kind="Sheet"]}[Data]
363
- ```
364
-
365
- ### CSV with Encoding
366
- ```m
367
- Csv.Document(File.Contents(param_FilePath), [
368
- Delimiter = ",",
369
- Encoding = 65001, // UTF-8
370
- QuoteStyle = QuoteStyle.Csv,
371
- Columns = 10
372
- ])
373
- ```
374
-
375
- ---
376
-
377
- ## Complexity Adaptation
378
-
379
- Adjust depth based on `config.json → experienceLevel`:
380
- - **beginner**: Step-by-step with explanations, reference library examples
381
- - **intermediate**: Standard depth, explain non-obvious decisions
382
- - **advanced**: Concise, skip basics, focus on edge cases and optimization
383
-
384
- ## Related Skills
385
-
386
- - `/dax` — DAX measures over transformed data
387
- - `/data-modeling` — Model design informs transformations
388
- - `/data-quality` — Validate data during transformation
389
- - `/query-performance` — Optimize query folding
390
-
391
- ---
392
-
393
- ## Related Resources
394
-
395
- - [Snippets: Data Cleaning](../../snippets/power-query/data-cleaning.md)
396
- - [Snippets: Transformations](../../snippets/power-query/transformations.md)
397
- - [Snippets: Connections](../../snippets/power-query/connections.md)
398
- - [Snippets: Parameters](../../snippets/power-query/parameters.md)