@luquimbo/bi-superpowers 3.1.1 → 3.2.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 (107) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.claude-plugin/skill-manifest.json +1 -1
  4. package/.plugin/plugin.json +1 -1
  5. package/bin/build-plugin.js +6 -6
  6. package/bin/cli.js +169 -310
  7. package/bin/commands/install.js +87 -70
  8. package/bin/lib/agents.js +19 -0
  9. package/bin/lib/mcp-config.js +23 -4
  10. package/desktop-extension/manifest.json +4 -11
  11. package/desktop-extension/server.js +34 -25
  12. package/package.json +3 -9
  13. package/skills/pbi-connect/SKILL.md +1 -1
  14. package/skills/project-kickoff/SKILL.md +1 -1
  15. package/bin/commands/add.js +0 -533
  16. package/bin/commands/add.test.js +0 -77
  17. package/bin/commands/changelog.js +0 -443
  18. package/bin/commands/pull.js +0 -287
  19. package/bin/commands/pull.test.js +0 -36
  20. package/bin/commands/push.js +0 -231
  21. package/bin/commands/push.test.js +0 -14
  22. package/bin/commands/search.js +0 -344
  23. package/bin/commands/search.test.js +0 -115
  24. package/bin/commands/setup.js +0 -545
  25. package/bin/commands/setup.test.js +0 -46
  26. package/bin/commands/sync-profile.js +0 -405
  27. package/bin/commands/sync-profile.test.js +0 -14
  28. package/bin/commands/sync-source.js +0 -418
  29. package/bin/commands/sync-source.test.js +0 -14
  30. package/bin/utils/errors.js +0 -159
  31. package/bin/utils/git.js +0 -298
  32. package/bin/utils/logger.js +0 -142
  33. package/bin/utils/pbix.js +0 -305
  34. package/bin/utils/pbix.test.js +0 -37
  35. package/bin/utils/profiles.js +0 -312
  36. package/bin/utils/projects.js +0 -169
  37. package/bin/utils/readline.js +0 -206
  38. package/bin/utils/readline.test.js +0 -47
  39. package/docs/openrouter-free-models.md +0 -92
  40. package/library/examples/README.md +0 -151
  41. package/library/examples/finance-reporting/README.md +0 -351
  42. package/library/examples/finance-reporting/data-model.md +0 -267
  43. package/library/examples/finance-reporting/measures.dax +0 -557
  44. package/library/examples/hr-analytics/README.md +0 -371
  45. package/library/examples/hr-analytics/data-model.md +0 -315
  46. package/library/examples/hr-analytics/measures.dax +0 -460
  47. package/library/examples/marketing-analytics/README.md +0 -37
  48. package/library/examples/marketing-analytics/data-model.md +0 -62
  49. package/library/examples/marketing-analytics/measures.dax +0 -110
  50. package/library/examples/retail-analytics/README.md +0 -439
  51. package/library/examples/retail-analytics/data-model.md +0 -288
  52. package/library/examples/retail-analytics/measures.dax +0 -481
  53. package/library/examples/supply-chain/README.md +0 -37
  54. package/library/examples/supply-chain/data-model.md +0 -69
  55. package/library/examples/supply-chain/measures.dax +0 -77
  56. package/library/examples/udf-library/README.md +0 -228
  57. package/library/examples/udf-library/functions.dax +0 -571
  58. package/library/snippets/dax/README.md +0 -292
  59. package/library/snippets/dax/business-domains.md +0 -576
  60. package/library/snippets/dax/calculate-patterns.md +0 -276
  61. package/library/snippets/dax/calculation-groups.md +0 -489
  62. package/library/snippets/dax/error-handling.md +0 -495
  63. package/library/snippets/dax/iterators-and-aggregations.md +0 -474
  64. package/library/snippets/dax/kpis-and-metrics.md +0 -293
  65. package/library/snippets/dax/rankings-and-topn.md +0 -235
  66. package/library/snippets/dax/security-patterns.md +0 -413
  67. package/library/snippets/dax/text-and-formatting.md +0 -316
  68. package/library/snippets/dax/time-intelligence.md +0 -196
  69. package/library/snippets/dax/user-defined-functions.md +0 -477
  70. package/library/snippets/dax/virtual-tables.md +0 -546
  71. package/library/snippets/excel-formulas/README.md +0 -84
  72. package/library/snippets/excel-formulas/aggregations.md +0 -330
  73. package/library/snippets/excel-formulas/dates-and-times.md +0 -361
  74. package/library/snippets/excel-formulas/dynamic-arrays.md +0 -314
  75. package/library/snippets/excel-formulas/lookups.md +0 -169
  76. package/library/snippets/excel-formulas/text-functions.md +0 -363
  77. package/library/snippets/governance/naming-conventions.md +0 -97
  78. package/library/snippets/governance/review-checklists.md +0 -107
  79. package/library/snippets/power-query/README.md +0 -389
  80. package/library/snippets/power-query/api-integration.md +0 -707
  81. package/library/snippets/power-query/connections.md +0 -434
  82. package/library/snippets/power-query/data-cleaning.md +0 -298
  83. package/library/snippets/power-query/error-handling.md +0 -526
  84. package/library/snippets/power-query/parameters.md +0 -350
  85. package/library/snippets/power-query/performance.md +0 -506
  86. package/library/snippets/power-query/transformations.md +0 -330
  87. package/library/snippets/report-design/accessibility.md +0 -78
  88. package/library/snippets/report-design/chart-selection.md +0 -54
  89. package/library/snippets/report-design/layout-patterns.md +0 -87
  90. package/library/templates/data-models/README.md +0 -93
  91. package/library/templates/data-models/finance-model.md +0 -627
  92. package/library/templates/data-models/retail-star-schema.md +0 -473
  93. package/library/templates/excel/README.md +0 -83
  94. package/library/templates/excel/budget-tracker.md +0 -432
  95. package/library/templates/excel/data-entry-form.md +0 -533
  96. package/library/templates/power-bi/README.md +0 -72
  97. package/library/templates/power-bi/finance-report.md +0 -449
  98. package/library/templates/power-bi/kpi-scorecard.md +0 -461
  99. package/library/templates/power-bi/sales-dashboard.md +0 -281
  100. package/library/themes/excel/README.md +0 -436
  101. package/library/themes/power-bi/README.md +0 -271
  102. package/library/themes/power-bi/accessible.json +0 -307
  103. package/library/themes/power-bi/bi-superpowers-default.json +0 -858
  104. package/library/themes/power-bi/corporate-blue.json +0 -291
  105. package/library/themes/power-bi/dark-mode.json +0 -291
  106. package/library/themes/power-bi/minimal.json +0 -292
  107. package/library/themes/power-bi/print-friendly.json +0 -309
