@luquimbo/bi-superpowers 3.1.0 → 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 (110) 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/README.md +2 -2
  6. package/bin/build-plugin.js +6 -6
  7. package/bin/cli.js +169 -310
  8. package/bin/commands/install.js +87 -70
  9. package/bin/commands/install.test.js +2 -2
  10. package/bin/lib/agents.js +21 -2
  11. package/bin/lib/mcp-config.js +27 -5
  12. package/bin/lib/mcp-config.test.js +1 -1
  13. package/desktop-extension/manifest.json +4 -11
  14. package/desktop-extension/server.js +34 -25
  15. package/package.json +3 -9
  16. package/skills/pbi-connect/SKILL.md +1 -1
  17. package/skills/project-kickoff/SKILL.md +1 -1
  18. package/bin/commands/add.js +0 -533
  19. package/bin/commands/add.test.js +0 -77
  20. package/bin/commands/changelog.js +0 -443
  21. package/bin/commands/pull.js +0 -287
  22. package/bin/commands/pull.test.js +0 -36
  23. package/bin/commands/push.js +0 -231
  24. package/bin/commands/push.test.js +0 -14
  25. package/bin/commands/search.js +0 -344
  26. package/bin/commands/search.test.js +0 -115
  27. package/bin/commands/setup.js +0 -545
  28. package/bin/commands/setup.test.js +0 -46
  29. package/bin/commands/sync-profile.js +0 -405
  30. package/bin/commands/sync-profile.test.js +0 -14
  31. package/bin/commands/sync-source.js +0 -418
  32. package/bin/commands/sync-source.test.js +0 -14
  33. package/bin/utils/errors.js +0 -159
  34. package/bin/utils/git.js +0 -298
  35. package/bin/utils/logger.js +0 -142
  36. package/bin/utils/pbix.js +0 -305
  37. package/bin/utils/pbix.test.js +0 -37
  38. package/bin/utils/profiles.js +0 -312
  39. package/bin/utils/projects.js +0 -169
  40. package/bin/utils/readline.js +0 -206
  41. package/bin/utils/readline.test.js +0 -47
  42. package/docs/openrouter-free-models.md +0 -92
  43. package/library/examples/README.md +0 -151
  44. package/library/examples/finance-reporting/README.md +0 -351
  45. package/library/examples/finance-reporting/data-model.md +0 -267
  46. package/library/examples/finance-reporting/measures.dax +0 -557
  47. package/library/examples/hr-analytics/README.md +0 -371
  48. package/library/examples/hr-analytics/data-model.md +0 -315
  49. package/library/examples/hr-analytics/measures.dax +0 -460
  50. package/library/examples/marketing-analytics/README.md +0 -37
  51. package/library/examples/marketing-analytics/data-model.md +0 -62
  52. package/library/examples/marketing-analytics/measures.dax +0 -110
  53. package/library/examples/retail-analytics/README.md +0 -439
  54. package/library/examples/retail-analytics/data-model.md +0 -288
  55. package/library/examples/retail-analytics/measures.dax +0 -481
  56. package/library/examples/supply-chain/README.md +0 -37
  57. package/library/examples/supply-chain/data-model.md +0 -69
  58. package/library/examples/supply-chain/measures.dax +0 -77
  59. package/library/examples/udf-library/README.md +0 -228
  60. package/library/examples/udf-library/functions.dax +0 -571
  61. package/library/snippets/dax/README.md +0 -292
  62. package/library/snippets/dax/business-domains.md +0 -576
  63. package/library/snippets/dax/calculate-patterns.md +0 -276
  64. package/library/snippets/dax/calculation-groups.md +0 -489
  65. package/library/snippets/dax/error-handling.md +0 -495
  66. package/library/snippets/dax/iterators-and-aggregations.md +0 -474
  67. package/library/snippets/dax/kpis-and-metrics.md +0 -293
  68. package/library/snippets/dax/rankings-and-topn.md +0 -235
  69. package/library/snippets/dax/security-patterns.md +0 -413
  70. package/library/snippets/dax/text-and-formatting.md +0 -316
  71. package/library/snippets/dax/time-intelligence.md +0 -196
  72. package/library/snippets/dax/user-defined-functions.md +0 -477
  73. package/library/snippets/dax/virtual-tables.md +0 -546
  74. package/library/snippets/excel-formulas/README.md +0 -84
  75. package/library/snippets/excel-formulas/aggregations.md +0 -330
  76. package/library/snippets/excel-formulas/dates-and-times.md +0 -361
  77. package/library/snippets/excel-formulas/dynamic-arrays.md +0 -314
  78. package/library/snippets/excel-formulas/lookups.md +0 -169
  79. package/library/snippets/excel-formulas/text-functions.md +0 -363
  80. package/library/snippets/governance/naming-conventions.md +0 -97
  81. package/library/snippets/governance/review-checklists.md +0 -107
  82. package/library/snippets/power-query/README.md +0 -389
  83. package/library/snippets/power-query/api-integration.md +0 -707
  84. package/library/snippets/power-query/connections.md +0 -434
  85. package/library/snippets/power-query/data-cleaning.md +0 -298
  86. package/library/snippets/power-query/error-handling.md +0 -526
  87. package/library/snippets/power-query/parameters.md +0 -350
  88. package/library/snippets/power-query/performance.md +0 -506
  89. package/library/snippets/power-query/transformations.md +0 -330
  90. package/library/snippets/report-design/accessibility.md +0 -78
  91. package/library/snippets/report-design/chart-selection.md +0 -54
  92. package/library/snippets/report-design/layout-patterns.md +0 -87
  93. package/library/templates/data-models/README.md +0 -93
  94. package/library/templates/data-models/finance-model.md +0 -627
  95. package/library/templates/data-models/retail-star-schema.md +0 -473
  96. package/library/templates/excel/README.md +0 -83
  97. package/library/templates/excel/budget-tracker.md +0 -432
  98. package/library/templates/excel/data-entry-form.md +0 -533
  99. package/library/templates/power-bi/README.md +0 -72
  100. package/library/templates/power-bi/finance-report.md +0 -449
  101. package/library/templates/power-bi/kpi-scorecard.md +0 -461
  102. package/library/templates/power-bi/sales-dashboard.md +0 -281
  103. package/library/themes/excel/README.md +0 -436
  104. package/library/themes/power-bi/README.md +0 -271
  105. package/library/themes/power-bi/accessible.json +0 -307
  106. package/library/themes/power-bi/bi-superpowers-default.json +0 -858
  107. package/library/themes/power-bi/corporate-blue.json +0 -291
  108. package/library/themes/power-bi/dark-mode.json +0 -291
  109. package/library/themes/power-bi/minimal.json +0 -292
  110. package/library/themes/power-bi/print-friendly.json +0 -309
@@ -1,481 +0,0 @@
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
- // ============================================================================
@@ -1,37 +0,0 @@
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
@@ -1,69 +0,0 @@
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
@@ -1,77 +0,0 @@
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])