@luquimbo/bi-superpowers 5.0.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +5 -3
- package/.claude-plugin/plugin.json +1 -1
- package/.claude-plugin/skill-manifest.json +23 -7
- package/.plugin/plugin.json +1 -1
- package/AGENTS.md +123 -25
- package/CHANGELOG.md +459 -16
- package/README.md +28 -113
- package/bin/cli.js +1 -1
- package/bin/commands/diff.js +2 -2
- package/bin/commands/install.js +58 -45
- package/bin/commands/lint.js +2 -2
- package/bin/commands/validate-projects.js +1 -1
- package/bin/lib/generators/claude-plugin.js +14 -5
- package/bin/lib/generators/shared.js +9 -5
- package/bin/lib/mcp-config.js +22 -2
- package/bin/lib/skills.js +8 -8
- package/bin/mcp/powerbi-modeling-launcher.js +8 -4
- package/bin/postinstall.js +14 -12
- package/bin/utils/mcp-detect.js +11 -11
- package/commands/bi-connect.md +34 -17
- package/commands/bi-dax.md +385 -0
- package/commands/bi-kickoff.md +75 -44
- package/commands/bi-modeling.md +395 -0
- package/commands/bi-performance.md +455 -0
- package/commands/bi-start.md +30 -18
- package/desktop-extension/manifest.json +2 -2
- package/package.json +3 -2
- package/skills/bi-connect/SKILL.md +34 -17
- package/skills/bi-connect/scripts/update-check.js +1 -1
- package/skills/bi-dax/SKILL.md +387 -0
- package/skills/{bi-report → bi-dax}/scripts/update-check.js +1 -1
- package/skills/bi-kickoff/SKILL.md +75 -44
- package/skills/bi-kickoff/scripts/update-check.js +1 -1
- package/skills/bi-modeling/SKILL.md +397 -0
- package/skills/bi-modeling/scripts/update-check.js +403 -0
- package/skills/bi-performance/SKILL.md +457 -0
- package/skills/bi-performance/scripts/install-tabular-editor.ps1 +90 -0
- package/skills/bi-performance/scripts/run-bpa.ps1 +161 -0
- package/skills/bi-performance/scripts/update-check.js +403 -0
- package/skills/bi-start/SKILL.md +31 -19
- package/skills/bi-start/scripts/update-check.js +1 -1
- package/src/content/base.md +13 -8
- package/src/content/routing.md +1 -5
- package/src/content/skills/bi-connect.md +32 -15
- package/src/content/skills/bi-dax.md +358 -0
- package/src/content/skills/bi-kickoff.md +73 -42
- package/src/content/skills/bi-modeling.md +368 -0
- package/src/content/skills/bi-performance/SKILL.md +428 -0
- package/src/content/skills/bi-performance/scripts/install-tabular-editor.ps1 +90 -0
- package/src/content/skills/bi-performance/scripts/run-bpa.ps1 +161 -0
- package/src/content/skills/bi-start.md +30 -18
- package/theme/BISuperpowers.json +3888 -0
- package/commands/bi-report.md +0 -403
- package/skills/bi-report/SKILL.md +0 -405
- package/skills/bi-report/references/cli-commands.md +0 -184
- package/skills/bi-report/references/cli-setup.md +0 -101
- package/skills/bi-report/references/close-write-open-pattern.md +0 -80
- package/skills/bi-report/references/layouts/finance.md +0 -65
- package/skills/bi-report/references/layouts/generic.md +0 -46
- package/skills/bi-report/references/layouts/hr.md +0 -48
- package/skills/bi-report/references/layouts/marketing.md +0 -45
- package/skills/bi-report/references/layouts/operations.md +0 -44
- package/skills/bi-report/references/layouts/sales.md +0 -50
- package/skills/bi-report/references/native-visuals.md +0 -341
- package/skills/bi-report/references/pbi-desktop-installation.md +0 -87
- package/skills/bi-report/references/pbir-preview-activation.md +0 -40
- package/skills/bi-report/references/slicer.md +0 -89
- package/skills/bi-report/references/textbox.md +0 -101
- package/skills/bi-report/references/themes/BISuperpowers.json +0 -915
- package/skills/bi-report/references/troubleshooting.md +0 -135
- package/skills/bi-report/references/visual-types.md +0 -78
- package/skills/bi-report/scripts/apply-theme.js +0 -243
- package/skills/bi-report/scripts/create-visual.js +0 -942
- package/skills/bi-report/scripts/ensure-pbi-cli.sh +0 -41
- package/skills/bi-report/scripts/validate-pbir.js +0 -351
- package/src/content/skills/bi-report/SKILL.md +0 -376
- package/src/content/skills/bi-report/references/cli-commands.md +0 -184
- package/src/content/skills/bi-report/references/cli-setup.md +0 -101
- package/src/content/skills/bi-report/references/close-write-open-pattern.md +0 -80
- package/src/content/skills/bi-report/references/layouts/finance.md +0 -65
- package/src/content/skills/bi-report/references/layouts/generic.md +0 -46
- package/src/content/skills/bi-report/references/layouts/hr.md +0 -48
- package/src/content/skills/bi-report/references/layouts/marketing.md +0 -45
- package/src/content/skills/bi-report/references/layouts/operations.md +0 -44
- package/src/content/skills/bi-report/references/layouts/sales.md +0 -50
- package/src/content/skills/bi-report/references/native-visuals.md +0 -341
- package/src/content/skills/bi-report/references/pbi-desktop-installation.md +0 -87
- package/src/content/skills/bi-report/references/pbir-preview-activation.md +0 -40
- package/src/content/skills/bi-report/references/slicer.md +0 -89
- package/src/content/skills/bi-report/references/textbox.md +0 -101
- package/src/content/skills/bi-report/references/themes/BISuperpowers.json +0 -915
- package/src/content/skills/bi-report/references/troubleshooting.md +0 -135
- package/src/content/skills/bi-report/references/visual-types.md +0 -78
- package/src/content/skills/bi-report/scripts/apply-theme.js +0 -243
- package/src/content/skills/bi-report/scripts/create-visual.js +0 -942
- package/src/content/skills/bi-report/scripts/ensure-pbi-cli.sh +0 -41
- package/src/content/skills/bi-report/scripts/validate-pbir.js +0 -351
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# The close-write-open pattern
|
|
2
|
-
|
|
3
|
-
This is the most important pattern in the skill. Get it wrong and **none of the visuals you generate will render** — not because the JSON is invalid, but because Power BI Desktop refuses to re-read the files while it's open.
|
|
4
|
-
|
|
5
|
-
## The core fact
|
|
6
|
-
|
|
7
|
-
Power BI Desktop reads `visual.json`, `page.json`, and the rest of the PBIR tree **once**, when the `.pbip` is first loaded by the app process. After that, it holds the report in memory and ignores file changes on disk. This is **not** a bug we can work around with the public CLI — it's Desktop's current design.
|
|
8
|
-
|
|
9
|
-
Kurt Buhler documents this explicitly in the `power-bi-agentic-development/plugins/pbip/skills/pbip/SKILL.md`:
|
|
10
|
-
|
|
11
|
-
> **"PBI Desktop does not detect external changes. Close and reopen PBI Desktop after editing files externally."**
|
|
12
|
-
|
|
13
|
-
The subtle part: **"close"** here means kill the `PBIDesktop.exe` process, not `File → Close` inside the app. A file-level close keeps the app process alive with its cache intact. When the user then opens the file again via "Recent files" or drag, Desktop uses its cached state and silently ignores any new visual folders on disk.
|
|
14
|
-
|
|
15
|
-
## The correct sequence
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
1. User has Power BI Desktop open with the .pbip
|
|
19
|
-
2. Skill asks user to save any pending Desktop-side work
|
|
20
|
-
3. Skill kills PBIDesktop.exe (process-level)
|
|
21
|
-
4. Skill writes visuals via pbi CLI (while Desktop is dead)
|
|
22
|
-
5. Skill relaunches the .pbip via Start-Process
|
|
23
|
-
6. A new Desktop process boots, reads files from disk fresh, renders everything
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Commands
|
|
27
|
-
|
|
28
|
-
### Kill Desktop
|
|
29
|
-
|
|
30
|
-
Use `cmd //c` in Git Bash to avoid the MSYS path-mangling bug that eats the `/IM` flag:
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
cmd //c "taskkill /IM PBIDesktop.exe /F"
|
|
34
|
-
cmd //c "taskkill /IM msmdsrv.exe /F" # Analysis Services — Desktop usually kills this itself but belt-and-braces
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Verify termination:
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
tasklist | grep -iE "PBIDesktop|msmdsrv" # should return no lines
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Relaunch the .pbip
|
|
44
|
-
|
|
45
|
-
PowerShell's `Start-Process` runs the shell-open association, which for `.pbip` files launches Power BI Desktop:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
powershell -Command "Start-Process -FilePath './pbip-files/MyProject.pbip'"
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Desktop takes ~10-20 seconds to fully load the model and render the visuals. The user sees "loading" screens during that window.
|
|
52
|
-
|
|
53
|
-
## What does NOT work (confirmed failures)
|
|
54
|
-
|
|
55
|
-
- **`File → Close` + `File → Open Recent`** — keeps the process alive, cache persists, new visuals ignored
|
|
56
|
-
- **`Ctrl+Shift+F5` (CLI `pbi report reload`)** — only triggers a data refresh, not a structural re-scan of disk
|
|
57
|
-
- **`File → Save` after external writes** — Desktop saves its in-memory state back to disk, which may OVERWRITE the externally-written files with the old state. Dangerous.
|
|
58
|
-
- **Reopening the file by path while the same Desktop process is running** — same process, same cache, same problem
|
|
59
|
-
|
|
60
|
-
## Why `pbi report reload` exists if it doesn't solve this
|
|
61
|
-
|
|
62
|
-
The reload command is useful for smaller cases: refreshing data, picking up a theme change, re-running a single-visual query. It's not meant to discover newly-added visual folders, and the CLI docs don't claim it does.
|
|
63
|
-
|
|
64
|
-
## Gotchas
|
|
65
|
-
|
|
66
|
-
- **User has unsaved work in Desktop**: killing the process without prompting loses that work. Always ask before taskkill. If they have changes, tell them to save first.
|
|
67
|
-
- **msmdsrv.exe lingering**: Desktop usually cleans it up, but occasionally it stays. Kill it separately to free port 53xxx that the CLI uses for `pbi connect`.
|
|
68
|
-
- **Start-Process can't find the .pbip**: the path needs to be relative to CWD or absolute. If you're in `bi-superpowers/` but the .pbip is under `examples/smoke-test/pbip-files/`, use the full relative path.
|
|
69
|
-
- **User has multiple Desktops open**: `taskkill /IM PBIDesktop.exe /F` kills ALL of them. If the user works with multiple .pbip files simultaneously, warn them or narrow the kill to the specific PID (via `tasklist` first).
|
|
70
|
-
- **Virus scanner delays**: some AV tools lock the .pbip briefly after relaunch, causing a ~5-10s delay before Desktop shows anything. Normal, just wait.
|
|
71
|
-
|
|
72
|
-
## How this maps to the skill phases
|
|
73
|
-
|
|
74
|
-
| Phase | What to do |
|
|
75
|
-
|---|---|
|
|
76
|
-
| PHASE 2 end | `pbi disconnect` before kill (socket cleanup) |
|
|
77
|
-
| PHASE 3 | Kill Desktop (with user confirmation) |
|
|
78
|
-
| PHASE 4 | Write via CLI (Desktop is dead — no sync conflicts) |
|
|
79
|
-
| PHASE 5 | Relaunch via `Start-Process` |
|
|
80
|
-
| Post-PHASE 5 | User visually confirms render |
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# Finance layout (3 pages)
|
|
2
|
-
|
|
3
|
-
Assumed fact table: `GeneralLedger` (or similar). Common dims: `Date`, `Account`, `CostCenter`, `Scenario`. Key measures expected: total revenue, total expense, net profit, margin, variance vs budget.
|
|
4
|
-
|
|
5
|
-
Roles used below (to be resolved via the MCP):
|
|
6
|
-
- `primary-kpi` — top-line KPI (e.g., Net Revenue)
|
|
7
|
-
- `secondary-kpi-1/2/3` — 3 supporting KPIs (e.g., Gross Margin, EBITDA, Expense)
|
|
8
|
-
- `variance-measure` — signed delta (e.g., Variance vs Budget)
|
|
9
|
-
- `time-dim-column` — date column from Date dim
|
|
10
|
-
- `account-dim-column` — Account dim name or category
|
|
11
|
-
- `costcenter-dim-column` — CostCenter dim
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## Page 1: `ResumenEjecutivo` / "Resumen Ejecutivo"
|
|
16
|
-
|
|
17
|
-
**Grid (1280×720):**
|
|
18
|
-
|
|
19
|
-
| Visual | Primitive | Position (x, y, w, h) | Bindings |
|
|
20
|
-
|---|---|---|---|
|
|
21
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | static text "Resumen Ejecutivo" |
|
|
22
|
-
| KPI 1 | card | 16, 80, 280, 120 | `primary-kpi` |
|
|
23
|
-
| KPI 2 | card | 312, 80, 280, 120 | `secondary-kpi-1` |
|
|
24
|
-
| KPI 3 | card | 608, 80, 280, 120 | `secondary-kpi-2` |
|
|
25
|
-
| KPI 4 (variance, signed) | card + conditional color | 904, 80, 280, 120 | `variance-measure` |
|
|
26
|
-
| Revenue over time | line_chart | 16, 216, 816, 320 | `primary-kpi` × `time-dim-column` |
|
|
27
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
28
|
-
| Scenario slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | `Scenario[Scenario]` |
|
|
29
|
-
|
|
30
|
-
**Design notes:**
|
|
31
|
-
- Variance KPI: green/red conditional coloring is design intent only. Render as a plain card with theme/default colors unless a tested PBIR formatting implementation is available.
|
|
32
|
-
- Year slicer default: current year (single-select).
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Page 2: `AnalisisCuentas` / "Análisis por cuenta"
|
|
37
|
-
|
|
38
|
-
| Visual | Primitive | Position | Bindings |
|
|
39
|
-
|---|---|---|---|
|
|
40
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Análisis por cuenta" |
|
|
41
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
42
|
-
| CostCenter slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `CostCenter[Name]` |
|
|
43
|
-
| Top accounts bar | bar_chart (horizontal) | 16, 176, 608, 480 | `primary-kpi` by `account-dim-column`, TopN 15 |
|
|
44
|
-
| Detail matrix | matrix | 640, 176, 544, 480 | rows: `account-dim-column`, cols: `'Date'[Year]`, values: `primary-kpi` |
|
|
45
|
-
|
|
46
|
-
**Design notes:**
|
|
47
|
-
- Matrix uses gradient conditional formatting on the value column.
|
|
48
|
-
- Bar chart sorts descending by `primary-kpi`.
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## Page 3: `DetalleVariance` / "Detalle de variance"
|
|
53
|
-
|
|
54
|
-
| Visual | Primitive | Position | Bindings |
|
|
55
|
-
|---|---|---|---|
|
|
56
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Detalle de variance vs budget" |
|
|
57
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
58
|
-
| Scenario slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `Scenario[Scenario]` |
|
|
59
|
-
| Variance by costcenter | bar_chart | 16, 176, 608, 320 | `variance-measure` by `costcenter-dim-column`, bars colored by sign (diverging) |
|
|
60
|
-
| Variance trend | line_chart | 640, 176, 544, 320 | `variance-measure` by `time-dim-column` |
|
|
61
|
-
| Account × Month matrix | matrix | 16, 512, 1168, 144 | rows: `account-dim-column`, cols: `'Date'[Month]`, values: `variance-measure` with diverging gradient |
|
|
62
|
-
|
|
63
|
-
**Design notes:**
|
|
64
|
-
- Variance-sign coloring (diverging palette) is design intent only. Render bars/matrix with theme/default colors unless a tested PBIR formatting implementation is available.
|
|
65
|
-
- The bottom matrix is short (144px) so it acts as a "heatmap strip" rather than a scrollable table.
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# Generic layout (3 pages) — fallback
|
|
2
|
-
|
|
3
|
-
Use when `{domain}` is "otro" or unrecognized. Extract the "main" measure and "main" dimension from the model via MCP (usually the first fact-table measure and the first non-date dim column).
|
|
4
|
-
|
|
5
|
-
Roles:
|
|
6
|
-
- `primary-measure`, `secondary-measure`, `tertiary-measure` (whatever the model has)
|
|
7
|
-
- `primary-dim-column`, `secondary-dim-column`
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Page 1: `Resumen` / "Resumen"
|
|
12
|
-
|
|
13
|
-
| Visual | Primitive | Position | Bindings |
|
|
14
|
-
|---|---|---|---|
|
|
15
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Resumen" |
|
|
16
|
-
| KPI 1 | card | 16, 80, 280, 120 | `primary-measure` |
|
|
17
|
-
| KPI 2 | card | 312, 80, 280, 120 | `secondary-measure` |
|
|
18
|
-
| KPI 3 | card | 608, 80, 280, 120 | `tertiary-measure` (or omit and widen KPI1) |
|
|
19
|
-
| KPI 4 | card | 904, 80, 280, 120 | any YoY / variance measure available, else omit |
|
|
20
|
-
| Main trend | line_chart | 16, 216, 816, 320 | `primary-measure` × `time-dim-column` |
|
|
21
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
22
|
-
| Primary dim slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | `primary-dim-column` |
|
|
23
|
-
|
|
24
|
-
If the model has no `Date` table at all, drop the line chart and replace with a second bar chart.
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## Page 2: `Analisis` / "Análisis"
|
|
29
|
-
|
|
30
|
-
| Visual | Primitive | Position | Bindings |
|
|
31
|
-
|---|---|---|---|
|
|
32
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Análisis" |
|
|
33
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
34
|
-
| By primary dim | bar_chart | 16, 176, 608, 480 | `primary-measure` by `primary-dim-column` |
|
|
35
|
-
| By secondary dim | bar_chart | 640, 176, 544, 480 | `primary-measure` by `secondary-dim-column` |
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Page 3: `Detalle` / "Detalle"
|
|
40
|
-
|
|
41
|
-
| Visual | Primitive | Position | Bindings |
|
|
42
|
-
|---|---|---|---|
|
|
43
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Detalle" |
|
|
44
|
-
| Primary dim slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `primary-dim-column` |
|
|
45
|
-
| Secondary dim slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `secondary-dim-column` |
|
|
46
|
-
| Detail matrix | matrix | 16, 176, 1168, 480 | rows: `primary-dim-column`, cols: `secondary-dim-column`, values: `primary-measure` + `secondary-measure` |
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# HR / People layout (3 pages)
|
|
2
|
-
|
|
3
|
-
Assumed fact table: `HeadcountSnapshot` (or `EmployeeFact`). Dims: `Date`, `Employee`, `Department`, `Position`. Measures: headcount, hires, terminations, attrition rate, avg tenure, avg comp.
|
|
4
|
-
|
|
5
|
-
Roles:
|
|
6
|
-
- `headcount-measure`, `hires-measure`, `terminations-measure`, `attrition-rate-measure`
|
|
7
|
-
- `department-dim-column`, `position-dim-column`
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Page 1: `ResumenPlantilla` / "Resumen de plantilla"
|
|
12
|
-
|
|
13
|
-
| Visual | Primitive | Position | Bindings |
|
|
14
|
-
|---|---|---|---|
|
|
15
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Resumen de plantilla" |
|
|
16
|
-
| KPI — Headcount | card | 16, 80, 280, 120 | `headcount-measure` |
|
|
17
|
-
| KPI — Hires YTD | card | 312, 80, 280, 120 | `hires-measure` |
|
|
18
|
-
| KPI — Terminations YTD | card | 608, 80, 280, 120 | `terminations-measure` |
|
|
19
|
-
| KPI — Attrition % | card + conditional color | 904, 80, 280, 120 | `attrition-rate-measure` (red above threshold) |
|
|
20
|
-
| Headcount over time | line_chart | 16, 216, 816, 320 | `headcount-measure` × `time-dim-column` |
|
|
21
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
22
|
-
| Department slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | `department-dim-column` |
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Page 2: `AnalisisDepartamento` / "Análisis por departamento"
|
|
27
|
-
|
|
28
|
-
| Visual | Primitive | Position | Bindings |
|
|
29
|
-
|---|---|---|---|
|
|
30
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Análisis por departamento" |
|
|
31
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
32
|
-
| Headcount by dept | bar_chart (horizontal) | 16, 176, 608, 480 | `headcount-measure` by `department-dim-column` |
|
|
33
|
-
| Attrition by dept | bar_chart (horizontal) | 640, 176, 544, 480 | `attrition-rate-measure` by `department-dim-column` with diverging color |
|
|
34
|
-
|
|
35
|
-
**Design notes:** Attrition chart colors bars by value (higher = redder) to surface hotspots immediately.
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Page 3: `DetalleEmpleados` / "Detalle de empleados"
|
|
40
|
-
|
|
41
|
-
| Visual | Primitive | Position | Bindings |
|
|
42
|
-
|---|---|---|---|
|
|
43
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Detalle de empleados" |
|
|
44
|
-
| Department slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `department-dim-column` |
|
|
45
|
-
| Position slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `position-dim-column` |
|
|
46
|
-
| Employee matrix | matrix | 16, 176, 1168, 480 | rows: `Employee[FullName]`, cols: `'Date'[Year]`, values: `headcount-measure` (as snapshot) + tenure if available |
|
|
47
|
-
|
|
48
|
-
**Design notes:** If the model has PII, strongly suggest adding RLS (`/bi-connect` → MCP) before sharing. Surface this to the user during kickoff.
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# Marketing layout (3 pages)
|
|
2
|
-
|
|
3
|
-
Assumed fact: `Campaigns` / `MarketingSpend`. Dims: `Date`, `Channel`, `Audience`, `Product` / `Campaign`. Measures: spend, impressions, clicks, conversions, CPA, ROAS, CTR, conversion rate.
|
|
4
|
-
|
|
5
|
-
Roles:
|
|
6
|
-
- `spend-measure`, `conversions-measure`, `cpa-measure`, `roas-measure`
|
|
7
|
-
- `ctr-measure`, `conversion-rate-measure`
|
|
8
|
-
- `channel-dim-column`, `campaign-dim-column`, `audience-dim-column`
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Page 1: `ResumenMarketing` / "Resumen de marketing"
|
|
13
|
-
|
|
14
|
-
| Visual | Primitive | Position | Bindings |
|
|
15
|
-
|---|---|---|---|
|
|
16
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Resumen de marketing" |
|
|
17
|
-
| KPI — Spend | card | 16, 80, 280, 120 | `spend-measure` |
|
|
18
|
-
| KPI — Conversions | card | 312, 80, 280, 120 | `conversions-measure` |
|
|
19
|
-
| KPI — CPA | card | 608, 80, 280, 120 | `cpa-measure` |
|
|
20
|
-
| KPI — ROAS | card + conditional | 904, 80, 280, 120 | `roas-measure` (green > 1, red < 1) |
|
|
21
|
-
| Spend trend | line_chart | 16, 216, 816, 320 | `spend-measure` × `time-dim-column` |
|
|
22
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
23
|
-
| Channel slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | `channel-dim-column` |
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## Page 2: `AnalisisCanal` / "Análisis por canal"
|
|
28
|
-
|
|
29
|
-
| Visual | Primitive | Position | Bindings |
|
|
30
|
-
|---|---|---|---|
|
|
31
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Análisis por canal" |
|
|
32
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
33
|
-
| Spend by channel | bar_chart | 16, 176, 608, 480 | `spend-measure` by `channel-dim-column` |
|
|
34
|
-
| ROAS by channel | bar_chart | 640, 176, 544, 480 | `roas-measure` by `channel-dim-column`, diverging color |
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Page 3: `FunnelCampañas` / "Funnel por campaña"
|
|
39
|
-
|
|
40
|
-
| Visual | Primitive | Position | Bindings |
|
|
41
|
-
|---|---|---|---|
|
|
42
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Funnel por campaña" |
|
|
43
|
-
| Channel slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `channel-dim-column` |
|
|
44
|
-
| Audience slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `audience-dim-column` |
|
|
45
|
-
| Campaign matrix | matrix | 16, 176, 1168, 480 | rows: `campaign-dim-column`, values: `spend-measure` + `conversions-measure` + `ctr-measure` + `conversion-rate-measure` + `cpa-measure` with column conditional color |
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Operations / Supply Chain layout (3 pages)
|
|
2
|
-
|
|
3
|
-
Assumed fact: `Orders` or `Shipments`. Dims: `Date`, `Customer`, `Product`, `Facility`. Measures: volume (orders/units), SLA %, open orders, aging.
|
|
4
|
-
|
|
5
|
-
Roles:
|
|
6
|
-
- `volume-measure`, `sla-measure`, `open-orders-measure`, `aging-measure`
|
|
7
|
-
- `facility-dim-column`, `product-dim-column`
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Page 1: `ResumenOperaciones` / "Resumen operacional"
|
|
12
|
-
|
|
13
|
-
| Visual | Primitive | Position | Bindings |
|
|
14
|
-
|---|---|---|---|
|
|
15
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Resumen operacional" |
|
|
16
|
-
| KPI — Volume | card | 16, 80, 280, 120 | `volume-measure` |
|
|
17
|
-
| KPI — SLA % | card + conditional | 312, 80, 280, 120 | `sla-measure` (red below target) |
|
|
18
|
-
| KPI — Open orders | card | 608, 80, 280, 120 | `open-orders-measure` |
|
|
19
|
-
| KPI — Aging (avg days) | card | 904, 80, 280, 120 | `aging-measure` |
|
|
20
|
-
| Volume trend | line_chart | 16, 216, 816, 320 | `volume-measure` × `time-dim-column` |
|
|
21
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
22
|
-
| Facility slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | `facility-dim-column` |
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Page 2: `AnalisisFacility` / "Análisis por facility"
|
|
27
|
-
|
|
28
|
-
| Visual | Primitive | Position | Bindings |
|
|
29
|
-
|---|---|---|---|
|
|
30
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Análisis por facility" |
|
|
31
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
32
|
-
| SLA by facility | bar_chart | 16, 176, 608, 480 | `sla-measure` by `facility-dim-column`, diverging color (red below target) |
|
|
33
|
-
| Volume by facility | bar_chart | 640, 176, 544, 480 | `volume-measure` by `facility-dim-column` |
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Page 3: `DetalleOrdenes` / "Detalle de órdenes"
|
|
38
|
-
|
|
39
|
-
| Visual | Primitive | Position | Bindings |
|
|
40
|
-
|---|---|---|---|
|
|
41
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Detalle de órdenes" |
|
|
42
|
-
| Facility slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `facility-dim-column` |
|
|
43
|
-
| Status slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | order status column if present |
|
|
44
|
-
| Orders matrix | matrix | 16, 176, 1168, 480 | rows: `product-dim-column` + `facility-dim-column`, values: `volume-measure` + `open-orders-measure` + `aging-measure` with gradient |
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# Sales / Revenue layout (3 pages)
|
|
2
|
-
|
|
3
|
-
Assumed fact table: `Sales`. Common dims: `Date`, `Customer`, `Product`, `Salesperson`. Key measures: revenue, units, AOV, orders, revenue YoY.
|
|
4
|
-
|
|
5
|
-
Roles:
|
|
6
|
-
- `primary-kpi` — revenue total
|
|
7
|
-
- `secondary-kpi-1/2/3` — units, orders, AOV
|
|
8
|
-
- `yoy-measure` — revenue YoY %
|
|
9
|
-
- `customer-dim-column`, `product-dim-column`, `salesperson-dim-column`
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Page 1: `ResumenVentas` / "Resumen de ventas"
|
|
14
|
-
|
|
15
|
-
| Visual | Primitive | Position | Bindings |
|
|
16
|
-
|---|---|---|---|
|
|
17
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Resumen de ventas" |
|
|
18
|
-
| KPI 1 — revenue | card | 16, 80, 280, 120 | `primary-kpi` |
|
|
19
|
-
| KPI 2 — units | card | 312, 80, 280, 120 | `secondary-kpi-1` |
|
|
20
|
-
| KPI 3 — orders | card | 608, 80, 280, 120 | `secondary-kpi-2` |
|
|
21
|
-
| KPI 4 — YoY % | card + conditional color | 904, 80, 280, 120 | `yoy-measure` (signed) |
|
|
22
|
-
| Revenue over time | line_chart | 16, 216, 816, 320 | `primary-kpi` × `time-dim-column` |
|
|
23
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
24
|
-
| Channel / Segment slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | best available segmentation column |
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## Page 2: `ClientesProductos` / "Clientes y productos"
|
|
29
|
-
|
|
30
|
-
| Visual | Primitive | Position | Bindings |
|
|
31
|
-
|---|---|---|---|
|
|
32
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Clientes y productos" |
|
|
33
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
34
|
-
| Top customers bar | bar_chart (horizontal) | 16, 176, 608, 480 | `primary-kpi` by `customer-dim-column`, TopN 10 |
|
|
35
|
-
| Top products bar | bar_chart (horizontal) | 640, 176, 544, 480 | `primary-kpi` by `product-dim-column`, TopN 10 |
|
|
36
|
-
|
|
37
|
-
**Design notes:** Both bar charts share the year slicer. Use descending sort.
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Page 3: `PipelineDetalle` / "Pipeline y detalle"
|
|
42
|
-
|
|
43
|
-
| Visual | Primitive | Position | Bindings |
|
|
44
|
-
|---|---|---|---|
|
|
45
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Pipeline y detalle" |
|
|
46
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
47
|
-
| Salesperson slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `salesperson-dim-column` |
|
|
48
|
-
| Pipeline matrix | matrix | 16, 176, 1168, 480 | rows: `salesperson-dim-column`, cols: `'Date'[Month]`, values: `primary-kpi` + `secondary-kpi-2` |
|
|
49
|
-
|
|
50
|
-
**Design notes:** Matrix uses conditional color scale on revenue column. Subtotals enabled.
|