Implement branch front end (#13489)

First PR to support workflow branches on frontend
This commit is contained in:
martmull
2025-08-04 16:11:46 +02:00
committed by GitHub
parent 2c87c6fc1b
commit 9a05673093
124 changed files with 3735 additions and 938 deletions
@@ -0,0 +1,92 @@
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 { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
import { getWorkspaceSchemaName } from 'src/engine/workspace-datasource/utils/get-workspace-schema-name.util';
@Command({
name: 'upgrade:1-3:add-next-step-ids-to-workflow-runs-trigger',
description: 'Add next step ids to workflow runs trigger',
})
export class AddNextStepIdsToWorkflowRunsTrigger extends ActiveOrSuspendedWorkspacesMigrationCommandRunner {
constructor(
@InjectRepository(Workspace, 'core')
protected readonly workspaceRepository: Repository<Workspace>,
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
) {
super(workspaceRepository, twentyORMGlobalManager);
}
override async runOnWorkspace({
workspaceId,
}: RunOnWorkspaceArgs): Promise<void> {
const mainDataSource =
await this.workspaceDataSourceService.connectToMainDataSource();
const schemaName = getWorkspaceSchemaName(workspaceId);
const workflowRuns = await mainDataSource.query(
`SELECT id, state FROM ${schemaName}."workflowRun"`,
);
let updatedWorkflowRunCount = 0;
for (const workflowRun of workflowRuns) {
try {
if (isDefined(workflowRun.state.flow.trigger.nextStepIds)) {
continue;
}
const rootSteps = this.getRootSteps(workflowRun.state.flow.steps || []);
const nextStepIds = rootSteps.map((step) => step.id);
const updatedState = {
...workflowRun.state,
flow: {
...workflowRun.state.flow,
trigger: {
...workflowRun.state.flow.trigger,
nextStepIds,
},
},
};
await mainDataSource.query(
`UPDATE ${schemaName}."workflowRun" SET state = '${JSON.stringify(updatedState)}'::jsonb`,
);
updatedWorkflowRunCount += 1;
} catch (error) {
this.logger.error(
`Error while adding nextStepIds to workflowRun state '${workflowRun.id}'`,
error,
);
}
}
this.logger.log(
`${updatedWorkflowRunCount}/${workflowRuns.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));
}
}
@@ -1,6 +1,7 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AddNextStepIdsToWorkflowRunsTrigger } from 'src/database/commands/upgrade-version-command/1-3/1-3-add-next-step-ids-to-workflow-runs-trigger.command';
import { AssignRolesToExistingApiKeysCommand } from 'src/database/commands/upgrade-version-command/1-3/1-3-assign-roles-to-existing-api-keys.command';
import { ApiKey } from 'src/engine/core-modules/api-key/api-key.entity';
import { ApiKeyModule } from 'src/engine/core-modules/api-key/api-key.module';
@@ -14,6 +15,7 @@ import { RoleModule } from 'src/engine/metadata-modules/role/role.module';
import { WorkspaceFeatureFlagsMapCacheModule } from 'src/engine/metadata-modules/workspace-feature-flags-map-cache/workspace-feature-flags-map-cache.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { TwentyORMModule } from 'src/engine/twenty-orm/twenty-orm.module';
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
@Module({
imports: [
@@ -28,6 +30,7 @@ import { TwentyORMModule } from 'src/engine/twenty-orm/twenty-orm.module';
],
'core',
),
WorkspaceDataSourceModule,
ApiKeyModule,
FeatureFlagModule,
TwentyORMModule,
@@ -35,7 +38,13 @@ import { TwentyORMModule } from 'src/engine/twenty-orm/twenty-orm.module';
WorkspacePermissionsCacheModule,
WorkspaceFeatureFlagsMapCacheModule,
],
providers: [AssignRolesToExistingApiKeysCommand],
exports: [AssignRolesToExistingApiKeysCommand],
providers: [
AssignRolesToExistingApiKeysCommand,
AddNextStepIdsToWorkflowRunsTrigger,
],
exports: [
AssignRolesToExistingApiKeysCommand,
AddNextStepIdsToWorkflowRunsTrigger,
],
})
export class V1_3_UpgradeVersionCommandModule {}
@@ -34,6 +34,7 @@ import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
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 { AddNextStepIdsToWorkflowRunsTrigger } from 'src/database/commands/upgrade-version-command/1-3/1-3-add-next-step-ids-to-workflow-runs-trigger.command';
const execPromise = promisify(exec);
@@ -157,6 +158,8 @@ export class UpgradeCommand extends UpgradeCommandRunner {
// 1.3 Commands
protected readonly assignRolesToExistingApiKeysCommand: AssignRolesToExistingApiKeysCommand,
// protected readonly addNextStepIdsToWorkflowVersionTriggers: AddNextStepIdsToWorkflowVersionTriggers,
protected readonly addNextStepIdsToWorkflowRunsTrigger: AddNextStepIdsToWorkflowRunsTrigger,
) {
super(
workspaceRepository,
@@ -216,7 +219,10 @@ export class UpgradeCommand extends UpgradeCommandRunner {
};
const commands_130: VersionCommands = {
beforeSyncMetadata: [],
beforeSyncMetadata: [
this.addNextStepIdsToWorkflowVersionTriggers, // We add that command again because nextStepIds where not added on freshly created triggers. It will be done in 1.3
this.addNextStepIdsToWorkflowRunsTrigger,
],
afterSyncMetadata: [],
};