Skip to content

Commit b0aa031

Browse files
umbopepatokibanamachinecnasikas
authored
[ResponseOps][Cases] Add timing metrics to cases SO (elastic#219070)
## Summary - Adds the `in_progress_at` timestamp to Cases Saved Objects - Adds the `time_to_acknowledge`, `time_to_investigate` and `time_to_resolve` timing metrics to Cases Saved Objects ## References Closes elastic#217638 ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed (passed ✅) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Christos Nasikas <xristosnasikas@gmail.com> Co-authored-by: Christos Nasikas <christos.nasikas@elastic.co>
1 parent 5ded658 commit b0aa031

15 files changed

Lines changed: 771 additions & 12 deletions

File tree

x-pack/platform/plugins/shared/cases/common/types/domain/case/v1.test.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ const basicCase = {
9393
],
9494
observables: [],
9595
incremental_id: undefined,
96+
in_progress_at: undefined,
97+
time_to_acknowledge: undefined,
98+
time_to_investigate: undefined,
99+
time_to_resolve: undefined,
96100
};
97101

98102
describe('RelatedCaseRt', () => {
@@ -207,7 +211,10 @@ describe('CaseAttributesRt', () => {
207211
},
208212
],
209213
observables: [],
210-
incremental_id: undefined,
214+
in_progress_at: undefined,
215+
time_to_acknowledge: undefined,
216+
time_to_investigate: undefined,
217+
time_to_resolve: undefined,
211218
};
212219

213220
it('has expected attributes in request', () => {

x-pack/platform/plugins/shared/cases/common/types/domain/case/v1.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ export const CaseAttributesRt = rt.intersection([
130130
rt.exact(
131131
rt.partial({
132132
incremental_id: rt.union([rt.number, rt.null]),
133+
in_progress_at: rt.union([rt.string, rt.null]),
134+
time_to_acknowledge: rt.union([rt.number, rt.null]),
135+
time_to_investigate: rt.union([rt.number, rt.null]),
136+
time_to_resolve: rt.union([rt.number, rt.null]),
133137
})
134138
),
135139
]);

x-pack/platform/plugins/shared/cases/server/client/cases/bulk_update.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ describe('update', () => {
3232
},
3333
],
3434
};
35+
3536
const casesClientMock = createCasesClientMock();
3637
casesClientMock.configure.get = jest.fn().mockResolvedValue([]);
3738

@@ -1896,4 +1897,48 @@ describe('update', () => {
18961897
});
18971898
});
18981899
});
1900+
1901+
describe('Metrics', () => {
1902+
const clientArgs = createCasesClientMockArgs();
1903+
1904+
beforeEach(() => {
1905+
jest.clearAllMocks();
1906+
clientArgs.services.caseService.getCases.mockResolvedValue({ saved_objects: mockCases });
1907+
clientArgs.services.caseService.getAllCaseComments.mockResolvedValue({
1908+
saved_objects: [],
1909+
total: 0,
1910+
per_page: 10,
1911+
page: 1,
1912+
});
1913+
1914+
clientArgs.services.caseService.patchCases.mockResolvedValue({
1915+
saved_objects: mockCases,
1916+
});
1917+
1918+
clientArgs.services.attachmentService.getter.getCaseCommentStats.mockResolvedValue(new Map());
1919+
});
1920+
1921+
it('calculates metrics correctly', async () => {
1922+
await bulkUpdate(
1923+
{
1924+
cases: [
1925+
{
1926+
id: mockCases[0].id,
1927+
version: mockCases[0].version ?? '',
1928+
status: CaseStatuses.closed,
1929+
},
1930+
],
1931+
},
1932+
clientArgs,
1933+
casesClientMock
1934+
);
1935+
1936+
const updatedAttributes =
1937+
clientArgs.services.caseService.patchCases.mock.calls[0][0].cases[0].updatedAttributes;
1938+
1939+
expect(updatedAttributes.time_to_acknowledge).toEqual(expect.any(Number));
1940+
expect(updatedAttributes.time_to_investigate).toEqual(expect.any(Number));
1941+
expect(updatedAttributes.time_to_resolve).toEqual(expect.any(Number));
1942+
});
1943+
});
18991944
});

x-pack/platform/plugins/shared/cases/server/client/cases/bulk_update.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ import {
4444
fillMissingCustomFields,
4545
getClosedInfoForUpdate,
4646
getDurationForUpdate,
47+
getInProgressInfoForUpdate,
48+
getTimingMetricsForUpdate,
4749
} from './utils';
4850
import { LICENSING_CASE_ASSIGNMENT_FEATURE } from '../../common/constants';
4951
import type { LicensingService } from '../../services/licensing';
@@ -656,6 +658,17 @@ const createPatchCasesPayload = ({
656658
closedAt: updatedDt,
657659
createdAt: originalCase.attributes.created_at,
658660
}),
661+
...getInProgressInfoForUpdate({
662+
status: trimmedCaseAttributes.status,
663+
stateTransitionTimestamp: updatedDt,
664+
inProgressAt: originalCase.attributes.in_progress_at,
665+
}),
666+
...getTimingMetricsForUpdate({
667+
status: trimmedCaseAttributes.status,
668+
stateTransitionTimestamp: updatedDt,
669+
createdAt: originalCase.attributes.created_at,
670+
inProgressAt: originalCase.attributes.in_progress_at,
671+
}),
659672
updated_at: updatedDt,
660673
updated_by: user,
661674
},

x-pack/platform/plugins/shared/cases/server/client/cases/push.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ import {
3131
OWNER_FIELD,
3232
} from '../../../common/constants';
3333

34-
import { createIncident, getDurationInSeconds, getUserProfiles } from './utils';
34+
import {
35+
createIncident,
36+
getDurationInSeconds,
37+
getTimingMetricsForUpdate,
38+
getUserProfiles,
39+
} from './utils';
3540
import { createCaseError } from '../../common/error';
3641
import {
3742
createAlertUpdateStatusRequest,
@@ -230,6 +235,14 @@ export const push = async (
230235
createdAt: theCase.created_at,
231236
})
232237
: {}),
238+
...(shouldMarkAsClosed
239+
? getTimingMetricsForUpdate({
240+
status: CaseStatuses.closed,
241+
stateTransitionTimestamp: pushedDate,
242+
createdAt: theCase.created_at,
243+
inProgressAt: theCase.in_progress_at,
244+
})
245+
: {}),
233246
external_service: externalService,
234247
updated_at: pushedDate,
235248
updated_by: { username, full_name, email, profile_uid },

0 commit comments

Comments
 (0)