@luquimbo/bi-superpowers 1.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 (193) hide show
  1. package/.claude-plugin/plugin.json +8 -0
  2. package/.mcp.json +25 -0
  3. package/AGENTS.md +244 -0
  4. package/CHANGELOG.md +265 -0
  5. package/LICENSE +21 -0
  6. package/README.md +211 -0
  7. package/bin/build-plugin.js +30 -0
  8. package/bin/cli.js +1064 -0
  9. package/bin/commands/add.js +533 -0
  10. package/bin/commands/add.test.js +77 -0
  11. package/bin/commands/build-desktop.js +166 -0
  12. package/bin/commands/changelog.js +443 -0
  13. package/bin/commands/diff.js +325 -0
  14. package/bin/commands/lint.js +419 -0
  15. package/bin/commands/lint.test.js +103 -0
  16. package/bin/commands/mcp-setup.js +246 -0
  17. package/bin/commands/pull.js +287 -0
  18. package/bin/commands/pull.test.js +36 -0
  19. package/bin/commands/push.js +231 -0
  20. package/bin/commands/push.test.js +14 -0
  21. package/bin/commands/search.js +344 -0
  22. package/bin/commands/search.test.js +115 -0
  23. package/bin/commands/setup.js +545 -0
  24. package/bin/commands/setup.test.js +46 -0
  25. package/bin/commands/sync-profile.js +405 -0
  26. package/bin/commands/sync-profile.test.js +14 -0
  27. package/bin/commands/sync-source.js +418 -0
  28. package/bin/commands/sync-source.test.js +14 -0
  29. package/bin/commands/watch.js +206 -0
  30. package/bin/lib/generators/claude-plugin.js +266 -0
  31. package/bin/lib/generators/claude-plugin.test.js +110 -0
  32. package/bin/lib/generators/index.js +116 -0
  33. package/bin/lib/generators/shared.js +282 -0
  34. package/bin/lib/licensing/index.js +35 -0
  35. package/bin/lib/licensing/storage.js +364 -0
  36. package/bin/lib/licensing/storage.test.js +55 -0
  37. package/bin/lib/licensing/validator.js +213 -0
  38. package/bin/lib/licensing/validator.test.js +137 -0
  39. package/bin/lib/microsoft-mcp.js +176 -0
  40. package/bin/lib/microsoft-mcp.test.js +106 -0
  41. package/bin/lib/skills.js +84 -0
  42. package/bin/mcp/powerbi-modeling-launcher.js +38 -0
  43. package/bin/postinstall.js +44 -0
  44. package/bin/utils/errors.js +159 -0
  45. package/bin/utils/git.js +298 -0
  46. package/bin/utils/logger.js +142 -0
  47. package/bin/utils/mcp-detect.js +274 -0
  48. package/bin/utils/mcp-detect.test.js +105 -0
  49. package/bin/utils/pbix.js +305 -0
  50. package/bin/utils/pbix.test.js +37 -0
  51. package/bin/utils/profiles.js +312 -0
  52. package/bin/utils/projects.js +168 -0
  53. package/bin/utils/readline.js +206 -0
  54. package/bin/utils/readline.test.js +47 -0
  55. package/bin/utils/tui.js +314 -0
  56. package/bin/utils/tui.test.js +127 -0
  57. package/commands/contributions.md +265 -0
  58. package/commands/data-model-design.md +468 -0
  59. package/commands/dax-doctor.md +248 -0
  60. package/commands/fabric-scripts.md +452 -0
  61. package/commands/migration-assistant.md +290 -0
  62. package/commands/model-documenter.md +242 -0
  63. package/commands/pbi-connect.md +239 -0
  64. package/commands/project-kickoff.md +905 -0
  65. package/commands/report-layout.md +296 -0
  66. package/commands/rls-design.md +533 -0
  67. package/commands/theme-tweaker.md +624 -0
  68. package/config.example.json +23 -0
  69. package/config.json +23 -0
  70. package/desktop-extension/manifest.json +37 -0
  71. package/desktop-extension/package.json +10 -0
  72. package/desktop-extension/server.js +95 -0
  73. package/docs/openrouter-free-models.md +92 -0
  74. package/library/examples/README.md +151 -0
  75. package/library/examples/finance-reporting/README.md +351 -0
  76. package/library/examples/finance-reporting/data-model.md +267 -0
  77. package/library/examples/finance-reporting/measures.dax +557 -0
  78. package/library/examples/hr-analytics/README.md +371 -0
  79. package/library/examples/hr-analytics/data-model.md +315 -0
  80. package/library/examples/hr-analytics/measures.dax +460 -0
  81. package/library/examples/marketing-analytics/README.md +37 -0
  82. package/library/examples/marketing-analytics/data-model.md +62 -0
  83. package/library/examples/marketing-analytics/measures.dax +110 -0
  84. package/library/examples/retail-analytics/README.md +439 -0
  85. package/library/examples/retail-analytics/data-model.md +288 -0
  86. package/library/examples/retail-analytics/measures.dax +481 -0
  87. package/library/examples/supply-chain/README.md +37 -0
  88. package/library/examples/supply-chain/data-model.md +69 -0
  89. package/library/examples/supply-chain/measures.dax +77 -0
  90. package/library/examples/udf-library/README.md +228 -0
  91. package/library/examples/udf-library/functions.dax +571 -0
  92. package/library/snippets/dax/README.md +292 -0
  93. package/library/snippets/dax/business-domains.md +576 -0
  94. package/library/snippets/dax/calculate-patterns.md +276 -0
  95. package/library/snippets/dax/calculation-groups.md +489 -0
  96. package/library/snippets/dax/error-handling.md +495 -0
  97. package/library/snippets/dax/iterators-and-aggregations.md +474 -0
  98. package/library/snippets/dax/kpis-and-metrics.md +293 -0
  99. package/library/snippets/dax/rankings-and-topn.md +235 -0
  100. package/library/snippets/dax/security-patterns.md +413 -0
  101. package/library/snippets/dax/text-and-formatting.md +316 -0
  102. package/library/snippets/dax/time-intelligence.md +196 -0
  103. package/library/snippets/dax/user-defined-functions.md +477 -0
  104. package/library/snippets/dax/virtual-tables.md +546 -0
  105. package/library/snippets/excel-formulas/README.md +84 -0
  106. package/library/snippets/excel-formulas/aggregations.md +330 -0
  107. package/library/snippets/excel-formulas/dates-and-times.md +361 -0
  108. package/library/snippets/excel-formulas/dynamic-arrays.md +314 -0
  109. package/library/snippets/excel-formulas/lookups.md +169 -0
  110. package/library/snippets/excel-formulas/text-functions.md +363 -0
  111. package/library/snippets/governance/naming-conventions.md +97 -0
  112. package/library/snippets/governance/review-checklists.md +107 -0
  113. package/library/snippets/power-query/README.md +389 -0
  114. package/library/snippets/power-query/api-integration.md +707 -0
  115. package/library/snippets/power-query/connections.md +434 -0
  116. package/library/snippets/power-query/data-cleaning.md +298 -0
  117. package/library/snippets/power-query/error-handling.md +526 -0
  118. package/library/snippets/power-query/parameters.md +350 -0
  119. package/library/snippets/power-query/performance.md +506 -0
  120. package/library/snippets/power-query/transformations.md +330 -0
  121. package/library/snippets/report-design/accessibility.md +78 -0
  122. package/library/snippets/report-design/chart-selection.md +54 -0
  123. package/library/snippets/report-design/layout-patterns.md +87 -0
  124. package/library/templates/data-models/README.md +93 -0
  125. package/library/templates/data-models/finance-model.md +627 -0
  126. package/library/templates/data-models/retail-star-schema.md +473 -0
  127. package/library/templates/excel/README.md +83 -0
  128. package/library/templates/excel/budget-tracker.md +432 -0
  129. package/library/templates/excel/data-entry-form.md +533 -0
  130. package/library/templates/power-bi/README.md +72 -0
  131. package/library/templates/power-bi/finance-report.md +449 -0
  132. package/library/templates/power-bi/kpi-scorecard.md +461 -0
  133. package/library/templates/power-bi/sales-dashboard.md +281 -0
  134. package/library/themes/excel/README.md +436 -0
  135. package/library/themes/power-bi/README.md +271 -0
  136. package/library/themes/power-bi/accessible.json +307 -0
  137. package/library/themes/power-bi/bi-superpowers-default.json +858 -0
  138. package/library/themes/power-bi/corporate-blue.json +291 -0
  139. package/library/themes/power-bi/dark-mode.json +291 -0
  140. package/library/themes/power-bi/minimal.json +292 -0
  141. package/library/themes/power-bi/print-friendly.json +309 -0
  142. package/package.json +93 -0
  143. package/skills/contributions/SKILL.md +267 -0
  144. package/skills/data-model-design/SKILL.md +470 -0
  145. package/skills/data-modeling/SKILL.md +254 -0
  146. package/skills/data-quality/SKILL.md +664 -0
  147. package/skills/dax/SKILL.md +708 -0
  148. package/skills/dax-doctor/SKILL.md +250 -0
  149. package/skills/dax-udf/SKILL.md +489 -0
  150. package/skills/deployment/SKILL.md +320 -0
  151. package/skills/excel-formulas/SKILL.md +463 -0
  152. package/skills/fabric-scripts/SKILL.md +454 -0
  153. package/skills/fast-standard/SKILL.md +509 -0
  154. package/skills/governance/SKILL.md +205 -0
  155. package/skills/migration-assistant/SKILL.md +292 -0
  156. package/skills/model-documenter/SKILL.md +244 -0
  157. package/skills/pbi-connect/SKILL.md +241 -0
  158. package/skills/power-query/SKILL.md +406 -0
  159. package/skills/project-kickoff/SKILL.md +907 -0
  160. package/skills/query-performance/SKILL.md +480 -0
  161. package/skills/report-design/SKILL.md +207 -0
  162. package/skills/report-layout/SKILL.md +298 -0
  163. package/skills/rls-design/SKILL.md +535 -0
  164. package/skills/semantic-model/SKILL.md +237 -0
  165. package/skills/testing-validation/SKILL.md +643 -0
  166. package/skills/theme-tweaker/SKILL.md +626 -0
  167. package/src/content/base.md +237 -0
  168. package/src/content/mcp-requirements.json +69 -0
  169. package/src/content/routing.md +203 -0
  170. package/src/content/skills/contributions.md +259 -0
  171. package/src/content/skills/data-model-design.md +462 -0
  172. package/src/content/skills/data-modeling.md +246 -0
  173. package/src/content/skills/data-quality.md +656 -0
  174. package/src/content/skills/dax-doctor.md +242 -0
  175. package/src/content/skills/dax-udf.md +481 -0
  176. package/src/content/skills/dax.md +700 -0
  177. package/src/content/skills/deployment.md +312 -0
  178. package/src/content/skills/excel-formulas.md +455 -0
  179. package/src/content/skills/fabric-scripts.md +446 -0
  180. package/src/content/skills/fast-standard.md +501 -0
  181. package/src/content/skills/governance.md +197 -0
  182. package/src/content/skills/migration-assistant.md +284 -0
  183. package/src/content/skills/model-documenter.md +236 -0
  184. package/src/content/skills/pbi-connect.md +233 -0
  185. package/src/content/skills/power-query.md +398 -0
  186. package/src/content/skills/project-kickoff.md +899 -0
  187. package/src/content/skills/query-performance.md +472 -0
  188. package/src/content/skills/report-design.md +199 -0
  189. package/src/content/skills/report-layout.md +290 -0
  190. package/src/content/skills/rls-design.md +527 -0
  191. package/src/content/skills/semantic-model.md +229 -0
  192. package/src/content/skills/testing-validation.md +635 -0
  193. package/src/content/skills/theme-tweaker.md +618 -0
