@luquimbo/bi-superpowers 2.0.1 → 3.0.1

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 (76) 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 +59 -8
  11. package/bin/commands/install.test.js +77 -0
  12. package/bin/lib/generators/claude-plugin.js +6 -31
  13. package/bin/lib/generators/claude-plugin.test.js +12 -11
  14. package/bin/lib/mcp-config.js +287 -0
  15. package/bin/lib/mcp-config.test.js +273 -0
  16. package/bin/lib/microsoft-mcp.js +6 -20
  17. package/bin/lib/microsoft-mcp.test.js +25 -21
  18. package/bin/postinstall.js +18 -23
  19. package/bin/utils/mcp-detect.js +4 -20
  20. package/bin/utils/mcp-detect.test.js +9 -33
  21. package/package.json +1 -1
  22. package/skills/pbi-connect/SKILL.md +1 -1
  23. package/skills/project-kickoff/SKILL.md +1 -1
  24. package/commands/contributions.md +0 -265
  25. package/commands/data-model-design.md +0 -468
  26. package/commands/dax-doctor.md +0 -248
  27. package/commands/fabric-scripts.md +0 -452
  28. package/commands/migration-assistant.md +0 -290
  29. package/commands/model-documenter.md +0 -242
  30. package/commands/report-layout.md +0 -296
  31. package/commands/rls-design.md +0 -533
  32. package/commands/theme-tweaker.md +0 -624
  33. package/skills/contributions/SKILL.md +0 -267
  34. package/skills/data-model-design/SKILL.md +0 -470
  35. package/skills/data-modeling/SKILL.md +0 -280
  36. package/skills/data-quality/SKILL.md +0 -664
  37. package/skills/dax/SKILL.md +0 -746
  38. package/skills/dax-doctor/SKILL.md +0 -250
  39. package/skills/dax-udf/SKILL.md +0 -489
  40. package/skills/deployment/SKILL.md +0 -320
  41. package/skills/excel-formulas/SKILL.md +0 -463
  42. package/skills/fabric-scripts/SKILL.md +0 -454
  43. package/skills/fast-standard/SKILL.md +0 -509
  44. package/skills/governance/SKILL.md +0 -258
  45. package/skills/migration-assistant/SKILL.md +0 -292
  46. package/skills/model-documenter/SKILL.md +0 -244
  47. package/skills/power-query/SKILL.md +0 -406
  48. package/skills/query-performance/SKILL.md +0 -480
  49. package/skills/report-design/SKILL.md +0 -207
  50. package/skills/report-layout/SKILL.md +0 -298
  51. package/skills/rls-design/SKILL.md +0 -535
  52. package/skills/semantic-model/SKILL.md +0 -237
  53. package/skills/testing-validation/SKILL.md +0 -643
  54. package/skills/theme-tweaker/SKILL.md +0 -626
  55. package/src/content/skills/contributions.md +0 -259
  56. package/src/content/skills/data-model-design.md +0 -462
  57. package/src/content/skills/data-modeling.md +0 -272
  58. package/src/content/skills/data-quality.md +0 -656
  59. package/src/content/skills/dax-doctor.md +0 -242
  60. package/src/content/skills/dax-udf.md +0 -481
  61. package/src/content/skills/dax.md +0 -738
  62. package/src/content/skills/deployment.md +0 -312
  63. package/src/content/skills/excel-formulas.md +0 -455
  64. package/src/content/skills/fabric-scripts.md +0 -446
  65. package/src/content/skills/fast-standard.md +0 -501
  66. package/src/content/skills/governance.md +0 -250
  67. package/src/content/skills/migration-assistant.md +0 -284
  68. package/src/content/skills/model-documenter.md +0 -236
  69. package/src/content/skills/power-query.md +0 -398
  70. package/src/content/skills/query-performance.md +0 -472
  71. package/src/content/skills/report-design.md +0 -199
  72. package/src/content/skills/report-layout.md +0 -290
  73. package/src/content/skills/rls-design.md +0 -527
  74. package/src/content/skills/semantic-model.md +0 -229
  75. package/src/content/skills/testing-validation.md +0 -635
  76. 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)