Plugging + improving the new orchestrator (#14430)
# Introduction Initially this PR was about introducing integration coverage for view field v2 tests But feature itself wasn't finished, so ended up in a TDD style devlopment ## The new orchestrator Orchestrator will organize each flat entity diffing inferring either validation errors or actions sequentially. A new builder has been introduced when extended requires to define flat entity validation utils and action generation for `delete` `update` `create` operations. It's highly typed using generics ## View field integration testing Introduce coverage on failing basic tests cases for view field operations, successfull create is also covered. We could still add more coverage, will be done later in following PRs ## Remaining tasks for upcoming PRs: - [ ] rename builder methods names to add generate action in their names - [x] refactor view validation to handle field and view uniqueness index combination - [ ] implem strict update validator on view and view field - [ ] dynamic cache invalidation post run - [ ] Add coverage to successful and failing view field operations - [ ] error formatting summary computation - [ ] extract types out of the workspace entity builder ## Some vision Currently flat field metadata maps is nested in the flat object metadata maps, making its build nested too. ( not extending the new generic builder ) We will refactor this part for both to be stored extra flat such as the other existing flat entities. It will require a small refactor to the generic builder that will not only have impact on the currently built flat entity optimistic cache but to an other one ( for example when building a create object action it will also have an impact flat field maps )
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
||||
import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/core-modules/common/constant/empty-flat-entity-maps.constant';
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
|
||||
export const EMPTY_ALL_FLAT_ENTITY_MAPS = {
|
||||
flatObjectMetadataMaps: {
|
||||
byId: {},
|
||||
idByNameSingular: {},
|
||||
},
|
||||
flatViewFieldMaps: EMPTY_FLAT_ENTITY_MAPS,
|
||||
flatViewMaps: EMPTY_FLAT_ENTITY_MAPS,
|
||||
} as const satisfies AllFlatEntityMaps;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type FlatEntity } from 'src/engine/core-modules/common/types/flat-entity.type';
|
||||
|
||||
export const EMPTY_FLAT_ENTITY_MAPS = {
|
||||
byId: {},
|
||||
idByUniversalIdentifier: {},
|
||||
} as const satisfies FlatEntityMaps<FlatEntity>;
|
||||
@@ -0,0 +1,10 @@
|
||||
import { type FlatViewField } from 'src/engine/core-modules/view/flat-view/types/flat-view-field.type';
|
||||
import { type FlatView } from 'src/engine/core-modules/view/flat-view/types/flat-view.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
|
||||
export type AllFlatEntitiesByMetadataEngineName = {
|
||||
// flatFieldMetadata: FlatFieldMetadata;
|
||||
objectMetadata: FlatObjectMetadata;
|
||||
view: FlatView;
|
||||
viewField: FlatViewField;
|
||||
};
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import { type FlatViewFieldMaps } from 'src/engine/core-modules/view/flat-view/types/flat-view-field-maps.type';
|
||||
import { type FlatViewMaps } from 'src/engine/core-modules/view/flat-view/types/flat-view-maps.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
|
||||
export type AllFlatEntityMaps = {
|
||||
flatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
flatViewMaps: FlatViewMaps;
|
||||
flatViewFieldMaps: FlatViewFieldMaps;
|
||||
};
|
||||
|
||||
// export type AllFlatEntityMaps = {
|
||||
// [P in keyof AllFlatEntities as `${P}Maps`]: FlatEntityMaps<AllFlatEntities[P]>;
|
||||
// };
|
||||
+7
-4
@@ -8,15 +8,18 @@ import {
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type FlatEntity } from 'src/engine/core-modules/common/types/flat-entity.type';
|
||||
|
||||
export type FindFlatEntityByIdInFlatEntityMapsOrThrowArgs<
|
||||
T extends FlatEntity,
|
||||
> = {
|
||||
flatEntityMaps: FlatEntityMaps<T>;
|
||||
flatEntityId: string;
|
||||
};
|
||||
export const findFlatEntityByIdInFlatEntityMapsOrThrow = <
|
||||
T extends FlatEntity,
|
||||
>({
|
||||
flatEntityMaps,
|
||||
flatEntityId,
|
||||
}: {
|
||||
flatEntityMaps: FlatEntityMaps<T>;
|
||||
flatEntityId: string;
|
||||
}): T => {
|
||||
}: FindFlatEntityByIdInFlatEntityMapsOrThrowArgs<T>): T => {
|
||||
const flatEntity = flatEntityMaps.byId[flatEntityId];
|
||||
|
||||
if (!isDefined(flatEntity)) {
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import { type FlatEntity } from 'src/engine/core-modules/common/types/flat-entity.type';
|
||||
import {
|
||||
findFlatEntityByIdInFlatEntityMapsOrThrow,
|
||||
type FindFlatEntityByIdInFlatEntityMapsOrThrowArgs,
|
||||
} from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
|
||||
export const findFlatEntityByIdInFlatEntityMaps = <T extends FlatEntity>(
|
||||
args: FindFlatEntityByIdInFlatEntityMapsOrThrowArgs<T>,
|
||||
): T | undefined => {
|
||||
try {
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow(args);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/core-modules/common/constant/empty-flat-entity-maps.constant';
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type FlatEntity } from 'src/engine/core-modules/common/types/flat-entity.type';
|
||||
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
|
||||
export const getSubFlatEntityMapsOrThrow = <T extends FlatEntity>({
|
||||
flatEntityIds,
|
||||
flatEntityMaps,
|
||||
}: {
|
||||
flatEntityMaps: FlatEntityMaps<T>;
|
||||
flatEntityIds: string[];
|
||||
}): FlatEntityMaps<T> => {
|
||||
return flatEntityIds.reduce<FlatEntityMaps<T>>((acc, flatEntityId) => {
|
||||
const flatEntity = findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId,
|
||||
flatEntityMaps,
|
||||
});
|
||||
|
||||
return addFlatEntityToFlatEntityMapsOrThrow({
|
||||
flatEntity,
|
||||
flatEntityMaps: acc,
|
||||
});
|
||||
}, EMPTY_FLAT_ENTITY_MAPS);
|
||||
};
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/core-modules/common/constant/empty-flat-entity-maps.constant';
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type FlatEntity } from 'src/engine/core-modules/common/types/flat-entity.type';
|
||||
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
|
||||
export const getSubFlatEntityMaps = <T extends FlatEntity>({
|
||||
flatEntityIds,
|
||||
flatEntityMaps,
|
||||
}: {
|
||||
flatEntityMaps: FlatEntityMaps<T>;
|
||||
flatEntityIds: string[];
|
||||
}): FlatEntityMaps<T> => {
|
||||
return flatEntityIds.reduce<FlatEntityMaps<T>>((acc, flatEntityId) => {
|
||||
const flatEntity = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId,
|
||||
flatEntityMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(flatEntity)) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
return addFlatEntityToFlatEntityMapsOrThrow({
|
||||
flatEntity,
|
||||
flatEntityMaps: acc,
|
||||
});
|
||||
}, EMPTY_FLAT_ENTITY_MAPS);
|
||||
};
|
||||
+2
-1
@@ -2,10 +2,11 @@ import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { ViewCacheService } from 'src/engine/core-modules/view/cache/services/view-cache.service';
|
||||
import { ViewFieldEntity } from 'src/engine/core-modules/view/entities/view-field.entity';
|
||||
import { ViewEntity } from 'src/engine/core-modules/view/entities/view.entity';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([ViewEntity])],
|
||||
imports: [TypeOrmModule.forFeature([ViewEntity, ViewFieldEntity])],
|
||||
providers: [ViewCacheService],
|
||||
exports: [ViewCacheService],
|
||||
})
|
||||
|
||||
+36
@@ -3,8 +3,11 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { ViewFieldEntity } from 'src/engine/core-modules/view/entities/view-field.entity';
|
||||
import { ViewEntity } from 'src/engine/core-modules/view/entities/view.entity';
|
||||
import { FlatViewFieldMaps } from 'src/engine/core-modules/view/flat-view/types/flat-view-field-maps.type';
|
||||
import { FlatViewMaps } from 'src/engine/core-modules/view/flat-view/types/flat-view-maps.type';
|
||||
import { fromViewFieldEntityToFlatViewField } from 'src/engine/core-modules/view/flat-view/utils/from-view-field-entity-to-flat-view-field.util';
|
||||
import { generateFlatViewMaps } from 'src/engine/core-modules/view/flat-view/utils/generate-flat-view-maps.util';
|
||||
|
||||
type GetExistingOrRecomputeFlatViewMapsResult = {
|
||||
@@ -18,6 +21,8 @@ export class ViewCacheService {
|
||||
constructor(
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
@InjectRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: Repository<ViewFieldEntity>,
|
||||
) {}
|
||||
|
||||
async getExistingOrRecomputeFlatViewMaps({
|
||||
@@ -30,6 +35,7 @@ export class ViewCacheService {
|
||||
where: {
|
||||
workspaceId,
|
||||
},
|
||||
withDeleted: true,
|
||||
relations: ['viewFields'],
|
||||
select: {
|
||||
viewFields: {
|
||||
@@ -44,4 +50,34 @@ export class ViewCacheService {
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
};
|
||||
}
|
||||
|
||||
public async getExistingFlatViewFieldMapsFromCache({
|
||||
workspaceId,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
}): Promise<{ flatViewFieldMaps: FlatViewFieldMaps }> {
|
||||
// TODO: get from cache later
|
||||
const existingViewFields = await this.viewFieldRepository.find({
|
||||
where: {
|
||||
workspaceId,
|
||||
},
|
||||
withDeleted: true,
|
||||
});
|
||||
|
||||
const flatViewFieldMaps: FlatViewFieldMaps = {
|
||||
byId: {},
|
||||
idByUniversalIdentifier: {},
|
||||
};
|
||||
|
||||
for (const viewFieldEntity of existingViewFields) {
|
||||
const flatViewField = fromViewFieldEntityToFlatViewField(viewFieldEntity);
|
||||
|
||||
flatViewFieldMaps.byId[flatViewField.id] = flatViewField;
|
||||
flatViewFieldMaps.idByUniversalIdentifier[
|
||||
flatViewField.universalIdentifier
|
||||
] = flatViewField.id;
|
||||
}
|
||||
|
||||
return { flatViewFieldMaps };
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import { type FlatViewField } from 'src/engine/core-modules/view/flat-view/types/flat-view-field.type';
|
||||
|
||||
export const FLAT_VIEW_EDITABLE_PROPERTIES = [
|
||||
'isVisible',
|
||||
'size',
|
||||
'position',
|
||||
'aggregateOperation',
|
||||
] as const satisfies (keyof FlatViewField)[];
|
||||
+3
-4
@@ -1,8 +1,7 @@
|
||||
import { FLAT_VIEW_EDITABLE_PROPERTIES } from 'src/engine/core-modules/view/flat-view/constants/flat-view-editable-properties.constant';
|
||||
import { type FlatViewField } from 'src/engine/core-modules/view/flat-view/types/flat-view-field.type';
|
||||
|
||||
export const FLAT_VIEW_FIELD_PROPERTIES_TO_COMPARE = [
|
||||
'isVisible',
|
||||
'size',
|
||||
'position',
|
||||
'aggregateOperation',
|
||||
...FLAT_VIEW_EDITABLE_PROPERTIES,
|
||||
'deletedAt',
|
||||
] as const satisfies (keyof FlatViewField)[];
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import { type FlatViewField } from 'src/engine/core-modules/view/flat-view/types/flat-view-field.type';
|
||||
|
||||
export type FailedFlatViewFieldValidationMinimalInformation = Partial<
|
||||
Pick<FlatViewField, 'id' | 'fieldMetadataId' | 'viewId'>
|
||||
>;
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
import { type FailedFlatViewFieldValidationMinimalInformation } from 'src/engine/core-modules/view/flat-view/types/failed-flat-view-field-validation-minimal-information.type';
|
||||
import { type FlatViewFieldValidationError } from 'src/engine/core-modules/view/flat-view/types/flat-view-field-validation-error.type';
|
||||
import { type WorkspaceMigrationViewFieldActionTypeV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-field-action-v2.type';
|
||||
|
||||
export type FailedFlatViewFieldValidation = {
|
||||
type: WorkspaceMigrationViewFieldActionTypeV2;
|
||||
viewFieldLevelErrors: FlatViewFieldValidationError[];
|
||||
failedViewFieldValidationMinimalInformation: Partial<FailedFlatViewFieldValidationMinimalInformation>;
|
||||
};
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import { type FlatView } from 'src/engine/core-modules/view/flat-view/types/flat-view.type';
|
||||
|
||||
export type FailedFlatViewValidationMinimalInformation = Partial<
|
||||
Pick<FlatView, 'id' | 'name' | 'objectMetadataId'>
|
||||
>;
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
import { type FailedFlatViewValidationMinimalInformation } from 'src/engine/core-modules/view/flat-view/types/failed-flat-view-validation-minimal-information.type';
|
||||
import { type FlatViewValidationError } from 'src/engine/core-modules/view/flat-view/types/flat-view-validation-error.type';
|
||||
import { type WorkspaceMigrationViewActionTypeV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-action-v2.type';
|
||||
|
||||
export type FailedFlatViewValidation = {
|
||||
type: WorkspaceMigrationViewActionTypeV2;
|
||||
viewLevelErrors: FlatViewValidationError[];
|
||||
failedViewValidationMinimalInformation: Partial<FailedFlatViewValidationMinimalInformation>;
|
||||
};
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
export type FlatViewFieldValidationError = {
|
||||
message: string;
|
||||
code: string;
|
||||
};
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
import { type ViewExceptionCode } from 'src/engine/core-modules/view/exceptions/view.exception';
|
||||
|
||||
export type FlatViewValidationError = {
|
||||
code: ViewExceptionCode;
|
||||
message: string;
|
||||
userFriendlyMessage?: string;
|
||||
value?: unknown;
|
||||
};
|
||||
+3
-3
@@ -10,7 +10,7 @@ import {
|
||||
ViewFieldException,
|
||||
ViewFieldExceptionCode,
|
||||
} from 'src/engine/core-modules/view/exceptions/view-field.exception';
|
||||
import { FLAT_VIEW_FIELD_PROPERTIES_TO_COMPARE } from 'src/engine/core-modules/view/flat-view/constants/flat-view-field-properties-to-compare.constant';
|
||||
import { FLAT_VIEW_EDITABLE_PROPERTIES } from 'src/engine/core-modules/view/flat-view/constants/flat-view-editable-properties.constant';
|
||||
import { type FlatViewFieldMaps } from 'src/engine/core-modules/view/flat-view/types/flat-view-field-maps.type';
|
||||
import { type FlatViewField } from 'src/engine/core-modules/view/flat-view/types/flat-view-field.type';
|
||||
import { mergeUpdateInExistingRecord } from 'src/utils/merge-update-in-existing-record.util';
|
||||
@@ -39,12 +39,12 @@ export const fromUpdateViewFieldInputToFlatViewFieldToUpdateOrThrow = ({
|
||||
}
|
||||
const updatedEditableFieldProperties = extractAndSanitizeObjectStringFields(
|
||||
rawUpdateViewFieldInput.update,
|
||||
FLAT_VIEW_FIELD_PROPERTIES_TO_COMPARE,
|
||||
FLAT_VIEW_EDITABLE_PROPERTIES,
|
||||
);
|
||||
|
||||
return mergeUpdateInExistingRecord({
|
||||
existing: existingFlatViewFieldToUpdate,
|
||||
properties: FLAT_VIEW_FIELD_PROPERTIES_TO_COMPARE,
|
||||
properties: FLAT_VIEW_EDITABLE_PROPERTIES,
|
||||
update: updatedEditableFieldProperties,
|
||||
});
|
||||
};
|
||||
|
||||
+96
-76
@@ -1,61 +1,34 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
|
||||
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { getSubFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/get-sub-flat-entity-maps-or-throw.util';
|
||||
import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
|
||||
import { ViewCacheService } from 'src/engine/core-modules/view/cache/services/view-cache.service';
|
||||
import { CreateViewFieldInput } from 'src/engine/core-modules/view/dtos/inputs/create-view-field.input';
|
||||
import { DeleteViewFieldInput } from 'src/engine/core-modules/view/dtos/inputs/delete-view-field.input';
|
||||
import { DestroyViewFieldInput } from 'src/engine/core-modules/view/dtos/inputs/destroy-view-field.input';
|
||||
import { UpdateViewFieldInput } from 'src/engine/core-modules/view/dtos/inputs/update-view-field.input';
|
||||
import { ViewFieldDTO } from 'src/engine/core-modules/view/dtos/view-field.dto';
|
||||
import { ViewFieldEntity } from 'src/engine/core-modules/view/entities/view-field.entity';
|
||||
import { FlatViewFieldMaps } from 'src/engine/core-modules/view/flat-view/types/flat-view-field-maps.type';
|
||||
import { fromCreateViewFieldInputToFlatViewFieldToCreate } from 'src/engine/core-modules/view/flat-view/utils/from-create-view-field-input-to-flat-view-field-to-create.util';
|
||||
import { fromDeleteViewFieldInputToFlatViewFieldOrThrow } from 'src/engine/core-modules/view/flat-view/utils/from-delete-view-field-input-to-flat-view-field-or-throw.util';
|
||||
import { fromDestroyViewFieldInputToFlatViewFieldOrThrow } from 'src/engine/core-modules/view/flat-view/utils/from-destroy-view-field-input-to-flat-view-field-or-throw.util';
|
||||
import { fromUpdateViewFieldInputToFlatViewFieldToUpdateOrThrow } from 'src/engine/core-modules/view/flat-view/utils/from-update-view-field-input-to-flat-view-field-to-update-or-throw.util';
|
||||
import { fromViewFieldEntityToFlatViewField } from 'src/engine/core-modules/view/flat-view/utils/from-view-field-entity-to-flat-view-field.util';
|
||||
import { WorkspaceMigrationOrchestratorException } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-orchestrator-exception';
|
||||
import { WorkspaceMigrationBuildOrchestratorService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service';
|
||||
import { WorkspaceMetadataCacheService } from 'src/engine/metadata-modules/workspace-metadata-cache/services/workspace-metadata-cache.service';
|
||||
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewFieldV2Service {
|
||||
constructor(
|
||||
@InjectRepository(ViewFieldEntity)
|
||||
private readonly viewFieldRepository: Repository<ViewFieldEntity>,
|
||||
private readonly workspaceMigrationOrchestratorService: WorkspaceMigrationBuildOrchestratorService,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly viewCacheService: ViewCacheService,
|
||||
private readonly workspaceMetadataCacheService: WorkspaceMetadataCacheService,
|
||||
) {}
|
||||
|
||||
// TODO: move to cache service
|
||||
private async getExistingFlatViewFieldMapsFromCache(
|
||||
workspaceId: string,
|
||||
): Promise<FlatViewFieldMaps> {
|
||||
const existingViewFields = await this.viewFieldRepository.find({
|
||||
where: { workspaceId },
|
||||
});
|
||||
|
||||
const flatViewFieldMaps: FlatViewFieldMaps = {
|
||||
byId: {},
|
||||
idByUniversalIdentifier: {},
|
||||
};
|
||||
|
||||
for (const viewFieldEntity of existingViewFields) {
|
||||
const flatViewField = fromViewFieldEntityToFlatViewField(viewFieldEntity);
|
||||
|
||||
flatViewFieldMaps.byId[flatViewField.id] = flatViewField;
|
||||
flatViewFieldMaps.idByUniversalIdentifier[
|
||||
flatViewField.universalIdentifier
|
||||
] = flatViewField.id;
|
||||
}
|
||||
|
||||
return flatViewFieldMaps;
|
||||
}
|
||||
|
||||
async createOne({
|
||||
createViewFieldInput,
|
||||
workspaceId,
|
||||
@@ -63,8 +36,20 @@ export class ViewFieldV2Service {
|
||||
createViewFieldInput: CreateViewFieldInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewFieldDTO> {
|
||||
const existingFlatViewFieldMaps =
|
||||
await this.getExistingFlatViewFieldMapsFromCache(workspaceId);
|
||||
const { flatObjectMetadataMaps: existingFlatObjectMetadataMaps } =
|
||||
await this.workspaceMetadataCacheService.getExistingOrRecomputeFlatObjectMetadataMaps(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
const { flatViewFieldMaps: existingFlatViewFieldMaps } =
|
||||
await this.viewCacheService.getExistingFlatViewFieldMapsFromCache({
|
||||
workspaceId,
|
||||
});
|
||||
const { flatViewMaps: existingFlatViewMaps } =
|
||||
await this.viewCacheService.getExistingOrRecomputeFlatViewMaps({
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const flatViewFieldToCreate =
|
||||
fromCreateViewFieldInputToFlatViewFieldToCreate({
|
||||
@@ -78,14 +63,18 @@ export class ViewFieldV2Service {
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationOrchestratorService.buildWorkspaceMigrations(
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
entityMaps: {
|
||||
viewField: {
|
||||
fromFlatViewFieldMaps: existingFlatViewFieldMaps,
|
||||
toFlatViewFieldMaps,
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewFieldMaps: {
|
||||
from: existingFlatViewFieldMaps,
|
||||
to: toFlatViewFieldMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: false,
|
||||
@@ -95,13 +84,16 @@ export class ViewFieldV2Service {
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationOrchestratorException(
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while creating view field',
|
||||
);
|
||||
}
|
||||
|
||||
const recomputedExistingFlatViewFieldMaps =
|
||||
await this.getExistingFlatViewFieldMapsFromCache(workspaceId);
|
||||
const { flatViewFieldMaps: recomputedExistingFlatViewFieldMaps } =
|
||||
await this.viewCacheService.getExistingFlatViewFieldMapsFromCache({
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: flatViewFieldToCreate.id,
|
||||
@@ -116,8 +108,10 @@ export class ViewFieldV2Service {
|
||||
workspaceId: string;
|
||||
updateViewFieldInput: UpdateViewFieldInput;
|
||||
}): Promise<ViewFieldDTO> {
|
||||
const existingFlatViewFieldMaps =
|
||||
await this.getExistingFlatViewFieldMapsFromCache(workspaceId);
|
||||
const { flatViewFieldMaps: existingFlatViewFieldMaps } =
|
||||
await this.viewCacheService.getExistingFlatViewFieldMapsFromCache({
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const optimisticallyUpdatedFlatView =
|
||||
fromUpdateViewFieldInputToFlatViewFieldToUpdateOrThrow({
|
||||
@@ -125,18 +119,22 @@ export class ViewFieldV2Service {
|
||||
updateViewFieldInput,
|
||||
});
|
||||
|
||||
const fromFlatViewFieldMaps = getSubFlatEntityMapsOrThrow({
|
||||
flatEntityIds: [optimisticallyUpdatedFlatView.id],
|
||||
flatEntityMaps: existingFlatViewFieldMaps,
|
||||
});
|
||||
const toFlatViewFieldMaps = replaceFlatEntityInFlatEntityMapsOrThrow({
|
||||
flatEntity: optimisticallyUpdatedFlatView,
|
||||
flatEntityMaps: existingFlatViewFieldMaps,
|
||||
flatEntityMaps: fromFlatViewFieldMaps,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationOrchestratorService.buildWorkspaceMigrations(
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
entityMaps: {
|
||||
viewField: {
|
||||
fromFlatViewFieldMaps: existingFlatViewFieldMaps,
|
||||
toFlatViewFieldMaps,
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewFieldMaps: {
|
||||
from: fromFlatViewFieldMaps,
|
||||
to: toFlatViewFieldMaps,
|
||||
},
|
||||
},
|
||||
buildOptions: {
|
||||
@@ -148,13 +146,16 @@ export class ViewFieldV2Service {
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationOrchestratorException(
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while updating view field',
|
||||
);
|
||||
}
|
||||
|
||||
const recomputedExistingFlatViewFieldMaps =
|
||||
await this.getExistingFlatViewFieldMapsFromCache(workspaceId);
|
||||
const { flatViewFieldMaps: recomputedExistingFlatViewFieldMaps } =
|
||||
await this.viewCacheService.getExistingFlatViewFieldMapsFromCache({
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: optimisticallyUpdatedFlatView.id,
|
||||
@@ -169,8 +170,10 @@ export class ViewFieldV2Service {
|
||||
deleteViewFieldInput: DeleteViewFieldInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewFieldDTO> {
|
||||
const existingFlatViewFieldMaps =
|
||||
await this.getExistingFlatViewFieldMapsFromCache(workspaceId);
|
||||
const { flatViewFieldMaps: existingFlatViewFieldMaps } =
|
||||
await this.viewCacheService.getExistingFlatViewFieldMapsFromCache({
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const optimisticallyUpdatedFlatViewWithDeletedAt =
|
||||
fromDeleteViewFieldInputToFlatViewFieldOrThrow({
|
||||
@@ -184,12 +187,12 @@ export class ViewFieldV2Service {
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationOrchestratorService.buildWorkspaceMigrations(
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
entityMaps: {
|
||||
viewField: {
|
||||
fromFlatViewFieldMaps: existingFlatViewFieldMaps,
|
||||
toFlatViewFieldMaps,
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewFieldMaps: {
|
||||
from: existingFlatViewFieldMaps,
|
||||
to: toFlatViewFieldMaps,
|
||||
},
|
||||
},
|
||||
buildOptions: {
|
||||
@@ -201,13 +204,16 @@ export class ViewFieldV2Service {
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationOrchestratorException(
|
||||
'Multiple validation errors occurred while updating view field',
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while deleting view field',
|
||||
);
|
||||
}
|
||||
|
||||
const recomputedExistingFlatViewFieldMaps =
|
||||
await this.getExistingFlatViewFieldMapsFromCache(workspaceId);
|
||||
const { flatViewFieldMaps: recomputedExistingFlatViewFieldMaps } =
|
||||
await this.viewCacheService.getExistingFlatViewFieldMapsFromCache({
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: optimisticallyUpdatedFlatViewWithDeletedAt.id,
|
||||
@@ -222,8 +228,14 @@ export class ViewFieldV2Service {
|
||||
destroyViewFieldInput: DestroyViewFieldInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewFieldDTO> {
|
||||
const existingFlatViewFieldMaps =
|
||||
await this.getExistingFlatViewFieldMapsFromCache(workspaceId);
|
||||
const { flatViewFieldMaps: existingFlatViewFieldMaps } =
|
||||
await this.viewCacheService.getExistingFlatViewFieldMapsFromCache({
|
||||
workspaceId,
|
||||
});
|
||||
const { flatViewMaps: existingFlatViewMaps } =
|
||||
await this.viewCacheService.getExistingOrRecomputeFlatViewMaps({
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const existingViewFieldToDelete =
|
||||
fromDestroyViewFieldInputToFlatViewFieldOrThrow({
|
||||
@@ -231,20 +243,27 @@ export class ViewFieldV2Service {
|
||||
flatViewFieldMaps: existingFlatViewFieldMaps,
|
||||
});
|
||||
|
||||
const toFlatViewFieldMaps = deleteFlatEntityFromFlatEntityMapsOrThrow({
|
||||
const fromFlatViewFieldMaps = getSubFlatEntityMapsOrThrow({
|
||||
flatEntityIds: [existingViewFieldToDelete.id],
|
||||
flatEntityMaps: existingFlatViewFieldMaps,
|
||||
});
|
||||
const toFlatViewFieldMaps = deleteFlatEntityFromFlatEntityMapsOrThrow({
|
||||
flatEntityMaps: fromFlatViewFieldMaps,
|
||||
entityToDeleteId: existingViewFieldToDelete.id,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationOrchestratorService.buildWorkspaceMigrations(
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
entityMaps: {
|
||||
viewField: {
|
||||
fromFlatViewFieldMaps: existingFlatViewFieldMaps,
|
||||
toFlatViewFieldMaps,
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewFieldMaps: {
|
||||
from: fromFlatViewFieldMaps,
|
||||
to: toFlatViewFieldMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: true,
|
||||
@@ -254,7 +273,8 @@ export class ViewFieldV2Service {
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationOrchestratorException(
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while deleting view field',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { v4 } from 'uuid';
|
||||
|
||||
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
|
||||
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
|
||||
import { getSubFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/get-sub-flat-entity-maps-or-throw.util';
|
||||
import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
|
||||
import { ViewCacheService } from 'src/engine/core-modules/view/cache/services/view-cache.service';
|
||||
import { ViewEntity } from 'src/engine/core-modules/view/entities/view.entity';
|
||||
@@ -20,20 +21,24 @@ import {
|
||||
import { VIEW_ENTITY_RELATION_PROPERTIES } from 'src/engine/core-modules/view/flat-view/constants/view-entity-relation-properties.constant';
|
||||
import { FlatViewMaps } from 'src/engine/core-modules/view/flat-view/types/flat-view-maps.type';
|
||||
import { fromPartialFlatViewToFlatViewWithDefault } from 'src/engine/core-modules/view/flat-view/utils/from-partial-flat-view-to-flat-view-to-with-default.util';
|
||||
import { WorkspaceMigrationOrchestratorException } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-orchestrator-exception';
|
||||
import { WorkspaceMigrationBuildOrchestratorService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service';
|
||||
import { WorkspaceMetadataCacheService } from 'src/engine/metadata-modules/workspace-metadata-cache/services/workspace-metadata-cache.service';
|
||||
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewV2Service {
|
||||
constructor(
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
private readonly workspaceMigrationOrchestratorService: WorkspaceMigrationBuildOrchestratorService,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly viewCacheService: ViewCacheService,
|
||||
private readonly workspaceMetadataCacheService: WorkspaceMetadataCacheService,
|
||||
) {}
|
||||
|
||||
async createOne(viewData: Partial<ViewEntity>): Promise<ViewEntity> {
|
||||
if (!isDefined(viewData.workspaceId)) {
|
||||
const { workspaceId } = viewData;
|
||||
|
||||
if (!isDefined(workspaceId)) {
|
||||
throw new ViewException(
|
||||
generateViewExceptionMessage(
|
||||
ViewExceptionMessageKey.WORKSPACE_ID_REQUIRED,
|
||||
@@ -47,9 +52,16 @@ export class ViewV2Service {
|
||||
);
|
||||
}
|
||||
|
||||
const { flatObjectMetadataMaps: existingFlatObjectMetadataMaps } =
|
||||
await this.workspaceMetadataCacheService.getExistingOrRecomputeFlatObjectMetadataMaps(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
const { flatViewMaps: existingFlatViewMaps } =
|
||||
await this.viewCacheService.getExistingOrRecomputeFlatViewMaps({
|
||||
workspaceId: viewData.workspaceId,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const flatViewFromCreateInput = fromPartialFlatViewToFlatViewWithDefault({
|
||||
@@ -63,24 +75,28 @@ export class ViewV2Service {
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationOrchestratorService.buildWorkspaceMigrations(
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
entityMaps: {
|
||||
view: {
|
||||
fromFlatViewMaps: existingFlatViewMaps,
|
||||
toFlatViewMaps,
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewMaps: {
|
||||
from: existingFlatViewMaps,
|
||||
to: toFlatViewMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: false,
|
||||
},
|
||||
workspaceId: viewData.workspaceId,
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationOrchestratorException(
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while creating view',
|
||||
);
|
||||
}
|
||||
@@ -129,19 +145,22 @@ export class ViewV2Service {
|
||||
universalIdentifier: existingViewToUpdate.universalIdentifier ?? '',
|
||||
});
|
||||
|
||||
const toFlatViewMaps: FlatViewMaps =
|
||||
replaceFlatEntityInFlatEntityMapsOrThrow({
|
||||
flatEntity: flatViewFromUpdateInput,
|
||||
flatEntityMaps: existingFlatViewMaps,
|
||||
});
|
||||
const fromFlatViewMaps = getSubFlatEntityMapsOrThrow({
|
||||
flatEntityIds: [flatViewFromUpdateInput.id],
|
||||
flatEntityMaps: existingFlatViewMaps,
|
||||
});
|
||||
const toFlatViewMaps = replaceFlatEntityInFlatEntityMapsOrThrow({
|
||||
flatEntity: flatViewFromUpdateInput,
|
||||
flatEntityMaps: fromFlatViewMaps,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationOrchestratorService.buildWorkspaceMigrations(
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
entityMaps: {
|
||||
view: {
|
||||
fromFlatViewMaps: existingFlatViewMaps,
|
||||
toFlatViewMaps,
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewMaps: {
|
||||
from: fromFlatViewMaps,
|
||||
to: toFlatViewMaps,
|
||||
},
|
||||
},
|
||||
buildOptions: {
|
||||
@@ -153,7 +172,8 @@ export class ViewV2Service {
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationOrchestratorException(
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while updating view',
|
||||
);
|
||||
}
|
||||
@@ -185,19 +205,23 @@ export class ViewV2Service {
|
||||
);
|
||||
}
|
||||
|
||||
const fromFlatViewMaps = getSubFlatEntityMapsOrThrow({
|
||||
flatEntityIds: [existingViewToDelete.id],
|
||||
flatEntityMaps: existingFlatViewMaps,
|
||||
});
|
||||
const toFlatViewMaps: FlatViewMaps =
|
||||
deleteFlatEntityFromFlatEntityMapsOrThrow({
|
||||
flatEntityMaps: existingFlatViewMaps,
|
||||
flatEntityMaps: fromFlatViewMaps,
|
||||
entityToDeleteId: existingViewToDelete.id,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationOrchestratorService.buildWorkspaceMigrations(
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
entityMaps: {
|
||||
view: {
|
||||
fromFlatViewMaps: existingFlatViewMaps,
|
||||
toFlatViewMaps,
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatViewMaps: {
|
||||
from: fromFlatViewMaps,
|
||||
to: toFlatViewMaps,
|
||||
},
|
||||
},
|
||||
buildOptions: {
|
||||
@@ -209,7 +233,8 @@ export class ViewV2Service {
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationOrchestratorException(
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while deleting view',
|
||||
);
|
||||
}
|
||||
|
||||
+6
@@ -28,8 +28,14 @@ import {
|
||||
ViewException,
|
||||
ViewExceptionCode,
|
||||
} from 'src/engine/core-modules/view/exceptions/view.exception';
|
||||
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
import { workspaceMigrationBuilderExceptionV2Formatter } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/workspace-migration-builder-exception-v2-formatter';
|
||||
|
||||
export const viewGraphqlApiExceptionHandler = (error: Error) => {
|
||||
if (error instanceof WorkspaceMigrationBuilderExceptionV2) {
|
||||
return workspaceMigrationBuilderExceptionV2Formatter(error);
|
||||
}
|
||||
|
||||
if (error instanceof ViewException) {
|
||||
switch (error.code) {
|
||||
case ViewExceptionCode.VIEW_NOT_FOUND:
|
||||
|
||||
+4
-1
@@ -7,6 +7,7 @@ import { ViewGroupException } from 'src/engine/core-modules/view/exceptions/view
|
||||
import { ViewSortException } from 'src/engine/core-modules/view/exceptions/view-sort.exception';
|
||||
import { ViewException } from 'src/engine/core-modules/view/exceptions/view.exception';
|
||||
import { viewGraphqlApiExceptionHandler } from 'src/engine/core-modules/view/utils/view-graphql-api-exception-handler.util';
|
||||
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
|
||||
@Catch(
|
||||
ViewException,
|
||||
@@ -15,6 +16,7 @@ import { viewGraphqlApiExceptionHandler } from 'src/engine/core-modules/view/uti
|
||||
ViewFilterGroupException,
|
||||
ViewGroupException,
|
||||
ViewSortException,
|
||||
WorkspaceMigrationBuilderExceptionV2,
|
||||
)
|
||||
export class ViewGraphqlApiExceptionFilter implements ExceptionFilter {
|
||||
catch(
|
||||
@@ -24,7 +26,8 @@ export class ViewGraphqlApiExceptionFilter implements ExceptionFilter {
|
||||
| ViewFilterException
|
||||
| ViewFilterGroupException
|
||||
| ViewGroupException
|
||||
| ViewSortException,
|
||||
| ViewSortException
|
||||
| WorkspaceMigrationBuilderExceptionV2,
|
||||
) {
|
||||
return viewGraphqlApiExceptionHandler(exception);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user