@@ -1,474 +0,0 @@
1
- # Iterator Functions and Advanced Aggregations
2
-
3
- Patterns for SUMX, AVERAGEX, MAXX, MINX, COUNTX, and related iterator functions.
4
-
5
- ---
6
-
7
- ## Basic Iterator Patterns
8
-
9
- ### SUMX - Row-by-Row Calculation
10
-
11
- ```dax
12
- -- Calculate extended price (quantity × unit price)
13
- Revenue =
14
- SUMX(
15
- Sales,
16
- Sales[Quantity] * Sales[UnitPrice]
17
- )
18
- ```
19
-
20
- ```dax
21
- -- With discount applied
22
- Revenue_Net =
23
- SUMX(
24
- Sales,
25
- Sales[Quantity] * Sales[UnitPrice] * (1 - Sales[Discount])
26
- )
27
- ```
28
-
29
- ### AVERAGEX - Average of Calculated Values
30
-
31
- ```dax
32
- -- Average order value
33
- Avg_Order_Value =
34
- AVERAGEX(
35
- VALUES(Sales[OrderID]),
36
- CALCULATE(SUM(Sales[Amount]))
37
- )
38
- ```
39
-
40
- ```dax
41
- -- Average unit price weighted by quantity
42
- Weighted_Avg_Price =
43
- DIVIDE(
44
- SUMX(Sales, Sales[Quantity] * Sales[UnitPrice]),
45
- SUM(Sales[Quantity])
46
- )
47
- ```
48
-
49
- ### MAXX/MINX - Extremes of Calculated Values
50
-
51
- ```dax
52
- -- Highest single transaction
53
- Max_Transaction =
54
- MAXX(
55
- Sales,
56
- Sales[Quantity] * Sales[UnitPrice]
57
- )
58
- ```
59
-
60
- ```dax
61
- -- Lowest performing product's sales
62
- Min_Product_Sales =
63
- MINX(
64
- VALUES(Products[ProductName]),
65
- CALCULATE(SUM(Sales[Amount]))
66
- )
67
- ```
68
-
69
- ```dax
70
- -- Best performing month
71
- Best_Month_Sales =
72
- MAXX(
73
- VALUES('Date'[MonthYear]),
74
- CALCULATE(SUM(Sales[Amount]))
75
- )
76
- ```
77
-
78
- ### COUNTX - Conditional Counting
79
-
80
- ```dax
81
- -- Count high-value transactions
82
- High_Value_Count =
83
- COUNTX(
84
- FILTER(Sales, Sales[Amount] > 1000),
85
- Sales[TransactionID]
86
- )
87
- ```
88
-
89
- ```dax
90
- -- Count profitable products
91
- Profitable_Products =
92
- COUNTX(
93
- FILTER(
94
- ALL(Products),
95
- CALCULATE([ProfitMargin]) > 0.15
96
- ),
97
- Products[ProductID]
98
- )
99
- ```
100
-
101
- ---
102
-
103
- ## Advanced Iterator Patterns
104
-
105
- ### Nested Iterators
106
-
107
- ```dax
108
- -- Total by customer by product (double iteration)
109
- Customer_Product_Total =
110
- SUMX(
111
- VALUES(Customers[CustomerName]),
112
- SUMX(
113
- VALUES(Products[ProductName]),
114
- CALCULATE(SUM(Sales[Amount]))
115
- )
116
- )
117
- ```
118
-
119
- ```dax
120
- -- Average of customer totals
121
- Avg_Customer_Total =
122
- AVERAGEX(
123
- VALUES(Customers[CustomerID]),
124
- CALCULATE(SUM(Sales[Amount]))
125
- )
126
- ```
127
-
128
- ### RANKX - Dynamic Rankings
129
-
130
- ```dax
131
- -- Rank products by sales
132
- Product_Rank =
133
- RANKX(
134
- ALL(Products[ProductName]),
135
- CALCULATE(SUM(Sales[Amount])),
136
- ,
137
- DESC,
138
- DENSE
139
- )
140
- ```
141
-
142
- ```dax
143
- -- Rank within category
144
- Product_Rank_InCategory =
145
- RANKX(
146
- ALLEXCEPT(Products, Products[Category]),
147
- CALCULATE(SUM(Sales[Amount])),
148
- ,
149
- DESC,
150
- DENSE
151
- )
152
- ```
153
-
154
- ```dax
155
- -- Dynamic rank (respects filters)
156
- Product_Rank_Dynamic =
157
- IF(
158
- HASONEVALUE(Products[ProductName]),
159
- RANKX(
160
- ALLSELECTED(Products[ProductName]),
161
- CALCULATE(SUM(Sales[Amount])),
162
- ,
163
- DESC,
164
- DENSE
165
- )
166
- )
167
- ```
168
-
169
- ### CONCATENATEX - String Aggregation
170
-
171
- ```dax
172
- -- List of products purchased
173
- Products_Purchased =
174
- CONCATENATEX(
175
- VALUES(Products[ProductName]),
176
- Products[ProductName],
177
- ", ",
178
- Products[ProductName], ASC
179
- )
180
- ```
181
-
182
- ```dax
183
- -- Top 3 products by sales
184
- Top3_Products =
185
- CONCATENATEX(
186
- TOPN(
187
- 3,
188
- VALUES(Products[ProductName]),
189
- CALCULATE(SUM(Sales[Amount])),
190
- DESC
191
- ),
192
- Products[ProductName],
193
- ", ",
194
- CALCULATE(SUM(Sales[Amount])), DESC
195
- )
196
- ```
197
-
198
- ### PRODUCTX - Compound Growth
199
-
200
- ```dax
201
- -- Compound monthly growth rate
202
- CAGR =
203
- VAR _StartValue = CALCULATE(SUM(Sales[Amount]), FIRSTDATE('Date'[Date]))
204
- VAR _EndValue = CALCULATE(SUM(Sales[Amount]), LASTDATE('Date'[Date]))
205
- VAR _Periods = DATEDIFF(MIN('Date'[Date]), MAX('Date'[Date]), YEAR)
206
- RETURN
207
- IF(
208
- _Periods > 0 && _StartValue > 0,
209
- POWER(DIVIDE(_EndValue, _StartValue), DIVIDE(1, _Periods)) - 1
210
- )
211
- ```
212
-
213
- ```dax
214
- -- Geometric mean of growth rates
215
- Geometric_Avg_Growth =
216
- VAR _GrowthTable =
217
- ADDCOLUMNS(
218
- SUMMARIZE(Sales, 'Date'[Year]),
219
- "@Growth", 1 + DIVIDE(
220
- CALCULATE(SUM(Sales[Amount])) - CALCULATE(SUM(Sales[Amount]), PREVIOUSYEAR('Date'[Date])),
221
- CALCULATE(SUM(Sales[Amount]), PREVIOUSYEAR('Date'[Date]))
222
- )
223
- )
224
- VAR _Product =
225
- PRODUCTX(
226
- FILTER(_GrowthTable, [@Growth] > 0),
227
- [@Growth]
228
- )
229
- VAR _Count =
230
- COUNTROWS(FILTER(_GrowthTable, [@Growth] > 0))
231
- RETURN
232
- IF(_Count > 0, POWER(_Product, 1 / _Count) - 1)
233
- ```
234
-
235
- ---
236
-
237
- ## Performance-Optimized Patterns
238
-
239
- ### Using Variables with Iterators
240
-
241
- ```dax
242
- -- Optimized: Store table reference in variable
243
- Revenue_Optimized =
244
- VAR _SalesTable = Sales
245
- RETURN
246
- SUMX(
247
- _SalesTable,
248
- [Quantity] * [UnitPrice]
249
- )
250
- ```
251
-
252
- ```dax
253
- -- Avoid recalculating in iterator
254
- Margin_Optimized =
255
- VAR _TotalCost = SUM(Sales[Cost])
256
- VAR _TotalRevenue = SUM(Sales[Revenue])
257
- RETURN
258
- DIVIDE(_TotalRevenue - _TotalCost, _TotalRevenue)
259
- ```
260
-
261
- ### GENERATE vs Nested SUMX
262
-
263
- ```dax
264
- -- Using GENERATE for better performance
265
- Sales_Analysis =
266
- VAR _CustomerSales =
267
- GENERATE(
268
- VALUES(Customers[CustomerID]),
269
- ROW("@Sales", CALCULATE(SUM(Sales[Amount])))
270
- )
271
- RETURN
272
- AVERAGEX(_CustomerSales, [@Sales])
273
- ```
274
-
275
- ### ADDCOLUMNS for Pre-Calculation
276
-
277
- ```dax
278
- -- Pre-calculate values before iteration
279
- Avg_Profit_Margin =
280
- VAR _ProductMetrics =
281
- ADDCOLUMNS(
282
- ALL(Products[ProductName]),
283
- "@Revenue", CALCULATE(SUM(Sales[Amount])),
284
- "@Cost", CALCULATE(SUM(Sales[Cost]))
285
- )
286
- RETURN
287
- AVERAGEX(
288
- _ProductMetrics,
289
- DIVIDE([@Revenue] - [@Cost], [@Revenue])
290
- )
291
- ```
292
-
293
- ---
294
-
295
- ## Statistical Functions
296
-
297
- ### Standard Deviation (Sample)
298
-
299
- ```dax
300
- StdDev_Sales =
301
- VAR _Avg = AVERAGEX(VALUES('Date'[Month]), CALCULATE(SUM(Sales[Amount])))
302
- VAR _Variance =
303
- AVERAGEX(
304
- VALUES('Date'[Month]),
305
- POWER(CALCULATE(SUM(Sales[Amount])) - _Avg, 2)
306
- )
307
- RETURN
308
- SQRT(_Variance)
309
- ```
310
-
311
- ### Median Using MEDIANX
312
-
313
- ```dax
314
- Median_Order_Value =
315
- MEDIANX(
316
- VALUES(Sales[OrderID]),
317
- CALCULATE(SUM(Sales[Amount]))
318
- )
319
- ```
320
-
321
- ### Percentile Calculation
322
-
323
- ```dax
324
- Percentile_75_Sales =
325
- VAR _AllCustomerSales =
326
- ADDCOLUMNS(
327
- VALUES(Customers[CustomerID]),
328
- "@Sales", CALCULATE(SUM(Sales[Amount]))
329
- )
330
- VAR _75thPercentile =
331
- PERCENTILEX.INC(_AllCustomerSales, [@Sales], 0.75)
332
- RETURN
333
- _75thPercentile
334
- ```
335
-
336
- ### Coefficient of Variation
337
-
338
- ```dax
339
- CV_Sales =
340
- VAR _Avg = AVERAGEX(VALUES('Date'[Month]), CALCULATE(SUM(Sales[Amount])))
341
- VAR _StdDev =
342
- SQRT(
343
- AVERAGEX(
344
- VALUES('Date'[Month]),
345
- POWER(CALCULATE(SUM(Sales[Amount])) - _Avg, 2)
346
- )
347
- )
348
- RETURN
349
- DIVIDE(_StdDev, _Avg)
350
- ```
351
-
352
- ---
353
-
354
- ## FILTER vs Iterator Performance
355
-
356
- ### When to Use FILTER
357
-
358
- ```dax
359
- -- Good: FILTER with simple column condition (foldable)
360
- Sales_HighValue =
361
- CALCULATE(
362
- SUM(Sales[Amount]),
363
- Sales[Amount] > 1000
364
- )
365
-
366
- -- Better than iterator when filtering on columns
367
- ```
368
-
369
- ### When to Use Iterator
370
-
371
- ```dax
372
- -- Good: Complex row-by-row calculation
373
- Net_Revenue =
374
- SUMX(
375
- Sales,
376
- (Sales[Quantity] * Sales[UnitPrice]) - Sales[Discount] - Sales[Tax]
377
- )
378
-
379
- -- Necessary when calculation spans multiple columns per row
380
- ```
381
-
382
- ### Hybrid Approach
383
-
384
- ```dax
385
- -- Combine for best performance
386
- Profitable_Revenue =
387
- SUMX(
388
- FILTER(
389
- Sales,
390
- Sales[ProfitFlag] = TRUE() -- Simple filter first
391
- ),
392
- Sales[Quantity] * Sales[UnitPrice] * (1 - Sales[Discount]) -- Then iterate
393
- )
394
- ```
395
-
396
- ---
397
-
398
- ## Common Mistakes to Avoid
399
-
400
- ### Mistake 1: Unnecessary Context Transition
401
-
402
- ```dax
403
- -- Bad: Forces context transition on every row
404
- Revenue_Bad =
405
- SUMX(
406
- Sales,
407
- CALCULATE(Sales[Quantity] * Sales[UnitPrice])
408
- )
409
-
410
- -- Good: No CALCULATE needed
411
- Revenue_Good =
412
- SUMX(
413
- Sales,
414
- Sales[Quantity] * Sales[UnitPrice]
415
- )
416
- ```
417
-
418
- ### Mistake 2: Iterating Over Wrong Table
419
-
420
- ```dax
421
- -- Bad: Iterates over entire table
422
- Avg_Product_Sales_Bad =
423
- AVERAGEX(
424
- Sales, -- Wrong! Iterates every row
425
- Sales[Amount]
426
- )
427
-
428
- -- Good: Iterate over unique products
429
- Avg_Product_Sales_Good =
430
- AVERAGEX(
431
- VALUES(Products[ProductName]), -- Correct: One iteration per product
432
- CALCULATE(SUM(Sales[Amount]))
433
- )
434
- ```
435
-
436
- ### Mistake 3: Missing ALL in Rankings
437
-
438
- ```dax
439
- -- Bad: Rank doesn't work correctly with filters
440
- Rank_Bad =
441
- RANKX(
442
- Products, -- Wrong! Affected by filter context
443
- [Sales]
444
- )
445
-
446
- -- Good: Use ALL for consistent ranking
447
- Rank_Good =
448
- RANKX(
449
- ALL(Products[ProductName]), -- Correct: Ranks all products
450
- CALCULATE(SUM(Sales[Amount]))
451
- )
452
- ```
453
-
454
- ---
455
-
456
- ## Usage Notes
457
-
458
- 1. **Iterator functions iterate row by row** - They're powerful but can be slow on large tables
459
- 2. **Use simple aggregations when possible** - SUM, AVERAGE, COUNT are faster than iterators
460
- 3. **Pre-filter tables** - Use FILTER before SUMX to reduce iterations
461
- 4. **Store repeated calculations in variables** - Avoid recalculating inside iterators
462
- 5. **Use ADDCOLUMNS/GENERATE** - Create virtual tables for complex multi-step calculations
463
- 6. **DENSE vs SKIP in RANKX** - DENSE: no gaps; SKIP: gaps for ties
464
-
465
- ## Performance Guidelines
466
-
467
- | Operation | Rows | Performance |
468
- |-----------|------|-------------|
469
- | SUMX/AVERAGEX | < 100K | Fast |
470
- | SUMX/AVERAGEX | 100K - 1M | Monitor |
471
- | SUMX/AVERAGEX | > 1M | Optimize |
472
- | Nested iterators | Any | Expensive |
473
- | RANKX with ALL | < 10K unique | Fast |
474
- | RANKX with ALL | > 10K unique | Monitor |