Skip to content

Commit 03e5180

Browse files
feat(insights): add getTopFailureCount to MaestroProcesses and Cases [PLT-103284] (#456)
Add getTopFailureCount(startTime, endTime) to MaestroProcessesService and CasesService. Returns top 10 processes ranked by faulted instance count. Backend returns runCount (reused response type) — SDK renames to failureCount for clarity. processKey is null from API, defaulted to empty string. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 30b5a58 commit 03e5180

15 files changed

Lines changed: 369 additions & 7 deletions

File tree

docs/oauth-scopes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ This page lists the specific OAuth scopes required in external app for each SDK
7272
| `getAll()` | `PIMS` |
7373
| `getIncidents()` | `PIMS` |
7474
| `getTopRunCount()` | `Insights.RealTimeData Insights OR.Folders.Read` |
75+
| `getTopFaultedCount()` | `Insights.RealTimeData Insights OR.Folders.Read` |
7576
| `getInstanceStatusTimeline()` | `Insights.RealTimeData Insights OR.Folders.Read` |
7677
| `getTopExecutionDuration()` | `Insights.RealTimeData Insights OR.Folders.Read` |
7778

@@ -95,6 +96,7 @@ This page lists the specific OAuth scopes required in external app for each SDK
9596
|--------|-------------|
9697
| `getAll()` | `PIMS` |
9798
| `getTopRunCount()` | `Insights.RealTimeData Insights OR.Folders.Read` |
99+
| `getTopFaultedCount()` | `Insights.RealTimeData Insights OR.Folders.Read` |
98100
| `getInstanceStatusTimeline()` | `Insights.RealTimeData Insights OR.Folders.Read` |
99101
| `getTopExecutionDuration()` | `Insights.RealTimeData Insights OR.Folders.Read` |
100102

src/models/maestro/cases.models.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Model classes for Maestro cases
44
*/
55

6-
import { CaseGetAllResponse, CaseGetTopRunCountResponse, CaseGetTopDurationResponse } from './cases.types';
6+
import { CaseGetAllResponse, CaseGetTopRunCountResponse, CaseGetTopFaultedCountResponse, CaseGetTopDurationResponse } from './cases.types';
77
import { TopQueryOptions, InstanceStatusTimelineResponse, TimelineOptions } from './insights.types';
88

99
/**
@@ -80,6 +80,45 @@ export interface CasesServiceModel {
8080
*/
8181
getTopRunCount(startTime: Date, endTime: Date, options?: TopQueryOptions): Promise<CaseGetTopRunCountResponse[]>;
8282

83+
/**
84+
* Get the top 10 case processes ranked by failure count within a time range.
85+
*
86+
* Returns an array of up to 10 case processes sorted by how many instances faulted,
87+
* useful for identifying the most error-prone case processes in a given period.
88+
*
89+
* @param startTime - Start of the time range to query
90+
* @param endTime - End of the time range to query
91+
* @param options - Optional filters (packageId, processKey, version)
92+
* @returns Promise resolving to an array of {@link CaseGetTopFaultedCountResponse}
93+
* @example
94+
* ```typescript
95+
* import { Cases } from '@uipath/uipath-typescript/cases';
96+
*
97+
* const cases = new Cases(sdk);
98+
*
99+
* // Get top case processes by faulted count for the last 7 days
100+
* const topFailing = await cases.getTopFaultedCount(
101+
* new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
102+
* new Date()
103+
* );
104+
*
105+
* for (const process of topFailing) {
106+
* console.log(`${process.packageId}: ${process.faultedCount} failures`);
107+
* }
108+
* ```
109+
*
110+
* @example
111+
* ```typescript
112+
* // Get top case processes by faulted count for a specific package
113+
* const filtered = await cases.getTopFaultedCount(
114+
* new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
115+
* new Date(),
116+
* { packageId: '<packageId>' }
117+
* );
118+
* ```
119+
*/
120+
getTopFaultedCount(startTime: Date, endTime: Date, options?: TopQueryOptions): Promise<CaseGetTopFaultedCountResponse[]>;
121+
83122
/**
84123
* Get all instances status counts aggregated by date for case management processes.
85124
*

src/models/maestro/cases.types.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Types and interfaces for Maestro case management
44
*/
55

6-
import { GetTopRunCountResponse, GetTopDurationResponse } from './insights.types';
6+
import { GetTopRunCountResponse, GetTopDurationResponse, GetTopFaultedCountResponse } from './insights.types';
77

88
/**
99
* Case information with instance statistics
@@ -53,10 +53,18 @@ export interface CaseGetTopRunCountResponse extends GetTopRunCountResponse {
5353
name: string;
5454
}
5555

56+
/**
57+
* Response for a single entry in top cases by failure count
58+
*/
59+
export interface CaseGetTopFaultedCountResponse extends GetTopFaultedCountResponse {
60+
/** Human-readable case name */
61+
name: string;
62+
}
63+
5664
/**
5765
* Response for a single entry in top cases by duration
5866
*/
5967
export interface CaseGetTopDurationResponse extends GetTopDurationResponse {
6068
/** Human-readable case name */
6169
name: string;
62-
}
70+
}

