Skip to content

Commit c2a5327

Browse files
Add negativeFields to event metadata (#954)
* Add negativeFields to event metadata * Address copilot comment --------- Co-authored-by: Assem Hafez <[email protected]>
1 parent 0ba26c3 commit c2a5327

12 files changed

+261
-8
lines changed

src/views/workflow-history/helpers/__tests__/get-common-history-group-fields.test.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,57 @@ describe('getCommonHistoryGroupFields', () => {
130130
});
131131
}
132132
);
133+
134+
it('should include negativeFields when eventStatusToNegativeFieldsMap is provided', () => {
135+
const eventStatusToNegativeFieldsMap = {
136+
timerStartedEventAttributes: ['startReason', 'startDetails'],
137+
timerFiredEventAttributes: ['fireReason', 'fireDetails'],
138+
};
139+
140+
const group = setup({
141+
eventStatusToNegativeFieldsMap,
142+
});
143+
144+
expect(group.eventsMetadata[0].negativeFields).toEqual([
145+
'startReason',
146+
'startDetails',
147+
]);
148+
expect(group.eventsMetadata[1].negativeFields).toEqual([
149+
'fireReason',
150+
'fireDetails',
151+
]);
152+
});
153+
154+
it('should not include negativeFields when eventStatusToNegativeFieldsMap is not provided', () => {
155+
const group = setup({});
156+
157+
group.eventsMetadata.forEach((metadata) => {
158+
expect(metadata.negativeFields).toBeUndefined();
159+
});
160+
});
161+
162+
it('should not include negativeFields when eventStatusToNegativeFieldsMap is empty', () => {
163+
const group = setup({
164+
eventStatusToNegativeFieldsMap: {},
165+
});
166+
167+
group.eventsMetadata.forEach((metadata) => {
168+
expect(metadata.negativeFields).toBeUndefined();
169+
});
170+
});
171+
172+
it('should only include negativeFields for events that have mappings', () => {
173+
const eventStatusToNegativeFieldsMap = {
174+
timerStartedEventAttributes: ['startReason'],
175+
};
176+
177+
const group = setup({
178+
eventStatusToNegativeFieldsMap,
179+
});
180+
181+
expect(group.eventsMetadata[0].negativeFields).toEqual(['startReason']);
182+
expect(group.eventsMetadata[1].negativeFields).toBeUndefined();
183+
});
133184
});
134185

