Add nextStepIds to trigger (#13413)
We will have floating steps in our workflow with the branch design. Currently, a step without parent is considered linked to the trigger. We need to distinguish the 2 cases. Thus this PR: - add `nextStepIds` to workflowVersion.trigger - create a command to migrate existing triggers
This commit is contained in:
@ -0,0 +1,97 @@
|
|||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
|
||||||
|
import { Command } from 'nest-commander';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ActiveOrSuspendedWorkspacesMigrationCommandRunner,
|
||||||
|
RunOnWorkspaceArgs,
|
||||||
|
} from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner';
|
||||||
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||||
|
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||||
|
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
|
|
||||||
|
@Command({
|
||||||
|
name: 'upgrade:1-2:add-next-step-ids-to-workflow-version-triggers',
|
||||||
|
description: 'Add next step ids to workflow version triggers',
|
||||||
|
})
|
||||||
|
export class AddNextStepIdsToWorkflowVersionTriggers extends ActiveOrSuspendedWorkspacesMigrationCommandRunner {
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(Workspace, 'core')
|
||||||
|
protected readonly workspaceRepository: Repository<Workspace>,
|
||||||
|
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||||
|
) {
|
||||||
|
super(workspaceRepository, twentyORMGlobalManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
override async runOnWorkspace({
|
||||||
|
workspaceId,
|
||||||
|
}: RunOnWorkspaceArgs): Promise<void> {
|
||||||
|
const workflowVersionRepository =
|
||||||
|
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowVersionWorkspaceEntity>(
|
||||||
|
workspaceId,
|
||||||
|
'workflowVersion',
|
||||||
|
{ shouldBypassPermissionChecks: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
const workflowVersions = await workflowVersionRepository.find();
|
||||||
|
|
||||||
|
for (const workflowVersion of workflowVersions) {
|
||||||
|
try {
|
||||||
|
const { trigger, steps } = workflowVersion;
|
||||||
|
|
||||||
|
if (!isDefined(trigger)) {
|
||||||
|
this.logger.warn(
|
||||||
|
`Undefined trigger for workflowVersion ${workflowVersion.id}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDefined(steps)) {
|
||||||
|
this.logger.warn(
|
||||||
|
`Undefined steps for workflowVersion ${workflowVersion.id}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootSteps = this.getRootSteps(steps);
|
||||||
|
|
||||||
|
if (rootSteps.length === 0) {
|
||||||
|
this.logger.warn(
|
||||||
|
`No root steps found for workflowVersion ${workflowVersion.id}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await workflowVersionRepository.update(workflowVersion.id, {
|
||||||
|
trigger: {
|
||||||
|
...trigger,
|
||||||
|
nextStepIds: rootSteps.map((step) => step.id),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(
|
||||||
|
`Error while adding nextStepIds to workflowVersion ${workflowVersion.id}`,
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.log(`${workflowVersions.length} triggers updated`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getRootSteps(steps: WorkflowAction[]): WorkflowAction[] {
|
||||||
|
const childIds = new Set<string>();
|
||||||
|
|
||||||
|
for (const step of steps) {
|
||||||
|
step.nextStepIds?.forEach((id) => childIds.add(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
return steps.filter((step) => !childIds.has(step.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,10 +3,17 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
|||||||
|
|
||||||
import { RemoveWorkflowRunsWithoutState } from 'src/database/commands/upgrade-version-command/1-2/1-2-remove-workflow-runs-without-state.command';
|
import { RemoveWorkflowRunsWithoutState } from 'src/database/commands/upgrade-version-command/1-2/1-2-remove-workflow-runs-without-state.command';
|
||||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
import { AddNextStepIdsToWorkflowVersionTriggers } from 'src/database/commands/upgrade-version-command/1-2/1-2-add-next-step-ids-to-workflow-version-triggers.command';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [TypeOrmModule.forFeature([Workspace], 'core')],
|
imports: [TypeOrmModule.forFeature([Workspace], 'core')],
|
||||||
providers: [RemoveWorkflowRunsWithoutState],
|
providers: [
|
||||||
exports: [RemoveWorkflowRunsWithoutState],
|
RemoveWorkflowRunsWithoutState,
|
||||||
|
AddNextStepIdsToWorkflowVersionTriggers,
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
RemoveWorkflowRunsWithoutState,
|
||||||
|
AddNextStepIdsToWorkflowVersionTriggers,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class V1_2_UpgradeVersionCommandModule {}
|
export class V1_2_UpgradeVersionCommandModule {}
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.
|
|||||||
import { SyncWorkspaceMetadataCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command';
|
import { SyncWorkspaceMetadataCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command';
|
||||||
import { compareVersionMajorAndMinor } from 'src/utils/version/compare-version-minor-and-major';
|
import { compareVersionMajorAndMinor } from 'src/utils/version/compare-version-minor-and-major';
|
||||||
import { RemoveWorkflowRunsWithoutState } from 'src/database/commands/upgrade-version-command/1-2/1-2-remove-workflow-runs-without-state.command';
|
import { RemoveWorkflowRunsWithoutState } from 'src/database/commands/upgrade-version-command/1-2/1-2-remove-workflow-runs-without-state.command';
|
||||||
|
import { AddNextStepIdsToWorkflowVersionTriggers } from 'src/database/commands/upgrade-version-command/1-2/1-2-add-next-step-ids-to-workflow-version-triggers.command';
|
||||||
|
|
||||||
const execPromise = promisify(exec);
|
const execPromise = promisify(exec);
|
||||||
|
|
||||||
@ -151,6 +152,7 @@ export class UpgradeCommand extends UpgradeCommandRunner {
|
|||||||
|
|
||||||
// 1.2 Commands
|
// 1.2 Commands
|
||||||
protected readonly removeWorkflowRunsWithoutState: RemoveWorkflowRunsWithoutState,
|
protected readonly removeWorkflowRunsWithoutState: RemoveWorkflowRunsWithoutState,
|
||||||
|
protected readonly addNextStepIdsToWorkflowVersionTriggers: AddNextStepIdsToWorkflowVersionTriggers,
|
||||||
|
|
||||||
// 1.3 Commands
|
// 1.3 Commands
|
||||||
) {
|
) {
|
||||||
@ -204,7 +206,10 @@ export class UpgradeCommand extends UpgradeCommandRunner {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const commands_120: VersionCommands = {
|
const commands_120: VersionCommands = {
|
||||||
beforeSyncMetadata: [this.removeWorkflowRunsWithoutState],
|
beforeSyncMetadata: [
|
||||||
|
this.removeWorkflowRunsWithoutState,
|
||||||
|
this.addNextStepIdsToWorkflowVersionTriggers,
|
||||||
|
],
|
||||||
afterSyncMetadata: [],
|
afterSyncMetadata: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ type BaseTrigger = {
|
|||||||
name: string;
|
name: string;
|
||||||
type: WorkflowTriggerType;
|
type: WorkflowTriggerType;
|
||||||
settings: BaseWorkflowTriggerSettings;
|
settings: BaseWorkflowTriggerSettings;
|
||||||
|
nextStepIds?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WorkflowDatabaseEventTrigger = BaseTrigger & {
|
export type WorkflowDatabaseEventTrigger = BaseTrigger & {
|
||||||
@ -25,11 +26,6 @@ export type WorkflowDatabaseEventTrigger = BaseTrigger & {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum WorkflowManualTriggerAvailability {
|
|
||||||
EVERYWHERE = 'EVERYWHERE',
|
|
||||||
WHEN_RECORD_SELECTED = 'WHEN_RECORD_SELECTED',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type WorkflowManualTrigger = BaseTrigger & {
|
export type WorkflowManualTrigger = BaseTrigger & {
|
||||||
type: WorkflowTriggerType.MANUAL;
|
type: WorkflowTriggerType.MANUAL;
|
||||||
settings: BaseWorkflowTriggerSettings & {
|
settings: BaseWorkflowTriggerSettings & {
|
||||||
@ -77,8 +73,6 @@ export type WorkflowWebhookTrigger = BaseTrigger & {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WorkflowManualTriggerSettings = WorkflowManualTrigger['settings'];
|
|
||||||
|
|
||||||
export type WorkflowTrigger =
|
export type WorkflowTrigger =
|
||||||
| WorkflowDatabaseEventTrigger
|
| WorkflowDatabaseEventTrigger
|
||||||
| WorkflowManualTrigger
|
| WorkflowManualTrigger
|
||||||
|
|||||||
Reference in New Issue
Block a user