@@ -0,0 +1,481 @@
1
+ // ============================================================================
2
+ // RETAIL ANALYTICS - DAX MEASURE LIBRARY
3
+ // ============================================================================
4
+ // Organized by category for easy navigation and maintenance
5
+ // All measures follow BI Agent Superpowers naming conventions
6
+ // ============================================================================
7
+
8
+
9
+ // ----------------------------------------------------------------------------
10
+ // BASE MEASURES
11
+ // ----------------------------------------------------------------------------
12
+
13
+ Revenue =
14
+ SUM(FactSales[Amount])
15
+
16
+ Cost =
17
+ SUMX(
18
+ FactSales,
19
+ FactSales[Quantity] * RELATED(DimProduct[UnitCost])
20
+ )
21
+
22
+ Profit =
23
+ [Revenue] - [Cost]
24
+
25
+ Profit Margin % =
26
+ DIVIDE([Profit], [Revenue])
27
+
28
+ Quantity =
29
+ SUM(FactSales[Quantity])
30
+
31
+ Transactions =
32
+ COUNTROWS(FactSales)
33
+
34
+ Avg Order Value =
35
+ DIVIDE([Revenue], [Transactions])
36
+
37
+ Avg Unit Price =
38
+ DIVIDE([Revenue], [Quantity])
39
+
40
+
41
+ // ----------------------------------------------------------------------------
42
+ // TIME INTELLIGENCE - YEAR-TO-DATE
43
+ // ----------------------------------------------------------------------------
44
+
45
+ Revenue YTD =
46
+ TOTALYTD([Revenue], DimDate[Date])
47
+
48
+ Profit YTD =
49
+ TOTALYTD([Profit], DimDate[Date])
50
+
51
+ Quantity YTD =
52
+ TOTALYTD([Quantity], DimDate[Date])
53
+
54
+
55
+ // ----------------------------------------------------------------------------
56
+ // TIME INTELLIGENCE - PRIOR YEAR
57
+ // ----------------------------------------------------------------------------
58
+
59
+ Revenue PY =
60
+ CALCULATE(
61
+ [Revenue],
62
+ SAMEPERIODLASTYEAR(DimDate[Date])
63
+ )
64
+
65
+ Profit PY =
66
+ CALCULATE(
67
+ [Profit],
68
+ SAMEPERIODLASTYEAR(DimDate[Date])
69
+ )
70
+
71
+ Revenue YTD PY =
72
+ CALCULATE(
73
+ [Revenue YTD],
74
+ SAMEPERIODLASTYEAR(DimDate[Date])
75
+ )
76
+
77
+
78
+ // ----------------------------------------------------------------------------
79
+ // TIME INTELLIGENCE - GROWTH RATES
80
+ // ----------------------------------------------------------------------------
81
+
82
+ Revenue YoY % =
83
+ VAR _Current = [Revenue]
84
+ VAR _PY = [Revenue PY]
85
+ RETURN
86
+ DIVIDE(_Current - _PY, _PY)
87
+
88
+ Revenue YoY Var =
89
+ [Revenue] - [Revenue PY]
90
+
91
+ Profit YoY % =
92
+ VAR _Current = [Profit]
93
+ VAR _PY = [Profit PY]
94
+ RETURN
95
+ DIVIDE(_Current - _PY, _PY)
96
+
97
+ Revenue YTD YoY % =
98
+ VAR _Current = [Revenue YTD]
99
+ VAR _PY = [Revenue YTD PY]
100
+ RETURN
101
+ DIVIDE(_Current - _PY, _PY)
102
+
103
+
104
+ // ----------------------------------------------------------------------------
105
+ // TIME INTELLIGENCE - ROLLING PERIODS
106
+ // ----------------------------------------------------------------------------
107
+
108
+ Revenue R3M =
109
+ CALCULATE(
110
+ [Revenue],
111
+ DATESINPERIOD(DimDate[Date], MAX(DimDate[Date]), -3, MONTH)
112
+ )
113
+
114
+ Revenue R12M =
115
+ CALCULATE(
116
+ [Revenue],
117
+ DATESINPERIOD(DimDate[Date], MAX(DimDate[Date]), -12, MONTH)
118
+ )
119
+
120
+ Revenue R3M Avg =
121
+ AVERAGEX(
122
+ DATESINPERIOD(DimDate[Date], MAX(DimDate[Date]), -3, MONTH),
123
+ [Revenue]
124
+ )
125
+
126
+
127
+ // ----------------------------------------------------------------------------
128
+ // TIME INTELLIGENCE - MONTH COMPARISONS
129
+ // ----------------------------------------------------------------------------
130
+
131
+ Revenue PM =
132
+ CALCULATE(
133
+ [Revenue],
134
+ PREVIOUSMONTH(DimDate[Date])
135
+ )
136
+
137
+ Revenue MoM % =
138
+ VAR _Current = [Revenue]
139
+ VAR _PM = [Revenue PM]
140
+ RETURN
141
+ DIVIDE(_Current - _PM, _PM)
142
+
143
+
144
+ // ----------------------------------------------------------------------------
145
+ // RANKINGS
146
+ // ----------------------------------------------------------------------------
147
+
148
+ Product Rank =
149
+ IF(
150
+ HASONEVALUE(DimProduct[ProductName]),
151
+ RANKX(
152
+ ALL(DimProduct[ProductName]),
153
+ [Revenue],
154
+ ,
155
+ DESC,
156
+ DENSE
157
+ )
158
+ )
159
+
160
+ Store Rank =
161
+ IF(
162
+ HASONEVALUE(DimStore[StoreName]),
163
+ RANKX(
164
+ ALL(DimStore[StoreName]),
165
+ [Revenue],
166
+ ,
167
+ DESC,
168
+ DENSE
169
+ )
170
+ )
171
+
172
+ Customer Rank =
173
+ IF(
174
+ HASONEVALUE(DimCustomer[CustomerName]),
175
+ RANKX(
176
+ ALL(DimCustomer[CustomerName]),
177
+ [Revenue],
178
+ ,
179
+ DESC,
180
+ DENSE
181
+ )
182
+ )
183
+
184
+ Category Rank =
185
+ IF(
186
+ HASONEVALUE(DimProduct[Category]),
187
+ RANKX(
188
+ ALL(DimProduct[Category]),
189
+ [Revenue],
190
+ ,
191
+ DESC,
192
+ DENSE
193
+ )
194
+ )
195
+
196
+
197
+ // ----------------------------------------------------------------------------
198
+ // TOP N CALCULATIONS
199
+ // ----------------------------------------------------------------------------
200
+
201
+ Revenue Top 10 Products =
202
+ CALCULATE(
203
+ [Revenue],
204
+ TOPN(10, ALL(DimProduct[ProductName]), [Revenue], DESC)
205
+ )
206
+
207
+ Revenue Top 5 Customers =
208
+ CALCULATE(
209
+ [Revenue],
210
+ TOPN(5, ALL(DimCustomer[CustomerName]), [Revenue], DESC)
211
+ )
212
+
213
+ Revenue Top 3 Stores =
214
+ CALCULATE(
215
+ [Revenue],
216
+ TOPN(3, ALL(DimStore[StoreName]), [Revenue], DESC)
217
+ )
218
+
219
+ // Percentage of top 10 products
220
+ Top 10 Products % =
221
+ DIVIDE(
222
+ [Revenue Top 10 Products],
223
+ CALCULATE([Revenue], ALL(DimProduct))
224
+ )
225
+
226
+
227
+ // ----------------------------------------------------------------------------
228
+ // PERCENTAGES & RATIOS
229
+ // ----------------------------------------------------------------------------
230
+
231
+ Revenue % of Total =
232
+ DIVIDE(
233
+ [Revenue],
234
+ CALCULATE([Revenue], ALL(FactSales))
235
+ )
236
+
237
+ Revenue % of Category =
238
+ DIVIDE(
239
+ [Revenue],
240
+ CALCULATE([Revenue], ALLEXCEPT(DimProduct, DimProduct[Category]))
241
+ )
242
+
243
+ Revenue % of Store =
244
+ DIVIDE(
245
+ [Revenue],
246
+ CALCULATE([Revenue], ALLEXCEPT(DimStore, DimStore[StoreName]))
247
+ )
248
+
249
+ Revenue % of Region =
250
+ DIVIDE(
251
+ [Revenue],
252
+ CALCULATE([Revenue], ALLEXCEPT(DimStore, DimStore[Region]))
253
+ )
254
+
255
+
256
+ // ----------------------------------------------------------------------------
257
+ // CUSTOMER METRICS
258
+ // ----------------------------------------------------------------------------
259
+
260
+ Customer Count =
261
+ DISTINCTCOUNT(FactSales[CustomerKey])
262
+
263
+ New Customers =
264
+ VAR _CurrentPeriodStart = MIN(DimDate[Date])
265
+ RETURN
266
+ CALCULATE(
267
+ DISTINCTCOUNT(FactSales[CustomerKey]),
268
+ FILTER(
269
+ ALL(DimCustomer),
270
+ DimCustomer[JoinDate] >= _CurrentPeriodStart
271
+ )
272
+ )
273
+
274
+ Repeat Customers =
275
+ VAR _CustomersThisPeriod = VALUES(FactSales[CustomerKey])
276
+ VAR _CustomersWithHistory =
277
+ FILTER(
278
+ _CustomersThisPeriod,
279
+ CALCULATE(
280
+ COUNTROWS(FactSales),
281
+ ALLEXCEPT(FactSales, FactSales[CustomerKey]),
282
+ DimDate[Date] < MIN(DimDate[Date])
283
+ ) > 0
284
+ )
285
+ RETURN
286
+ COUNTROWS(_CustomersWithHistory)
287
+
288
+ Revenue per Customer =
289
+ DIVIDE([Revenue], [Customer Count])
290
+
291
+
292
+ // ----------------------------------------------------------------------------
293
+ // PRODUCT METRICS
294
+ // ----------------------------------------------------------------------------
295
+
296
+ Product Count =
297
+ DISTINCTCOUNT(FactSales[ProductKey])
298
+
299
+ Active Products =
300
+ CALCULATE(
301
+ DISTINCTCOUNT(DimProduct[ProductKey]),
302
+ DimProduct[IsActive] = TRUE()
303
+ )
304
+
305
+ Units per Transaction =
306
+ DIVIDE([Quantity], [Transactions])
307
+
308
+ Basket Size =
309
+ AVERAGEX(
310
+ VALUES(FactSales[SalesKey]),
311
+ CALCULATE(DISTINCTCOUNT(FactSales[ProductKey]))
312
+ )
313
+
314
+
315
+ // ----------------------------------------------------------------------------
316
+ // STORE METRICS
317
+ // ----------------------------------------------------------------------------
318
+
319
+ Store Count =
320
+ DISTINCTCOUNT(FactSales[StoreKey])
321
+
322
+ Revenue per SqFt =
323
+ DIVIDE(
324
+ [Revenue],
325
+ SUM(DimStore[SquareFeet])
326
+ )
327
+
328
+ Revenue per Employee =
329
+ DIVIDE(
330
+ [Revenue],
331
+ SUM(DimStore[EmployeeCount])
332
+ )
333
+
334
+
335
+ // ----------------------------------------------------------------------------
336
+ // CONDITIONAL FORMATTING MEASURES
337
+ // ----------------------------------------------------------------------------
338
+
339
+ Revenue YoY Color =
340
+ VAR _YoY = [Revenue YoY %]
341
+ RETURN
342
+ SWITCH(
343
+ TRUE(),
344
+ ISBLANK(_YoY), "#A3A3A3", // Neutral gray
345
+ _YoY >= 0.1, "#166534", // Dark green - exceeds 10%
346
+ _YoY >= 0, "#22C55E", // Green - positive
347
+ _YoY >= -0.1, "#EAB308", // Yellow - slightly down
348
+ "#991B1B" // Dark red - down >10%
349
+ )
350
+
351
+ Profit Margin Color =
352
+ VAR _Margin = [Profit Margin %]
353
+ RETURN
354
+ SWITCH(
355
+ TRUE(),
356
+ ISBLANK(_Margin), "#A3A3A3",
357
+ _Margin >= 0.25, "#166534", // High margin
358
+ _Margin >= 0.15, "#22C55E", // Target margin
359
+ _Margin >= 0.10, "#EAB308", // Low margin
360
+ "#991B1B" // Critical margin
361
+ )
362
+
363
+ Trend Indicator =
364
+ VAR _YoY = [Revenue YoY %]
365
+ RETURN
366
+ SWITCH(
367
+ TRUE(),
368
+ ISBLANK(_YoY), "•",
369
+ _YoY >= 0.1, "▲▲",
370
+ _YoY >= 0, "▲",
371
+ _YoY >= -0.1, "▼",
372
+ "▼▼"
373
+ )
374
+
375
+
376
+ // ----------------------------------------------------------------------------
377
+ // DISPLAY / HELPER MEASURES
378
+ // ----------------------------------------------------------------------------
379
+
380
+ Revenue Display =
381
+ VAR _Value = [Revenue]
382
+ RETURN
383
+ IF(
384
+ _Value >= 1000000,
385
+ FORMAT(_Value / 1000000, "$#,##0.0") & "M",
386
+ IF(
387
+ _Value >= 1000,
388
+ FORMAT(_Value / 1000, "$#,##0.0") & "K",
389
+ FORMAT(_Value, "$#,##0")
390
+ )
391
+ )
392
+
393
+ Revenue YoY Display =
394
+ VAR _YoY = [Revenue YoY %]
395
+ RETURN
396
+ IF(
397
+ ISBLANK(_YoY),
398
+ "--",
399
+ IF(_YoY >= 0, "+", "") & FORMAT(_YoY, "0.0%")
400
+ )
401
+
402
+ Selected Period =
403
+ VAR _MinDate = MIN(DimDate[Date])
404
+ VAR _MaxDate = MAX(DimDate[Date])
405
+ RETURN
406
+ FORMAT(_MinDate, "MMM D, YYYY") & " - " & FORMAT(_MaxDate, "MMM D, YYYY")
407
+
408
+ Last Refresh =
409
+ "Last updated: " & FORMAT(NOW(), "MMM D, YYYY h:mm AM/PM")
410
+
411
+
412
+ // ----------------------------------------------------------------------------
413
+ // DATA QUALITY CHECKS
414
+ // ----------------------------------------------------------------------------
415
+
416
+ _Data Quality Sales =
417
+ VAR _TotalRows = COUNTROWS(FactSales)
418
+ VAR _NullAmount = CALCULATE(COUNTROWS(FactSales), ISBLANK(FactSales[Amount]))
419
+ VAR _NegativeAmount = CALCULATE(COUNTROWS(FactSales), FactSales[Amount] < 0)
420
+ RETURN
421
+ "Total: " & _TotalRows &
422
+ " | Null Amounts: " & _NullAmount &
423
+ " | Negative: " & _NegativeAmount
424
+
425
+ _Missing Keys =
426
+ VAR _OrphanProducts =
427
+ COUNTROWS(
428
+ FILTER(
429
+ FactSales,
430
+ ISBLANK(RELATED(DimProduct[ProductName]))
431
+ )
432
+ )
433
+ VAR _OrphanCustomers =
434
+ COUNTROWS(
435
+ FILTER(
436
+ FactSales,
437
+ ISBLANK(RELATED(DimCustomer[CustomerName]))
438
+ )
439
+ )
440
+ RETURN
441
+ "Orphan Products: " & _OrphanProducts &
442
+ " | Orphan Customers: " & _OrphanCustomers
443
+
444
+
445
+ // ============================================================================
446
+ // MEASURE ORGANIZATION
447
+ // ============================================================================
448
+ // Create Display Folders in Power BI:
449
+ //
450
+ // 📊 Base Metrics
451
+ // - Revenue, Cost, Profit, Profit Margin %, Quantity, Transactions, AOV
452
+ //
453
+ // 📅 Time Intelligence
454
+ // - YTD: Revenue YTD, Profit YTD, Quantity YTD
455
+ // - Prior Year: Revenue PY, Profit PY, Revenue YTD PY
456
+ // - Growth: Revenue YoY %, Revenue YoY Var, Profit YoY %, Revenue YTD YoY %
457
+ // - Rolling: Revenue R3M, Revenue R12M, Revenue R3M Avg
458
+ // - Month: Revenue PM, Revenue MoM %
459
+ //
460
+ // 🏆 Rankings
461
+ // - Product Rank, Store Rank, Customer Rank, Category Rank
462
+ //
463
+ // 🎯 Top N
464
+ // - Revenue Top 10 Products, Revenue Top 5 Customers, Revenue Top 3 Stores
465
+ //
466
+ // 📈 Percentages
467
+ // - Revenue % of Total, Revenue % of Category, Revenue % of Store
468
+ //
469
+ // 👤 Customer
470
+ // - Customer Count, New Customers, Repeat Customers, Revenue per Customer
471
+ //
472
+ // 🏪 Store
473
+ // - Store Count, Revenue per SqFt, Revenue per Employee
474
+ //
475
+ // 🎨 Formatting
476
+ // - Revenue YoY Color, Profit Margin Color, Trend Indicator
477
+ //
478
+ // 🔧 Helpers (Hidden)
479
+ // - Revenue Display, Selected Period, Last Refresh
480
+ // - _Data Quality Sales, _Missing Keys
481
+ // ============================================================================
@@ -0,0 +1,37 @@
1
+ # Supply Chain Analytics Example
2
+
3
+ Reference implementation for a supply chain Power BI model.
4
+
5
+ ## Business Context
6
+
7
+ Track inventory levels, supplier performance, lead times, and fulfillment rates across warehouses and distribution centers.
8
+
9
+ ## Key Metrics
10
+
11
+ | Metric | Description |
12
+ |--------|-------------|
13
+ | Fill Rate | % of orders fulfilled completely |
14
+ | Inventory Turnover | How often inventory is sold and replaced |
15
+ | Days of Supply | Days of inventory remaining at current demand |
16
+ | On-Time Delivery | % of orders delivered by promised date |
17
+ | Supplier Lead Time | Average days from PO to receipt |
18
+ | Stockout Rate | % of SKUs with zero inventory |
19
+ | Carrying Cost | Cost to hold inventory per unit per period |
20
+
21
+ ## Data Model
22
+
23
+ See [data-model.md](data-model.md) for the complete star schema design.
24
+
25
+ ## Files
26
+
27
+ | File | Purpose |
28
+ |------|---------|
29
+ | `data-model.md` | Star schema with tables and relationships |
30
+ | `measures.dax` | Core DAX measures for supply chain KPIs |
31
+
32
+ ## Report Pages
33
+
34
+ 1. **Executive Summary** — KPI cards, fill rate trend, top suppliers
35
+ 2. **Inventory Health** — Stock levels by warehouse, days of supply heatmap
36
+ 3. **Supplier Scorecard** — Lead time, quality, on-time delivery by supplier
37
+ 4. **Demand vs Supply** — Forecast accuracy, stockout risk analysis
@@ -0,0 +1,69 @@
1
+ # Supply Chain Data Model
2
+
3
+ ## Star Schema
4
+
5
+ ```
6
+ ┌─────────────┐
7
+ │ DimDate │
8
+ │─────────────│
9
+ │ DateKey (PK)│
10
+ │ Date │
11
+ │ Month │
12
+ │ Quarter │
13
+ │ Year │
14
+ │ FiscalMonth │
15
+ │ FiscalYear │
16
+ └──────┬──────┘
17
+
18
+ ┌─────────────┐ ┌───────┴───────┐ ┌──────────────┐
19
+ │ DimSupplier │ │ FactInventory │ │ DimWarehouse │
20
+ │─────────────│ │───────────────│ │──────────────│
21
+ │ SupplierKey │◄───│ SupplierKey │───►│ WarehouseKey │
22
+ │ SupplierName│ │ WarehouseKey │ │ WarehouseName│
23
+ │ Country │ │ ProductKey │ │ Region │
24
+ │ LeadTimeDays│ │ DateKey │ │ Capacity │
25
+ │ Rating │ │ QuantityOnHand│ │ Type │
26
+ └─────────────┘ │ QuantityOnOrder│ └──────────────┘
27
+ │ ReorderPoint │
28
+ ┌─────────────┐ │ UnitCost │ ┌──────────────┐
29
+ │ DimProduct │ │ DaysOfSupply │ │ FactOrders │
30
+ │─────────────│ └───────────────┘ │──────────────│
31
+ │ ProductKey │◄────────────────────────│ ProductKey │
32
+ │ ProductName │ │ │ CustomerKey │
33
+ │ Category │ │ │ DateKey │
34
+ │ SubCategory │ ▼ │ WarehouseKey │
35
+ │ SKU │ ┌───────────────┐ │ Quantity │
36
+ │ UnitWeight │ │FactPurchaseOrder│ │ ShipDate │
37
+ │ IsActive │ │───────────────│ │ PromisedDate │
38
+ └─────────────┘ │ POKey (PK) │ │ IsOnTime │
39
+ │ SupplierKey │ │ IsFilled │
40
+ │ ProductKey │ └──────────────┘
41
+ │ DateKey │
42
+ │ Quantity │
43
+ │ UnitCost │
44
+ │ ReceivedDate │
45
+ │ LeadTimeDays │
46
+ └───────────────┘
47
+ ```
48
+
49
+ ## Relationships
50
+
51
+ | From | To | Cardinality | Direction |
52
+ |------|----|-------------|-----------|
53
+ | FactInventory[DateKey] | DimDate[DateKey] | Many-to-One | Single |
54
+ | FactInventory[ProductKey] | DimProduct[ProductKey] | Many-to-One | Single |
55
+ | FactInventory[SupplierKey] | DimSupplier[SupplierKey] | Many-to-One | Single |
56
+ | FactInventory[WarehouseKey] | DimWarehouse[WarehouseKey] | Many-to-One | Single |
57
+ | FactOrders[DateKey] | DimDate[DateKey] | Many-to-One | Single |
58
+ | FactOrders[ProductKey] | DimProduct[ProductKey] | Many-to-One | Single |
59
+ | FactOrders[WarehouseKey] | DimWarehouse[WarehouseKey] | Many-to-One | Single |
60
+ | FactPurchaseOrder[DateKey] | DimDate[DateKey] | Many-to-One | Single |
61
+ | FactPurchaseOrder[ProductKey] | DimProduct[ProductKey] | Many-to-One | Single |
62
+ | FactPurchaseOrder[SupplierKey] | DimSupplier[SupplierKey] | Many-to-One | Single |
63
+
64
+ ## Notes
65
+
66
+ - `FactInventory` is a periodic snapshot (daily snapshot of stock levels)
67
+ - `FactOrders` tracks customer orders and fulfillment
68
+ - `FactPurchaseOrder` tracks supplier orders and lead times
69
+ - `DaysOfSupply` in FactInventory is pre-calculated for performance
@@ -0,0 +1,77 @@
1
+ // Supply Chain KPI Measures
2
+ // ========================
3
+ // Core measures for supply chain analytics model.
4
+
5
+ // --- Inventory Metrics ---
6
+
7
+ // Total units currently in stock across all warehouses
8
+ TotalOnHand =
9
+ SUM(FactInventory[QuantityOnHand])
10
+
11
+ // Total units on order from suppliers
12
+ TotalOnOrder =
13
+ SUM(FactInventory[QuantityOnOrder])
14
+
15
+ // Inventory turnover: how many times inventory is sold and replaced
16
+ // Higher is better — indicates efficient inventory management
17
+ InventoryTurnover =
18
+ VAR _COGS = SUM(FactOrders[Quantity]) * AVERAGE(FactInventory[UnitCost])
19
+ VAR _AvgInventory = AVERAGE(FactInventory[QuantityOnHand]) * AVERAGE(FactInventory[UnitCost])
20
+ RETURN DIVIDE(_COGS, _AvgInventory)
21
+
22
+ // Average days of supply remaining at current demand rate
23
+ AvgDaysOfSupply =
24
+ AVERAGE(FactInventory[DaysOfSupply])
25
+
26
+ // Percentage of SKUs with zero inventory (stockout)
27
+ StockoutRate =
28
+ VAR _TotalSKUs = DISTINCTCOUNT(FactInventory[ProductKey])
29
+ VAR _StockoutSKUs =
30
+ CALCULATE(
31
+ DISTINCTCOUNT(FactInventory[ProductKey]),
32
+ FactInventory[QuantityOnHand] = 0
33
+ )
34
+ RETURN DIVIDE(_StockoutSKUs, _TotalSKUs)
35
+
36
+ // --- Fulfillment Metrics ---
37
+
38
+ // Fill rate: percentage of orders fulfilled completely
39
+ FillRate =
40
+ VAR _TotalOrders = COUNTROWS(FactOrders)
41
+ VAR _FilledOrders = CALCULATE(COUNTROWS(FactOrders), FactOrders[IsFilled] = TRUE())
42
+ RETURN DIVIDE(_FilledOrders, _TotalOrders)
43
+
44
+ // On-time delivery rate
45
+ OnTimeDeliveryRate =
46
+ VAR _TotalOrders = COUNTROWS(FactOrders)
47
+ VAR _OnTimeOrders = CALCULATE(COUNTROWS(FactOrders), FactOrders[IsOnTime] = TRUE())
48
+ RETURN DIVIDE(_OnTimeOrders, _TotalOrders)
49
+
50
+ // --- Supplier Metrics ---
51
+
52
+ // Average supplier lead time in days
53
+ AvgLeadTime =
54
+ AVERAGE(FactPurchaseOrder[LeadTimeDays])
55
+
56
+ // Supplier on-time rate (received by expected date)
57
+ SupplierOnTimeRate =
58
+ VAR _TotalPOs = COUNTROWS(FactPurchaseOrder)
59
+ VAR _OnTimePOs =
60
+ CALCULATE(
61
+ COUNTROWS(FactPurchaseOrder),
62
+ FactPurchaseOrder[LeadTimeDays] <= RELATED(DimSupplier[LeadTimeDays])
63
+ )
64
+ RETURN DIVIDE(_OnTimePOs, _TotalPOs)
65
+
66
+ // --- Cost Metrics ---
67
+
68
+ // Total inventory carrying cost (simplified: unitCost * quantity * holding rate)
69
+ CarryingCost =
70
+ SUMX(
71
+ FactInventory,
72
+ FactInventory[QuantityOnHand] * FactInventory[UnitCost] * 0.25 / 365
73
+ )
74
+
75
+ // Total purchase order value
76
+ TotalPOValue =
77
+ SUMX(FactPurchaseOrder, FactPurchaseOrder[Quantity] * FactPurchaseOrder[UnitCost])