135186
// using timer events for testing
@@ -139,6 +190,7 @@ function setup({
139190
eventToLabel,
140191
eventToStatus,
141192
closeEvent,
193+
eventStatusToNegativeFieldsMap,
142194
}: {
143195
events?: TimerHistoryEvent[];
144196
eventToStatus?: HistoryGroupEventToStatusMap<TimerHistoryGroup>;
@@ -147,6 +199,7 @@ function setup({
147199
HistoryGroupEventToStringMap<TimerHistoryGroup>
148200
>;
149201
closeEvent?: TimerHistoryEvent;
202+
eventStatusToNegativeFieldsMap?: any;
150203
}) {
151204
const mockEvents: TimerHistoryEvent[] = events || [
152205
startTimerTaskEvent,
@@ -170,6 +223,7 @@ function setup({
170223
mockedEventToStatus,
171224
mockedEventToLabel,
172225
eventToTimeLabelPrefixMap,
173-
closeEvent
226+
closeEvent,
227+
eventStatusToNegativeFieldsMap
174228
);
175229
}

src/views/workflow-history/helpers/get-common-history-group-fields.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import parseGrpcTimestamp from '@/utils/datetime/parse-grpc-timestamp';
33

44
import { type WorkflowEventStatus } from '../workflow-history-event-status-badge/workflow-history-event-status-badge.types';
55
import {
6+
type HistoryGroupEventStatusToNegativeFieldsMap,
67
type HistoryEventsGroup,
78
type HistoryGroupEventToStatusMap,
89
type HistoryGroupEventToStringMap,
@@ -12,10 +13,11 @@ export default function getCommonHistoryGroupFields<
1213
GroupT extends HistoryEventsGroup,
1314
>(
1415
events: GroupT['events'],
15-
HistoryGroupEventToStatusMap: HistoryGroupEventToStatusMap<GroupT>,
16+
historyGroupEventToStatusMap: HistoryGroupEventToStatusMap<GroupT>,
1617
eventToLabelMap: HistoryGroupEventToStringMap<GroupT>,
1718
eventToTimeLabelPrefixMap: Partial<HistoryGroupEventToStringMap<GroupT>>,
18-
closeEvent: GroupT['events'][number] | null | undefined
19+
closeEvent: GroupT['events'][number] | null | undefined,
20+
eventStatusToNegativeFieldsMap?: HistoryGroupEventStatusToNegativeFieldsMap<GroupT>
1921
): Pick<
2022
GroupT,
2123
| 'eventsMetadata'
@@ -28,7 +30,7 @@ export default function getCommonHistoryGroupFields<
2830
> {
2931
const eventsMetadata = events.map((event, index) => {
3032
const attrs = event.attributes as GroupT['events'][number]['attributes'];
31-
const getEventStatus = HistoryGroupEventToStatusMap[attrs];
33+
const getEventStatus = historyGroupEventToStatusMap[attrs];
3234
const eventStatus: WorkflowEventStatus =
3335
typeof getEventStatus === 'function'
3436
? getEventStatus(event, events, index)
@@ -38,11 +40,14 @@ export default function getCommonHistoryGroupFields<
3840
? eventToTimeLabelPrefixMap[attrs]
3941
: `${eventToLabelMap[attrs]} at`;
4042

43+
const negativeFields = eventStatusToNegativeFieldsMap?.[attrs];
44+
4145
return {
4246
label: eventToLabelMap[attrs],
4347
status: eventStatus,
4448
timeMs,
4549
timeLabel: timeMs ? `${prefix} ${formatDate(timeMs)}` : '',
50+
...(negativeFields?.length ? { negativeFields } : {}),
4651
};
4752
});
4853

src/views/workflow-history/helpers/get-history-group-from-events/__tests__/get-activity-group-from-events.test.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,4 +311,53 @@ describe('getActivityGroupFromEvents', () => {
311311

312312
expect(group.shortLabel).toBeUndefined();
313313
});
314+
315+
it('should include negativeFields for failed activity events', () => {
316+
const events: ExtendedActivityHistoryEvent[] = [
317+
scheduleActivityTaskEvent,
318+
startActivityTaskEvent,
319+
failedActivityTaskEvent,
320+
];
321+
const group = getActivityGroupFromEvents(events);
322+
323+
// The failed event should have negativeFields
324+
const failedEventMetadata = group.eventsMetadata.find(
325+
(metadata) => metadata.status === 'FAILED'
326+
);
327+
expect(failedEventMetadata?.negativeFields).toEqual(['reason', 'details']);
328+
329+
// Other events should not have negativeFields
330+
const otherEventsMetadata = group.eventsMetadata.filter(
331+
(metadata) => metadata.status !== 'FAILED'
332+
);
333+
otherEventsMetadata.forEach((metadata) => {
334+
expect(metadata.negativeFields).toBeUndefined();
335+
});
336+
});
337+
338+
it('should include negativeFields for timed out activity events', () => {
339+
const events: ExtendedActivityHistoryEvent[] = [
340+
scheduleActivityTaskEvent,
341+
startActivityTaskEvent,
342+
timeoutActivityTaskEvent,
343+
];
344+
const group = getActivityGroupFromEvents(events);
345+
346+
// The timed out event should have negativeFields
347+
const timedOutEventMetadata = group.eventsMetadata.find(
348+
(metadata) => metadata.status === 'FAILED' // timeout events have FAILED status
349+
);
350+
expect(timedOutEventMetadata?.negativeFields).toEqual([
351+
'reason',
352+
'details',
353+
]);
354+
355+
// Other events should not have negativeFields
356+
const otherEventsMetadata = group.eventsMetadata.filter(
357+
(metadata) => metadata.status !== 'FAILED'
358+
);
359+
otherEventsMetadata.forEach((metadata) => {
360+
expect(metadata.negativeFields).toBeUndefined();
361+
});
362+
});
314363
});

src/views/workflow-history/helpers/get-history-group-from-events/__tests__/get-child-workflow-execution-group-from-events.test.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,4 +228,53 @@ describe('getChildWorkflowExecutionGroupFromEvents', () => {
228228
);
229229
expect(groupWithMissingCloseEvent.closeTimeMs).toEqual(null);
230230
});
231+
232+
it('should include negativeFields for failed child workflow events', () => {
233+
const events: ChildWorkflowExecutionHistoryEvent[] = [
234+
initiateChildWorkflowEvent,
235+
startChildWorkflowEvent,
236+
failChildWorkflowEvent,
237+
];
238+
const group = getChildWorkflowExecutionGroupFromEvents(events);
239+
240+
// The failed event should have negativeFields
241+
const failedEventMetadata = group.eventsMetadata.find(
242+
(metadata) => metadata.status === 'FAILED'
243+
);
244+
expect(failedEventMetadata?.negativeFields).toEqual(['details', 'reason']);
245+
246+
// Other events should not have negativeFields
247+
const otherEventsMetadata = group.eventsMetadata.filter(
248+
(metadata) => metadata.status !== 'FAILED'
249+
);
250+
otherEventsMetadata.forEach((metadata) => {
251+
expect(metadata.negativeFields).toBeUndefined();
252+
});
253+
});
254+
255+
it('should include negativeFields for timed out child workflow events', () => {
256+
const events: ChildWorkflowExecutionHistoryEvent[] = [
257+
initiateChildWorkflowEvent,
258+
startChildWorkflowEvent,
259+
timeoutChildWorkflowEvent,
260+
];
261+
const group = getChildWorkflowExecutionGroupFromEvents(events);
262+
263+
// The timed out event should have negativeFields
264+
const timedOutEventMetadata = group.eventsMetadata.find(
265+
(metadata) => metadata.status === 'FAILED' // timeout events have FAILED status
266+
);
267+
expect(timedOutEventMetadata?.negativeFields).toEqual([
268+
'details',
269+
'reason',
270+
]);
271+
272+
// Other events should not have negativeFields
273+
const otherEventsMetadata = group.eventsMetadata.filter(
274+
(metadata) => metadata.status !== 'FAILED'
275+
);
276+
otherEventsMetadata.forEach((metadata) => {
277+
expect(metadata.negativeFields).toBeUndefined();
278+
});
279+
});
231280
});

src/views/workflow-history/helpers/get-history-group-from-events/__tests__/get-decision-group-from-events.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,4 +310,27 @@ describe('getDecisionGroupFromEvents', () => {
310310
]);
311311
expect(groupWithMissingCloseEvent.closeTimeMs).toEqual(null);
312312
});
313+
314+
it('should include negativeFields for failed decision events', () => {
315+
const events: ExtendedDecisionHistoryEvent[] = [
316+
scheduleDecisionTaskEvent,
317+
startDecisionTaskEvent,
318+
failedDecisionTaskEvent,
319+
];
320+
const group = getDecisionGroupFromEvents(events);
321+
322+
// The failed event should have negativeFields
323+
const failedEventMetadata = group.eventsMetadata.find(
324+
(metadata) => metadata.status === 'FAILED'
325+
);
326+
expect(failedEventMetadata?.negativeFields).toEqual(['reason', 'details']);
327+
328+
// Other events should not have negativeFields
329+
const otherEventsMetadata = group.eventsMetadata.filter(
330+
(metadata) => metadata.status !== 'FAILED'
331+
);
332+
otherEventsMetadata.forEach((metadata) => {
333+
expect(metadata.negativeFields).toBeUndefined();
334+
});
335+
});
313336
});

