Add submit form step endpoint (#10538)
- add endpoint to submit form step - update context and output of workflow run - resume workflow execution
This commit is contained in:
@ -0,0 +1,24 @@
|
|||||||
|
import { Field, InputType } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import graphqlTypeJson from 'graphql-type-json';
|
||||||
|
|
||||||
|
@InputType()
|
||||||
|
export class SubmitFormStepInput {
|
||||||
|
@Field(() => String, {
|
||||||
|
description: 'Workflow version ID',
|
||||||
|
nullable: false,
|
||||||
|
})
|
||||||
|
stepId: string;
|
||||||
|
|
||||||
|
@Field(() => String, {
|
||||||
|
description: 'Workflow run ID',
|
||||||
|
nullable: false,
|
||||||
|
})
|
||||||
|
workflowRunId: string;
|
||||||
|
|
||||||
|
@Field(() => graphqlTypeJson, {
|
||||||
|
description: 'Form response in JSON format',
|
||||||
|
nullable: false,
|
||||||
|
})
|
||||||
|
response: JSON;
|
||||||
|
}
|
||||||
@ -3,13 +3,14 @@ import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
|||||||
|
|
||||||
import { CreateWorkflowVersionStepInput } from 'src/engine/core-modules/workflow/dtos/create-workflow-version-step-input.dto';
|
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 { DeleteWorkflowVersionStepInput } from 'src/engine/core-modules/workflow/dtos/delete-workflow-version-step-input.dto';
|
||||||
|
import { SubmitFormStepInput } from 'src/engine/core-modules/workflow/dtos/submit-form-step-input.dto';
|
||||||
import { UpdateWorkflowVersionStepInput } from 'src/engine/core-modules/workflow/dtos/update-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 { WorkflowActionDTO } from 'src/engine/core-modules/workflow/dtos/workflow-step.dto';
|
||||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||||
import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
|
import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
|
||||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||||
import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-step/workflow-version-step.workspace-service';
|
import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-step/workflow-version-step.workspace-service';
|
||||||
|
|
||||||
@Resolver()
|
@Resolver()
|
||||||
@UseGuards(WorkspaceAuthGuard, UserAuthGuard)
|
@UseGuards(WorkspaceAuthGuard, UserAuthGuard)
|
||||||
@ -56,4 +57,20 @@ export class WorkflowVersionStepResolver {
|
|||||||
stepId,
|
stepId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Mutation(() => Boolean)
|
||||||
|
async submitFormStep(
|
||||||
|
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||||
|
@Args('input')
|
||||||
|
{ stepId, workflowRunId, response }: SubmitFormStepInput,
|
||||||
|
) {
|
||||||
|
await this.workflowVersionStepWorkspaceService.submitFormStep({
|
||||||
|
workspaceId,
|
||||||
|
stepId,
|
||||||
|
workflowRunId,
|
||||||
|
response,
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||||
|
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkflowEventListenerWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity';
|
import { WorkflowEventListenerWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity';
|
||||||
import { WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
|
import { WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
|
||||||
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||||
|
import { WorkflowActionType } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
import {
|
import {
|
||||||
WorkflowTriggerException,
|
WorkflowTriggerException,
|
||||||
WorkflowTriggerExceptionCode,
|
WorkflowTriggerExceptionCode,
|
||||||
} from 'src/modules/workflow/workflow-trigger/exceptions/workflow-trigger.exception';
|
} from 'src/modules/workflow/workflow-trigger/exceptions/workflow-trigger.exception';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { WorkflowActionType } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
|
||||||
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkflowCommonWorkspaceService {
|
export class WorkflowCommonWorkspaceService {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
|
|||||||
|
|
||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
import { WorkflowSchemaModule } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.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 { WorkflowVersionStepModule } from 'src/modules/workflow/workflow-builder/workflow-step/workflow-version-step.module';
|
||||||
import { WorkflowVersionModule } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-version.module';
|
import { WorkflowVersionModule } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-version.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
|||||||
@ -5,12 +5,16 @@ import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
|
|||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
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 { 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 { 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';
|
import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-step/workflow-version-step.workspace-service';
|
||||||
|
import { WorkflowRunModule } from 'src/modules/workflow/workflow-runner/workflow-run/workflow-run.module';
|
||||||
|
import { WorkflowRunnerModule } from 'src/modules/workflow/workflow-runner/workflow-runner.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
WorkflowSchemaModule,
|
WorkflowSchemaModule,
|
||||||
ServerlessFunctionModule,
|
ServerlessFunctionModule,
|
||||||
|
WorkflowRunnerModule,
|
||||||
|
WorkflowRunModule,
|
||||||
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
|
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
|
||||||
],
|
],
|
||||||
providers: [WorkflowVersionStepWorkspaceService],
|
providers: [WorkflowVersionStepWorkspaceService],
|
||||||
@ -14,6 +14,7 @@ import {
|
|||||||
WorkflowVersionStepException,
|
WorkflowVersionStepException,
|
||||||
WorkflowVersionStepExceptionCode,
|
WorkflowVersionStepExceptionCode,
|
||||||
} from 'src/modules/workflow/common/exceptions/workflow-version-step.exception';
|
} from 'src/modules/workflow/common/exceptions/workflow-version-step.exception';
|
||||||
|
import { StepOutput } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
|
||||||
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
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 { 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 { BaseWorkflowActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-settings.type';
|
||||||
@ -21,6 +22,8 @@ import {
|
|||||||
WorkflowAction,
|
WorkflowAction,
|
||||||
WorkflowActionType,
|
WorkflowActionType,
|
||||||
} from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
} from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
|
import { WorkflowRunWorkspaceService } from 'src/modules/workflow/workflow-runner/workflow-run/workflow-run.workspace-service';
|
||||||
|
import { WorkflowRunnerWorkspaceService } from 'src/modules/workflow/workflow-runner/workspace-services/workflow-runner.workspace-service';
|
||||||
|
|
||||||
const TRIGGER_STEP_ID = 'trigger';
|
const TRIGGER_STEP_ID = 'trigger';
|
||||||
|
|
||||||
@ -44,6 +47,8 @@ export class WorkflowVersionStepWorkspaceService {
|
|||||||
private readonly serverlessFunctionService: ServerlessFunctionService,
|
private readonly serverlessFunctionService: ServerlessFunctionService,
|
||||||
@InjectRepository(ObjectMetadataEntity, 'metadata')
|
@InjectRepository(ObjectMetadataEntity, 'metadata')
|
||||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||||
|
private readonly workflowRunWorkspaceService: WorkflowRunWorkspaceService,
|
||||||
|
private readonly workflowRunnerWorkspaceService: WorkflowRunnerWorkspaceService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async createWorkflowVersionStep({
|
async createWorkflowVersionStep({
|
||||||
@ -237,6 +242,58 @@ export class WorkflowVersionStepWorkspaceService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async submitFormStep({
|
||||||
|
workspaceId,
|
||||||
|
stepId,
|
||||||
|
workflowRunId,
|
||||||
|
response,
|
||||||
|
}: {
|
||||||
|
workspaceId: string;
|
||||||
|
stepId: string;
|
||||||
|
workflowRunId: string;
|
||||||
|
response: object;
|
||||||
|
}) {
|
||||||
|
const workflowRun =
|
||||||
|
await this.workflowRunWorkspaceService.getWorkflowRunOrFail(
|
||||||
|
workflowRunId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const step = workflowRun.output?.flow?.steps?.find(
|
||||||
|
(step) => step.id === stepId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isDefined(step)) {
|
||||||
|
throw new WorkflowVersionStepException(
|
||||||
|
'Step not found',
|
||||||
|
WorkflowVersionStepExceptionCode.NOT_FOUND,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newStepOutput: StepOutput = {
|
||||||
|
id: stepId,
|
||||||
|
output: {
|
||||||
|
result: response,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedContext = {
|
||||||
|
...workflowRun.context,
|
||||||
|
[stepId]: response,
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.workflowRunWorkspaceService.saveWorkflowRunState({
|
||||||
|
workflowRunId,
|
||||||
|
stepOutput: newStepOutput,
|
||||||
|
context: updatedContext,
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.workflowRunnerWorkspaceService.resume({
|
||||||
|
workspaceId,
|
||||||
|
workflowRunId,
|
||||||
|
lastExecutedStepId: stepId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async enrichOutputSchema({
|
private async enrichOutputSchema({
|
||||||
step,
|
step,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@ -5,8 +5,7 @@ import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
|
|||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
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 { 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 { 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 { WorkflowVersionStepModule } from 'src/modules/workflow/workflow-builder/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';
|
import { WorkflowVersionWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-version.workspace-service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
@ -14,15 +13,10 @@ import { WorkflowVersionWorkspaceService } from 'src/modules/workflow/workflow-b
|
|||||||
WorkflowVersionStepModule,
|
WorkflowVersionStepModule,
|
||||||
WorkflowSchemaModule,
|
WorkflowSchemaModule,
|
||||||
ServerlessFunctionModule,
|
ServerlessFunctionModule,
|
||||||
|
WorkflowVersionStepModule,
|
||||||
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
|
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [WorkflowVersionWorkspaceService],
|
||||||
WorkflowVersionWorkspaceService,
|
exports: [WorkflowVersionWorkspaceService],
|
||||||
WorkflowVersionStepWorkspaceService,
|
|
||||||
],
|
|
||||||
exports: [
|
|
||||||
WorkflowVersionWorkspaceService,
|
|
||||||
WorkflowVersionStepWorkspaceService,
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class WorkflowVersionModule {}
|
export class WorkflowVersionModule {}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import {
|
|||||||
import { assertWorkflowVersionHasSteps } from 'src/modules/workflow/common/utils/assert-workflow-version-has-steps';
|
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 { 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 { 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 { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-step/workflow-version-step.workspace-service';
|
||||||
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|||||||
@ -5,8 +5,10 @@ import { Process } from 'src/engine/core-modules/message-queue/decorators/proces
|
|||||||
import { Processor } from 'src/engine/core-modules/message-queue/decorators/processor.decorator';
|
import { Processor } from 'src/engine/core-modules/message-queue/decorators/processor.decorator';
|
||||||
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
||||||
import { ThrottlerService } from 'src/engine/core-modules/throttler/throttler.service';
|
import { ThrottlerService } from 'src/engine/core-modules/throttler/throttler.service';
|
||||||
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkflowRunStatus } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
|
import { WorkflowRunStatus } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
|
||||||
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
|
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
|
||||||
|
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
import { WorkflowExecutorWorkspaceService } from 'src/modules/workflow/workflow-executor/workspace-services/workflow-executor.workspace-service';
|
import { WorkflowExecutorWorkspaceService } from 'src/modules/workflow/workflow-executor/workspace-services/workflow-executor.workspace-service';
|
||||||
import {
|
import {
|
||||||
WorkflowRunException,
|
WorkflowRunException,
|
||||||
@ -16,9 +18,9 @@ import { WorkflowRunWorkspaceService } from 'src/modules/workflow/workflow-runne
|
|||||||
|
|
||||||
export type RunWorkflowJobData = {
|
export type RunWorkflowJobData = {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
workflowVersionId: string;
|
|
||||||
workflowRunId: string;
|
workflowRunId: string;
|
||||||
payload: object;
|
payload?: object;
|
||||||
|
lastExecutedStepId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@Processor({ queueName: MessageQueue.workflowQueue, scope: Scope.REQUEST })
|
@Processor({ queueName: MessageQueue.workflowQueue, scope: Scope.REQUEST })
|
||||||
@ -29,61 +31,27 @@ export class RunWorkflowJob {
|
|||||||
private readonly workflowRunWorkspaceService: WorkflowRunWorkspaceService,
|
private readonly workflowRunWorkspaceService: WorkflowRunWorkspaceService,
|
||||||
private readonly throttlerService: ThrottlerService,
|
private readonly throttlerService: ThrottlerService,
|
||||||
private readonly environmentService: EnvironmentService,
|
private readonly environmentService: EnvironmentService,
|
||||||
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Process(RunWorkflowJob.name)
|
@Process(RunWorkflowJob.name)
|
||||||
async handle({
|
async handle({
|
||||||
workflowVersionId,
|
|
||||||
workflowRunId,
|
workflowRunId,
|
||||||
payload,
|
payload,
|
||||||
|
lastExecutedStepId,
|
||||||
}: RunWorkflowJobData): Promise<void> {
|
}: RunWorkflowJobData): Promise<void> {
|
||||||
const context = {
|
|
||||||
trigger: payload,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const workflowVersion =
|
if (lastExecutedStepId) {
|
||||||
await this.workflowCommonWorkspaceService.getWorkflowVersionOrFail(
|
await this.resumeWorkflowExecution({
|
||||||
workflowVersionId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!workflowVersion.trigger || !workflowVersion.steps) {
|
|
||||||
throw new WorkflowRunException(
|
|
||||||
'Workflow version has no trigger or steps',
|
|
||||||
WorkflowRunExceptionCode.WORKFLOW_RUN_INVALID,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.workflowRunWorkspaceService.startWorkflowRun({
|
|
||||||
workflowRunId,
|
|
||||||
context,
|
|
||||||
output: {
|
|
||||||
flow: {
|
|
||||||
trigger: workflowVersion.trigger,
|
|
||||||
steps: workflowVersion.steps,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.throttleExecution(workflowVersion.workflowId);
|
|
||||||
|
|
||||||
const { error, pendingEvent } =
|
|
||||||
await this.workflowExecutorWorkspaceService.execute({
|
|
||||||
workflowRunId,
|
workflowRunId,
|
||||||
currentStepIndex: 0,
|
lastExecutedStepId,
|
||||||
steps: workflowVersion.steps,
|
});
|
||||||
context,
|
} else {
|
||||||
|
await this.startWorkflowExecution({
|
||||||
|
workflowRunId,
|
||||||
|
payload: payload ?? {},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (pendingEvent) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.workflowRunWorkspaceService.endWorkflowRun({
|
|
||||||
workflowRunId,
|
|
||||||
status: error ? WorkflowRunStatus.FAILED : WorkflowRunStatus.COMPLETED,
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await this.workflowRunWorkspaceService.endWorkflowRun({
|
await this.workflowRunWorkspaceService.endWorkflowRun({
|
||||||
workflowRunId,
|
workflowRunId,
|
||||||
@ -93,6 +61,123 @@ export class RunWorkflowJob {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async startWorkflowExecution({
|
||||||
|
workflowRunId,
|
||||||
|
payload,
|
||||||
|
}: {
|
||||||
|
workflowRunId: string;
|
||||||
|
payload: object;
|
||||||
|
}): Promise<void> {
|
||||||
|
const context = {
|
||||||
|
trigger: payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
const workflowRun =
|
||||||
|
await this.workflowRunWorkspaceService.getWorkflowRunOrFail(
|
||||||
|
workflowRunId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const workflowVersion =
|
||||||
|
await this.workflowCommonWorkspaceService.getWorkflowVersionOrFail(
|
||||||
|
workflowRun.workflowVersionId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!workflowVersion.trigger || !workflowVersion.steps) {
|
||||||
|
throw new WorkflowRunException(
|
||||||
|
'Workflow version has no trigger or steps',
|
||||||
|
WorkflowRunExceptionCode.WORKFLOW_RUN_INVALID,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.workflowRunWorkspaceService.startWorkflowRun({
|
||||||
|
workflowRunId,
|
||||||
|
context,
|
||||||
|
output: {
|
||||||
|
flow: {
|
||||||
|
trigger: workflowVersion.trigger,
|
||||||
|
steps: workflowVersion.steps,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.throttleExecution(workflowVersion.workflowId);
|
||||||
|
|
||||||
|
await this.executeWorkflow({
|
||||||
|
workflowRunId,
|
||||||
|
currentStepIndex: 0,
|
||||||
|
steps: workflowVersion.steps,
|
||||||
|
context,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async resumeWorkflowExecution({
|
||||||
|
workflowRunId,
|
||||||
|
lastExecutedStepId,
|
||||||
|
}: {
|
||||||
|
workflowRunId: string;
|
||||||
|
lastExecutedStepId: string;
|
||||||
|
}): Promise<void> {
|
||||||
|
const workflowRun =
|
||||||
|
await this.workflowRunWorkspaceService.getWorkflowRunOrFail(
|
||||||
|
workflowRunId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (workflowRun.status !== WorkflowRunStatus.RUNNING) {
|
||||||
|
throw new WorkflowRunException(
|
||||||
|
'Workflow is not running',
|
||||||
|
WorkflowRunExceptionCode.WORKFLOW_RUN_INVALID,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastExecutedStepIndex = workflowRun.output?.flow?.steps?.findIndex(
|
||||||
|
(step) => step.id === lastExecutedStepId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (lastExecutedStepIndex === undefined) {
|
||||||
|
throw new WorkflowRunException(
|
||||||
|
'Last executed step not found',
|
||||||
|
WorkflowRunExceptionCode.INVALID_INPUT,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.executeWorkflow({
|
||||||
|
workflowRunId,
|
||||||
|
currentStepIndex: lastExecutedStepIndex + 1,
|
||||||
|
steps: workflowRun.output?.flow?.steps ?? [],
|
||||||
|
context: workflowRun.context ?? {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async executeWorkflow({
|
||||||
|
workflowRunId,
|
||||||
|
currentStepIndex,
|
||||||
|
steps,
|
||||||
|
context,
|
||||||
|
}: {
|
||||||
|
workflowRunId: string;
|
||||||
|
currentStepIndex: number;
|
||||||
|
steps: WorkflowAction[];
|
||||||
|
context: Record<string, any>;
|
||||||
|
}) {
|
||||||
|
const { error, pendingEvent } =
|
||||||
|
await this.workflowExecutorWorkspaceService.execute({
|
||||||
|
workflowRunId,
|
||||||
|
currentStepIndex,
|
||||||
|
steps,
|
||||||
|
context,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (pendingEvent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.workflowRunWorkspaceService.endWorkflowRun({
|
||||||
|
workflowRunId,
|
||||||
|
status: error ? WorkflowRunStatus.FAILED : WorkflowRunStatus.COMPLETED,
|
||||||
|
error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async throttleExecution(workflowId: string) {
|
private async throttleExecution(workflowId: string) {
|
||||||
try {
|
try {
|
||||||
await this.throttlerService.throttle(
|
await this.throttlerService.throttle(
|
||||||
|
|||||||
@ -163,4 +163,26 @@ export class WorkflowRunWorkspaceService {
|
|||||||
context,
|
context,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getWorkflowRunOrFail(
|
||||||
|
workflowRunId: string,
|
||||||
|
): Promise<WorkflowRunWorkspaceEntity> {
|
||||||
|
const workflowRunRepository =
|
||||||
|
await this.twentyORMManager.getRepository<WorkflowRunWorkspaceEntity>(
|
||||||
|
'workflowRun',
|
||||||
|
);
|
||||||
|
|
||||||
|
const workflowRun = await workflowRunRepository.findOne({
|
||||||
|
where: { id: workflowRunId },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!workflowRun) {
|
||||||
|
throw new WorkflowRunException(
|
||||||
|
'Workflow run not found',
|
||||||
|
WorkflowRunExceptionCode.WORKFLOW_RUN_NOT_FOUND,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return workflowRun;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,6 @@ export class WorkflowRunnerWorkspaceService {
|
|||||||
RunWorkflowJob.name,
|
RunWorkflowJob.name,
|
||||||
{
|
{
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersionId,
|
|
||||||
payload: payload,
|
payload: payload,
|
||||||
workflowRunId,
|
workflowRunId,
|
||||||
},
|
},
|
||||||
@ -53,4 +52,23 @@ export class WorkflowRunnerWorkspaceService {
|
|||||||
|
|
||||||
return { workflowRunId };
|
return { workflowRunId };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async resume({
|
||||||
|
workspaceId,
|
||||||
|
workflowRunId,
|
||||||
|
lastExecutedStepId,
|
||||||
|
}: {
|
||||||
|
workspaceId: string;
|
||||||
|
workflowRunId: string;
|
||||||
|
lastExecutedStepId: string;
|
||||||
|
}) {
|
||||||
|
await this.messageQueueService.add<RunWorkflowJobData>(
|
||||||
|
RunWorkflowJob.name,
|
||||||
|
{
|
||||||
|
workspaceId,
|
||||||
|
workflowRunId,
|
||||||
|
lastExecutedStepId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user