Refactor global datasource part 3 (#16447)
## Context Following https://github.com/twentyhq/twenty/pull/16399 Now using the new global orm manager everywhere and returning a GlobalDatasource/WorkspaceDatasource based on a feature flag. This means we now need to wrap all our ORM calls within executeInWorkspaceContext callback (at least for now) so the global datasource can dynamically hydrate its context via the new store (the global datasource does not store anything related to workspaces as it is now a unique singleton). If feature flag is off it still uses local data stored in the workspace datasource.
This commit is contained in:
+33
-27
@@ -1,18 +1,19 @@
|
||||
import { assertIsDefinedOrThrow } from 'twenty-shared/utils';
|
||||
|
||||
import { type WorkspacePostQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
import { type WorkspaceAuthContext } from 'src/engine/api/common/interfaces/workspace-auth-context.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
|
||||
import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
import { RecordPositionService } from 'src/engine/core-modules/record-position/services/record-position.service';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception';
|
||||
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
|
||||
import {
|
||||
WorkflowVersionStatus,
|
||||
type WorkflowVersionWorkspaceEntity,
|
||||
} from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import { type WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||
import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception';
|
||||
|
||||
@WorkspaceQueryHook({
|
||||
key: `workflow.createMany`,
|
||||
@@ -22,7 +23,7 @@ export class WorkflowCreateManyPostQueryHook
|
||||
implements WorkspacePostQueryHookInstance
|
||||
{
|
||||
constructor(
|
||||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager,
|
||||
private readonly recordPositionService: RecordPositionService,
|
||||
) {}
|
||||
|
||||
@@ -35,32 +36,37 @@ export class WorkflowCreateManyPostQueryHook
|
||||
|
||||
assertIsDefinedOrThrow(workspace, WorkspaceNotFoundDefaultError);
|
||||
|
||||
const workflowVersionRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowVersionWorkspaceEntity>(
|
||||
workspace.id,
|
||||
'workflowVersion',
|
||||
);
|
||||
await this.globalWorkspaceOrmManager.executeInWorkspaceContext(
|
||||
authContext as WorkspaceAuthContext,
|
||||
async () => {
|
||||
const workflowVersionRepository =
|
||||
await this.globalWorkspaceOrmManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||
workspace.id,
|
||||
'workflowVersion',
|
||||
);
|
||||
|
||||
const position = await this.recordPositionService.buildRecordPosition({
|
||||
value: 'first',
|
||||
objectMetadata: {
|
||||
isCustom: false,
|
||||
nameSingular: 'workflowVersion',
|
||||
const position = await this.recordPositionService.buildRecordPosition({
|
||||
value: 'first',
|
||||
objectMetadata: {
|
||||
isCustom: false,
|
||||
nameSingular: 'workflowVersion',
|
||||
},
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
const workflowVersionsToCreate = payload.map((workflow) => ({
|
||||
workflowId: workflow.id,
|
||||
status: WorkflowVersionStatus.DRAFT,
|
||||
name: 'v1',
|
||||
position,
|
||||
}));
|
||||
|
||||
await Promise.all(
|
||||
workflowVersionsToCreate.map((workflowVersion) => {
|
||||
return workflowVersionRepository.insert(workflowVersion);
|
||||
}),
|
||||
);
|
||||
},
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
const workflowVersionsToCreate = payload.map((workflow) => ({
|
||||
workflowId: workflow.id,
|
||||
status: WorkflowVersionStatus.DRAFT,
|
||||
name: 'v1',
|
||||
position,
|
||||
}));
|
||||
|
||||
await Promise.all(
|
||||
workflowVersionsToCreate.map((workflowVersion) => {
|
||||
return workflowVersionRepository.insert(workflowVersion);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+28
-22
@@ -1,18 +1,19 @@
|
||||
import { assertIsDefinedOrThrow } from 'twenty-shared/utils';
|
||||
|
||||
import { type WorkspacePostQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
import { type WorkspaceAuthContext } from 'src/engine/api/common/interfaces/workspace-auth-context.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
|
||||
import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
import { RecordPositionService } from 'src/engine/core-modules/record-position/services/record-position.service';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception';
|
||||
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
|
||||
import {
|
||||
WorkflowVersionStatus,
|
||||
type WorkflowVersionWorkspaceEntity,
|
||||
} from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import { type WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||
import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception';
|
||||
|
||||
@WorkspaceQueryHook({
|
||||
key: `workflow.createOne`,
|
||||
@@ -22,7 +23,7 @@ export class WorkflowCreateOnePostQueryHook
|
||||
implements WorkspacePostQueryHookInstance
|
||||
{
|
||||
constructor(
|
||||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager,
|
||||
private readonly recordPositionService: RecordPositionService,
|
||||
) {}
|
||||
|
||||
@@ -37,26 +38,31 @@ export class WorkflowCreateOnePostQueryHook
|
||||
|
||||
const workflow = payload[0];
|
||||
|
||||
const workflowVersionRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowVersionWorkspaceEntity>(
|
||||
workspace.id,
|
||||
'workflowVersion',
|
||||
);
|
||||
await this.globalWorkspaceOrmManager.executeInWorkspaceContext(
|
||||
authContext as WorkspaceAuthContext,
|
||||
async () => {
|
||||
const workflowVersionRepository =
|
||||
await this.globalWorkspaceOrmManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||
workspace.id,
|
||||
'workflowVersion',
|
||||
);
|
||||
|
||||
const position = await this.recordPositionService.buildRecordPosition({
|
||||
value: 'first',
|
||||
objectMetadata: {
|
||||
isCustom: false,
|
||||
nameSingular: 'workflowVersion',
|
||||
const position = await this.recordPositionService.buildRecordPosition({
|
||||
value: 'first',
|
||||
objectMetadata: {
|
||||
isCustom: false,
|
||||
nameSingular: 'workflowVersion',
|
||||
},
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
await workflowVersionRepository.insert({
|
||||
workflowId: workflow.id,
|
||||
status: WorkflowVersionStatus.DRAFT,
|
||||
name: 'v1',
|
||||
position,
|
||||
});
|
||||
},
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
await workflowVersionRepository.insert({
|
||||
workflowId: workflow.id,
|
||||
status: WorkflowVersionStatus.DRAFT,
|
||||
name: 'v1',
|
||||
position,
|
||||
});
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+91
-84
@@ -2,14 +2,15 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { buildObjectIdByNameMaps } from 'src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util';
|
||||
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
|
||||
import { type WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util';
|
||||
import {
|
||||
WorkflowCommonException,
|
||||
WorkflowCommonExceptionCode,
|
||||
@@ -39,7 +40,7 @@ export type ObjectMetadataInfo = {
|
||||
@Injectable()
|
||||
export class WorkflowCommonWorkspaceService {
|
||||
constructor(
|
||||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager,
|
||||
private readonly serverlessFunctionService: ServerlessFunctionService,
|
||||
private readonly workspaceManyOrAllFlatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
) {}
|
||||
@@ -58,20 +59,27 @@ export class WorkflowCommonWorkspaceService {
|
||||
);
|
||||
}
|
||||
|
||||
const workflowVersionRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowVersionWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowVersion',
|
||||
{ shouldBypassPermissionChecks: true }, // settings permissions are checked at resolver-level
|
||||
);
|
||||
const authContext = buildSystemAuthContext(workspaceId);
|
||||
|
||||
const workflowVersion = await workflowVersionRepository.findOne({
|
||||
where: {
|
||||
id: workflowVersionId,
|
||||
return this.globalWorkspaceOrmManager.executeInWorkspaceContext(
|
||||
authContext,
|
||||
async () => {
|
||||
const workflowVersionRepository =
|
||||
await this.globalWorkspaceOrmManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowVersion',
|
||||
{ shouldBypassPermissionChecks: true },
|
||||
);
|
||||
|
||||
const workflowVersion = await workflowVersionRepository.findOne({
|
||||
where: {
|
||||
id: workflowVersionId,
|
||||
},
|
||||
});
|
||||
|
||||
return this.getValidWorkflowVersionOrFail(workflowVersion);
|
||||
},
|
||||
});
|
||||
|
||||
return this.getValidWorkflowVersionOrFail(workflowVersion);
|
||||
);
|
||||
}
|
||||
|
||||
async getValidWorkflowVersionOrFail(
|
||||
@@ -84,14 +92,6 @@ export class WorkflowCommonWorkspaceService {
|
||||
);
|
||||
}
|
||||
|
||||
// FIXME: For now we will make the trigger optional. Later, we'll have to ensure the trigger is defined when publishing the flow.
|
||||
// if (!workflowVersion.trigger) {
|
||||
// throw new WorkflowTriggerException(
|
||||
// 'Workflow version does not contains trigger',
|
||||
// WorkflowTriggerExceptionCode.INVALID_WORKFLOW_VERSION,
|
||||
// );
|
||||
// }
|
||||
|
||||
return { ...workflowVersion, trigger: workflowVersion.trigger };
|
||||
}
|
||||
|
||||
@@ -163,73 +163,80 @@ export class WorkflowCommonWorkspaceService {
|
||||
workspaceId: string;
|
||||
operation: 'restore' | 'delete' | 'destroy';
|
||||
}): Promise<void> {
|
||||
const workflowVersionRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowVersionWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowVersion',
|
||||
{ shouldBypassPermissionChecks: true }, // settings permissions are checked at resolver-level
|
||||
);
|
||||
const authContext = buildSystemAuthContext(workspaceId);
|
||||
|
||||
const workflowRunRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowRunWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowRun',
|
||||
{ shouldBypassPermissionChecks: true }, // settings permissions are checked at resolver-level
|
||||
);
|
||||
await this.globalWorkspaceOrmManager.executeInWorkspaceContext(
|
||||
authContext,
|
||||
async () => {
|
||||
const workflowVersionRepository =
|
||||
await this.globalWorkspaceOrmManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowVersion',
|
||||
{ shouldBypassPermissionChecks: true },
|
||||
);
|
||||
|
||||
const workflowAutomatedTriggerRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowAutomatedTriggerWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowAutomatedTrigger',
|
||||
{ shouldBypassPermissionChecks: true }, // settings permissions are checked at resolver-level
|
||||
);
|
||||
const workflowRunRepository =
|
||||
await this.globalWorkspaceOrmManager.getRepository<WorkflowRunWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowRun',
|
||||
{ shouldBypassPermissionChecks: true },
|
||||
);
|
||||
|
||||
for (const workflowId of workflowIds) {
|
||||
switch (operation) {
|
||||
case 'delete':
|
||||
await workflowAutomatedTriggerRepository.softDelete({
|
||||
const workflowAutomatedTriggerRepository =
|
||||
await this.globalWorkspaceOrmManager.getRepository<WorkflowAutomatedTriggerWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowAutomatedTrigger',
|
||||
{ shouldBypassPermissionChecks: true },
|
||||
);
|
||||
|
||||
for (const workflowId of workflowIds) {
|
||||
switch (operation) {
|
||||
case 'delete':
|
||||
await workflowAutomatedTriggerRepository.softDelete({
|
||||
workflowId,
|
||||
});
|
||||
|
||||
await workflowRunRepository.softDelete({
|
||||
workflowId,
|
||||
});
|
||||
|
||||
await workflowVersionRepository.softDelete({
|
||||
workflowId,
|
||||
});
|
||||
|
||||
break;
|
||||
case 'restore':
|
||||
await workflowAutomatedTriggerRepository.restore({
|
||||
workflowId,
|
||||
});
|
||||
|
||||
await workflowRunRepository.restore({
|
||||
workflowId,
|
||||
});
|
||||
|
||||
await workflowVersionRepository.restore({
|
||||
workflowId,
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
await this.deactivateVersionOnDelete({
|
||||
workflowVersionRepository,
|
||||
workflowId,
|
||||
workspaceId,
|
||||
operation,
|
||||
});
|
||||
|
||||
await workflowRunRepository.softDelete({
|
||||
await this.handleServerlessFunctionSubEntities({
|
||||
workflowVersionRepository,
|
||||
workflowId,
|
||||
workspaceId,
|
||||
operation,
|
||||
});
|
||||
|
||||
await workflowVersionRepository.softDelete({
|
||||
workflowId,
|
||||
});
|
||||
|
||||
break;
|
||||
case 'restore':
|
||||
await workflowAutomatedTriggerRepository.restore({
|
||||
workflowId,
|
||||
});
|
||||
|
||||
await workflowRunRepository.restore({
|
||||
workflowId,
|
||||
});
|
||||
|
||||
await workflowVersionRepository.restore({
|
||||
workflowId,
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
await this.deactivateVersionOnDelete({
|
||||
workflowVersionRepository,
|
||||
workflowId,
|
||||
workspaceId,
|
||||
operation,
|
||||
});
|
||||
|
||||
await this.handleServerlessFunctionSubEntities({
|
||||
workflowVersionRepository,
|
||||
workflowId,
|
||||
workspaceId,
|
||||
operation,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
private async deactivateVersionOnDelete({
|
||||
@@ -248,10 +255,10 @@ export class WorkflowCommonWorkspaceService {
|
||||
}
|
||||
|
||||
const workflowRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowWorkspaceEntity>(
|
||||
await this.globalWorkspaceOrmManager.getRepository<WorkflowWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflow',
|
||||
{ shouldBypassPermissionChecks: true }, // settings permissions are checked at resolver-level
|
||||
{ shouldBypassPermissionChecks: true },
|
||||
);
|
||||
|
||||
const workflow = await workflowRepository.findOne({
|
||||
|
||||
+63
-50
@@ -9,7 +9,8 @@ import {
|
||||
type UpdateOneResolverArgs,
|
||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
|
||||
import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util';
|
||||
import {
|
||||
WorkflowQueryValidationException,
|
||||
WorkflowQueryValidationExceptionCode,
|
||||
@@ -25,7 +26,7 @@ import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/work
|
||||
export class WorkflowVersionValidationWorkspaceService {
|
||||
constructor(
|
||||
private readonly workflowCommonWorkspaceService: WorkflowCommonWorkspaceService,
|
||||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager,
|
||||
) {}
|
||||
|
||||
async validateWorkflowVersionForCreateOne(
|
||||
@@ -45,32 +46,38 @@ export class WorkflowVersionValidationWorkspaceService {
|
||||
);
|
||||
}
|
||||
|
||||
const workflowVersionRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowVersionWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowVersion',
|
||||
{ shouldBypassPermissionChecks: true }, // settings permissions are checked at resolver-level
|
||||
);
|
||||
const authContext = buildSystemAuthContext(workspaceId);
|
||||
|
||||
const workflowAlreadyHasDraftVersion =
|
||||
await workflowVersionRepository.exists({
|
||||
where: {
|
||||
workflowId: payload.data.workflowId,
|
||||
status: WorkflowVersionStatus.DRAFT,
|
||||
// FIXME: soft-deleted rows selection will have to be improved globally
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
});
|
||||
await this.globalWorkspaceOrmManager.executeInWorkspaceContext(
|
||||
authContext,
|
||||
async () => {
|
||||
const workflowVersionRepository =
|
||||
await this.globalWorkspaceOrmManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowVersion',
|
||||
{ shouldBypassPermissionChecks: true },
|
||||
);
|
||||
|
||||
if (workflowAlreadyHasDraftVersion) {
|
||||
throw new WorkflowQueryValidationException(
|
||||
'Cannot create multiple draft versions for the same workflow',
|
||||
WorkflowQueryValidationExceptionCode.FORBIDDEN,
|
||||
{
|
||||
userFriendlyMessage: msg`Cannot create multiple draft versions for the same workflow`,
|
||||
},
|
||||
);
|
||||
}
|
||||
const workflowAlreadyHasDraftVersion =
|
||||
await workflowVersionRepository.exists({
|
||||
where: {
|
||||
workflowId: payload.data.workflowId,
|
||||
status: WorkflowVersionStatus.DRAFT,
|
||||
deletedAt: IsNull(),
|
||||
},
|
||||
});
|
||||
|
||||
if (workflowAlreadyHasDraftVersion) {
|
||||
throw new WorkflowQueryValidationException(
|
||||
'Cannot create multiple draft versions for the same workflow',
|
||||
WorkflowQueryValidationExceptionCode.FORBIDDEN,
|
||||
{
|
||||
userFriendlyMessage: msg`Cannot create multiple draft versions for the same workflow`,
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async validateWorkflowVersionForUpdateOne({
|
||||
@@ -86,8 +93,6 @@ export class WorkflowVersionValidationWorkspaceService {
|
||||
workflowVersionId: payload.id,
|
||||
});
|
||||
|
||||
// If the only field updated is the name, we can update the workflow version
|
||||
// Otherwise, we need to assert that the workflow version is a draft
|
||||
if (!(Object.keys(payload.data).length === 1 && payload.data.name)) {
|
||||
assertWorkflowVersionIsDraft(workflowVersion);
|
||||
}
|
||||
@@ -123,29 +128,37 @@ export class WorkflowVersionValidationWorkspaceService {
|
||||
|
||||
assertWorkflowVersionIsDraft(workflowVersion);
|
||||
|
||||
const workflowVersionRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowVersionWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowVersion',
|
||||
{ shouldBypassPermissionChecks: true }, // settings permissions are checked at resolver-level
|
||||
);
|
||||
const authContext = buildSystemAuthContext(workspaceId);
|
||||
|
||||
const otherWorkflowVersionsExist = await workflowVersionRepository.exists({
|
||||
where: {
|
||||
workflowId: workflowVersion.workflowId,
|
||||
deletedAt: IsNull(),
|
||||
id: Not(workflowVersion.id),
|
||||
await this.globalWorkspaceOrmManager.executeInWorkspaceContext(
|
||||
authContext,
|
||||
async () => {
|
||||
const workflowVersionRepository =
|
||||
await this.globalWorkspaceOrmManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||
workspaceId,
|
||||
'workflowVersion',
|
||||
{ shouldBypassPermissionChecks: true },
|
||||
);
|
||||
|
||||
const otherWorkflowVersionsExist =
|
||||
await workflowVersionRepository.exists({
|
||||
where: {
|
||||
workflowId: workflowVersion.workflowId,
|
||||
deletedAt: IsNull(),
|
||||
id: Not(workflowVersion.id),
|
||||
},
|
||||
});
|
||||
|
||||
if (!otherWorkflowVersionsExist) {
|
||||
throw new WorkflowQueryValidationException(
|
||||
'The initial version of a workflow can not be deleted',
|
||||
WorkflowQueryValidationExceptionCode.FORBIDDEN,
|
||||
{
|
||||
userFriendlyMessage: msg`The initial version of a workflow can not be deleted`,
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (!otherWorkflowVersionsExist) {
|
||||
throw new WorkflowQueryValidationException(
|
||||
'The initial version of a workflow can not be deleted',
|
||||
WorkflowQueryValidationExceptionCode.FORBIDDEN,
|
||||
{
|
||||
userFriendlyMessage: msg`The initial version of a workflow can not be deleted`,
|
||||
},
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user