src/views/workflow-history/helpers/get-history-group-from-events/__tests__/get-single-event-group-from-events.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,35 @@ describe('getSingleEventGroupFromEvents', () => {
138138
expect(group.closeTimeMs).toEqual(null);
139139
}
140140
});
141+
142+
it('should include negativeFields for failed workflow execution events', () => {
143+
const group = getSingleEventGroupFromEvents([failWorkflowExecutionEvent]);
144+
const eventMetadata = group.eventsMetadata[0];
145+
146+
expect(eventMetadata.status).toBe('FAILED');
147+
expect(eventMetadata.negativeFields).toEqual(['details', 'reason']);
148+
});
149+
150+
it('should include negativeFields for terminated workflow execution events', () => {
151+
const group = getSingleEventGroupFromEvents([
152+
terminateWorkflowExecutionEvent,
153+
]);
154+
const eventMetadata = group.eventsMetadata[0];
155+
156+
expect(eventMetadata.status).toBe('FAILED');
157+
expect(eventMetadata.negativeFields).toEqual(['details', 'reason']);
158+
});
159+
160+
it('should include negativeFields for continued as new workflow execution events', () => {
161+
const group = getSingleEventGroupFromEvents([
162+
continueAsNewWorkflowExecutionEvent,
163+
]);
164+
const eventMetadata = group.eventsMetadata[0];
165+
166+
expect(eventMetadata.status).toBe('COMPLETED');
167+
expect(eventMetadata.negativeFields).toEqual([
168+
'failureDetails',
169+
'failureReason',
170+
]);
171+
});
141172
});

