-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add enable workflow trigger endpoint (#6443)
Basic endpoint that only returns a boolean currently and overrides the previous listener.
- Loading branch information
Showing
13 changed files
with
279 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
...engine/core-modules/workflow/utils/workflow-trigger-graphql-api-exception-handler.util.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { | ||
InternalServerError, | ||
UserInputError, | ||
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; | ||
import { | ||
WorkflowTriggerException, | ||
WorkflowTriggerExceptionCode, | ||
} from 'src/modules/workflow/standard-objects/workflow-trigger/workflow-trigger.exception'; | ||
|
||
export const workflowTriggerGraphqlApiExceptionHandler = (error: Error) => { | ||
if (error instanceof WorkflowTriggerException) { | ||
switch (error.code) { | ||
case WorkflowTriggerExceptionCode.INVALID_INPUT: | ||
throw new UserInputError(error.message); | ||
case WorkflowTriggerExceptionCode.INVALID_WORKFLOW_TRIGGER: | ||
case WorkflowTriggerExceptionCode.INVALID_WORKFLOW_VERSION: | ||
default: | ||
throw new InternalServerError(error.message); | ||
} | ||
} | ||
|
||
throw error; | ||
}; |
9 changes: 9 additions & 0 deletions
9
packages/twenty-server/src/engine/core-modules/workflow/workflow-trigger.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { Module } from '@nestjs/common'; | ||
|
||
import { WorkflowTriggerResolver } from 'src/engine/core-modules/workflow/workflow-trigger.resolver'; | ||
import { WorkflowTriggerService } from 'src/modules/workflow/standard-objects/workflow-trigger/workflow-trigger.service'; | ||
|
||
@Module({ | ||
providers: [WorkflowTriggerService, WorkflowTriggerResolver], | ||
}) | ||
export class WorkflowTriggerModule {} |
31 changes: 31 additions & 0 deletions
31
packages/twenty-server/src/engine/core-modules/workflow/workflow-trigger.resolver.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { UseGuards } from '@nestjs/common'; | ||
import { Args, Mutation, Resolver } from '@nestjs/graphql'; | ||
|
||
import { workflowTriggerGraphqlApiExceptionHandler } from 'src/engine/core-modules/workflow/utils/workflow-trigger-graphql-api-exception-handler.util'; | ||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; | ||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; | ||
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard'; | ||
import { WorkflowTriggerService } from 'src/modules/workflow/standard-objects/workflow-trigger/workflow-trigger.service'; | ||
|
||
@UseGuards(JwtAuthGuard) | ||
@Resolver() | ||
export class WorkflowTriggerResolver { | ||
constructor( | ||
private readonly workflowTriggerService: WorkflowTriggerService, | ||
) {} | ||
|
||
@Mutation(() => Boolean) | ||
async enableWorkflowTrigger( | ||
@AuthWorkspace() { id: workspaceId }: Workspace, | ||
@Args('workflowVersionId') workflowVersionId: string, | ||
) { | ||
try { | ||
return await this.workflowTriggerService.enableWorkflowTrigger( | ||
workspaceId, | ||
workflowVersionId, | ||
); | ||
} catch (error) { | ||
workflowTriggerGraphqlApiExceptionHandler(error); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
...-server/src/modules/workflow/standard-objects/workflow-event-listener.workspace-entity.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface'; | ||
|
||
import { FeatureFlagKeys } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; | ||
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; | ||
import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; | ||
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; | ||
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; | ||
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator'; | ||
import { WorkspaceGate } from 'src/engine/twenty-orm/decorators/workspace-gate.decorator'; | ||
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator'; | ||
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; | ||
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator'; | ||
import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; | ||
import { WORKFLOW_EVENT_LISTENER_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/standard-objects/workflow.workspace-entity'; | ||
|
||
@WorkspaceEntity({ | ||
standardId: STANDARD_OBJECT_IDS.workflowEventListener, | ||
namePlural: 'workflowEventListeners', | ||
labelSingular: 'WorkflowEventListener', | ||
labelPlural: 'WorkflowEventListeners', | ||
description: 'A workflow event listener', | ||
labelIdentifierStandardId: | ||
WORKFLOW_EVENT_LISTENER_STANDARD_FIELD_IDS.eventName, | ||
}) | ||
@WorkspaceGate({ | ||
featureFlag: FeatureFlagKeys.IsWorkflowEnabled, | ||
}) | ||
@WorkspaceIsSystem() | ||
export class WorkflowEventListenerWorkspaceEntity extends BaseWorkspaceEntity { | ||
@WorkspaceField({ | ||
standardId: WORKFLOW_EVENT_LISTENER_STANDARD_FIELD_IDS.eventName, | ||
type: FieldMetadataType.TEXT, | ||
label: 'Name', | ||
description: 'The workflow event listener name', | ||
icon: 'IconPhoneCheck', | ||
}) | ||
eventName: string; | ||
|
||
// Relations | ||
@WorkspaceRelation({ | ||
standardId: WORKFLOW_EVENT_LISTENER_STANDARD_FIELD_IDS.workflow, | ||
type: RelationMetadataType.MANY_TO_ONE, | ||
label: 'Workflow', | ||
description: 'WorkflowEventListener workflow', | ||
icon: 'IconSettingsAutomation', | ||
inverseSideTarget: () => WorkflowWorkspaceEntity, | ||
inverseSideFieldKey: 'eventListeners', | ||
}) | ||
@WorkspaceIsNullable() | ||
workflow: Relation<WorkflowWorkspaceEntity>; | ||
|
||
@WorkspaceJoinColumn('workflow') | ||
workflowId: string; | ||
} |
14 changes: 14 additions & 0 deletions
14
...rver/src/modules/workflow/standard-objects/workflow-trigger/workflow-trigger.exception.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { CustomException } from 'src/utils/custom-exception'; | ||
|
||
export class WorkflowTriggerException extends CustomException { | ||
code: WorkflowTriggerExceptionCode; | ||
constructor(message: string, code: WorkflowTriggerExceptionCode) { | ||
super(message, code); | ||
} | ||
} | ||
|
||
export enum WorkflowTriggerExceptionCode { | ||
INVALID_INPUT = 'INVALID_INPUT', | ||
INVALID_WORKFLOW_TRIGGER = 'INVALID_WORKFLOW_TRIGGER', | ||
INVALID_WORKFLOW_VERSION = 'INVALID_WORKFLOW_VERSION', | ||
} |
99 changes: 99 additions & 0 deletions
99
...server/src/modules/workflow/standard-objects/workflow-trigger/workflow-trigger.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
|
||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; | ||
import { WorkflowEventListenerWorkspaceEntity } from 'src/modules/workflow/standard-objects/workflow-event-listener.workspace-entity'; | ||
import { | ||
WorkflowTriggerException, | ||
WorkflowTriggerExceptionCode, | ||
} from 'src/modules/workflow/standard-objects/workflow-trigger/workflow-trigger.exception'; | ||
import { | ||
WorkflowDatabaseEventTrigger, | ||
WorkflowTrigger, | ||
WorkflowTriggerType, | ||
WorkflowVersionWorkspaceEntity, | ||
} from 'src/modules/workflow/standard-objects/workflow-version.workspace-entity'; | ||
|
||
@Injectable() | ||
export class WorkflowTriggerService { | ||
constructor( | ||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager, | ||
) {} | ||
|
||
async enableWorkflowTrigger(workspaceId: string, workflowVersionId: string) { | ||
const workflowVersionRepository = | ||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowVersionWorkspaceEntity>( | ||
workspaceId, | ||
'workflowVersion', | ||
); | ||
|
||
const workflowVersion = await workflowVersionRepository.findOne({ | ||
where: { | ||
id: workflowVersionId, | ||
}, | ||
}); | ||
|
||
if (!workflowVersion) { | ||
throw new WorkflowTriggerException( | ||
'Workflow version not found', | ||
WorkflowTriggerExceptionCode.INVALID_INPUT, | ||
); | ||
} | ||
|
||
const trigger = workflowVersion.trigger as unknown as WorkflowTrigger; | ||
|
||
if (!trigger || !trigger?.type) { | ||
throw new WorkflowTriggerException( | ||
'Workflow version does not contains trigger', | ||
WorkflowTriggerExceptionCode.INVALID_WORKFLOW_VERSION, | ||
); | ||
} | ||
|
||
switch (trigger.type) { | ||
case WorkflowTriggerType.DATABASE_EVENT: | ||
await this.upsertWorkflowEventListener( | ||
workspaceId, | ||
workflowVersion.workflowId, | ||
trigger, | ||
); | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
private async upsertWorkflowEventListener( | ||
workspaceId: string, | ||
workflowId: string, | ||
trigger: WorkflowDatabaseEventTrigger, | ||
) { | ||
const eventName = trigger?.settings?.eventName; | ||
|
||
if (!eventName) { | ||
throw new WorkflowTriggerException( | ||
'No event name provided in database event trigger', | ||
WorkflowTriggerExceptionCode.INVALID_WORKFLOW_TRIGGER, | ||
); | ||
} | ||
|
||
const workflowEventListenerRepository = | ||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowEventListenerWorkspaceEntity>( | ||
workspaceId, | ||
'workflowEventListener', | ||
); | ||
|
||
// TODO: Use upsert when available for workspace entities | ||
await workflowEventListenerRepository.delete({ | ||
workflowId, | ||
eventName, | ||
}); | ||
|
||
const workflowEventListener = await workflowEventListenerRepository.create({ | ||
workflowId, | ||
eventName, | ||
}); | ||
|
||
await workflowEventListenerRepository.save(workflowEventListener); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters