diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/factories/workflow-action.factory.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/factories/workflow-action.factory.ts index ae4c14ecbe..3f0244f2b6 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/factories/workflow-action.factory.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/factories/workflow-action.factory.ts @@ -8,6 +8,7 @@ import { } from 'src/modules/workflow/workflow-executor/exceptions/workflow-step-executor.exception'; import { AiAgentWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/ai-agent/ai-agent.workflow-action'; import { CodeWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/code/code.workflow-action'; +import { EmptyWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/empty/empty.workflow-action'; import { FilterWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/filter/filter.workflow-action'; import { FormWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/form/form.workflow-action'; import { IteratorWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/iterator/iterator.workflow-action'; @@ -31,6 +32,7 @@ export class WorkflowActionFactory { private readonly iteratorWorkflowAction: IteratorWorkflowAction, private readonly toolExecutorWorkflowAction: ToolExecutorWorkflowAction, private readonly aiAgentWorkflowAction: AiAgentWorkflowAction, + private readonly emptyWorkflowAction: EmptyWorkflowAction, ) {} get(stepType: WorkflowActionType): WorkflowAction { @@ -57,6 +59,8 @@ export class WorkflowActionFactory { return this.toolExecutorWorkflowAction; case WorkflowActionType.AI_AGENT: return this.aiAgentWorkflowAction; + case WorkflowActionType.EMPTY: + return this.emptyWorkflowAction; default: throw new WorkflowStepExecutorException( `Workflow step executor not found for step type '${stepType}'`, diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/empty/empty-action.module.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/empty/empty-action.module.ts new file mode 100644 index 0000000000..4254a15ee8 --- /dev/null +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/empty/empty-action.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; + +import { EmptyWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/empty/empty.workflow-action'; + +@Module({ + providers: [EmptyWorkflowAction], + exports: [EmptyWorkflowAction], +}) +export class EmptyActionModule {} diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/empty/empty.workflow-action.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/empty/empty.workflow-action.ts new file mode 100644 index 0000000000..90281504a6 --- /dev/null +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/empty/empty.workflow-action.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@nestjs/common'; + +import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface'; + +import { + WorkflowStepExecutorException, + WorkflowStepExecutorExceptionCode, +} from 'src/modules/workflow/workflow-executor/exceptions/workflow-step-executor.exception'; +import { type WorkflowActionInput } from 'src/modules/workflow/workflow-executor/types/workflow-action-input'; +import { type WorkflowActionOutput } from 'src/modules/workflow/workflow-executor/types/workflow-action-output.type'; +import { findStepOrThrow } from 'src/modules/workflow/workflow-executor/utils/find-step-or-throw.util'; +import { isWorkflowEmptyAction } from 'src/modules/workflow/workflow-executor/workflow-actions/empty/guards/is-workflow-empty-action.guard'; + +@Injectable() +export class EmptyWorkflowAction implements WorkflowAction { + async execute({ + currentStepId, + steps, + }: WorkflowActionInput): Promise { + const step = findStepOrThrow({ + stepId: currentStepId, + steps, + }); + + if (!isWorkflowEmptyAction(step)) { + throw new WorkflowStepExecutorException( + 'Step is not an empty action', + WorkflowStepExecutorExceptionCode.INVALID_STEP_TYPE, + ); + } + + return { result: {} }; + } +} diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/empty/guards/is-workflow-empty-action.guard.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/empty/guards/is-workflow-empty-action.guard.ts new file mode 100644 index 0000000000..d8e47e98e4 --- /dev/null +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/empty/guards/is-workflow-empty-action.guard.ts @@ -0,0 +1,10 @@ +import { + WorkflowActionType, + type WorkflowAction, +} from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type'; + +export const isWorkflowEmptyAction = ( + action: WorkflowAction, +): action is WorkflowAction & { type: WorkflowActionType.EMPTY } => { + return action.type === WorkflowActionType.EMPTY; +}; diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type.ts index fe86a839d0..9eb00c16ed 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type.ts @@ -25,6 +25,7 @@ export enum WorkflowActionType { HTTP_REQUEST = 'HTTP_REQUEST', AI_AGENT = 'AI_AGENT', ITERATOR = 'ITERATOR', + EMPTY = 'EMPTY', } type BaseWorkflowAction = { @@ -95,6 +96,10 @@ export type WorkflowIteratorAction = BaseWorkflowAction & { settings: WorkflowIteratorActionSettings; }; +export type WorkflowEmptyAction = BaseWorkflowAction & { + type: WorkflowActionType.EMPTY; +}; + export type WorkflowAction = | WorkflowCodeAction | WorkflowSendEmailAction @@ -106,4 +111,5 @@ export type WorkflowAction = | WorkflowFilterAction | WorkflowHttpRequestAction | WorkflowAiAgentAction - | WorkflowIteratorAction; + | WorkflowIteratorAction + | WorkflowEmptyAction; diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-executor.module.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-executor.module.ts index 4687c35db2..f47b9efc39 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-executor.module.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-executor.module.ts @@ -8,6 +8,7 @@ import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-commo import { WorkflowActionFactory } from 'src/modules/workflow/workflow-executor/factories/workflow-action.factory'; import { AiAgentActionModule } from 'src/modules/workflow/workflow-executor/workflow-actions/ai-agent/ai-agent-action.module'; import { CodeActionModule } from 'src/modules/workflow/workflow-executor/workflow-actions/code/code-action.module'; +import { EmptyActionModule } from 'src/modules/workflow/workflow-executor/workflow-actions/empty/empty-action.module'; import { FilterActionModule } from 'src/modules/workflow/workflow-executor/workflow-actions/filter/filter-action.module'; import { FormActionModule } from 'src/modules/workflow/workflow-executor/workflow-actions/form/form-action.module'; import { IteratorActionModule } from 'src/modules/workflow/workflow-executor/workflow-actions/iterator/iterator-action.module'; @@ -27,6 +28,7 @@ import { WorkflowRunModule } from 'src/modules/workflow/workflow-runner/workflow FilterActionModule, IteratorActionModule, AiAgentActionModule, + EmptyActionModule, FeatureFlagModule, AiModule, ],