src/views/workflow-history/helpers/get-history-group-from-events/get-activity-group-from-events.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import WORKFLOW_HISTORY_SHOULD_SHORTEN_GROUP_LABELS_CONFIG from '../../config/wo
22
import type {
33
ActivityHistoryGroup,
44
ExtendedActivityHistoryEvent,
5+
HistoryGroupEventStatusToNegativeFieldsMap,
56
HistoryGroupEventToStatusMap,
67
HistoryGroupEventToStringMap,
78
PendingActivityTaskStartEvent,
@@ -103,6 +104,12 @@ export default function getActivityGroupFromEvents(
103104
activityTaskTimedOutEventAttributes: 'FAILED',
104105
};
105106

107+
const eventStatusToNegativeFields: HistoryGroupEventStatusToNegativeFieldsMap<ActivityHistoryGroup> =
108+
{
109+
activityTaskFailedEventAttributes: ['reason', 'details'],
110+
activityTaskTimedOutEventAttributes: ['reason', 'details'],
111+
};
112+
106113
const pendingStartEventTimePrefix = pendingStartEvent?.[pendingStartAttr]
107114
.lastStartedTime
108115
? 'Last started at'
@@ -119,7 +126,8 @@ export default function getActivityGroupFromEvents(
119126
eventToStatus,
120127
eventToLabel,
121128
{ pendingActivityTaskStartEventAttributes: pendingStartEventTimePrefix },
122-
closeEvent || timeoutEvent
129+
closeEvent || timeoutEvent,
130+
eventStatusToNegativeFields
123131
),
124132
};
125133
}

src/views/workflow-history/helpers/get-history-group-from-events/get-child-workflow-execution-group-from-events.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type {
22
ChildWorkflowExecutionHistoryEvent,
33
ChildWorkflowExecutionHistoryGroup,
4+
HistoryGroupEventStatusToNegativeFieldsMap,
45
HistoryGroupEventToStatusMap,
56
HistoryGroupEventToStringMap,
67
} from '../../workflow-history.types';
@@ -73,6 +74,12 @@ export default function getChildWorkflowExecutionGroupFromEvents(
7374
childWorkflowExecutionTerminatedEventAttributes: 'FAILED',
7475
};
7576

77+
const eventStatusToNegativeFields: HistoryGroupEventStatusToNegativeFieldsMap<ChildWorkflowExecutionHistoryGroup> =
78+
{
79+
childWorkflowExecutionFailedEventAttributes: ['details', 'reason'],
80+
childWorkflowExecutionTimedOutEventAttributes: ['details', 'reason'],
81+
};
82+
7683
return {
7784
label,
7885
hasMissingEvents,
@@ -82,7 +89,8 @@ export default function getChildWorkflowExecutionGroupFromEvents(
8289
eventToStatus,
8390
eventToLabel,
8491
{},
85-
closeEvent || startFailedEvent
92+
closeEvent || startFailedEvent,
93+
eventStatusToNegativeFields
8694
),
8795
};
8896
}

src/views/workflow-history/helpers/get-history-group-from-events/get-decision-group-from-events.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type {
22
DecisionHistoryGroup,
33
ExtendedDecisionHistoryEvent,
4+
HistoryGroupEventStatusToNegativeFieldsMap,
45
HistoryGroupEventToStatusMap,
56
HistoryGroupEventToStringMap,
67
PendingDecisionTaskStartEvent,
@@ -101,6 +102,11 @@ export default function getDecisionGroupFromEvents(
101102
? 'Started at'
102103
: 'Scheduled at';
103104

105+
const eventStatusToNegativeFields: HistoryGroupEventStatusToNegativeFieldsMap<DecisionHistoryGroup> =
106+
{
107+
decisionTaskFailedEventAttributes: ['reason', 'details'],
108+
};
109+
104110
return {
105111
label,
106112
hasMissingEvents,
@@ -114,7 +120,8 @@ export default function getDecisionGroupFromEvents(
114120
{
115121
pendingDecisionTaskStartEventAttributes: pendingStartEventTimePrefix,
116122
},
117-
closeEvent || timeoutEvent
123+
closeEvent || timeoutEvent,
124+
eventStatusToNegativeFields
118125
),
119126
};
120127
}

0 commit comments

Comments
 (0)