Skip to content

Commit 9a77386

Browse files
authored
Fix workflow statuses (#7555)
Event was not emitted after first version insertion. So initial status was not set. Also adding workflow related objects to timeline activities.
1 parent 6998eb1 commit 9a77386

File tree

10 files changed

+291
-30
lines changed

10 files changed

+291
-30
lines changed

packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts

+10
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ export const TIMELINE_ACTIVITY_STANDARD_FIELD_IDS = {
191191
opportunity: '20202020-7664-4a35-a3df-580d389fd527',
192192
task: '20202020-b2f5-415c-9135-a31dfe49501b',
193193
note: '20202020-ec55-4135-8da5-3a20badc0156',
194+
workflow: '20202020-616c-4ad3-a2e9-c477c341e295',
195+
workflowVersion: '20202020-74f1-4711-a129-e14ca0ecd744',
196+
workflowRun: '20202020-96f0-401b-9186-a3a0759225ac',
194197
custom: '20202020-4a71-41b0-9f83-9cdcca3f8b14',
195198
linkedRecordCachedName: '20202020-cfdb-4bef-bbce-a29f41230934',
196199
linkedRecordId: '20202020-2e0e-48c0-b445-ee6c1e61687d',
@@ -204,6 +207,8 @@ export const FAVORITE_STANDARD_FIELD_IDS = {
204207
company: '20202020-cff5-4682-8bf9-069169e08279',
205208
opportunity: '20202020-dabc-48e1-8318-2781a2b32aa2',
206209
workflow: '20202020-b11b-4dc8-999a-6bd0a947b463',
210+
workflowVersion: '20202020-e1b8-4caf-b55a-3ab4d4cbcd21',
211+
workflowRun: '20202020-db5a-4fe4-9a13-9afa22b1e762',
207212
task: '20202020-1b1b-4b3b-8b1b-7f8d6a1d7d5c',
208213
note: '20202020-1f25-43fe-8b00-af212fdde824',
209214
view: '20202020-5a93-4fa9-acce-e73481a0bbdf',
@@ -411,6 +416,7 @@ export const WORKFLOW_STANDARD_FIELD_IDS = {
411416
runs: '20202020-759b-4340-b58b-e73595c4df4f',
412417
eventListeners: '20202020-0229-4c66-832e-035c67579a38',
413418
favorites: '20202020-c554-4c41-be7a-cf9cd4b0d512',
419+
timelineActivities: '20202020-906e-486a-a798-131a5f081faf',
414420
};
415421

416422
export const WORKFLOW_RUN_STANDARD_FIELD_IDS = {
@@ -423,6 +429,8 @@ export const WORKFLOW_RUN_STANDARD_FIELD_IDS = {
423429
position: '20202020-7802-4c40-ae89-1f506fe3365c',
424430
createdBy: '20202020-6007-401a-8aa5-e6f38581a6f3',
425431
output: '20202020-7be4-4db2-8ac6-3ff0d740843d',
432+
favorites: '20202020-4baf-4604-b899-2f7fcfbbf90d',
433+
timelineActivities: '20202020-af4d-4eb0-babc-eb960a45b356',
426434
};
427435

428436
export const WORKFLOW_VERSION_STANDARD_FIELD_IDS = {
@@ -433,6 +441,8 @@ export const WORKFLOW_VERSION_STANDARD_FIELD_IDS = {
433441
position: '20202020-791d-4950-ab28-0e704767ae1c',
434442
runs: '20202020-1d08-46df-901a-85045f18099a',
435443
steps: '20202020-5988-4a64-b94a-1f9b7b989039',
444+
favorites: '20202020-b8e0-4e57-928d-b51671cc71f2',
445+
timelineActivities: '20202020-fcb0-4695-b17e-3b43a421c633',
436446
};
437447

438448
export const WORKSPACE_MEMBER_STANDARD_FIELD_IDS = {

packages/twenty-server/src/modules/favorite/standard-objects/favorite.workspace-entity.ts

+44
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-obj
2222
import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity';
2323
import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity';
2424
import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.workspace-entity';
25+
import { WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
26+
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
2527
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
2628
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
2729

@@ -128,6 +130,48 @@ export class FavoriteWorkspaceEntity extends BaseWorkspaceEntity {
128130
})
129131
workflowId: string;
130132

133+
@WorkspaceRelation({
134+
standardId: FAVORITE_STANDARD_FIELD_IDS.workflowVersion,
135+
type: RelationMetadataType.MANY_TO_ONE,
136+
label: 'Workflow',
137+
description: 'Favorite workflow version',
138+
icon: 'IconSettingsAutomation',
139+
inverseSideTarget: () => WorkflowVersionWorkspaceEntity,
140+
inverseSideFieldKey: 'favorites',
141+
})
142+
@WorkspaceGate({
143+
featureFlag: FeatureFlagKey.IsWorkflowEnabled,
144+
})
145+
@WorkspaceIsNullable()
146+
workflowVersion: Relation<WorkflowVersionWorkspaceEntity> | null;
147+
148+
@WorkspaceJoinColumn('workflowVersion')
149+
@WorkspaceGate({
150+
featureFlag: FeatureFlagKey.IsWorkflowEnabled,
151+
})
152+
workflowVersionId: string;
153+
154+
@WorkspaceRelation({
155+
standardId: FAVORITE_STANDARD_FIELD_IDS.workflowRun,
156+
type: RelationMetadataType.MANY_TO_ONE,
157+
label: 'Workflow',
158+
description: 'Favorite workflow run',
159+
icon: 'IconSettingsAutomation',
160+
inverseSideTarget: () => WorkflowRunWorkspaceEntity,
161+
inverseSideFieldKey: 'favorites',
162+
})
163+
@WorkspaceGate({
164+
featureFlag: FeatureFlagKey.IsWorkflowEnabled,
165+
})
166+
@WorkspaceIsNullable()
167+
workflowRun: Relation<WorkflowRunWorkspaceEntity> | null;
168+
169+
@WorkspaceJoinColumn('workflowRun')
170+
@WorkspaceGate({
171+
featureFlag: FeatureFlagKey.IsWorkflowEnabled,
172+
})
173+
workflowRunId: string;
174+
131175
@WorkspaceRelation({
132176
standardId: FAVORITE_STANDARD_FIELD_IDS.task,
133177
type: RelationMetadataType.MANY_TO_ONE,

packages/twenty-server/src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts

+68
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
22

3+
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
34
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
45
import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
56
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
67
import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-entity';
78
import { WorkspaceDynamicRelation } from 'src/engine/twenty-orm/decorators/workspace-dynamic-relation.decorator';
89
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
910
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
11+
import { WorkspaceGate } from 'src/engine/twenty-orm/decorators/workspace-gate.decorator';
1012
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
1113
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
1214
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
@@ -19,6 +21,9 @@ import { NoteWorkspaceEntity } from 'src/modules/note/standard-objects/note.work
1921
import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity';
2022
import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity';
2123
import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity';
24+
import { WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
25+
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
26+
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
2227
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
2328

2429
@WorkspaceEntity({
@@ -182,6 +187,69 @@ export class TimelineActivityWorkspaceEntity extends BaseWorkspaceEntity {
182187
@WorkspaceJoinColumn('task')
183188
taskId: string | null;
184189

190+
@WorkspaceRelation({
191+
standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.workflow,
192+
type: RelationMetadataType.MANY_TO_ONE,
193+
label: 'Workflow',
194+
description: 'Event workflow',
195+
icon: 'IconTargetArrow',
196+
inverseSideTarget: () => WorkflowWorkspaceEntity,
197+
inverseSideFieldKey: 'timelineActivities',
198+
})
199+
@WorkspaceGate({
200+
featureFlag: FeatureFlagKey.IsWorkflowEnabled,
201+
})
202+
@WorkspaceIsNullable()
203+
workflow: Relation<WorkflowWorkspaceEntity> | null;
204+
205+
@WorkspaceJoinColumn('workflow')
206+
@WorkspaceGate({
207+
featureFlag: FeatureFlagKey.IsWorkflowEnabled,
208+
})
209+
workflowId: string | null;
210+
211+
@WorkspaceRelation({
212+
standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.workflowVersion,
213+
type: RelationMetadataType.MANY_TO_ONE,
214+
label: 'WorkflowVersion',
215+
description: 'Event workflow version',
216+
icon: 'IconTargetArrow',
217+
inverseSideTarget: () => WorkflowVersionWorkspaceEntity,
218+
inverseSideFieldKey: 'timelineActivities',
219+
})
220+
@WorkspaceGate({
221+
featureFlag: FeatureFlagKey.IsWorkflowEnabled,
222+
})
223+
@WorkspaceIsNullable()
224+
workflowVersion: Relation<WorkflowVersionWorkspaceEntity> | null;
225+
226+
@WorkspaceJoinColumn('workflowVersion')
227+
@WorkspaceGate({
228+
featureFlag: FeatureFlagKey.IsWorkflowEnabled,
229+
})
230+
workflowVersionId: string | null;
231+
232+
@WorkspaceRelation({
233+
standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.workflowRun,
234+
type: RelationMetadataType.MANY_TO_ONE,
235+
label: 'Workflow Run',
236+
description: 'Event workflow run',
237+
icon: 'IconTargetArrow',
238+
inverseSideTarget: () => WorkflowRunWorkspaceEntity,
239+
inverseSideFieldKey: 'timelineActivities',
240+
})
241+
@WorkspaceGate({
242+
featureFlag: FeatureFlagKey.IsWorkflowEnabled,
243+
})
244+
@WorkspaceIsNullable()
245+
workflowRun: Relation<WorkflowRunWorkspaceEntity> | null;
246+
247+
@WorkspaceJoinColumn('workflowRun')
248+
@WorkspaceGate({
249+
featureFlag: FeatureFlagKey.IsWorkflowEnabled,
250+
})
251+
workflowRunId: string | null;
252+
185253
@WorkspaceDynamicRelation({
186254
type: RelationMetadataType.MANY_TO_ONE,
187255
argsFactory: (oppositeObjectMetadata) => ({
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
import { InjectRepository } from '@nestjs/typeorm';
2+
3+
import { Repository } from 'typeorm';
4+
15
import { WorkspaceQueryPostHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
26

37
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
48
import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
59
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
10+
import { ObjectRecordCreateEvent } from 'src/engine/core-modules/event-emitter/types/object-record-create.event';
11+
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
612
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
13+
import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
714
import {
815
WorkflowVersionStatus,
916
WorkflowVersionWorkspaceEntity,
@@ -17,10 +24,15 @@ import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-ob
1724
export class WorkflowCreateManyPostQueryHook
1825
implements WorkspaceQueryPostHookInstance
1926
{
20-
constructor(private readonly twentyORMManager: TwentyORMManager) {}
27+
constructor(
28+
private readonly twentyORMManager: TwentyORMManager,
29+
private readonly workspaceEventEmitter: WorkspaceEventEmitter,
30+
@InjectRepository(ObjectMetadataEntity, 'metadata')
31+
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
32+
) {}
2133

2234
async execute(
23-
_authContext: AuthContext,
35+
authContext: AuthContext,
2436
_objectName: string,
2537
payload: WorkflowWorkspaceEntity[],
2638
): Promise<void> {
@@ -29,14 +41,39 @@ export class WorkflowCreateManyPostQueryHook
2941
'workflowVersion',
3042
);
3143

44+
const workflowVersionsToCreate = payload.map((workflow) => {
45+
return workflowVersionRepository.create({
46+
workflowId: workflow.id,
47+
status: WorkflowVersionStatus.DRAFT,
48+
name: 'v1',
49+
});
50+
});
51+
3252
await Promise.all(
33-
payload.map((workflow) => {
34-
return workflowVersionRepository.insert({
35-
workflowId: workflow.id,
36-
status: WorkflowVersionStatus.DRAFT,
37-
name: 'v1',
38-
});
53+
workflowVersionsToCreate.map((workflowVersion) => {
54+
return workflowVersionRepository.save(workflowVersion);
55+
}),
56+
);
57+
58+
const objectMetadata = await this.objectMetadataRepository.findOneOrFail({
59+
where: {
60+
nameSingular: 'workflowVersion',
61+
},
62+
});
63+
64+
this.workspaceEventEmitter.emit(
65+
`workflowVersion.created`,
66+
workflowVersionsToCreate.map((workflowVersionToCreate) => {
67+
return {
68+
userId: authContext.user?.id,
69+
recordId: workflowVersionToCreate.id,
70+
objectMetadata,
71+
properties: {
72+
after: workflowVersionToCreate,
73+
},
74+
} satisfies ObjectRecordCreateEvent<any>;
3975
}),
76+
authContext.workspace.id,
4077
);
4178
}
4279
}

packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-create-one.post-query.hook.ts

+38-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
import { InjectRepository } from '@nestjs/typeorm';
2+
3+
import { Repository } from 'typeorm';
4+
15
import { WorkspaceQueryPostHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
26

37
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
48
import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
59
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
10+
import { ObjectRecordCreateEvent } from 'src/engine/core-modules/event-emitter/types/object-record-create.event';
11+
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
612
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
13+
import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
714
import {
815
WorkflowVersionStatus,
916
WorkflowVersionWorkspaceEntity,
@@ -17,10 +24,15 @@ import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-ob
1724
export class WorkflowCreateOnePostQueryHook
1825
implements WorkspaceQueryPostHookInstance
1926
{
20-
constructor(private readonly twentyORMManager: TwentyORMManager) {}
27+
constructor(
28+
private readonly twentyORMManager: TwentyORMManager,
29+
private readonly workspaceEventEmitter: WorkspaceEventEmitter,
30+
@InjectRepository(ObjectMetadataEntity, 'metadata')
31+
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
32+
) {}
2133

2234
async execute(
23-
_authContext: AuthContext,
35+
authContext: AuthContext,
2436
_objectName: string,
2537
payload: WorkflowWorkspaceEntity[],
2638
): Promise<void> {
@@ -31,10 +43,33 @@ export class WorkflowCreateOnePostQueryHook
3143
'workflowVersion',
3244
);
3345

34-
await workflowVersionRepository.insert({
46+
const workflowVersionToCreate = await workflowVersionRepository.create({
3547
workflowId: workflow.id,
3648
status: WorkflowVersionStatus.DRAFT,
3749
name: 'v1',
3850
});
51+
52+
await workflowVersionRepository.save(workflowVersionToCreate);
53+
54+
const objectMetadata = await this.objectMetadataRepository.findOneOrFail({
55+
where: {
56+
nameSingular: 'workflowVersion',
57+
},
58+
});
59+
60+
this.workspaceEventEmitter.emit(
61+
`workflowVersion.created`,
62+
[
63+
{
64+
userId: authContext.user?.id,
65+
recordId: workflowVersionToCreate.id,
66+
objectMetadata,
67+
properties: {
68+
after: workflowVersionToCreate,
69+
},
70+
} satisfies ObjectRecordCreateEvent<any>,
71+
],
72+
authContext.workspace.id,
73+
);
3974
}
4075
}

packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-query-hook.module.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { Module } from '@nestjs/common';
22

3+
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
4+
5+
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
36
import { WorkflowCreateManyPostQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-create-many.post-query.hook';
47
import { WorkflowCreateManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-create-many.pre-query.hook';
8+
import { WorkflowCreateOnePostQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-create-one.post-query.hook';
59
import { WorkflowCreateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-create-one.pre-query.hook';
610
import { WorkflowRunCreateManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-create-many.pre-query.hook';
711
import { WorkflowRunCreateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-create-one.pre-query.hook';
@@ -17,6 +21,9 @@ import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/work
1721
import { WorkflowVersionValidationWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-version-validation.workspace-service';
1822

1923
@Module({
24+
imports: [
25+
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
26+
],
2027
providers: [
2128
WorkflowCreateOnePreQueryHook,
2229
WorkflowCreateManyPreQueryHook,
@@ -30,6 +37,7 @@ import { WorkflowVersionValidationWorkspaceService } from 'src/modules/workflow/
3037
WorkflowVersionUpdateManyPreQueryHook,
3138
WorkflowVersionDeleteOnePreQueryHook,
3239
WorkflowVersionDeleteManyPreQueryHook,
40+
WorkflowCreateOnePostQueryHook,
3341
WorkflowCreateManyPostQueryHook,
3442
WorkflowVersionValidationWorkspaceService,
3543
WorkflowCommonWorkspaceService,

packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity.ts

-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ export class WorkflowEventListenerWorkspaceEntity extends BaseWorkspaceEntity {
3434
type: FieldMetadataType.TEXT,
3535
label: 'Name',
3636
description: 'The workflow event listener name',
37-
icon: 'IconPhoneCheck',
3837
})
3938
eventName: string;
4039

0 commit comments

Comments
 (0)