Move workflow versions and steps building to workflow-builder folder (#10523)
We are starting to put too many services in common folder. Version and step building should be separated into different services and go to the builder folder. Today builder folder only manage schema. We should: - keep services responsible for only one action - keep modules based on the actual action these provide rather than having common module This PR: - creates a service for workflow version builder - moves version and step builders to workflow builder folder rather than commun - creates separated folders for schema, version and steps No logic has been added. Only modules created and functions moved.
This commit is contained in:
@ -9,15 +9,15 @@ import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { WorkflowBuilderWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-builder.workspace-service';
|
||||
import { OutputSchema } from 'src/modules/workflow/workflow-builder/types/output-schema.type';
|
||||
import { OutputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
|
||||
import { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service';
|
||||
|
||||
@Resolver()
|
||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard)
|
||||
@UseFilters(WorkflowTriggerGraphqlApiExceptionFilter)
|
||||
export class WorkflowBuilderResolver {
|
||||
constructor(
|
||||
private readonly workflowBuilderWorkspaceService: WorkflowBuilderWorkspaceService,
|
||||
private readonly workflowSchemaWorkspaceService: WorkflowSchemaWorkspaceService,
|
||||
) {}
|
||||
|
||||
@Mutation(() => graphqlTypeJson)
|
||||
@ -25,7 +25,7 @@ export class WorkflowBuilderResolver {
|
||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||
@Args('input') { step }: ComputeStepOutputSchemaInput,
|
||||
): Promise<OutputSchema> {
|
||||
return this.workflowBuilderWorkspaceService.computeStepOutputSchema({
|
||||
return this.workflowSchemaWorkspaceService.computeStepOutputSchema({
|
||||
step,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
@ -1,22 +1,18 @@
|
||||
import { UseFilters, UseGuards } from '@nestjs/common';
|
||||
import { UseGuards } from '@nestjs/common';
|
||||
import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
||||
|
||||
import { CreateDraftFromWorkflowVersionInput } from 'src/engine/core-modules/workflow/dtos/create-draft-from-workflow-version-input';
|
||||
import { CreateWorkflowVersionStepInput } from 'src/engine/core-modules/workflow/dtos/create-workflow-version-step-input.dto';
|
||||
import { DeleteWorkflowVersionStepInput } from 'src/engine/core-modules/workflow/dtos/delete-workflow-version-step-input.dto';
|
||||
import { UpdateWorkflowVersionStepInput } from 'src/engine/core-modules/workflow/dtos/update-workflow-version-step-input.dto';
|
||||
import { WorkflowActionDTO } from 'src/engine/core-modules/workflow/dtos/workflow-step.dto';
|
||||
import { WorkflowTriggerGraphqlApiExceptionFilter } from 'src/engine/core-modules/workflow/filters/workflow-trigger-graphql-api-exception.filter';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-version-step.workspace-service';
|
||||
import { WorkflowVersionDTO } from 'src/engine/core-modules/workflow/dtos/workflow-version.dto';
|
||||
import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-step/workflow-version-step.workspace-service';
|
||||
|
||||
@Resolver()
|
||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard)
|
||||
@UseFilters(WorkflowTriggerGraphqlApiExceptionFilter)
|
||||
export class WorkflowVersionStepResolver {
|
||||
constructor(
|
||||
private readonly workflowVersionStepWorkspaceService: WorkflowVersionStepWorkspaceService,
|
||||
@ -60,24 +56,4 @@ export class WorkflowVersionStepResolver {
|
||||
stepId,
|
||||
});
|
||||
}
|
||||
|
||||
@Mutation(() => WorkflowVersionDTO)
|
||||
async createDraftFromWorkflowVersion(
|
||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||
@Args('input')
|
||||
{
|
||||
workflowId,
|
||||
workflowVersionIdToCopy,
|
||||
}: CreateDraftFromWorkflowVersionInput,
|
||||
): Promise<WorkflowVersionDTO> {
|
||||
return {
|
||||
id: await this.workflowVersionStepWorkspaceService.createDraftFromWorkflowVersion(
|
||||
{
|
||||
workspaceId,
|
||||
workflowId,
|
||||
workflowVersionIdToCopy,
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
import { UseGuards } from '@nestjs/common';
|
||||
import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
||||
|
||||
import { CreateDraftFromWorkflowVersionInput } from 'src/engine/core-modules/workflow/dtos/create-draft-from-workflow-version-input';
|
||||
import { WorkflowVersionDTO } from 'src/engine/core-modules/workflow/dtos/workflow-version.dto';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { WorkflowVersionWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-version.workspace-service';
|
||||
|
||||
@Resolver()
|
||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard)
|
||||
export class WorkflowVersionResolver {
|
||||
constructor(
|
||||
private readonly workflowVersionWorkspaceService: WorkflowVersionWorkspaceService,
|
||||
) {}
|
||||
|
||||
@Mutation(() => WorkflowVersionDTO)
|
||||
async createDraftFromWorkflowVersion(
|
||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||
@Args('input')
|
||||
{
|
||||
workflowId,
|
||||
workflowVersionIdToCopy,
|
||||
}: CreateDraftFromWorkflowVersionInput,
|
||||
): Promise<WorkflowVersionDTO> {
|
||||
return {
|
||||
id: await this.workflowVersionWorkspaceService.createDraftFromWorkflowVersion(
|
||||
{
|
||||
workspaceId,
|
||||
workflowId,
|
||||
workflowVersionIdToCopy,
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,18 +1,26 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { WorkflowTriggerResolver } from 'src/engine/core-modules/workflow/resolvers/workflow-trigger.resolver';
|
||||
import { WorkflowBuilderResolver } from 'src/engine/core-modules/workflow/resolvers/workflow-builder.resolver';
|
||||
import { WorkflowTriggerModule } from 'src/modules/workflow/workflow-trigger/workflow-trigger.module';
|
||||
import { WorkflowTriggerResolver } from 'src/engine/core-modules/workflow/resolvers/workflow-trigger.resolver';
|
||||
import { WorkflowVersionStepResolver } from 'src/engine/core-modules/workflow/resolvers/workflow-version-step.resolver';
|
||||
import { WorkflowBuilderModule } from 'src/modules/workflow/workflow-builder/workflow-builder.module';
|
||||
import { WorkflowVersionResolver } from 'src/engine/core-modules/workflow/resolvers/workflow-version.resolver';
|
||||
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
|
||||
import { WorkflowBuilderModule } from 'src/modules/workflow/workflow-builder/workflow-builder.module';
|
||||
import { WorkflowVersionModule } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-version.module';
|
||||
import { WorkflowTriggerModule } from 'src/modules/workflow/workflow-trigger/workflow-trigger.module';
|
||||
|
||||
@Module({
|
||||
imports: [WorkflowTriggerModule, WorkflowBuilderModule, WorkflowCommonModule],
|
||||
imports: [
|
||||
WorkflowTriggerModule,
|
||||
WorkflowBuilderModule,
|
||||
WorkflowCommonModule,
|
||||
WorkflowVersionModule,
|
||||
],
|
||||
providers: [
|
||||
WorkflowTriggerResolver,
|
||||
WorkflowBuilderResolver,
|
||||
WorkflowVersionStepResolver,
|
||||
WorkflowVersionResolver,
|
||||
],
|
||||
})
|
||||
export class WorkflowApiModule {}
|
||||
|
||||
@ -23,7 +23,7 @@ import GraphQLJSON from 'graphql-type-json';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { ServerlessFunctionSyncStatus } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
||||
import { InputSchema } from 'src/modules/workflow/workflow-builder/types/input-schema.type';
|
||||
import { InputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/input-schema.type';
|
||||
|
||||
registerEnumType(ServerlessFunctionSyncStatus, {
|
||||
name: 'ServerlessFunctionSyncStatus',
|
||||
|
||||
@ -7,7 +7,7 @@ import {
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { InputSchema } from 'src/modules/workflow/workflow-builder/types/input-schema.type';
|
||||
import { InputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/input-schema.type';
|
||||
|
||||
const DEFAULT_SERVERLESS_TIMEOUT_SECONDS = 300; // 5 minutes
|
||||
|
||||
|
||||
@ -1,28 +1,12 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
|
||||
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
|
||||
import { WorkflowQueryHookModule } from 'src/modules/workflow/common/query-hooks/workflow-query-hook.module';
|
||||
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
|
||||
import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-version-step.workspace-service';
|
||||
import { WorkflowBuilderModule } from 'src/modules/workflow/workflow-builder/workflow-builder.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
WorkflowQueryHookModule,
|
||||
WorkflowBuilderModule,
|
||||
ServerlessFunctionModule,
|
||||
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
|
||||
],
|
||||
providers: [
|
||||
WorkflowCommonWorkspaceService,
|
||||
WorkflowVersionStepWorkspaceService,
|
||||
],
|
||||
exports: [
|
||||
WorkflowCommonWorkspaceService,
|
||||
WorkflowVersionStepWorkspaceService,
|
||||
],
|
||||
imports: [WorkflowQueryHookModule, ServerlessFunctionModule],
|
||||
providers: [WorkflowCommonWorkspaceService],
|
||||
exports: [WorkflowCommonWorkspaceService],
|
||||
})
|
||||
export class WorkflowCommonModule {}
|
||||
|
||||
@ -1,16 +1,23 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
|
||||
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
|
||||
import { WorkflowBuilderWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-builder.workspace-service';
|
||||
import { WorkflowSchemaModule } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.module';
|
||||
import { WorkflowVersionStepModule } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-step/workflow-version-step.module';
|
||||
import { WorkflowVersionModule } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-version.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
|
||||
ServerlessFunctionModule,
|
||||
WorkflowSchemaModule,
|
||||
WorkflowVersionModule,
|
||||
WorkflowVersionStepModule,
|
||||
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
|
||||
],
|
||||
exports: [
|
||||
WorkflowSchemaModule,
|
||||
WorkflowVersionModule,
|
||||
WorkflowVersionStepModule,
|
||||
],
|
||||
providers: [WorkflowBuilderWorkspaceService],
|
||||
exports: [WorkflowBuilderWorkspaceService],
|
||||
})
|
||||
export class WorkflowBuilderModule {}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { InputSchemaPropertyType } from 'src/modules/workflow/workflow-builder/types/input-schema.type';
|
||||
import { InputSchemaPropertyType } from 'src/modules/workflow/workflow-builder/workflow-schema/types/input-schema.type';
|
||||
|
||||
export type Leaf = {
|
||||
isLeaf: true;
|
||||
@ -2,8 +2,8 @@ import { v4 } from 'uuid';
|
||||
|
||||
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { BaseOutputSchema } from 'src/modules/workflow/workflow-builder/types/output-schema.type';
|
||||
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/utils/generate-fake-object-record';
|
||||
import { BaseOutputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
|
||||
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record';
|
||||
import { camelToTitleCase } from 'src/utils/camel-to-title-case';
|
||||
|
||||
export const generateFakeObjectRecordEvent = (
|
||||
@ -5,8 +5,8 @@ import {
|
||||
Leaf,
|
||||
Node,
|
||||
RecordOutputSchema,
|
||||
} from 'src/modules/workflow/workflow-builder/types/output-schema.type';
|
||||
import { shouldGenerateFieldFakeValue } from 'src/modules/workflow/workflow-builder/utils/should-generate-field-fake-value';
|
||||
} from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
|
||||
import { shouldGenerateFieldFakeValue } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/should-generate-field-fake-value';
|
||||
import { camelToTitleCase } from 'src/utils/camel-to-title-case';
|
||||
|
||||
const generateObjectRecordFields = (
|
||||
@ -0,0 +1,12 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata')],
|
||||
providers: [WorkflowSchemaWorkspaceService],
|
||||
exports: [WorkflowSchemaWorkspaceService],
|
||||
})
|
||||
export class WorkflowSchemaModule {}
|
||||
@ -1,17 +1,16 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
||||
import { checkStringIsDatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/utils/check-string-is-database-event-action';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||
import { generateFakeValue } from 'src/engine/utils/generate-fake-value';
|
||||
import { OutputSchema } from 'src/modules/workflow/workflow-builder/types/output-schema.type';
|
||||
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/utils/generate-fake-object-record';
|
||||
import { generateFakeObjectRecordEvent } from 'src/modules/workflow/workflow-builder/utils/generate-fake-object-record-event';
|
||||
import { OutputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
|
||||
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record';
|
||||
import { generateFakeObjectRecordEvent } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record-event';
|
||||
import {
|
||||
WorkflowAction,
|
||||
WorkflowActionType,
|
||||
@ -22,9 +21,8 @@ import {
|
||||
} from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';
|
||||
|
||||
@Injectable()
|
||||
export class WorkflowBuilderWorkspaceService {
|
||||
export class WorkflowSchemaWorkspaceService {
|
||||
constructor(
|
||||
private readonly serverlessFunctionService: ServerlessFunctionService,
|
||||
@InjectRepository(ObjectMetadataEntity, 'metadata')
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
) {}
|
||||
@ -0,0 +1,19 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
|
||||
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
|
||||
import { WorkflowSchemaModule } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.module';
|
||||
import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-step/workflow-version-step.workspace-service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
WorkflowSchemaModule,
|
||||
ServerlessFunctionModule,
|
||||
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
|
||||
],
|
||||
providers: [WorkflowVersionStepWorkspaceService],
|
||||
exports: [WorkflowVersionStepWorkspaceService],
|
||||
})
|
||||
export class WorkflowVersionStepModule {}
|
||||
@ -5,25 +5,17 @@ import { isDefined } from 'twenty-shared';
|
||||
import { Repository } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
||||
import { BASE_TYPESCRIPT_PROJECT_INPUT_SCHEMA } from 'src/engine/core-modules/serverless/drivers/constants/base-typescript-project-input-schema';
|
||||
import { WorkflowActionDTO } from 'src/engine/core-modules/workflow/dtos/workflow-step.dto';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
|
||||
import {
|
||||
WorkflowVersionStepException,
|
||||
WorkflowVersionStepExceptionCode,
|
||||
} from 'src/modules/workflow/common/exceptions/workflow-version-step.exception';
|
||||
import {
|
||||
WorkflowVersionStatus,
|
||||
WorkflowVersionWorkspaceEntity,
|
||||
} from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import { assertWorkflowVersionHasSteps } from 'src/modules/workflow/common/utils/assert-workflow-version-has-steps';
|
||||
import { assertWorkflowVersionIsDraft } from 'src/modules/workflow/common/utils/assert-workflow-version-is-draft.util';
|
||||
import { assertWorkflowVersionTriggerIsDefined } from 'src/modules/workflow/common/utils/assert-workflow-version-trigger-is-defined.util';
|
||||
import { WorkflowBuilderWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-builder.workspace-service';
|
||||
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service';
|
||||
import { BaseWorkflowActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-settings.type';
|
||||
import {
|
||||
WorkflowAction,
|
||||
@ -48,230 +40,12 @@ const BASE_STEP_DEFINITION: BaseWorkflowActionSettings = {
|
||||
export class WorkflowVersionStepWorkspaceService {
|
||||
constructor(
|
||||
private readonly twentyORMManager: TwentyORMManager,
|
||||
private readonly workflowBuilderWorkspaceService: WorkflowBuilderWorkspaceService,
|
||||
private readonly workflowSchemaWorkspaceService: WorkflowSchemaWorkspaceService,
|
||||
private readonly serverlessFunctionService: ServerlessFunctionService,
|
||||
@InjectRepository(ObjectMetadataEntity, 'metadata')
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
private readonly workspaceEventEmitter: WorkspaceEventEmitter,
|
||||
) {}
|
||||
|
||||
private async getStepDefaultDefinition({
|
||||
type,
|
||||
workspaceId,
|
||||
}: {
|
||||
type: WorkflowActionType;
|
||||
workspaceId: string;
|
||||
}): Promise<WorkflowAction> {
|
||||
const newStepId = v4();
|
||||
|
||||
switch (type) {
|
||||
case WorkflowActionType.CODE: {
|
||||
const newServerlessFunction =
|
||||
await this.serverlessFunctionService.createOneServerlessFunction(
|
||||
{
|
||||
name: 'A Serverless Function Code Workflow Step',
|
||||
description: '',
|
||||
},
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
if (!isDefined(newServerlessFunction)) {
|
||||
throw new WorkflowVersionStepException(
|
||||
'Fail to create Code Step',
|
||||
WorkflowVersionStepExceptionCode.FAILURE,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Code - Serverless Function',
|
||||
type: WorkflowActionType.CODE,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
outputSchema: {
|
||||
link: {
|
||||
isLeaf: true,
|
||||
icon: 'IconVariable',
|
||||
tab: 'test',
|
||||
label: 'Generate Function Output',
|
||||
},
|
||||
_outputSchemaType: 'LINK',
|
||||
},
|
||||
input: {
|
||||
serverlessFunctionId: newServerlessFunction.id,
|
||||
serverlessFunctionVersion: 'draft',
|
||||
serverlessFunctionInput: BASE_TYPESCRIPT_PROJECT_INPUT_SCHEMA,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
case WorkflowActionType.SEND_EMAIL: {
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Send Email',
|
||||
type: WorkflowActionType.SEND_EMAIL,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
input: {
|
||||
connectedAccountId: '',
|
||||
email: '',
|
||||
subject: '',
|
||||
body: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
case WorkflowActionType.CREATE_RECORD: {
|
||||
const activeObjectMetadataItem =
|
||||
await this.objectMetadataRepository.findOne({
|
||||
where: { workspaceId, isActive: true, isSystem: false },
|
||||
});
|
||||
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Create Record',
|
||||
type: WorkflowActionType.CREATE_RECORD,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
input: {
|
||||
objectName: activeObjectMetadataItem?.nameSingular || '',
|
||||
objectRecord: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
case WorkflowActionType.UPDATE_RECORD: {
|
||||
const activeObjectMetadataItem =
|
||||
await this.objectMetadataRepository.findOne({
|
||||
where: { workspaceId, isActive: true, isSystem: false },
|
||||
});
|
||||
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Update Record',
|
||||
type: WorkflowActionType.UPDATE_RECORD,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
input: {
|
||||
objectName: activeObjectMetadataItem?.nameSingular || '',
|
||||
objectRecord: {},
|
||||
objectRecordId: '',
|
||||
fieldsToUpdate: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
case WorkflowActionType.DELETE_RECORD: {
|
||||
const activeObjectMetadataItem =
|
||||
await this.objectMetadataRepository.findOne({
|
||||
where: { workspaceId, isActive: true, isSystem: false },
|
||||
});
|
||||
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Delete Record',
|
||||
type: WorkflowActionType.DELETE_RECORD,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
input: {
|
||||
objectName: activeObjectMetadataItem?.nameSingular || '',
|
||||
objectRecordId: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
case WorkflowActionType.FIND_RECORDS: {
|
||||
const activeObjectMetadataItem =
|
||||
await this.objectMetadataRepository.findOne({
|
||||
where: { workspaceId, isActive: true, isSystem: false },
|
||||
});
|
||||
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Search Records',
|
||||
type: WorkflowActionType.FIND_RECORDS,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
input: {
|
||||
objectName: activeObjectMetadataItem?.nameSingular || '',
|
||||
limit: 1,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
default:
|
||||
throw new WorkflowVersionStepException(
|
||||
`WorkflowActionType '${type}' unknown`,
|
||||
WorkflowVersionStepExceptionCode.UNKNOWN,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async duplicateStep({
|
||||
step,
|
||||
workspaceId,
|
||||
}: {
|
||||
step: WorkflowAction;
|
||||
workspaceId: string;
|
||||
}): Promise<WorkflowAction> {
|
||||
switch (step.type) {
|
||||
case WorkflowActionType.CODE: {
|
||||
await this.serverlessFunctionService.usePublishedVersionAsDraft({
|
||||
id: step.settings.input.serverlessFunctionId,
|
||||
version: step.settings.input.serverlessFunctionVersion,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
return {
|
||||
...step,
|
||||
settings: {
|
||||
...step.settings,
|
||||
input: {
|
||||
...step.settings.input,
|
||||
serverlessFunctionVersion: 'draft',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
default: {
|
||||
return step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async enrichOutputSchema({
|
||||
step,
|
||||
workspaceId,
|
||||
}: {
|
||||
step: WorkflowAction;
|
||||
workspaceId: string;
|
||||
}): Promise<WorkflowAction> {
|
||||
// We don't enrich on the fly for code workflow action. OutputSchema is computed and updated when testing the serverless function
|
||||
if (step.type === WorkflowActionType.CODE) {
|
||||
return step;
|
||||
}
|
||||
|
||||
const result = { ...step };
|
||||
const outputSchema =
|
||||
await this.workflowBuilderWorkspaceService.computeStepOutputSchema({
|
||||
step,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
result.settings = {
|
||||
...result.settings,
|
||||
outputSchema: outputSchema || {},
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async createWorkflowVersionStep({
|
||||
workspaceId,
|
||||
workflowVersionId,
|
||||
@ -431,83 +205,63 @@ export class WorkflowVersionStepWorkspaceService {
|
||||
return stepToDelete;
|
||||
}
|
||||
|
||||
async createDraftFromWorkflowVersion({
|
||||
async duplicateStep({
|
||||
step,
|
||||
workspaceId,
|
||||
workflowId,
|
||||
workflowVersionIdToCopy,
|
||||
}: {
|
||||
step: WorkflowAction;
|
||||
workspaceId: string;
|
||||
workflowId: string;
|
||||
workflowVersionIdToCopy: string;
|
||||
}) {
|
||||
const workflowVersionRepository =
|
||||
await this.twentyORMManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||
'workflowVersion',
|
||||
);
|
||||
}): Promise<WorkflowAction> {
|
||||
switch (step.type) {
|
||||
case WorkflowActionType.CODE: {
|
||||
await this.serverlessFunctionService.usePublishedVersionAsDraft({
|
||||
id: step.settings.input.serverlessFunctionId,
|
||||
version: step.settings.input.serverlessFunctionVersion,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const workflowVersionToCopy = await workflowVersionRepository.findOne({
|
||||
where: {
|
||||
id: workflowVersionIdToCopy,
|
||||
workflowId,
|
||||
},
|
||||
});
|
||||
return {
|
||||
...step,
|
||||
settings: {
|
||||
...step.settings,
|
||||
input: {
|
||||
...step.settings.input,
|
||||
serverlessFunctionVersion: 'draft',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
default: {
|
||||
return step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isDefined(workflowVersionToCopy)) {
|
||||
throw new WorkflowVersionStepException(
|
||||
'WorkflowVersion to copy not found',
|
||||
WorkflowVersionStepExceptionCode.NOT_FOUND,
|
||||
);
|
||||
private async enrichOutputSchema({
|
||||
step,
|
||||
workspaceId,
|
||||
}: {
|
||||
step: WorkflowAction;
|
||||
workspaceId: string;
|
||||
}): Promise<WorkflowAction> {
|
||||
// We don't enrich on the fly for code workflow action. OutputSchema is computed and updated when testing the serverless function
|
||||
if (step.type === WorkflowActionType.CODE) {
|
||||
return step;
|
||||
}
|
||||
|
||||
assertWorkflowVersionTriggerIsDefined(workflowVersionToCopy);
|
||||
assertWorkflowVersionHasSteps(workflowVersionToCopy);
|
||||
|
||||
let draftWorkflowVersion = await workflowVersionRepository.findOne({
|
||||
where: {
|
||||
workflowId,
|
||||
status: WorkflowVersionStatus.DRAFT,
|
||||
},
|
||||
});
|
||||
|
||||
if (!isDefined(draftWorkflowVersion)) {
|
||||
const workflowVersionsCount = await workflowVersionRepository.count({
|
||||
where: {
|
||||
workflowId,
|
||||
},
|
||||
});
|
||||
|
||||
draftWorkflowVersion = await workflowVersionRepository.save({
|
||||
workflowId,
|
||||
name: `v${workflowVersionsCount + 1}`,
|
||||
status: WorkflowVersionStatus.DRAFT,
|
||||
});
|
||||
|
||||
await this.emitWorkflowVersionCreationEvent({
|
||||
workflowVersion: draftWorkflowVersion,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
|
||||
assertWorkflowVersionIsDraft(draftWorkflowVersion);
|
||||
|
||||
const newWorkflowVersionTrigger = workflowVersionToCopy.trigger;
|
||||
const newWorkflowVersionSteps: WorkflowAction[] = [];
|
||||
|
||||
for (const step of workflowVersionToCopy.steps) {
|
||||
const duplicatedStep = await this.duplicateStep({
|
||||
const result = { ...step };
|
||||
const outputSchema =
|
||||
await this.workflowSchemaWorkspaceService.computeStepOutputSchema({
|
||||
step,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
newWorkflowVersionSteps.push(duplicatedStep);
|
||||
}
|
||||
result.settings = {
|
||||
...result.settings,
|
||||
outputSchema: outputSchema || {},
|
||||
};
|
||||
|
||||
await workflowVersionRepository.update(draftWorkflowVersion.id, {
|
||||
steps: newWorkflowVersionSteps,
|
||||
trigger: newWorkflowVersionTrigger,
|
||||
});
|
||||
|
||||
return draftWorkflowVersion.id;
|
||||
return result;
|
||||
}
|
||||
|
||||
private async runWorkflowVersionStepDeletionSideEffects({
|
||||
@ -534,40 +288,161 @@ export class WorkflowVersionStepWorkspaceService {
|
||||
}
|
||||
}
|
||||
|
||||
private async emitWorkflowVersionCreationEvent({
|
||||
workflowVersion,
|
||||
private async getStepDefaultDefinition({
|
||||
type,
|
||||
workspaceId,
|
||||
}: {
|
||||
workflowVersion: WorkflowVersionWorkspaceEntity;
|
||||
type: WorkflowActionType;
|
||||
workspaceId: string;
|
||||
}) {
|
||||
const objectMetadata = await this.objectMetadataRepository.findOne({
|
||||
where: {
|
||||
nameSingular: 'workflowVersion',
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
}): Promise<WorkflowAction> {
|
||||
const newStepId = v4();
|
||||
|
||||
if (!objectMetadata) {
|
||||
throw new WorkflowVersionStepException(
|
||||
'Object metadata not found',
|
||||
WorkflowVersionStepExceptionCode.FAILURE,
|
||||
);
|
||||
}
|
||||
switch (type) {
|
||||
case WorkflowActionType.CODE: {
|
||||
const newServerlessFunction =
|
||||
await this.serverlessFunctionService.createOneServerlessFunction(
|
||||
{
|
||||
name: 'A Serverless Function Code Workflow Step',
|
||||
description: '',
|
||||
},
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
this.workspaceEventEmitter.emitDatabaseBatchEvent({
|
||||
objectMetadataNameSingular: 'workflowVersion',
|
||||
action: DatabaseEventAction.CREATED,
|
||||
events: [
|
||||
{
|
||||
recordId: workflowVersion.id,
|
||||
objectMetadata,
|
||||
properties: {
|
||||
after: workflowVersion,
|
||||
if (!isDefined(newServerlessFunction)) {
|
||||
throw new WorkflowVersionStepException(
|
||||
'Fail to create Code Step',
|
||||
WorkflowVersionStepExceptionCode.FAILURE,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Code - Serverless Function',
|
||||
type: WorkflowActionType.CODE,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
outputSchema: {
|
||||
link: {
|
||||
isLeaf: true,
|
||||
icon: 'IconVariable',
|
||||
tab: 'test',
|
||||
label: 'Generate Function Output',
|
||||
},
|
||||
_outputSchemaType: 'LINK',
|
||||
},
|
||||
input: {
|
||||
serverlessFunctionId: newServerlessFunction.id,
|
||||
serverlessFunctionVersion: 'draft',
|
||||
serverlessFunctionInput: BASE_TYPESCRIPT_PROJECT_INPUT_SCHEMA,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
workspaceId,
|
||||
});
|
||||
};
|
||||
}
|
||||
case WorkflowActionType.SEND_EMAIL: {
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Send Email',
|
||||
type: WorkflowActionType.SEND_EMAIL,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
input: {
|
||||
connectedAccountId: '',
|
||||
email: '',
|
||||
subject: '',
|
||||
body: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
case WorkflowActionType.CREATE_RECORD: {
|
||||
const activeObjectMetadataItem =
|
||||
await this.objectMetadataRepository.findOne({
|
||||
where: { workspaceId, isActive: true, isSystem: false },
|
||||
});
|
||||
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Create Record',
|
||||
type: WorkflowActionType.CREATE_RECORD,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
input: {
|
||||
objectName: activeObjectMetadataItem?.nameSingular || '',
|
||||
objectRecord: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
case WorkflowActionType.UPDATE_RECORD: {
|
||||
const activeObjectMetadataItem =
|
||||
await this.objectMetadataRepository.findOne({
|
||||
where: { workspaceId, isActive: true, isSystem: false },
|
||||
});
|
||||
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Update Record',
|
||||
type: WorkflowActionType.UPDATE_RECORD,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
input: {
|
||||
objectName: activeObjectMetadataItem?.nameSingular || '',
|
||||
objectRecord: {},
|
||||
objectRecordId: '',
|
||||
fieldsToUpdate: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
case WorkflowActionType.DELETE_RECORD: {
|
||||
const activeObjectMetadataItem =
|
||||
await this.objectMetadataRepository.findOne({
|
||||
where: { workspaceId, isActive: true, isSystem: false },
|
||||
});
|
||||
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Delete Record',
|
||||
type: WorkflowActionType.DELETE_RECORD,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
input: {
|
||||
objectName: activeObjectMetadataItem?.nameSingular || '',
|
||||
objectRecordId: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
case WorkflowActionType.FIND_RECORDS: {
|
||||
const activeObjectMetadataItem =
|
||||
await this.objectMetadataRepository.findOne({
|
||||
where: { workspaceId, isActive: true, isSystem: false },
|
||||
});
|
||||
|
||||
return {
|
||||
id: newStepId,
|
||||
name: 'Search Records',
|
||||
type: WorkflowActionType.FIND_RECORDS,
|
||||
valid: false,
|
||||
settings: {
|
||||
...BASE_STEP_DEFINITION,
|
||||
input: {
|
||||
objectName: activeObjectMetadataItem?.nameSingular || '',
|
||||
limit: 1,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
default:
|
||||
throw new WorkflowVersionStepException(
|
||||
`WorkflowActionType '${type}' unknown`,
|
||||
WorkflowVersionStepExceptionCode.UNKNOWN,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
|
||||
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
|
||||
import { WorkflowSchemaModule } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.module';
|
||||
import { WorkflowVersionStepModule } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-step/workflow-version-step.module';
|
||||
import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-step/workflow-version-step.workspace-service';
|
||||
import { WorkflowVersionWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-version.workspace-service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
WorkflowVersionStepModule,
|
||||
WorkflowSchemaModule,
|
||||
ServerlessFunctionModule,
|
||||
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
|
||||
],
|
||||
providers: [
|
||||
WorkflowVersionWorkspaceService,
|
||||
WorkflowVersionStepWorkspaceService,
|
||||
],
|
||||
exports: [
|
||||
WorkflowVersionWorkspaceService,
|
||||
WorkflowVersionStepWorkspaceService,
|
||||
],
|
||||
})
|
||||
export class WorkflowVersionModule {}
|
||||
@ -0,0 +1,151 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
|
||||
import {
|
||||
WorkflowVersionStepException,
|
||||
WorkflowVersionStepExceptionCode,
|
||||
} from 'src/modules/workflow/common/exceptions/workflow-version-step.exception';
|
||||
import {
|
||||
WorkflowVersionStatus,
|
||||
WorkflowVersionWorkspaceEntity,
|
||||
} from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import { assertWorkflowVersionHasSteps } from 'src/modules/workflow/common/utils/assert-workflow-version-has-steps';
|
||||
import { assertWorkflowVersionIsDraft } from 'src/modules/workflow/common/utils/assert-workflow-version-is-draft.util';
|
||||
import { assertWorkflowVersionTriggerIsDefined } from 'src/modules/workflow/common/utils/assert-workflow-version-trigger-is-defined.util';
|
||||
import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-step/workflow-version-step.workspace-service';
|
||||
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||
|
||||
@Injectable()
|
||||
export class WorkflowVersionWorkspaceService {
|
||||
constructor(
|
||||
private readonly twentyORMManager: TwentyORMManager,
|
||||
private readonly workflowVersionStepWorkspaceService: WorkflowVersionStepWorkspaceService,
|
||||
@InjectRepository(ObjectMetadataEntity, 'metadata')
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
private readonly workspaceEventEmitter: WorkspaceEventEmitter,
|
||||
) {}
|
||||
|
||||
async createDraftFromWorkflowVersion({
|
||||
workspaceId,
|
||||
workflowId,
|
||||
workflowVersionIdToCopy,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
workflowId: string;
|
||||
workflowVersionIdToCopy: string;
|
||||
}) {
|
||||
const workflowVersionRepository =
|
||||
await this.twentyORMManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||
'workflowVersion',
|
||||
);
|
||||
|
||||
const workflowVersionToCopy = await workflowVersionRepository.findOne({
|
||||
where: {
|
||||
id: workflowVersionIdToCopy,
|
||||
workflowId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!isDefined(workflowVersionToCopy)) {
|
||||
throw new WorkflowVersionStepException(
|
||||
'WorkflowVersion to copy not found',
|
||||
WorkflowVersionStepExceptionCode.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
assertWorkflowVersionTriggerIsDefined(workflowVersionToCopy);
|
||||
assertWorkflowVersionHasSteps(workflowVersionToCopy);
|
||||
|
||||
let draftWorkflowVersion = await workflowVersionRepository.findOne({
|
||||
where: {
|
||||
workflowId,
|
||||
status: WorkflowVersionStatus.DRAFT,
|
||||
},
|
||||
});
|
||||
|
||||
if (!isDefined(draftWorkflowVersion)) {
|
||||
const workflowVersionsCount = await workflowVersionRepository.count({
|
||||
where: {
|
||||
workflowId,
|
||||
},
|
||||
});
|
||||
|
||||
draftWorkflowVersion = await workflowVersionRepository.save({
|
||||
workflowId,
|
||||
name: `v${workflowVersionsCount + 1}`,
|
||||
status: WorkflowVersionStatus.DRAFT,
|
||||
});
|
||||
|
||||
await this.emitWorkflowVersionCreationEvent({
|
||||
workflowVersion: draftWorkflowVersion,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
|
||||
assertWorkflowVersionIsDraft(draftWorkflowVersion);
|
||||
|
||||
const newWorkflowVersionTrigger = workflowVersionToCopy.trigger;
|
||||
const newWorkflowVersionSteps: WorkflowAction[] = [];
|
||||
|
||||
for (const step of workflowVersionToCopy.steps) {
|
||||
const duplicatedStep =
|
||||
await this.workflowVersionStepWorkspaceService.duplicateStep({
|
||||
step,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
newWorkflowVersionSteps.push(duplicatedStep);
|
||||
}
|
||||
|
||||
await workflowVersionRepository.update(draftWorkflowVersion.id, {
|
||||
steps: newWorkflowVersionSteps,
|
||||
trigger: newWorkflowVersionTrigger,
|
||||
});
|
||||
|
||||
return draftWorkflowVersion.id;
|
||||
}
|
||||
|
||||
private async emitWorkflowVersionCreationEvent({
|
||||
workflowVersion,
|
||||
workspaceId,
|
||||
}: {
|
||||
workflowVersion: WorkflowVersionWorkspaceEntity;
|
||||
workspaceId: string;
|
||||
}) {
|
||||
const objectMetadata = await this.objectMetadataRepository.findOne({
|
||||
where: {
|
||||
nameSingular: 'workflowVersion',
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!objectMetadata) {
|
||||
throw new WorkflowVersionStepException(
|
||||
'Object metadata not found',
|
||||
WorkflowVersionStepExceptionCode.FAILURE,
|
||||
);
|
||||
}
|
||||
|
||||
this.workspaceEventEmitter.emitDatabaseBatchEvent({
|
||||
objectMetadataNameSingular: 'workflowVersion',
|
||||
action: DatabaseEventAction.CREATED,
|
||||
events: [
|
||||
{
|
||||
recordId: workflowVersion.id,
|
||||
objectMetadata,
|
||||
properties: {
|
||||
after: workflowVersion,
|
||||
},
|
||||
},
|
||||
],
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import { OutputSchema } from 'src/modules/workflow/workflow-builder/types/output-schema.type';
|
||||
import { OutputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
|
||||
import { WorkflowCodeActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/code/types/workflow-code-action-settings.type';
|
||||
import { WorkflowFormActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/form/types/workflow-form-action-settings.type';
|
||||
import { WorkflowSendEmailActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/types/workflow-send-email-action-settings.type';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { OutputSchema } from 'src/modules/workflow/workflow-builder/types/output-schema.type';
|
||||
import { OutputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
|
||||
|
||||
export enum WorkflowTriggerType {
|
||||
DATABASE_EVENT = 'DATABASE_EVENT',
|
||||
|
||||
Reference in New Issue
Block a user