@miragon/pulse-analytics-connector 0.0.0-bootstrap.0 → 0.21.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.
- package/LICENSE +21 -0
- package/README.md +86 -3
- package/dist/bpmn-name-lookup.d.ts +72 -0
- package/dist/bpmn-name-lookup.d.ts.map +1 -0
- package/dist/bpmn-name-lookup.js +123 -0
- package/dist/bpmn-name-lookup.js.map +1 -0
- package/dist/bpmn-name-lookup.test.d.ts +2 -0
- package/dist/bpmn-name-lookup.test.d.ts.map +1 -0
- package/dist/bpmn-name-lookup.test.js +287 -0
- package/dist/bpmn-name-lookup.test.js.map +1 -0
- package/dist/bpmn-names.d.ts +38 -0
- package/dist/bpmn-names.d.ts.map +1 -0
- package/dist/bpmn-names.js +22 -0
- package/dist/bpmn-names.js.map +1 -0
- package/dist/brand-gates.test.d.ts +2 -0
- package/dist/brand-gates.test.d.ts.map +1 -0
- package/dist/brand-gates.test.js +58 -0
- package/dist/brand-gates.test.js.map +1 -0
- package/dist/builder-texts.d.ts +4 -0
- package/dist/builder-texts.d.ts.map +1 -0
- package/dist/builder-texts.js +14 -0
- package/dist/builder-texts.js.map +1 -0
- package/dist/builder-texts.test.d.ts +2 -0
- package/dist/builder-texts.test.d.ts.map +1 -0
- package/dist/builder-texts.test.js +32 -0
- package/dist/builder-texts.test.js.map +1 -0
- package/dist/definition.d.ts +3 -0
- package/dist/definition.d.ts.map +1 -0
- package/dist/definition.js +151 -0
- package/dist/definition.js.map +1 -0
- package/dist/engine-ids.d.ts +42 -0
- package/dist/engine-ids.d.ts.map +1 -0
- package/dist/engine-ids.js +50 -0
- package/dist/engine-ids.js.map +1 -0
- package/dist/engine-scope.test.d.ts +2 -0
- package/dist/engine-scope.test.d.ts.map +1 -0
- package/dist/engine-scope.test.js +260 -0
- package/dist/engine-scope.test.js.map +1 -0
- package/dist/heatmap-data.d.ts +15 -0
- package/dist/heatmap-data.d.ts.map +1 -0
- package/dist/heatmap-data.js +2 -0
- package/dist/heatmap-data.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/instructions.d.ts +8 -0
- package/dist/instructions.d.ts.map +1 -0
- package/dist/instructions.js +33 -0
- package/dist/instructions.js.map +1 -0
- package/dist/messages/de.ask-ai.d.ts +9 -0
- package/dist/messages/de.ask-ai.d.ts.map +1 -0
- package/dist/messages/de.ask-ai.js +18 -0
- package/dist/messages/de.ask-ai.js.map +1 -0
- package/dist/messages/de.builder.d.ts +12 -0
- package/dist/messages/de.builder.d.ts.map +1 -0
- package/dist/messages/de.builder.js +53 -0
- package/dist/messages/de.builder.js.map +1 -0
- package/dist/messages/de.server.d.ts +8 -0
- package/dist/messages/de.server.d.ts.map +1 -0
- package/dist/messages/de.server.js +26 -0
- package/dist/messages/de.server.js.map +1 -0
- package/dist/messages/de.sweep.d.ts +10 -0
- package/dist/messages/de.sweep.d.ts.map +1 -0
- package/dist/messages/de.sweep.js +203 -0
- package/dist/messages/de.sweep.js.map +1 -0
- package/dist/messages/en.ask-ai.d.ts +25 -0
- package/dist/messages/en.ask-ai.d.ts.map +1 -0
- package/dist/messages/en.ask-ai.js +24 -0
- package/dist/messages/en.ask-ai.js.map +1 -0
- package/dist/messages/en.builder.d.ts +12 -0
- package/dist/messages/en.builder.d.ts.map +1 -0
- package/dist/messages/en.builder.js +53 -0
- package/dist/messages/en.builder.js.map +1 -0
- package/dist/messages/en.server.d.ts +8 -0
- package/dist/messages/en.server.d.ts.map +1 -0
- package/dist/messages/en.server.js +26 -0
- package/dist/messages/en.server.js.map +1 -0
- package/dist/messages/en.sweep.d.ts +11 -0
- package/dist/messages/en.sweep.d.ts.map +1 -0
- package/dist/messages/en.sweep.js +204 -0
- package/dist/messages/en.sweep.js.map +1 -0
- package/dist/messages/glossary.d.ts +26 -0
- package/dist/messages/glossary.d.ts.map +1 -0
- package/dist/messages/glossary.js +37 -0
- package/dist/messages/glossary.js.map +1 -0
- package/dist/messages/glossary.test.d.ts +2 -0
- package/dist/messages/glossary.test.d.ts.map +1 -0
- package/dist/messages/glossary.test.js +109 -0
- package/dist/messages/glossary.test.js.map +1 -0
- package/dist/messages/index.d.ts +12 -0
- package/dist/messages/index.d.ts.map +1 -0
- package/dist/messages/index.js +23 -0
- package/dist/messages/index.js.map +1 -0
- package/dist/messages/plural.d.ts +10 -0
- package/dist/messages/plural.d.ts.map +1 -0
- package/dist/messages/plural.js +17 -0
- package/dist/messages/plural.js.map +1 -0
- package/dist/messages/use-t.d.ts +10 -0
- package/dist/messages/use-t.d.ts.map +1 -0
- package/dist/messages/use-t.js +10 -0
- package/dist/messages/use-t.js.map +1 -0
- package/dist/module.d.ts +48 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +174 -0
- package/dist/module.js.map +1 -0
- package/dist/module.test.d.ts +2 -0
- package/dist/module.test.d.ts.map +1 -0
- package/dist/module.test.js +230 -0
- package/dist/module.test.js.map +1 -0
- package/dist/named-views.d.ts +27 -0
- package/dist/named-views.d.ts.map +1 -0
- package/dist/named-views.js +73 -0
- package/dist/named-views.js.map +1 -0
- package/dist/named-views.test.d.ts +2 -0
- package/dist/named-views.test.d.ts.map +1 -0
- package/dist/named-views.test.js +110 -0
- package/dist/named-views.test.js.map +1 -0
- package/dist/plugin.d.ts +44 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +52 -0
- package/dist/plugin.js.map +1 -0
- package/dist/prometheus-wiring.test.d.ts +2 -0
- package/dist/prometheus-wiring.test.d.ts.map +1 -0
- package/dist/prometheus-wiring.test.js +142 -0
- package/dist/prometheus-wiring.test.js.map +1 -0
- package/dist/server-locale.d.ts +48 -0
- package/dist/server-locale.d.ts.map +1 -0
- package/dist/server-locale.js +33 -0
- package/dist/server-locale.js.map +1 -0
- package/dist/settings-tools.d.ts +23 -0
- package/dist/settings-tools.d.ts.map +1 -0
- package/dist/settings-tools.js +100 -0
- package/dist/settings-tools.js.map +1 -0
- package/dist/settings.d.ts +77 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +99 -0
- package/dist/settings.js.map +1 -0
- package/dist/settings.test.d.ts +2 -0
- package/dist/settings.test.d.ts.map +1 -0
- package/dist/settings.test.js +299 -0
- package/dist/settings.test.js.map +1 -0
- package/dist/steps/app-config.d.ts +30 -0
- package/dist/steps/app-config.d.ts.map +1 -0
- package/dist/steps/app-config.js +46 -0
- package/dist/steps/app-config.js.map +1 -0
- package/dist/steps/dashboard.d.ts +12 -0
- package/dist/steps/dashboard.d.ts.map +1 -0
- package/dist/steps/dashboard.js +58 -0
- package/dist/steps/dashboard.js.map +1 -0
- package/dist/steps/failure-dashboard.d.ts +10 -0
- package/dist/steps/failure-dashboard.d.ts.map +1 -0
- package/dist/steps/failure-dashboard.js +32 -0
- package/dist/steps/failure-dashboard.js.map +1 -0
- package/dist/steps/index.d.ts +3 -0
- package/dist/steps/index.d.ts.map +1 -0
- package/dist/steps/index.js +3 -0
- package/dist/steps/index.js.map +1 -0
- package/dist/steps/steps.test.d.ts +2 -0
- package/dist/steps/steps.test.d.ts.map +1 -0
- package/dist/steps/steps.test.js +153 -0
- package/dist/steps/steps.test.js.map +1 -0
- package/dist/tool-names.d.ts +13 -0
- package/dist/tool-names.d.ts.map +1 -0
- package/dist/tool-names.js +27 -0
- package/dist/tool-names.js.map +1 -0
- package/dist/tools/cluster-compare.d.ts +8 -0
- package/dist/tools/cluster-compare.d.ts.map +1 -0
- package/dist/tools/cluster-compare.js +17 -0
- package/dist/tools/cluster-compare.js.map +1 -0
- package/dist/tools/element.d.ts +8 -0
- package/dist/tools/element.d.ts.map +1 -0
- package/dist/tools/element.js +25 -0
- package/dist/tools/element.js.map +1 -0
- package/dist/tools/engine-compare.d.ts +8 -0
- package/dist/tools/engine-compare.d.ts.map +1 -0
- package/dist/tools/engine-compare.js +18 -0
- package/dist/tools/engine-compare.js.map +1 -0
- package/dist/tools/engine-compare.test.d.ts +2 -0
- package/dist/tools/engine-compare.test.d.ts.map +1 -0
- package/dist/tools/engine-compare.test.js +166 -0
- package/dist/tools/engine-compare.test.js.map +1 -0
- package/dist/tools/engine-landscape.d.ts +7 -0
- package/dist/tools/engine-landscape.d.ts.map +1 -0
- package/dist/tools/engine-landscape.js +13 -0
- package/dist/tools/engine-landscape.js.map +1 -0
- package/dist/tools/engine-landscape.test.d.ts +2 -0
- package/dist/tools/engine-landscape.test.d.ts.map +1 -0
- package/dist/tools/engine-landscape.test.js +110 -0
- package/dist/tools/engine-landscape.test.js.map +1 -0
- package/dist/tools/failures.d.ts +7 -0
- package/dist/tools/failures.d.ts.map +1 -0
- package/dist/tools/failures.js +13 -0
- package/dist/tools/failures.js.map +1 -0
- package/dist/tools/health.d.ts +7 -0
- package/dist/tools/health.d.ts.map +1 -0
- package/dist/tools/health.js +23 -0
- package/dist/tools/health.js.map +1 -0
- package/dist/tools/health.test.d.ts +2 -0
- package/dist/tools/health.test.d.ts.map +1 -0
- package/dist/tools/health.test.js +119 -0
- package/dist/tools/health.test.js.map +1 -0
- package/dist/tools/index.d.ts +18 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +35 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/performance.d.ts +8 -0
- package/dist/tools/performance.d.ts.map +1 -0
- package/dist/tools/performance.js +25 -0
- package/dist/tools/performance.js.map +1 -0
- package/dist/tools/performance.test.d.ts +2 -0
- package/dist/tools/performance.test.d.ts.map +1 -0
- package/dist/tools/performance.test.js +176 -0
- package/dist/tools/performance.test.js.map +1 -0
- package/dist/tools/version-compare.d.ts +8 -0
- package/dist/tools/version-compare.d.ts.map +1 -0
- package/dist/tools/version-compare.js +17 -0
- package/dist/tools/version-compare.js.map +1 -0
- package/dist/tools/version-compare.test.d.ts +2 -0
- package/dist/tools/version-compare.test.d.ts.map +1 -0
- package/dist/tools/version-compare.test.js +82 -0
- package/dist/tools/version-compare.test.js.map +1 -0
- package/dist/toolsets.d.ts +17 -0
- package/dist/toolsets.d.ts.map +1 -0
- package/dist/toolsets.js +47 -0
- package/dist/toolsets.js.map +1 -0
- package/dist/toolsets.test.d.ts +2 -0
- package/dist/toolsets.test.d.ts.map +1 -0
- package/dist/toolsets.test.js +91 -0
- package/dist/toolsets.test.js.map +1 -0
- package/dist/view-title.test.d.ts +2 -0
- package/dist/view-title.test.d.ts.map +1 -0
- package/dist/view-title.test.js +91 -0
- package/dist/view-title.test.js.map +1 -0
- package/dist/widget-tools/comparisons.d.ts +13 -0
- package/dist/widget-tools/comparisons.d.ts.map +1 -0
- package/dist/widget-tools/comparisons.js +177 -0
- package/dist/widget-tools/comparisons.js.map +1 -0
- package/dist/widget-tools/comparisons.test.d.ts +2 -0
- package/dist/widget-tools/comparisons.test.d.ts.map +1 -0
- package/dist/widget-tools/comparisons.test.js +123 -0
- package/dist/widget-tools/comparisons.test.js.map +1 -0
- package/dist/widget-tools/shared.d.ts +36 -0
- package/dist/widget-tools/shared.d.ts.map +1 -0
- package/dist/widget-tools/shared.js +39 -0
- package/dist/widget-tools/shared.js.map +1 -0
- package/dist/widget-tools.d.ts +25 -0
- package/dist/widget-tools.d.ts.map +1 -0
- package/dist/widget-tools.js +269 -0
- package/dist/widget-tools.js.map +1 -0
- package/dist/widget-tools.test.d.ts +2 -0
- package/dist/widget-tools.test.d.ts.map +1 -0
- package/dist/widget-tools.test.js +272 -0
- package/dist/widget-tools.test.js.map +1 -0
- package/package.json +91 -5
- package/src/bpmn-name-lookup.test.ts +333 -0
- package/src/bpmn-name-lookup.ts +197 -0
- package/src/bpmn-names.ts +51 -0
- package/src/brand-gates.test.ts +69 -0
- package/src/builder-texts.test.ts +40 -0
- package/src/builder-texts.ts +15 -0
- package/src/definition.ts +181 -0
- package/src/engine-ids.ts +85 -0
- package/src/engine-scope.test.ts +324 -0
- package/src/heatmap-data.ts +14 -0
- package/src/index.ts +4 -0
- package/src/instructions.ts +33 -0
- package/src/messages/GLOSSARY.md +88 -0
- package/src/messages/de.ask-ai.ts +28 -0
- package/src/messages/de.builder.ts +77 -0
- package/src/messages/de.server.ts +39 -0
- package/src/messages/de.sweep.ts +244 -0
- package/src/messages/en.ask-ai.ts +34 -0
- package/src/messages/en.builder.ts +76 -0
- package/src/messages/en.server.ts +39 -0
- package/src/messages/en.sweep.ts +240 -0
- package/src/messages/glossary.test.ts +122 -0
- package/src/messages/glossary.ts +62 -0
- package/src/messages/index.ts +24 -0
- package/src/messages/plural.ts +18 -0
- package/src/messages/use-t.ts +12 -0
- package/src/module.test.ts +319 -0
- package/src/module.ts +211 -0
- package/src/named-views.test.ts +141 -0
- package/src/named-views.ts +97 -0
- package/src/plugin.ts +94 -0
- package/src/prometheus-wiring.test.ts +174 -0
- package/src/server-locale.ts +59 -0
- package/src/settings-tools.ts +170 -0
- package/src/settings.test.ts +402 -0
- package/src/settings.ts +114 -0
- package/src/steps/app-config.ts +75 -0
- package/src/steps/dashboard.ts +73 -0
- package/src/steps/failure-dashboard.ts +38 -0
- package/src/steps/index.ts +2 -0
- package/src/steps/steps.test.ts +216 -0
- package/src/tool-names.ts +26 -0
- package/src/tools/cluster-compare.ts +28 -0
- package/src/tools/element.ts +35 -0
- package/src/tools/engine-compare.test.ts +210 -0
- package/src/tools/engine-compare.ts +30 -0
- package/src/tools/engine-landscape.test.ts +138 -0
- package/src/tools/engine-landscape.ts +21 -0
- package/src/tools/failures.ts +19 -0
- package/src/tools/health.test.ts +156 -0
- package/src/tools/health.ts +29 -0
- package/src/tools/index.ts +44 -0
- package/src/tools/performance.test.ts +210 -0
- package/src/tools/performance.ts +38 -0
- package/src/tools/version-compare.test.ts +97 -0
- package/src/tools/version-compare.ts +28 -0
- package/src/toolsets.test.ts +107 -0
- package/src/toolsets.ts +56 -0
- package/src/view-title.test.ts +123 -0
- package/src/widget-tools/comparisons.test.ts +170 -0
- package/src/widget-tools/comparisons.ts +229 -0
- package/src/widget-tools/shared.ts +67 -0
- package/src/widget-tools.test.ts +306 -0
- package/src/widget-tools.ts +375 -0
- package/src/widgets/analytics-dashboard/activity-bottleneck-table.tsx +179 -0
- package/src/widgets/analytics-dashboard/definition-breakdown.tsx +108 -0
- package/src/widgets/analytics-dashboard/execution-performance-kpi.tsx +94 -0
- package/src/widgets/analytics-dashboard/execution-summary-kpi.tsx +122 -0
- package/src/widgets/analytics-dashboard/lib.ts +43 -0
- package/src/widgets/bpmn-heatmap.test.tsx +75 -0
- package/src/widgets/bpmn-heatmap.tsx +127 -0
- package/src/widgets/catalogue-sync.test.ts +16 -0
- package/src/widgets/cluster-compare.tsx +148 -0
- package/src/widgets/comparison-shared.test.ts +237 -0
- package/src/widgets/comparison-shared.tsx +371 -0
- package/src/widgets/comparison-widgets.test.tsx +307 -0
- package/src/widgets/dashboard-widgets.test.tsx +397 -0
- package/src/widgets/engine-compare.tsx +87 -0
- package/src/widgets/engine-landscape.tsx +352 -0
- package/src/widgets/failure-dashboard/error-patterns-table.tsx +122 -0
- package/src/widgets/failure-dashboard/failure-rate-table.test.ts +80 -0
- package/src/widgets/failure-dashboard/failure-rate-table.tsx +170 -0
- package/src/widgets/failure-dashboard/lib.ts +32 -0
- package/src/widgets/failure-dashboard/summary-kpi.tsx +122 -0
- package/src/widgets/failure-landscape-widgets.test.tsx +393 -0
- package/src/widgets/figure.tsx +79 -0
- package/src/widgets/hand-off.test.ts +126 -0
- package/src/widgets/hand-off.ts +102 -0
- package/src/widgets/index.ts +124 -0
- package/src/widgets/model-descriptions.dashboard.test.ts +280 -0
- package/src/widgets/model-descriptions.test.ts +251 -0
- package/src/widgets/model-descriptions.ts +428 -0
- package/src/widgets/names.test.ts +32 -0
- package/src/widgets/names.ts +39 -0
- package/src/widgets/query-gate.test.tsx +57 -0
- package/src/widgets/query-gate.tsx +50 -0
- package/src/widgets/settings-section.test.tsx +174 -0
- package/src/widgets/settings-section.tsx +244 -0
- package/src/widgets/version-compare.test.ts +68 -0
- package/src/widgets/version-compare.tsx +96 -0
- package/src/widgets/view-meta.ts +18 -0
- package/src/widgets/widget-render.test-support.tsx +103 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
import {
|
|
4
|
+
catalogTextFindings,
|
|
5
|
+
scanColors,
|
|
6
|
+
scanGlyphs,
|
|
7
|
+
scanIconSizes,
|
|
8
|
+
scanTypeScale,
|
|
9
|
+
} from "@miragon/pulse-widget-shell/testing"
|
|
10
|
+
import { deAskAi } from "./messages/de.ask-ai.js"
|
|
11
|
+
import { deBuilder } from "./messages/de.builder.js"
|
|
12
|
+
import { deServer } from "./messages/de.server.js"
|
|
13
|
+
import { deSweep } from "./messages/de.sweep.js"
|
|
14
|
+
import { enAskAi } from "./messages/en.ask-ai.js"
|
|
15
|
+
import { enBuilder } from "./messages/en.builder.js"
|
|
16
|
+
import { enServer } from "./messages/en.server.js"
|
|
17
|
+
import { enSweep } from "./messages/en.sweep.js"
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The analytics module under the brand gates every widget package runs
|
|
21
|
+
* (`@miragon/pulse-widget-shell/testing`, CLAUDE.md invariant 6): brand-lint
|
|
22
|
+
* reads Markdown, not the strings inside `.ts`/`.tsx`, so these hold the
|
|
23
|
+
* catalogs to the voice rules and the widget code to Lucide icons and role
|
|
24
|
+
* colours. The terms themselves are `messages/glossary.test.ts`.
|
|
25
|
+
*/
|
|
26
|
+
describe("analytics copy follows the voice rules", () => {
|
|
27
|
+
it.each([
|
|
28
|
+
["widget texts (de)", deSweep, "de"],
|
|
29
|
+
["widget texts (en)", enSweep, "en"],
|
|
30
|
+
["Ask-AI intents (de)", deAskAi, "de"],
|
|
31
|
+
["Ask-AI intents (en)", enAskAi, "en"],
|
|
32
|
+
["model summaries (de)", deServer, "de"],
|
|
33
|
+
["model summaries (en)", enServer, "en"],
|
|
34
|
+
["view builder names (de)", deBuilder, "de"],
|
|
35
|
+
["view builder names (en)", enBuilder, "en"],
|
|
36
|
+
] as const)("%s", (_, catalog, language) => {
|
|
37
|
+
expect(catalogTextFindings(catalog, { language })).toEqual([])
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const dir = (rel: string) => fileURLToPath(new URL(rel, import.meta.url))
|
|
42
|
+
|
|
43
|
+
describe("analytics widgets draw icons with Lucide, never glyphs or emoji", () => {
|
|
44
|
+
it.each(["./widgets", "./messages"])("%s has no forbidden glyph in JSX or strings", (rel) => {
|
|
45
|
+
expect(scanGlyphs(dir(rel))).toEqual([])
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
describe("analytics widgets draw icons at the CI sizes", () => {
|
|
50
|
+
// The kit Icon's 16 px in chrome (`dense` for table cells and chips),
|
|
51
|
+
// 24 px previews: a 12 or 14 px icon is a third size in the same view.
|
|
52
|
+
it("src/widgets has no icon at a size other than 16 or 24 px", () => {
|
|
53
|
+
expect(scanIconSizes(dir("./widgets"))).toEqual([])
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
describe("analytics widgets colour through role names only", () => {
|
|
58
|
+
it("src/widgets has no palette class or raw colour", () => {
|
|
59
|
+
expect(scanColors(dir("./widgets"))).toEqual([])
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
describe("analytics widgets set their text on the CI type scale", () => {
|
|
64
|
+
// Both rules: no Tailwind size (text-sm, text-xl …) and nothing below the
|
|
65
|
+
// 13 px floor (text-xs); the steps say what the text is (CI §4).
|
|
66
|
+
it("src/widgets uses only the type-scale steps", () => {
|
|
67
|
+
expect(scanTypeScale(dir("./widgets"))).toEqual([])
|
|
68
|
+
})
|
|
69
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest"
|
|
2
|
+
import {
|
|
3
|
+
displayTextCatalog,
|
|
4
|
+
displayTextsSentToModel,
|
|
5
|
+
missingDisplayTexts,
|
|
6
|
+
} from "@miragon/pulse-widget-shell/testing"
|
|
7
|
+
import { definition } from "./definition.js"
|
|
8
|
+
import { catalogs } from "./messages/index.js"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The view builder (toolkit 2.8) shows people each widget, data source and
|
|
12
|
+
* props field by its title and summary, else by its id. analytics names every
|
|
13
|
+
* one of them in English and German, from the `builder.*` entries of its
|
|
14
|
+
* catalogs — where `brand-gates.test.ts` and `messages/glossary.test.ts` hold
|
|
15
|
+
* them to the voice and the glossary like the widget texts.
|
|
16
|
+
*/
|
|
17
|
+
describe("analytics names every builder piece for people", () => {
|
|
18
|
+
it("every widget, step and props field has an en and a de title and summary", () => {
|
|
19
|
+
expect(missingDisplayTexts(definition)).toEqual([])
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it("none of those texts reaches the model through get-framework-manifest", () => {
|
|
23
|
+
expect(displayTextsSentToModel(definition)).toEqual([])
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it.each(["en", "de"] as const)("%s: no builder entry in the catalog goes unused", (language) => {
|
|
27
|
+
const shown = new Set(Object.values(displayTextCatalog(definition, language)))
|
|
28
|
+
const unused = Object.entries(catalogs[language])
|
|
29
|
+
.filter(([key]) => key.startsWith("builder."))
|
|
30
|
+
.filter(([, text]) => typeof text !== "string" || !shown.has(text))
|
|
31
|
+
.map(([key]) => key)
|
|
32
|
+
expect(unused).toEqual([])
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it("both languages name the same pieces", () => {
|
|
36
|
+
const keys = (language: "en" | "de") =>
|
|
37
|
+
Object.keys(catalogs[language]).filter((key) => key.startsWith("builder."))
|
|
38
|
+
expect(keys("de")).toEqual(keys("en"))
|
|
39
|
+
})
|
|
40
|
+
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createBuilderTexts } from "@miragon/pulse-widget-shell/server"
|
|
2
|
+
import { catalogs } from "./messages/index.js"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* How the view builder (toolkit 2.8) names analytics' widgets, pipeline steps
|
|
6
|
+
* and props fields for people, in English and German: the `builder.*`
|
|
7
|
+
* entries of analytics' catalogs (`messages/{en,de}.builder.ts`), held to the
|
|
8
|
+
* voice and glossary gates like the widget texts. The definitions'
|
|
9
|
+
* `description`s stay the model's text.
|
|
10
|
+
*/
|
|
11
|
+
const texts = createBuilderTexts(catalogs, "analytics")
|
|
12
|
+
|
|
13
|
+
export const builderAppTitle = texts.appTitle
|
|
14
|
+
export const builderText = texts.text
|
|
15
|
+
export const fieldText = texts.field
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
import type { AppDefinition } from "@miragon/mcp-toolkit-core"
|
|
3
|
+
import { PERIODS } from "@miragon/pulse-analytics-client"
|
|
4
|
+
import { loadDashboardStep, loadFailureDashboardStep } from "./steps/index.js"
|
|
5
|
+
import { builderAppTitle, builderText, fieldText } from "./builder-texts.js"
|
|
6
|
+
|
|
7
|
+
/** The self-fetch's engine scope — a configured engine id or several; omitted = all of them. */
|
|
8
|
+
const engineScopeProp = z
|
|
9
|
+
.union([z.string(), z.array(z.string())])
|
|
10
|
+
.optional()
|
|
11
|
+
.describe(
|
|
12
|
+
"Configured engine id(s) the self-fetch is scoped to. When omitted, every configured engine is aggregated.",
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
const dashboardPropsSchema = z.toJSONSchema(
|
|
16
|
+
z.object({
|
|
17
|
+
processDefinitionKey: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe(
|
|
21
|
+
"Scope the dashboard to a single process definition (e.g. 'miraveloLeasing'). When omitted, all processes are aggregated.",
|
|
22
|
+
)
|
|
23
|
+
.meta(fieldText("dashboard.processDefinitionKey")),
|
|
24
|
+
period: z
|
|
25
|
+
.enum(PERIODS)
|
|
26
|
+
.optional()
|
|
27
|
+
.describe("Time window for the self-fetch when no upstream pipeline step populates data.")
|
|
28
|
+
.meta(fieldText("dashboard.period")),
|
|
29
|
+
engine: engineScopeProp.meta(fieldText("dashboard.engine")),
|
|
30
|
+
}),
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
const failurePropsSchema = z.toJSONSchema(
|
|
34
|
+
z.object({ engine: engineScopeProp.meta(fieldText("failure.engine")) }),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
const engineLandscapePropsSchema = z.toJSONSchema(
|
|
38
|
+
z.object({
|
|
39
|
+
engine: z
|
|
40
|
+
.union([z.string(), z.array(z.string())])
|
|
41
|
+
.optional()
|
|
42
|
+
.describe(
|
|
43
|
+
"Engine ids to include in the landscape; when omitted, every configured engine (one reporting no metrics shows as not reporting).",
|
|
44
|
+
)
|
|
45
|
+
.meta(fieldText("engineLandscape.engine")),
|
|
46
|
+
}),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
export const definition: AppDefinition = {
|
|
50
|
+
name: "analytics",
|
|
51
|
+
// The view builder's names for people (en + de); `description` is the model's text.
|
|
52
|
+
title: builderAppTitle(),
|
|
53
|
+
steps: [loadDashboardStep, loadFailureDashboardStep],
|
|
54
|
+
widgets: [
|
|
55
|
+
{
|
|
56
|
+
id: "analytics:execution-summary-kpi",
|
|
57
|
+
...builderText("widget.execution-summary-kpi"),
|
|
58
|
+
description:
|
|
59
|
+
"Top-line KPIs: instances started and completed and incidents created within the period, plus instances running and incidents open right now.",
|
|
60
|
+
requires: [],
|
|
61
|
+
consumes: ["analytics:dashboard"],
|
|
62
|
+
size: "full",
|
|
63
|
+
propsSchema: dashboardPropsSchema,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "analytics:execution-performance-kpi",
|
|
67
|
+
...builderText("widget.execution-performance-kpi"),
|
|
68
|
+
description:
|
|
69
|
+
"Duration KPIs of the instances that ended within the period (avg, median, p95) and incidents per 100 started instances.",
|
|
70
|
+
requires: [],
|
|
71
|
+
consumes: ["analytics:dashboard"],
|
|
72
|
+
size: "full",
|
|
73
|
+
propsSchema: dashboardPropsSchema,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: "analytics:process-definition-breakdown",
|
|
77
|
+
...builderText("widget.process-definition-breakdown"),
|
|
78
|
+
description:
|
|
79
|
+
"Per-process-definition breakdown: instances started and completed and incidents created within the period, instances running now, average duration.",
|
|
80
|
+
requires: [],
|
|
81
|
+
consumes: ["analytics:dashboard"],
|
|
82
|
+
size: "full",
|
|
83
|
+
propsSchema: dashboardPropsSchema,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: "analytics:activity-bottleneck-table",
|
|
87
|
+
...builderText("widget.activity-bottleneck-table"),
|
|
88
|
+
description:
|
|
89
|
+
"Top (process, activity) pairs by total time spent within the period — surfaces bottlenecks across the process landscape.",
|
|
90
|
+
requires: [],
|
|
91
|
+
consumes: ["analytics:dashboard"],
|
|
92
|
+
size: "full",
|
|
93
|
+
propsSchema: dashboardPropsSchema,
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: "analytics:failure-summary-kpi",
|
|
97
|
+
...builderText("widget.failure-summary-kpi"),
|
|
98
|
+
description:
|
|
99
|
+
"Failure summary KPIs right now (open incidents, incident groups by type × process, most affected process).",
|
|
100
|
+
requires: [],
|
|
101
|
+
consumes: ["analytics:failureDashboard"],
|
|
102
|
+
size: "full",
|
|
103
|
+
propsSchema: failurePropsSchema,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: "analytics:error-patterns-table",
|
|
107
|
+
...builderText("widget.error-patterns-table"),
|
|
108
|
+
description:
|
|
109
|
+
"The incidents open right now, grouped by incident type and process definition, with counts.",
|
|
110
|
+
requires: [],
|
|
111
|
+
consumes: ["analytics:failureDashboard"],
|
|
112
|
+
size: "full",
|
|
113
|
+
propsSchema: failurePropsSchema,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: "analytics:failure-rate-table",
|
|
117
|
+
...builderText("widget.failure-rate-table"),
|
|
118
|
+
description:
|
|
119
|
+
"Per-process live failure state: running instances, dead jobs, open incidents and open incidents per 100 running instances.",
|
|
120
|
+
requires: [],
|
|
121
|
+
consumes: ["analytics:failureDashboard"],
|
|
122
|
+
size: "full",
|
|
123
|
+
propsSchema: failurePropsSchema,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: "analytics:cluster-compare",
|
|
127
|
+
...builderText("widget.cluster-compare"),
|
|
128
|
+
description:
|
|
129
|
+
"Side-by-side before/after comparison of instance KPIs around a deployment timestamp.",
|
|
130
|
+
requires: [],
|
|
131
|
+
consumes: ["analytics:clusterCompare"],
|
|
132
|
+
size: "full",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: "analytics:version-compare",
|
|
136
|
+
...builderText("widget.version-compare"),
|
|
137
|
+
description:
|
|
138
|
+
"Side-by-side per-version comparison of KPIs (starts, durations of the instances that ended; incident rates are not measured per version) across two process versions.",
|
|
139
|
+
requires: [],
|
|
140
|
+
consumes: ["analytics:versionCompare"],
|
|
141
|
+
size: "full",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: "analytics:engine-compare",
|
|
145
|
+
...builderText("widget.engine-compare"),
|
|
146
|
+
description:
|
|
147
|
+
"Side-by-side comparison of KPIs (starts, incident rate, durations of the instances that ended) for ONE process definition as it runs on two engines (e.g. prod-a vs prod-b). Requires a processDefinitionKey — see analytics:engine-landscape for which definitions qualify.",
|
|
148
|
+
requires: [],
|
|
149
|
+
consumes: ["analytics:engineCompare"],
|
|
150
|
+
size: "full",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: "analytics:engine-landscape",
|
|
154
|
+
...builderText("widget.engine-landscape"),
|
|
155
|
+
description:
|
|
156
|
+
"Cross-engine overview: the process × engine inventory matrix, absolute load per engine (running instances, incidents, failed jobs) and the process-independent job backlog. Counts rather than rates, because engines run different process mixes; highlights the definitions deployed on several engines as the valid comparison targets.",
|
|
157
|
+
requires: [],
|
|
158
|
+
consumes: ["analytics:engineLandscape"],
|
|
159
|
+
size: "full",
|
|
160
|
+
propsSchema: engineLandscapePropsSchema,
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
id: "analytics:bpmn-heatmap",
|
|
164
|
+
...builderText("widget.bpmn-heatmap"),
|
|
165
|
+
description:
|
|
166
|
+
"BPMN diagram with a per-element heat overlay from metrics, toggling between traversal frequency and average duration. Node-only; rendered on the latest deployed version's diagram.",
|
|
167
|
+
requires: [],
|
|
168
|
+
consumes: ["analytics:bpmnHeatmap"],
|
|
169
|
+
size: "full",
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
id: "analytics:settings",
|
|
173
|
+
...builderText("widget.settings"),
|
|
174
|
+
description:
|
|
175
|
+
"The analytics module's settings section: default look-back period and minimum comparison bucket size, applied when analytics calls omit them.",
|
|
176
|
+
requires: [],
|
|
177
|
+
consumes: ["analytics:settings"],
|
|
178
|
+
size: "full",
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { EngineFilterInput } from "@miragon/pulse-analytics-client"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Which engines analytics may read on this server. A Prometheus (or Thanos /
|
|
5
|
+
* Mimir) is often shared across teams, and every analytics query reads every
|
|
6
|
+
* `engine_id` it holds unless told otherwise — so analytics covers exactly the
|
|
7
|
+
* server's CONFIGURED engine ids, never "whatever Prometheus has":
|
|
8
|
+
*
|
|
9
|
+
* - the composition root injects them (`SharedResources.engineIds`, from the
|
|
10
|
+
* camunda7 module's engine list) — analytics has no engine-SDK dependency;
|
|
11
|
+
* - a standalone analytics boot names them in `ANALYTICS_ENGINE_IDS`;
|
|
12
|
+
* - with neither, analytics is FAIL-CLOSED: every engine-reading tool refuses
|
|
13
|
+
* with {@link NO_ENGINE_SCOPE_MESSAGE} (and the boot warns) instead of
|
|
14
|
+
* reading the whole Prometheus.
|
|
15
|
+
*
|
|
16
|
+
* An omitted `engine` argument resolves to all configured ids (the fleet
|
|
17
|
+
* view, labelled as such in results); an id outside them is refused.
|
|
18
|
+
*/
|
|
19
|
+
export interface AnalyticsEngineScope {
|
|
20
|
+
/** The configured ids, in configuration order; empty when none are configured. */
|
|
21
|
+
readonly ids: readonly string[]
|
|
22
|
+
/** The concrete ids a query reads for a caller's `engine` filter. Throws on an unknown id. */
|
|
23
|
+
resolve(requested: EngineFilterInput): string[]
|
|
24
|
+
/** One configured id (`field` names the argument in the refusal). */
|
|
25
|
+
require(id: string, field: string): string
|
|
26
|
+
/** True when `resolved` (a {@link resolve} result) covers every configured engine. */
|
|
27
|
+
coversFleet(resolved: readonly string[]): boolean
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* `args` with `engine` replaced by the concrete configured ids it resolves to
|
|
32
|
+
* — what every engine-reading tool hands its query, so no query ever runs
|
|
33
|
+
* unscoped against a shared Prometheus.
|
|
34
|
+
*/
|
|
35
|
+
export function withEngineScope<T extends { engine?: EngineFilterInput }>(
|
|
36
|
+
scope: AnalyticsEngineScope,
|
|
37
|
+
args: T,
|
|
38
|
+
): Omit<T, "engine"> & { engine: string[] } {
|
|
39
|
+
return { ...args, engine: scope.resolve(args.engine) }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const NO_ENGINE_SCOPE_MESSAGE =
|
|
43
|
+
"Analytics covers no engine: this server configures no engine ids. Activate the camunda7 module (its configured engines scope analytics) or set ANALYTICS_ENGINE_IDS to the engine_id values analytics may read."
|
|
44
|
+
|
|
45
|
+
/** True when the caller named no engine — the request covers the whole configured fleet. */
|
|
46
|
+
export function isFleetRequest(requested: EngineFilterInput): boolean {
|
|
47
|
+
if (requested === undefined || requested === null) return true
|
|
48
|
+
return (Array.isArray(requested) ? requested : [requested]).every((id) => id.length === 0)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function createEngineScope(configured: readonly string[] | undefined): AnalyticsEngineScope {
|
|
52
|
+
const ids = [...new Set((configured ?? []).map((id) => id.trim()).filter((id) => id.length > 0))]
|
|
53
|
+
|
|
54
|
+
function assertConfigured(): void {
|
|
55
|
+
if (ids.length === 0) throw new Error(NO_ENGINE_SCOPE_MESSAGE)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function refuseUnknown(unknown: string[], field: string): never {
|
|
59
|
+
const list = unknown.map((id) => `"${id}"`).join(", ")
|
|
60
|
+
throw new Error(
|
|
61
|
+
`Unknown engine ${list} in ${field} — analytics covers only this server's configured engines: ${ids.join(", ")}.`,
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
ids,
|
|
67
|
+
resolve(requested) {
|
|
68
|
+
assertConfigured()
|
|
69
|
+
if (isFleetRequest(requested)) return [...ids]
|
|
70
|
+
const list = typeof requested === "string" ? [requested] : (requested ?? [])
|
|
71
|
+
const named = [...new Set(list.filter((id) => id.length > 0))]
|
|
72
|
+
const unknown = named.filter((id) => !ids.includes(id))
|
|
73
|
+
if (unknown.length > 0) refuseUnknown(unknown, "engine")
|
|
74
|
+
return named
|
|
75
|
+
},
|
|
76
|
+
require(id, field) {
|
|
77
|
+
assertConfigured()
|
|
78
|
+
if (!ids.includes(id)) refuseUnknown([id], field)
|
|
79
|
+
return id
|
|
80
|
+
},
|
|
81
|
+
coversFleet(resolved) {
|
|
82
|
+
return ids.length > 0 && ids.every((id) => resolved.includes(id))
|
|
83
|
+
},
|
|
84
|
+
}
|
|
85
|
+
}
|