Update workflow version struct (#6716)

We want to avoid the nested structure of active pieces. Steps to execute
will now be separated from the trigger. It will be an array executed
sequentially.

For now a step can only be an action. But at some point it will also be
a branch or a loop
This commit is contained in:
Thomas Trompette
2024-08-22 17:59:16 +02:00
committed by GitHub
parent 579c2ebcea
commit 0a7700351f
18 changed files with 131 additions and 114 deletions
@@ -0,0 +1,13 @@
import { CustomException } from 'src/utils/custom-exception';
export class WorkflowStepExecutorException extends CustomException {
code: WorkflowStepExecutorExceptionCode;
constructor(message: string, code: WorkflowStepExecutorExceptionCode) {
super(message, code);
}
}
export enum WorkflowStepExecutorExceptionCode {
SCOPED_WORKSPACE_NOT_FOUND = 'SCOPED_WORKSPACE_NOT_FOUND',
INVALID_STEP_TYPE = 'INVALID_STEP_TYPE',
}
@@ -0,0 +1,26 @@
import { Injectable } from '@nestjs/common';
import { WorkflowStepType } from 'src/modules/workflow/common/types/workflow-step.type';
import {
WorkflowStepExecutorException,
WorkflowStepExecutorExceptionCode,
} from 'src/modules/workflow/workflow-step-executor/workflow-step-executor.exception';
import { WorkflowStepExecutor } from 'src/modules/workflow/workflow-step-executor/workflow-step-executor.interface';
import { CodeActionExecutor } from 'src/modules/workflow/workflow-step-executor/workflow-step-executors/code-action-executor';
@Injectable()
export class WorkflowStepExecutorFactory {
constructor(private readonly codeActionExecutor: CodeActionExecutor) {}
get(stepType: WorkflowStepType): WorkflowStepExecutor {
switch (stepType) {
case WorkflowStepType.CODE_ACTION:
return this.codeActionExecutor;
default:
throw new WorkflowStepExecutorException(
`Workflow step executor not found for step type '${stepType}'`,
WorkflowStepExecutorExceptionCode.INVALID_STEP_TYPE,
);
}
}
}
@@ -0,0 +1,12 @@
import { WorkflowResult } from 'src/modules/workflow/common/types/workflow-result.type';
import { WorkflowStep } from 'src/modules/workflow/common/types/workflow-step.type';
export interface WorkflowStepExecutor {
execute({
step,
payload,
}: {
step: WorkflowStep;
payload?: object;
}): Promise<WorkflowResult>;
}
@@ -0,0 +1,17 @@
import { Module } from '@nestjs/common';
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
import { WorkflowStepExecutorFactory } from 'src/modules/workflow/workflow-step-executor/workflow-step-executor.factory';
import { CodeActionExecutor } from 'src/modules/workflow/workflow-step-executor/workflow-step-executors/code-action-executor';
@Module({
imports: [ServerlessFunctionModule],
providers: [
WorkflowStepExecutorFactory,
CodeActionExecutor,
ScopedWorkspaceContextFactory,
],
exports: [WorkflowStepExecutorFactory],
})
export class WorkflowStepExecutorModule {}
@@ -0,0 +1,44 @@
import { Injectable } from '@nestjs/common';
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
import { WorkflowResult } from 'src/modules/workflow/common/types/workflow-result.type';
import { WorkflowCodeStep } from 'src/modules/workflow/common/types/workflow-step.type';
import {
WorkflowStepExecutorException,
WorkflowStepExecutorExceptionCode,
} from 'src/modules/workflow/workflow-step-executor/workflow-step-executor.exception';
import { WorkflowStepExecutor } from 'src/modules/workflow/workflow-step-executor/workflow-step-executor.interface';
@Injectable()
export class CodeActionExecutor implements WorkflowStepExecutor {
constructor(
private readonly serverlessFunctionService: ServerlessFunctionService,
private readonly scopedWorkspaceContextFactory: ScopedWorkspaceContextFactory,
) {}
async execute({
step,
payload,
}: {
step: WorkflowCodeStep;
payload?: object;
}): Promise<WorkflowResult> {
const { workspaceId } = this.scopedWorkspaceContextFactory.create();
if (!workspaceId) {
throw new WorkflowStepExecutorException(
'Scoped workspace not found',
WorkflowStepExecutorExceptionCode.SCOPED_WORKSPACE_NOT_FOUND,
);
}
const result = await this.serverlessFunctionService.executeOne(
step.settings.serverlessFunctionId,
workspaceId,
payload,
);
return { data: result.data, ...(result.error && { error: result.error }) };
}
}