@ampsec/platform-client 84.39.1 → 84.40.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/build/src/dto/analytics.dto.d.ts +117 -0
- package/build/src/dto/analytics.dto.js +25 -1
- package/build/src/dto/analytics.dto.js.map +1 -1
- package/build/src/dto/engagementMappings.dto.d.ts +6 -6
- package/build/src/dto/platform/platform.engagementMappings.dto.d.ts +6 -6
- package/build/src/services/analytics.service.d.ts +16 -2
- package/build/src/services/analytics.service.js +24 -1
- package/build/src/services/analytics.service.js.map +1 -1
- package/package.json +1 -1
- package/src/dto/analytics.dto.ts +31 -0
- package/src/services/analytics.service.ts +40 -4
|
@@ -38,3 +38,120 @@ export declare const _FindingMetricsSeriesDto: z.ZodObject<{
|
|
|
38
38
|
averageDaysToHeal?: number | undefined;
|
|
39
39
|
}>;
|
|
40
40
|
export type FindingMetricsSeriesDto = z.infer<typeof _FindingMetricsSeriesDto>;
|
|
41
|
+
/**
|
|
42
|
+
* Department-level finding metrics for the analytics dashboard.
|
|
43
|
+
* count = total findings; findingsClosed = completed; engaged = in progress; healed = closed after flow trigger.
|
|
44
|
+
*/
|
|
45
|
+
export declare const _DepartmentMetricsDto: z.ZodObject<{
|
|
46
|
+
department: z.ZodString;
|
|
47
|
+
count: z.ZodNumber;
|
|
48
|
+
findingsClosed: z.ZodNumber;
|
|
49
|
+
engaged: z.ZodNumber;
|
|
50
|
+
healed: z.ZodNumber;
|
|
51
|
+
}, "strip", z.ZodTypeAny, {
|
|
52
|
+
department: string;
|
|
53
|
+
count: number;
|
|
54
|
+
findingsClosed: number;
|
|
55
|
+
engaged: number;
|
|
56
|
+
healed: number;
|
|
57
|
+
}, {
|
|
58
|
+
department: string;
|
|
59
|
+
count: number;
|
|
60
|
+
findingsClosed: number;
|
|
61
|
+
engaged: number;
|
|
62
|
+
healed: number;
|
|
63
|
+
}>;
|
|
64
|
+
export type DepartmentMetricsDto = z.infer<typeof _DepartmentMetricsDto>;
|
|
65
|
+
/** Single use case option for the analytics dashboard (FlowSpec-derived or category-based). */
|
|
66
|
+
export declare const _AnalyticsUseCaseOption: z.ZodObject<{
|
|
67
|
+
id: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
68
|
+
value: z.ZodString;
|
|
69
|
+
displayValue: z.ZodString;
|
|
70
|
+
group: z.ZodEnum<["flowSpec", "category"]>;
|
|
71
|
+
findingKinds: z.ZodOptional<z.ZodString>;
|
|
72
|
+
}, "strip", z.ZodTypeAny, {
|
|
73
|
+
group: "category" | "flowSpec";
|
|
74
|
+
value: string;
|
|
75
|
+
id: string | number;
|
|
76
|
+
displayValue: string;
|
|
77
|
+
findingKinds?: string | undefined;
|
|
78
|
+
}, {
|
|
79
|
+
group: "category" | "flowSpec";
|
|
80
|
+
value: string;
|
|
81
|
+
id: string | number;
|
|
82
|
+
displayValue: string;
|
|
83
|
+
findingKinds?: string | undefined;
|
|
84
|
+
}>;
|
|
85
|
+
export type AnalyticsUseCaseOption = z.infer<typeof _AnalyticsUseCaseOption>;
|
|
86
|
+
/** Response from GET /analytics/use-cases. FlowSpec use cases first, then category use cases. */
|
|
87
|
+
export declare const _AnalyticsUseCasesResponse: z.ZodObject<{
|
|
88
|
+
flowSpecUseCases: z.ZodArray<z.ZodObject<{
|
|
89
|
+
id: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
90
|
+
value: z.ZodString;
|
|
91
|
+
displayValue: z.ZodString;
|
|
92
|
+
group: z.ZodEnum<["flowSpec", "category"]>;
|
|
93
|
+
findingKinds: z.ZodOptional<z.ZodString>;
|
|
94
|
+
}, "strip", z.ZodTypeAny, {
|
|
95
|
+
group: "category" | "flowSpec";
|
|
96
|
+
value: string;
|
|
97
|
+
id: string | number;
|
|
98
|
+
displayValue: string;
|
|
99
|
+
findingKinds?: string | undefined;
|
|
100
|
+
}, {
|
|
101
|
+
group: "category" | "flowSpec";
|
|
102
|
+
value: string;
|
|
103
|
+
id: string | number;
|
|
104
|
+
displayValue: string;
|
|
105
|
+
findingKinds?: string | undefined;
|
|
106
|
+
}>, "many">;
|
|
107
|
+
categoryUseCases: z.ZodArray<z.ZodObject<{
|
|
108
|
+
id: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
109
|
+
value: z.ZodString;
|
|
110
|
+
displayValue: z.ZodString;
|
|
111
|
+
group: z.ZodEnum<["flowSpec", "category"]>;
|
|
112
|
+
findingKinds: z.ZodOptional<z.ZodString>;
|
|
113
|
+
}, "strip", z.ZodTypeAny, {
|
|
114
|
+
group: "category" | "flowSpec";
|
|
115
|
+
value: string;
|
|
116
|
+
id: string | number;
|
|
117
|
+
displayValue: string;
|
|
118
|
+
findingKinds?: string | undefined;
|
|
119
|
+
}, {
|
|
120
|
+
group: "category" | "flowSpec";
|
|
121
|
+
value: string;
|
|
122
|
+
id: string | number;
|
|
123
|
+
displayValue: string;
|
|
124
|
+
findingKinds?: string | undefined;
|
|
125
|
+
}>, "many">;
|
|
126
|
+
}, "strip", z.ZodTypeAny, {
|
|
127
|
+
flowSpecUseCases: {
|
|
128
|
+
group: "category" | "flowSpec";
|
|
129
|
+
value: string;
|
|
130
|
+
id: string | number;
|
|
131
|
+
displayValue: string;
|
|
132
|
+
findingKinds?: string | undefined;
|
|
133
|
+
}[];
|
|
134
|
+
categoryUseCases: {
|
|
135
|
+
group: "category" | "flowSpec";
|
|
136
|
+
value: string;
|
|
137
|
+
id: string | number;
|
|
138
|
+
displayValue: string;
|
|
139
|
+
findingKinds?: string | undefined;
|
|
140
|
+
}[];
|
|
141
|
+
}, {
|
|
142
|
+
flowSpecUseCases: {
|
|
143
|
+
group: "category" | "flowSpec";
|
|
144
|
+
value: string;
|
|
145
|
+
id: string | number;
|
|
146
|
+
displayValue: string;
|
|
147
|
+
findingKinds?: string | undefined;
|
|
148
|
+
}[];
|
|
149
|
+
categoryUseCases: {
|
|
150
|
+
group: "category" | "flowSpec";
|
|
151
|
+
value: string;
|
|
152
|
+
id: string | number;
|
|
153
|
+
displayValue: string;
|
|
154
|
+
findingKinds?: string | undefined;
|
|
155
|
+
}[];
|
|
156
|
+
}>;
|
|
157
|
+
export type AnalyticsUseCasesResponse = z.infer<typeof _AnalyticsUseCasesResponse>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._FindingMetricsSeriesDto = void 0;
|
|
3
|
+
exports._AnalyticsUseCasesResponse = exports._AnalyticsUseCaseOption = exports._DepartmentMetricsDto = exports._FindingMetricsSeriesDto = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
/**
|
|
6
6
|
* One period of finding metrics from the analytics API.
|
|
@@ -18,4 +18,28 @@ exports._FindingMetricsSeriesDto = zod_1.z.object({
|
|
|
18
18
|
healed: zod_1.z.number().optional(),
|
|
19
19
|
averageDaysToHeal: zod_1.z.number().optional(),
|
|
20
20
|
});
|
|
21
|
+
/**
|
|
22
|
+
* Department-level finding metrics for the analytics dashboard.
|
|
23
|
+
* count = total findings; findingsClosed = completed; engaged = in progress; healed = closed after flow trigger.
|
|
24
|
+
*/
|
|
25
|
+
exports._DepartmentMetricsDto = zod_1.z.object({
|
|
26
|
+
department: zod_1.z.string(),
|
|
27
|
+
count: zod_1.z.number(),
|
|
28
|
+
findingsClosed: zod_1.z.number(),
|
|
29
|
+
engaged: zod_1.z.number(),
|
|
30
|
+
healed: zod_1.z.number(),
|
|
31
|
+
});
|
|
32
|
+
/** Single use case option for the analytics dashboard (FlowSpec-derived or category-based). */
|
|
33
|
+
exports._AnalyticsUseCaseOption = zod_1.z.object({
|
|
34
|
+
id: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]),
|
|
35
|
+
value: zod_1.z.string(),
|
|
36
|
+
displayValue: zod_1.z.string(),
|
|
37
|
+
group: zod_1.z.enum(['flowSpec', 'category']),
|
|
38
|
+
findingKinds: zod_1.z.string().optional(),
|
|
39
|
+
});
|
|
40
|
+
/** Response from GET /analytics/use-cases. FlowSpec use cases first, then category use cases. */
|
|
41
|
+
exports._AnalyticsUseCasesResponse = zod_1.z.object({
|
|
42
|
+
flowSpecUseCases: zod_1.z.array(exports._AnalyticsUseCaseOption),
|
|
43
|
+
categoryUseCases: zod_1.z.array(exports._AnalyticsUseCaseOption),
|
|
44
|
+
});
|
|
21
45
|
//# sourceMappingURL=analytics.dto.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.dto.js","sourceRoot":"","sources":["../../../src/dto/analytics.dto.ts"],"names":[],"mappings":";;;AAAA,6BAAsB;AAEtB;;;GAGG;AACU,QAAA,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/C,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;IACjB,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE;IACtB,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;IACjB,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,iBAAiB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACzC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"analytics.dto.js","sourceRoot":"","sources":["../../../src/dto/analytics.dto.ts"],"names":[],"mappings":";;;AAAA,6BAAsB;AAEtB;;;GAGG;AACU,QAAA,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/C,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;IACjB,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE;IACtB,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;IACjB,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,iBAAiB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACzC,CAAC,CAAC;AAIH;;;GAGG;AACU,QAAA,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE;IACtB,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;IACjB,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;IACnB,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE;CACnB,CAAC,CAAC;AAIH,+FAA+F;AAClF,QAAA,uBAAuB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC9C,EAAE,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;IACjB,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE;IACxB,KAAK,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACvC,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAGH,iGAAiG;AACpF,QAAA,0BAA0B,GAAG,OAAC,CAAC,MAAM,CAAC;IACjD,gBAAgB,EAAE,OAAC,CAAC,KAAK,CAAC,+BAAuB,CAAC;IAClD,gBAAgB,EAAE,OAAC,CAAC,KAAK,CAAC,+BAAuB,CAAC;CACnD,CAAC,CAAC"}
|
|
@@ -40,6 +40,9 @@ export declare const _EngagementMappingDto: z.ZodObject<{
|
|
|
40
40
|
forceTrigger?: boolean | undefined;
|
|
41
41
|
}>>;
|
|
42
42
|
}, "strip", z.ZodTypeAny, {
|
|
43
|
+
flowSpec: {
|
|
44
|
+
id: string;
|
|
45
|
+
};
|
|
43
46
|
finding: {
|
|
44
47
|
id: string;
|
|
45
48
|
uid: string;
|
|
@@ -47,15 +50,15 @@ export declare const _EngagementMappingDto: z.ZodObject<{
|
|
|
47
50
|
score: number;
|
|
48
51
|
bucket: string;
|
|
49
52
|
};
|
|
50
|
-
flowSpec: {
|
|
51
|
-
id: string;
|
|
52
|
-
};
|
|
53
53
|
engagementConfig?: {
|
|
54
54
|
consolidation?: boolean | undefined;
|
|
55
55
|
overrideGhostMode?: boolean | undefined;
|
|
56
56
|
forceTrigger?: boolean | undefined;
|
|
57
57
|
} | undefined;
|
|
58
58
|
}, {
|
|
59
|
+
flowSpec: {
|
|
60
|
+
id: string;
|
|
61
|
+
};
|
|
59
62
|
finding: {
|
|
60
63
|
id: string;
|
|
61
64
|
uid: string;
|
|
@@ -63,9 +66,6 @@ export declare const _EngagementMappingDto: z.ZodObject<{
|
|
|
63
66
|
score: number;
|
|
64
67
|
bucket: string;
|
|
65
68
|
};
|
|
66
|
-
flowSpec: {
|
|
67
|
-
id: string;
|
|
68
|
-
};
|
|
69
69
|
engagementConfig?: {
|
|
70
70
|
consolidation?: boolean | undefined;
|
|
71
71
|
overrideGhostMode?: boolean | undefined;
|
|
@@ -43,6 +43,9 @@ export declare const _PlatformEngagementMappingDto: z.ZodObject<z.objectUtil.ext
|
|
|
43
43
|
tid: z.ZodString;
|
|
44
44
|
}>, "strip", z.ZodTypeAny, {
|
|
45
45
|
tid: string;
|
|
46
|
+
flowSpec: {
|
|
47
|
+
id: string;
|
|
48
|
+
};
|
|
46
49
|
finding: {
|
|
47
50
|
id: string;
|
|
48
51
|
uid: string;
|
|
@@ -50,9 +53,6 @@ export declare const _PlatformEngagementMappingDto: z.ZodObject<z.objectUtil.ext
|
|
|
50
53
|
score: number;
|
|
51
54
|
bucket: string;
|
|
52
55
|
};
|
|
53
|
-
flowSpec: {
|
|
54
|
-
id: string;
|
|
55
|
-
};
|
|
56
56
|
engagementConfig?: {
|
|
57
57
|
consolidation?: boolean | undefined;
|
|
58
58
|
overrideGhostMode?: boolean | undefined;
|
|
@@ -60,6 +60,9 @@ export declare const _PlatformEngagementMappingDto: z.ZodObject<z.objectUtil.ext
|
|
|
60
60
|
} | undefined;
|
|
61
61
|
}, {
|
|
62
62
|
tid: string;
|
|
63
|
+
flowSpec: {
|
|
64
|
+
id: string;
|
|
65
|
+
};
|
|
63
66
|
finding: {
|
|
64
67
|
id: string;
|
|
65
68
|
uid: string;
|
|
@@ -67,9 +70,6 @@ export declare const _PlatformEngagementMappingDto: z.ZodObject<z.objectUtil.ext
|
|
|
67
70
|
score: number;
|
|
68
71
|
bucket: string;
|
|
69
72
|
};
|
|
70
|
-
flowSpec: {
|
|
71
|
-
id: string;
|
|
72
|
-
};
|
|
73
73
|
engagementConfig?: {
|
|
74
74
|
consolidation?: boolean | undefined;
|
|
75
75
|
overrideGhostMode?: boolean | undefined;
|
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
import { FindingMetricsSeriesDto } from '../dto';
|
|
1
|
+
import { AnalyticsUseCasesResponse, DepartmentMetricsDto, FindingMetricsSeriesDto } from '../dto';
|
|
2
2
|
import { RestClient } from './rest';
|
|
3
3
|
export interface AnalyticsFindingMetricsParams {
|
|
4
4
|
/** Comma-separated finding kinds (e.g. "CRITICAL_VULNERABILITY_OUT_OF_SLA,HIGH_VULNERABILITY_OUT_OF_SLA"). Omit for all kinds. */
|
|
5
5
|
findingKinds?: string;
|
|
6
6
|
periodType?: string;
|
|
7
7
|
periodCount?: number;
|
|
8
|
+
/** When true, response includes department-level metrics (departments array). */
|
|
9
|
+
includeDepartments?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface AnalyticsUseCasesParams {
|
|
12
|
+
/** When true, include use cases derived from FlowSpecs. Default false. */
|
|
13
|
+
includeFlowSpecUseCases?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface AnalyticsFindingMetricsResponse {
|
|
16
|
+
data: FindingMetricsSeriesDto[];
|
|
17
|
+
departments?: DepartmentMetricsDto[];
|
|
8
18
|
}
|
|
9
19
|
export declare class AnalyticsService {
|
|
10
20
|
private rest;
|
|
11
21
|
constructor(rest: RestClient);
|
|
12
|
-
/** Fetches
|
|
22
|
+
/** Fetches use cases for the analytics dashboard. FlowSpec-derived use cases only when includeFlowSpecUseCases is true. */
|
|
23
|
+
getUseCases: (params?: AnalyticsUseCasesParams) => Promise<AnalyticsUseCasesResponse>;
|
|
24
|
+
/** Fetches finding metrics series for the tenant. Optionally includes department breakdown when includeDepartments is true. */
|
|
13
25
|
getFindingMetricsSeries: (params?: AnalyticsFindingMetricsParams) => Promise<FindingMetricsSeriesDto[]>;
|
|
26
|
+
/** Fetches finding metrics series and optional department breakdown. Use when department progress UI is needed. */
|
|
27
|
+
getFindingMetricsSeriesWithDepartments: (params?: AnalyticsFindingMetricsParams) => Promise<AnalyticsFindingMetricsResponse>;
|
|
14
28
|
}
|
|
@@ -5,7 +5,16 @@ const constants_1 = require("./constants");
|
|
|
5
5
|
class AnalyticsService {
|
|
6
6
|
constructor(rest) {
|
|
7
7
|
this.rest = rest;
|
|
8
|
-
/** Fetches
|
|
8
|
+
/** Fetches use cases for the analytics dashboard. FlowSpec-derived use cases only when includeFlowSpecUseCases is true. */
|
|
9
|
+
this.getUseCases = async (params) => {
|
|
10
|
+
const res = await this.rest.call({
|
|
11
|
+
url: `/api/v1/${constants_1.KIND.ANALYTICS}/use-cases`,
|
|
12
|
+
method: 'GET',
|
|
13
|
+
params: params,
|
|
14
|
+
});
|
|
15
|
+
return res.data;
|
|
16
|
+
};
|
|
17
|
+
/** Fetches finding metrics series for the tenant. Optionally includes department breakdown when includeDepartments is true. */
|
|
9
18
|
this.getFindingMetricsSeries = async (params) => {
|
|
10
19
|
var _a;
|
|
11
20
|
const res = await this.rest.call({
|
|
@@ -16,6 +25,20 @@ class AnalyticsService {
|
|
|
16
25
|
const body = res.data;
|
|
17
26
|
return (_a = body === null || body === void 0 ? void 0 : body.data) !== null && _a !== void 0 ? _a : [];
|
|
18
27
|
};
|
|
28
|
+
/** Fetches finding metrics series and optional department breakdown. Use when department progress UI is needed. */
|
|
29
|
+
this.getFindingMetricsSeriesWithDepartments = async (params) => {
|
|
30
|
+
var _a;
|
|
31
|
+
const res = await this.rest.call({
|
|
32
|
+
url: `/api/v1/${constants_1.KIND.ANALYTICS}`,
|
|
33
|
+
method: 'GET',
|
|
34
|
+
params: { ...params, includeDepartments: true },
|
|
35
|
+
});
|
|
36
|
+
const body = res.data;
|
|
37
|
+
return {
|
|
38
|
+
data: (_a = body === null || body === void 0 ? void 0 : body.data) !== null && _a !== void 0 ? _a : [],
|
|
39
|
+
...((body === null || body === void 0 ? void 0 : body.departments) !== undefined && body.departments.length > 0 ? { departments: body.departments } : {}),
|
|
40
|
+
};
|
|
41
|
+
};
|
|
19
42
|
}
|
|
20
43
|
}
|
|
21
44
|
exports.AnalyticsService = AnalyticsService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.service.js","sourceRoot":"","sources":["../../../src/services/analytics.service.ts"],"names":[],"mappings":";;;AAEA,2CAAiC;
|
|
1
|
+
{"version":3,"file":"analytics.service.js","sourceRoot":"","sources":["../../../src/services/analytics.service.ts"],"names":[],"mappings":";;;AAEA,2CAAiC;AAqBjC,MAAa,gBAAgB;IAC3B,YAAoB,IAAgB;QAAhB,SAAI,GAAJ,IAAI,CAAY;QAEpC,2HAA2H;QAC3H,gBAAW,GAAG,KAAK,EAAE,MAAgC,EAAsC,EAAE;YAC3F,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC/B,GAAG,EAAE,WAAW,gBAAI,CAAC,SAAS,YAAY;gBAC1C,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,MAA+D;aACxE,CAAC,CAAC;YACH,OAAO,GAAG,CAAC,IAAiC,CAAC;QAC/C,CAAC,CAAC;QAEF,+HAA+H;QAC/H,4BAAuB,GAAG,KAAK,EAAE,MAAsC,EAAsC,EAAE;;YAC7G,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC/B,GAAG,EAAE,WAAW,gBAAI,CAAC,SAAS,EAAE;gBAChC,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,MAA+D;aACxE,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAuC,CAAC;YACzD,OAAO,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,mCAAI,EAAE,CAAC;QAC1B,CAAC,CAAC;QAEF,mHAAmH;QACnH,2CAAsC,GAAG,KAAK,EAAE,MAAsC,EAA4C,EAAE;;YAClI,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC/B,GAAG,EAAE,WAAW,gBAAI,CAAC,SAAS,EAAE;gBAChC,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,EAAC,GAAG,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAA0D;aACvG,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAuC,CAAC;YACzD,OAAO;gBACL,IAAI,EAAE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,mCAAI,EAAE;gBACtB,GAAG,CAAC,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,WAAW,MAAK,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,WAAW,EAAE,IAAI,CAAC,WAAW,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aAC3G,CAAC;QACJ,CAAC,CAAC;IAnCqC,CAAC;CAoCzC;AArCD,4CAqCC"}
|
package/package.json
CHANGED
package/src/dto/analytics.dto.ts
CHANGED
|
@@ -18,3 +18,34 @@ export const _FindingMetricsSeriesDto = z.object({
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
export type FindingMetricsSeriesDto = z.infer<typeof _FindingMetricsSeriesDto>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Department-level finding metrics for the analytics dashboard.
|
|
24
|
+
* count = total findings; findingsClosed = completed; engaged = in progress; healed = closed after flow trigger.
|
|
25
|
+
*/
|
|
26
|
+
export const _DepartmentMetricsDto = z.object({
|
|
27
|
+
department: z.string(),
|
|
28
|
+
count: z.number(),
|
|
29
|
+
findingsClosed: z.number(),
|
|
30
|
+
engaged: z.number(),
|
|
31
|
+
healed: z.number(),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export type DepartmentMetricsDto = z.infer<typeof _DepartmentMetricsDto>;
|
|
35
|
+
|
|
36
|
+
/** Single use case option for the analytics dashboard (FlowSpec-derived or category-based). */
|
|
37
|
+
export const _AnalyticsUseCaseOption = z.object({
|
|
38
|
+
id: z.union([z.string(), z.number()]),
|
|
39
|
+
value: z.string(),
|
|
40
|
+
displayValue: z.string(),
|
|
41
|
+
group: z.enum(['flowSpec', 'category']),
|
|
42
|
+
findingKinds: z.string().optional(),
|
|
43
|
+
});
|
|
44
|
+
export type AnalyticsUseCaseOption = z.infer<typeof _AnalyticsUseCaseOption>;
|
|
45
|
+
|
|
46
|
+
/** Response from GET /analytics/use-cases. FlowSpec use cases first, then category use cases. */
|
|
47
|
+
export const _AnalyticsUseCasesResponse = z.object({
|
|
48
|
+
flowSpecUseCases: z.array(_AnalyticsUseCaseOption),
|
|
49
|
+
categoryUseCases: z.array(_AnalyticsUseCaseOption),
|
|
50
|
+
});
|
|
51
|
+
export type AnalyticsUseCasesResponse = z.infer<typeof _AnalyticsUseCasesResponse>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {FindingMetricsSeriesDto} from '../dto';
|
|
1
|
+
import {AnalyticsUseCasesResponse, DepartmentMetricsDto, FindingMetricsSeriesDto} from '../dto';
|
|
2
2
|
import {RestClient} from './rest';
|
|
3
3
|
import {KIND} from './constants';
|
|
4
4
|
|
|
@@ -7,19 +7,55 @@ export interface AnalyticsFindingMetricsParams {
|
|
|
7
7
|
findingKinds?: string;
|
|
8
8
|
periodType?: string;
|
|
9
9
|
periodCount?: number;
|
|
10
|
+
/** When true, response includes department-level metrics (departments array). */
|
|
11
|
+
includeDepartments?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface AnalyticsUseCasesParams {
|
|
15
|
+
/** When true, include use cases derived from FlowSpecs. Default false. */
|
|
16
|
+
includeFlowSpecUseCases?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface AnalyticsFindingMetricsResponse {
|
|
20
|
+
data: FindingMetricsSeriesDto[];
|
|
21
|
+
departments?: DepartmentMetricsDto[];
|
|
10
22
|
}
|
|
11
23
|
|
|
12
24
|
export class AnalyticsService {
|
|
13
25
|
constructor(private rest: RestClient) {}
|
|
14
26
|
|
|
15
|
-
/** Fetches
|
|
27
|
+
/** Fetches use cases for the analytics dashboard. FlowSpec-derived use cases only when includeFlowSpecUseCases is true. */
|
|
28
|
+
getUseCases = async (params?: AnalyticsUseCasesParams): Promise<AnalyticsUseCasesResponse> => {
|
|
29
|
+
const res = await this.rest.call({
|
|
30
|
+
url: `/api/v1/${KIND.ANALYTICS}/use-cases`,
|
|
31
|
+
method: 'GET',
|
|
32
|
+
params: params as Record<string, string | number | boolean | undefined>,
|
|
33
|
+
});
|
|
34
|
+
return res.data as AnalyticsUseCasesResponse;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** Fetches finding metrics series for the tenant. Optionally includes department breakdown when includeDepartments is true. */
|
|
16
38
|
getFindingMetricsSeries = async (params?: AnalyticsFindingMetricsParams): Promise<FindingMetricsSeriesDto[]> => {
|
|
17
39
|
const res = await this.rest.call({
|
|
18
40
|
url: `/api/v1/${KIND.ANALYTICS}`,
|
|
19
41
|
method: 'GET',
|
|
20
|
-
params: params as Record<string, string | number | undefined>,
|
|
42
|
+
params: params as Record<string, string | number | boolean | undefined>,
|
|
21
43
|
});
|
|
22
|
-
const body = res.data as
|
|
44
|
+
const body = res.data as AnalyticsFindingMetricsResponse;
|
|
23
45
|
return body?.data ?? [];
|
|
24
46
|
};
|
|
47
|
+
|
|
48
|
+
/** Fetches finding metrics series and optional department breakdown. Use when department progress UI is needed. */
|
|
49
|
+
getFindingMetricsSeriesWithDepartments = async (params?: AnalyticsFindingMetricsParams): Promise<AnalyticsFindingMetricsResponse> => {
|
|
50
|
+
const res = await this.rest.call({
|
|
51
|
+
url: `/api/v1/${KIND.ANALYTICS}`,
|
|
52
|
+
method: 'GET',
|
|
53
|
+
params: {...params, includeDepartments: true} as Record<string, string | number | boolean | undefined>,
|
|
54
|
+
});
|
|
55
|
+
const body = res.data as AnalyticsFindingMetricsResponse;
|
|
56
|
+
return {
|
|
57
|
+
data: body?.data ?? [],
|
|
58
|
+
...(body?.departments !== undefined && body.departments.length > 0 ? {departments: body.departments} : {}),
|
|
59
|
+
};
|
|
60
|
+
};
|
|
25
61
|
}
|