src/models/maestro/insights.types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ export interface GetTopRunCountResponse extends GetTopBaseResponse {
3434
runCount: number;
3535
}
3636

37+
/**
38+
* Response for the top failure count Insights endpoint
39+
*/
40+
export interface GetTopFaultedCountResponse extends GetTopBaseResponse {
41+
/** Number of faulted instances in the given time range */
42+
faultedCount: number;
43+
}
44+
3745
/**
3846
* Time bucketing granularity for insights time-series queries.
3947
*

src/models/maestro/processes.models.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Model classes for Maestro processes
44
*/
55

6-
import { RawMaestroProcessGetAllResponse, ProcessGetTopRunCountResponse, ProcessGetTopDurationResponse } from './processes.types';
6+
import { RawMaestroProcessGetAllResponse, ProcessGetTopRunCountResponse, ProcessGetTopFaultedCountResponse, ProcessGetTopDurationResponse } from './processes.types';
77
import { ProcessIncidentGetResponse } from './process-incidents.types';
88
import { TopQueryOptions, InstanceStatusTimelineResponse, TimelineOptions } from './insights.types';
99

@@ -107,6 +107,45 @@ export interface MaestroProcessesServiceModel {
107107
*/
108108
getTopRunCount(startTime: Date, endTime: Date, options?: TopQueryOptions): Promise<ProcessGetTopRunCountResponse[]>;
109109

110+
/**
111+
* Get the top 10 processes ranked by failure count within a time range.
112+
*
113+
* Returns an array of up to 10 processes sorted by how many instances faulted,
114+
* useful for identifying the most error-prone processes in a given period.
115+
*
116+
* @param startTime - Start of the time range to query
117+
* @param endTime - End of the time range to query
118+
* @param options - Optional filters (packageId, processKey, version)
119+
* @returns Promise resolving to an array of {@link ProcessGetTopFaultedCountResponse}
120+
* @example
121+
* ```typescript
122+
* import { MaestroProcesses } from '@uipath/uipath-typescript/maestro-processes';
123+
*
124+
* const maestroProcesses = new MaestroProcesses(sdk);
125+
*
126+
* // Get top processes by faulted count for the last 7 days
127+
* const topFailing = await maestroProcesses.getTopFaultedCount(
128+
* new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
129+
* new Date()
130+
* );
131+
*
132+
* for (const process of topFailing) {
133+
* console.log(`${process.packageId}: ${process.faultedCount} failures`);
134+
* }
135+
* ```
136+
*
137+
* @example
138+
* ```typescript
139+
* // Get top processes by faulted count for a specific package
140+
* const filtered = await maestroProcesses.getTopFaultedCount(
141+
* new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
142+
* new Date(),
143+
* { packageId: '<packageId>' }
144+
* );
145+
* ```
146+
*/
147+
getTopFaultedCount(startTime: Date, endTime: Date, options?: TopQueryOptions): Promise<ProcessGetTopFaultedCountResponse[]>;
148+
110149
/**
111150
* Get all instances status counts aggregated by date for maestro processes.
112151
*

src/models/maestro/processes.types.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Types and interfaces for Maestro process management
44
*/
55

6-
import { GetTopRunCountResponse, GetTopDurationResponse } from './insights.types';
6+
import { GetTopRunCountResponse, GetTopDurationResponse, GetTopFaultedCountResponse } from './insights.types';
77

88
/**
99
* Process information with instance statistics
@@ -53,6 +53,14 @@ export interface ProcessGetTopRunCountResponse extends GetTopRunCountResponse {
5353
name: string;
5454
}
5555

56+
/**
57+
* Response for a single entry in top processes by failure count
58+
*/
59+
export interface ProcessGetTopFaultedCountResponse extends GetTopFaultedCountResponse {
60+
/** Human-readable process name */
61+
name: string;
62+
}
63+
5664
/**
5765
* Response for a single entry in top processes by duration
5866
*/

src/services/maestro/cases/cases.ts

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CaseGetAllResponse, CaseGetTopRunCountResponse, CaseGetTopDurationResponse, GetTopRunCountResponse, GetTopDurationResponse, InstanceStatusTimelineResponse } from '../../../models/maestro';
1+
import { CaseGetAllResponse, CaseGetTopRunCountResponse, CaseGetTopFaultedCountResponse, CaseGetTopDurationResponse, GetTopRunCountResponse, GetTopDurationResponse, InstanceStatusTimelineResponse } from '../../../models/maestro';
22
import type { TimelineOptions, TopQueryOptions } from '../../../models/maestro';
33
import { ProcessType } from '../../../models/maestro/cases.internal-types';
44
import { MAESTRO_ENDPOINTS } from '../../../utils/constants/endpoints';
@@ -145,6 +145,57 @@ export class CasesService extends BaseService implements CasesServiceModel {
145145
return fetchInstanceStatusTimeline(this.post.bind(this), startTime, endTime, true, options);
146146
}
147147

