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