148+
/**
149+
* Get the top 10 case processes ranked by failure count within a time range.
150+
*
151+
* Returns an array of up to 10 case processes sorted by how many instances faulted,
152+
* useful for identifying the most error-prone case processes in a given period.
153+
*
154+
* @param startTime - Start of the time range to query
155+
* @param endTime - End of the time range to query
156+
* @param options - Optional filters (packageId, processKey, version)
157+
* @returns Promise resolving to an array of {@link CaseGetTopFaultedCountResponse}
158+
* @example
159+
* ```typescript
160+
* import { Cases } from '@uipath/uipath-typescript/cases';
161+
*
162+
* const cases = new Cases(sdk);
163+
*
164+
* // Get top case processes by faulted count for the last 7 days
165+
* const topFailing = await cases.getTopFaultedCount(
166+
* new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
167+
* new Date()
168+
* );
169+
*
170+
* for (const process of topFailing) {
171+
* console.log(`${process.packageId}: ${process.faultedCount} failures`);
172+
* }
173+
* ```
174+
*
175+
* @example
176+
* ```typescript
177+
* // Get top case processes by faulted count for a specific package
178+
* const filtered = await cases.getTopFaultedCount(
179+
* new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
180+
* new Date(),
181+
* { packageId: '<packageId>' }
182+
* );
183+
* ```
184+
*/
185+
@track('Cases.GetTopFaultedCount')
186+
async getTopFaultedCount(startTime: Date, endTime: Date, options?: TopQueryOptions): Promise<CaseGetTopFaultedCountResponse[]> {
187+
const { data } = await this.post<GetTopRunCountResponse[]>(
188+
MAESTRO_ENDPOINTS.INSIGHTS.TOP_PROCESSES_WITH_FAILURE,
189+
buildInsightsTopBody(startTime, endTime, true, options)
190+
);
191+
return (data ?? []).map(item => ({
192+
packageId: item.packageId,
193+
processKey: item.processKey,
194+
faultedCount: item.runCount,
195+
name: this.extractCaseName(item.packageId),
196+
}));
197+
}
198+
148199
/**
149200
* Get the top 5 case processes ranked by total duration within a time range.
150201
*

src/services/maestro/processes/processes.ts

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MaestroProcessGetAllResponse, ProcessIncidentGetResponse, ProcessGetTopRunCountResponse, ProcessGetTopDurationResponse, GetTopRunCountResponse, GetTopDurationResponse, InstanceStatusTimelineResponse } from '../../../models/maestro';
1+
import { MaestroProcessGetAllResponse, ProcessIncidentGetResponse, ProcessGetTopRunCountResponse, ProcessGetTopFaultedCountResponse, ProcessGetTopDurationResponse, GetTopRunCountResponse, GetTopDurationResponse, InstanceStatusTimelineResponse } from '../../../models/maestro';
22
import type { TimelineOptions, TopQueryOptions } from '../../../models/maestro';
33
import type { IUiPath } from '../../../core/types';
44
import { MAESTRO_ENDPOINTS } from '../../../utils/constants/endpoints';
@@ -175,6 +175,57 @@ export class MaestroProcessesService extends BaseService implements MaestroProce
175175
return fetchInstanceStatusTimeline(this.post.bind(this), startTime, endTime, false, options);
176176
}
177177

178+
/**
179+
* Get the top 10 processes ranked by failure count within a time range.
180+
*
181+
* Returns an array of up to 10 processes sorted by how many instances faulted,
182+
* useful for identifying the most error-prone processes in a given period.
183+
*
184+
* @param startTime - Start of the time range to query
185+
* @param endTime - End of the time range to query
186+
* @param options - Optional filters (packageId, processKey, version)
187+
* @returns Promise resolving to an array of {@link ProcessGetTopFaultedCountResponse}
188+
* @example
189+
* ```typescript
190+
* import { MaestroProcesses } from '@uipath/uipath-typescript/maestro-processes';
191+
*
192+
* const maestroProcesses = new MaestroProcesses(sdk);
193+
*
194+
* // Get top processes by faulted count for the last 7 days
195+
* const topFailing = await maestroProcesses.getTopFaultedCount(
196+
* new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
197+
* new Date()
198+
* );
199+
*
200+
* for (const process of topFailing) {
201+
* console.log(`${process.packageId}: ${process.faultedCount} failures`);
202+
* }
203+
* ```
204+
*
205+
* @example
206+
* ```typescript
207+
* // Get top processes by faulted count for a specific package
208+
* const filtered = await maestroProcesses.getTopFaultedCount(
209+
* new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
210+
* new Date(),
211+
* { packageId: '<packageId>' }
212+
* );
213+
* ```
214+
*/
215+
@track('MaestroProcesses.GetTopFaultedCount')
216+
async getTopFaultedCount(startTime: Date, endTime: Date, options?: TopQueryOptions): Promise<ProcessGetTopFaultedCountResponse[]> {
217+
const { data } = await this.post<GetTopRunCountResponse[]>(
218+
MAESTRO_ENDPOINTS.INSIGHTS.TOP_PROCESSES_WITH_FAILURE,
219+
buildInsightsTopBody(startTime, endTime, false, options)
220+
);
221+
return (data ?? []).map(item => ({
222+
packageId: item.packageId,
223+
processKey: item.processKey,
224+
faultedCount: item.runCount,
225+
name: item.packageId,
226+
}));
227+
}
228+
178229
/**
179230
* Get the top 5 processes ranked by total duration within a time range.
180231
*

src/utils/constants/endpoints/maestro.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export const MAESTRO_ENDPOINTS = {
3939
STAGES_SUMMARY: `${INSIGHTS_RTM_BASE}/caseManagement/stages`,
4040
/** Top processes ranked by run count */
4141
TOP_PROCESSES_BY_RUN_COUNT: `${INSIGHTS_RTM_BASE}/agenticInstanceStatus/TopProcessesByRunCount`,
42+
/** Top processes ranked by failure count */
43+
TOP_PROCESSES_WITH_FAILURE: `${INSIGHTS_RTM_BASE}/agenticInstanceStatus/TopProcesseswithFailure`,
4244
/** Instance status aggregated by date for time-series charts */
4345
INSTANCE_STATUS_BY_DATE: `${INSIGHTS_RTM_BASE}/agenticInstanceStatus/InstanceStatusByDate`,
4446
/** Top processes ranked by total duration */

tests/integration/shared/maestro/cases.integration.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,29 @@ describe.each(modes)('Maestro Cases - Integration Tests [%s]', (mode) => {
9797
});
9898
});
9999

100+
describe.skip('getTopFaultedCount', () => {
101+
it('should retrieve top case processes by failure count', async () => {
102+
const { cases } = getServices();
103+
const now = new Date();
104+
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
105+
106+
const result = await cases.getTopFaultedCount(sevenDaysAgo, now);
107+
108+
expect(result).toBeDefined();
109+
expect(Array.isArray(result)).toBe(true);
110+
111+
if (result.length === 0) {
112+
throw new Error('No top cases by failure count returned — cannot validate response structure');
113+
}
114+
115+
const topProcess = result[0];
116+
expect(topProcess.packageId).toBeDefined();
117+
expect(typeof topProcess.faultedCount).toBe('number');
118+
expect(topProcess.name).toBeDefined();
119+
expect(typeof topProcess.name).toBe('string');
120+
});
121+
});
122+
100123
describe.skip('getTopExecutionDuration', () => {
101124
it('should retrieve top case processes by duration', async () => {
102125
const { cases } = getServices();

0 commit comments

Comments
 (0)