diff --git a/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts b/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts index 7270513a9d..bae22fdc2f 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts @@ -26,10 +26,8 @@ import { DatabaseEventTriggerV2Service } from 'src/engine/metadata-modules/datab import { FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input'; import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/services/field-metadata.service'; -import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { getFlatEntitiesByApplicationId } from 'src/engine/metadata-modules/flat-entity/utils/get-flat-entities-by-application-id.util'; -import { getSubFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; import { RouteTriggerV2Service } from 'src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service'; @@ -990,54 +988,37 @@ export class ApplicationSyncService { application.id, ); - const fromFlatObjectMetadataMaps = getSubFlatEntityMapsOrThrow({ - flatEntityIds: flatObjectMetadataMapsByApplicationId.map((obj) => obj.id), - flatEntityMaps: existingFlatObjectMetadataMaps, - }); - const flatIndexMetadataMapsByApplicationId = getFlatEntitiesByApplicationId( existingFlatIndexMetadataMaps, application.id, ); - const fromFlatIndexMetadataMaps = getSubFlatEntityMapsOrThrow({ - flatEntityIds: flatIndexMetadataMapsByApplicationId.map( - (field) => field.id, - ), - flatEntityMaps: existingFlatIndexMetadataMaps, - }); - const flatFieldMetadataMapsByApplicationId = getFlatEntitiesByApplicationId( existingFlatFieldMetadataMaps, application.id, ); - const fromFlatFieldMetadataMaps = getSubFlatEntityMapsOrThrow({ - flatEntityIds: flatFieldMetadataMapsByApplicationId.map((idx) => idx.id), - flatEntityMaps: existingFlatFieldMetadataMaps, - }); - await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatObjectMetadataMaps: { - from: fromFlatObjectMetadataMaps, - to: createEmptyFlatEntityMaps(), + allFlatEntityOperationByMetadataName: { + objectMetadata: { + flatEntityToCreate: [], + flatEntityToDelete: flatObjectMetadataMapsByApplicationId, + flatEntityToUpdate: [], }, - flatIndexMaps: { - from: fromFlatIndexMetadataMaps, - to: createEmptyFlatEntityMaps(), + index: { + flatEntityToCreate: [], + flatEntityToDelete: flatIndexMetadataMapsByApplicationId, + flatEntityToUpdate: [], }, - flatFieldMetadataMaps: { - from: fromFlatFieldMetadataMaps, - to: createEmptyFlatEntityMaps(), + fieldMetadata: { + flatEntityToCreate: [], + flatEntityToDelete: flatFieldMetadataMapsByApplicationId, + flatEntityToUpdate: [], }, }, workspaceId, - buildOptions: { - isSystemBuild: true, - inferDeletionFromMissingEntities: true, - }, + isSystemBuild: true, }, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.service.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.service.ts index c080d53d82..648883aded 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.service.ts @@ -10,7 +10,6 @@ import { type UpdateAgentInput } from 'src/engine/metadata-modules/ai/ai-agent/d import { fromCreateAgentInputToFlatAgent } from 'src/engine/metadata-modules/ai/ai-agent/utils/from-create-agent-input-to-flat-agent.util'; import { fromUpdateAgentInputToFlatAgentToUpdate } from 'src/engine/metadata-modules/ai/ai-agent/utils/from-update-agent-input-to-flat-agent-to-update.util'; import { FlatAgentWithRoleId } from 'src/engine/metadata-modules/flat-agent/types/flat-agent.type'; -import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; @@ -107,16 +106,6 @@ export class AgentService { input: CreateAgentInput & { isCustom: boolean }, workspaceId: string, ): Promise { - const { - flatAgentMaps: existingFlatAgentMaps, - flatRoleTargetMaps: existingFlatRoleTargetMaps, - flatRoleMaps: existingFlatRoleMaps, - } = await this.workspaceCacheService.getOrRecompute(workspaceId, [ - 'flatAgentMaps', - 'flatRoleTargetMaps', - 'flatRoleMaps', - ]); - const { workspaceCustomFlatApplication } = await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow( { @@ -137,27 +126,22 @@ export class AgentService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatAgentMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatAgentMaps, + allFlatEntityOperationByMetadataName: { + agent: { flatEntityToCreate: [flatAgentToCreate], flatEntityToDelete: [], flatEntityToUpdate: [], - }), - flatRoleTargetMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatRoleTargetMaps, + }, + roleTarget: { flatEntityToCreate: isDefined(flatRoleTargetToCreate) ? [flatRoleTargetToCreate] : [], flatEntityToDelete: [], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { flatRoleMaps: existingFlatRoleMaps }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -191,17 +175,11 @@ export class AgentService { input: UpdateAgentInput; workspaceId: string; }): Promise { - const { - flatAgentMaps: existingFlatAgentMaps, - flatRoleTargetMaps: existingFlatRoleTargetMaps, - flatRoleMaps: existingFlatRoleMaps, - flatRoleTargetByAgentIdMaps, - } = await this.workspaceCacheService.getOrRecompute(workspaceId, [ - 'flatAgentMaps', - 'flatRoleTargetMaps', - 'flatRoleMaps', - 'flatRoleTargetByAgentIdMaps', - ]); + const { flatRoleTargetByAgentIdMaps, flatAgentMaps } = + await this.workspaceCacheService.getOrRecompute(workspaceId, [ + 'flatRoleTargetByAgentIdMaps', + 'flatAgentMaps', + ]); const { flatAgentToUpdate, @@ -210,22 +188,20 @@ export class AgentService { flatRoleTargetToUpdate, } = fromUpdateAgentInputToFlatAgentToUpdate({ updateAgentInput: input, - flatAgentMaps: existingFlatAgentMaps, + flatAgentMaps, flatRoleTargetByAgentIdMaps, }); const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatAgentMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatAgentMaps, + allFlatEntityOperationByMetadataName: { + agent: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [flatAgentToUpdate], - }), - flatRoleTargetMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatRoleTargetMaps, + }, + roleTarget: { flatEntityToCreate: isDefined(flatRoleTargetToCreate) ? [flatRoleTargetToCreate] : [], @@ -235,16 +211,10 @@ export class AgentService { flatEntityToUpdate: isDefined(flatRoleTargetToUpdate) ? [flatRoleTargetToUpdate] : [], - }), - }, - dependencyAllFlatEntityMaps: { flatRoleMaps: existingFlatRoleMaps }, - buildOptions: { - isSystemBuild: false, - inferDeletionFromMissingEntities: { - roleTarget: isDefined(flatRoleTargetToDelete), }, }, workspaceId, + isSystemBuild: false, }, ); @@ -306,21 +276,15 @@ export class AgentService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatAgentMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatAgentMaps, + allFlatEntityOperationByMetadataName: { + agent: { flatEntityToCreate: [], flatEntityToDelete: [agentToDelete], flatEntityToUpdate: [], - }), - }, - buildOptions: { - isSystemBuild: false, - inferDeletionFromMissingEntities: { - agent: true, }, }, workspaceId, + isSystemBuild: false, }, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service.ts index a3f342648f..81b96c3dc0 100644 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service.ts @@ -14,7 +14,6 @@ import { FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/ import { fromCreateCronTriggerInputToFlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/utils/from-create-cron-trigger-input-to-flat-cron-trigger.util'; import { fromUpdateCronTriggerInputToFlatCronTriggerToUpdateOrThrow } from 'src/engine/metadata-modules/cron-trigger/utils/from-update-cron-trigger-input-to-flat-cron-trigger-to-update-or-throw.util'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; 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'; @@ -43,16 +42,6 @@ export class CronTriggerV2Service { }, ); - const flatEntityMaps = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'], - }, - ); - - const existingFlatCronTriggerMaps = flatEntityMaps.flatCronTriggerMaps; - const flatCronTriggerToCreate = fromCreateCronTriggerInputToFlatCronTrigger( { createCronTriggerInput: cronTriggerInput, @@ -65,22 +54,15 @@ export class CronTriggerV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - workspaceId, - fromToAllFlatEntityMaps: { - flatCronTriggerMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatCronTriggerMaps, + allFlatEntityOperationByMetadataName: { + cronTrigger: { flatEntityToCreate: [flatCronTriggerToCreate], flatEntityToDelete: [], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatServerlessFunctionMaps: - flatEntityMaps.flatServerlessFunctionMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, + workspaceId, + isSystemBuild: false, }, ); @@ -109,41 +91,32 @@ export class CronTriggerV2Service { cronTriggerInput: UpdateCronTriggerInput, workspaceId: string, ) { - const flatEntityMaps = + const { flatCronTriggerMaps } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatMapsKeys: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'], + flatMapsKeys: ['flatCronTriggerMaps'], }, ); - const existingFlatCronTriggerMaps = flatEntityMaps.flatCronTriggerMaps; - const optimisticallyUpdatedFlatCronTrigger = fromUpdateCronTriggerInputToFlatCronTriggerToUpdateOrThrow({ - flatCronTriggerMaps: existingFlatCronTriggerMaps, + flatCronTriggerMaps, updateCronTriggerInput: cronTriggerInput, }); const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - workspaceId, - fromToAllFlatEntityMaps: { - flatCronTriggerMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatCronTriggerMaps, + allFlatEntityOperationByMetadataName: { + cronTrigger: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [optimisticallyUpdatedFlatCronTrigger], - }), - }, - dependencyAllFlatEntityMaps: { - flatServerlessFunctionMaps: - flatEntityMaps.flatServerlessFunctionMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, + workspaceId, + isSystemBuild: false, }, ); @@ -175,19 +148,16 @@ export class CronTriggerV2Service { destroyCronTriggerInput: CronTriggerIdInput; workspaceId: string; }): Promise { - const { - flatCronTriggerMaps: existingFlatCronTriggerMaps, - flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, - } = + const { flatCronTriggerMaps } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatMapsKeys: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'], + flatMapsKeys: ['flatCronTriggerMaps'], }, ); const existingFlatCronTrigger = - existingFlatCronTriggerMaps.byId[destroyCronTriggerInput.id]; + flatCronTriggerMaps.byId[destroyCronTriggerInput.id]; if (!isDefined(existingFlatCronTrigger)) { throw new CronTriggerException( @@ -199,24 +169,15 @@ export class CronTriggerV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatCronTriggerMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatCronTriggerMaps, + allFlatEntityOperationByMetadataName: { + cronTrigger: { flatEntityToCreate: [], flatEntityToDelete: [existingFlatCronTrigger], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, - }, - buildOptions: { - isSystemBuild: false, - inferDeletionFromMissingEntities: { - cronTrigger: true, }, }, workspaceId, + isSystemBuild: false, }, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service.ts index a199278ade..5e56571ebc 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service.ts @@ -14,7 +14,6 @@ import { FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-e import { fromCreateDatabaseEventTriggerInputToFlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/utils/from-create-database-event-trigger-input-to-flat-database-event-trigger.util'; import { fromUpdateDatabaseEventTriggerInputToFlatDatabaseEventTriggerToUpdateOrThrow } from 'src/engine/metadata-modules/database-event-trigger/utils/from-update-database-event-trigger-input-to-flat-database-event-trigger-to-update-or-throw.util'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; 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'; @@ -43,20 +42,6 @@ export class DatabaseEventTriggerV2Service { }, ); - const flatEntityMaps = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatDatabaseEventTriggerMaps', - 'flatServerlessFunctionMaps', - ], - }, - ); - - const existingFlatDatabaseEventTriggerMaps = - flatEntityMaps.flatDatabaseEventTriggerMaps; - const flatDatabaseEventTriggerToCreate = fromCreateDatabaseEventTriggerInputToFlatDatabaseEventTrigger({ createDatabaseEventTriggerInput: databaseEventTriggerInput, @@ -68,22 +53,15 @@ export class DatabaseEventTriggerV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - workspaceId, - fromToAllFlatEntityMaps: { - flatDatabaseEventTriggerMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatDatabaseEventTriggerMaps, + allFlatEntityOperationByMetadataName: { + databaseEventTrigger: { flatEntityToCreate: [flatDatabaseEventTriggerToCreate], flatEntityToDelete: [], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatServerlessFunctionMaps: - flatEntityMaps.flatServerlessFunctionMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, + workspaceId, + isSystemBuild: false, }, ); @@ -115,24 +93,18 @@ export class DatabaseEventTriggerV2Service { databaseEventTriggerInput: UpdateDatabaseEventTriggerInput, workspaceId: string, ) { - const flatEntityMaps = + const { flatDatabaseEventTriggerMaps } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatMapsKeys: [ - 'flatDatabaseEventTriggerMaps', - 'flatServerlessFunctionMaps', - ], + flatMapsKeys: ['flatDatabaseEventTriggerMaps'], }, ); - const existingFlatDatabaseEventTriggerMaps = - flatEntityMaps.flatDatabaseEventTriggerMaps; - const optimisticallyUpdatedFlatDatabaseEventTrigger = fromUpdateDatabaseEventTriggerInputToFlatDatabaseEventTriggerToUpdateOrThrow( { - flatDatabaseEventTriggerMaps: existingFlatDatabaseEventTriggerMaps, + flatDatabaseEventTriggerMaps, updateDatabaseEventTriggerInput: databaseEventTriggerInput, }, ); @@ -140,24 +112,17 @@ export class DatabaseEventTriggerV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - workspaceId, - fromToAllFlatEntityMaps: { - flatDatabaseEventTriggerMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatDatabaseEventTriggerMaps, + allFlatEntityOperationByMetadataName: { + databaseEventTrigger: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [ optimisticallyUpdatedFlatDatabaseEventTrigger, ], - }), - }, - dependencyAllFlatEntityMaps: { - flatServerlessFunctionMaps: - flatEntityMaps.flatServerlessFunctionMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, + workspaceId, + isSystemBuild: false, }, ); @@ -192,24 +157,16 @@ export class DatabaseEventTriggerV2Service { destroyDatabaseEventTriggerInput: DatabaseEventTriggerIdInput; workspaceId: string; }): Promise { - const { - flatDatabaseEventTriggerMaps: existingFlatDatabaseEventTriggerMaps, - flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, - } = + const { flatDatabaseEventTriggerMaps } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatMapsKeys: [ - 'flatDatabaseEventTriggerMaps', - 'flatServerlessFunctionMaps', - ], + flatMapsKeys: ['flatDatabaseEventTriggerMaps'], }, ); const existingFlatDatabaseEventTrigger = - existingFlatDatabaseEventTriggerMaps.byId[ - destroyDatabaseEventTriggerInput.id - ]; + flatDatabaseEventTriggerMaps.byId[destroyDatabaseEventTriggerInput.id]; if (!isDefined(existingFlatDatabaseEventTrigger)) { throw new DatabaseEventTriggerException( @@ -221,24 +178,15 @@ export class DatabaseEventTriggerV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatDatabaseEventTriggerMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatDatabaseEventTriggerMaps, + allFlatEntityOperationByMetadataName: { + databaseEventTrigger: { flatEntityToCreate: [], flatEntityToDelete: [existingFlatDatabaseEventTrigger], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, - }, - buildOptions: { - isSystemBuild: false, - inferDeletionFromMissingEntities: { - databaseEventTrigger: true, }, }, workspaceId, + isSystemBuild: false, }, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/services/field-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/services/field-metadata.service.ts index 7cfbc4670d..c19a866853 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/services/field-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/services/field-metadata.service.ts @@ -15,7 +15,6 @@ import { FieldMetadataExceptionCode, } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; @@ -105,31 +104,20 @@ export class FieldMetadataService extends TypeOrmQueryService @@ -377,27 +340,20 @@ export class FieldMetadataService extends TypeOrmQueryService = { + flatEntityToUpdate: MetadataFlatEntity[]; + flatEntityToCreate: MetadataFlatEntity[]; + flatEntityToDelete: MetadataFlatEntity[]; +}; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util.ts index 40a8fed5ce..c5a9bc222d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util.ts @@ -1,24 +1,23 @@ -import { type AllFlatEntities } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entities.type'; -import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { type AllMetadataName } from 'twenty-shared/metadata'; + +import { type FlatEntityToCreateDeleteUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-to-create-delete-update.type'; +import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type'; import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util'; import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util'; import { getSubFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util'; import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util'; -type ComputeFlatEntityMapsFromToArgs = { - flatEntityMaps: FlatEntityMaps; - flatEntityToUpdate: T[]; - flatEntityToCreate: T[]; - flatEntityToDelete: T[]; -}; -export const computeFlatEntityMapsFromTo = ({ +export type ComputeFlatEntityMapsFromToArgs = { + flatEntityMaps: MetadataFlatEntityMaps; +} & FlatEntityToCreateDeleteUpdate; +export const computeFlatEntityMapsFromTo = ({ flatEntityMaps, flatEntityToCreate, flatEntityToDelete, flatEntityToUpdate, }: ComputeFlatEntityMapsFromToArgs): { - from: FlatEntityMaps; - to: FlatEntityMaps; + from: MetadataFlatEntityMaps; + to: MetadataFlatEntityMaps; } => { const fromFlatEntityMaps = flatEntityToDelete.length > 0 diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts index 6a6ca7f186..c1c44434b2 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts @@ -6,9 +6,11 @@ import { fromArrayToUniqueKeyRecord, isDefined } from 'twenty-shared/utils'; import { FindManyOptions, FindOneOptions, Repository } from 'typeorm'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; +import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type'; -import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; +import { MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type'; +import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util'; import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type'; @@ -94,39 +96,30 @@ export class ObjectMetadataService extends TypeOrmQueryService>( + (flatEntityMaps, flatFieldMetadata) => + addFlatEntityToFlatEntityMapsOrThrow({ + flatEntity: flatFieldMetadata, + flatEntityMaps, + }), + createEmptyFlatEntityMaps(), + ); const flatDefaultViewToCreate = await this.computeFlatViewToCreate({ objectMetadata: flatObjectMetadataToCreate, workspaceId, workspaceCustomApplicationId: workspaceCustomFlatApplication.id, - flatFieldMetadataMaps: flatFieldMetadataMapsFromTo.to, + flatFieldMetadataMaps: optimisticFlatFieldMetadataMaps, }); const flatDefaultViewFieldsToCreate = await this.computeFlatViewFieldsToCreate({ workspaceCustomApplicationId: workspaceCustomFlatApplication.id, - objectFlatFieldMetadatas: findManyFlatEntityByIdInFlatEntityMapsOrThrow( - { - flatEntityMaps: flatFieldMetadataMapsFromTo.to, - flatEntityIds: flatFieldMetadataToCreateOnObject.map( - ({ id }) => id, - ), - }, - ), + objectFlatFieldMetadatas: flatFieldMetadataToCreateOnObject, viewId: flatDefaultViewToCreate.id, workspaceId, }); @@ -407,37 +374,38 @@ export class ObjectMetadataService extends TypeOrmQueryService { - const { flatRoleMaps: existingFlatRoleMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatRoleMaps'], - }, - ); - const flatRoleToCreate = fromCreateRoleInputToFlatRoleToCreate({ createRoleInput: input, workspaceId, @@ -97,19 +88,15 @@ export class RoleService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatRoleMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatRoleMaps, + allFlatEntityOperationByMetadataName: { + role: { flatEntityToCreate: [flatRoleToCreate], flatEntityToDelete: [], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: {}, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -159,19 +146,15 @@ export class RoleService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatRoleMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatRoleMaps, + allFlatEntityOperationByMetadataName: { + role: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [flatRoleToUpdate], - }), - }, - dependencyAllFlatEntityMaps: {}, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -255,22 +238,15 @@ export class RoleService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatRoleMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatRoleMaps, + allFlatEntityOperationByMetadataName: { + role: { flatEntityToCreate: [], flatEntityToDelete: [flatRoleToDelete], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: {}, - buildOptions: { - inferDeletionFromMissingEntities: { - role: true, }, - isSystemBuild: false, }, workspaceId, + isSystemBuild: false, }, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service.ts index 0e401864e2..4697e125a5 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service.ts @@ -4,7 +4,6 @@ import { isDefined } from 'twenty-shared/utils'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { CreateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input'; import { RouteTriggerIdInput } from 'src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input'; @@ -43,16 +42,6 @@ export class RouteTriggerV2Service { }, ); - const flatEntityMaps = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatRouteTriggerMaps', 'flatServerlessFunctionMaps'], - }, - ); - - const existingFlatRouteMaps = flatEntityMaps.flatRouteTriggerMaps; - const flatRouteTriggerToCreate = fromCreateRouteTriggerInputToFlatRouteTrigger({ createRouteTriggerInput: routeTriggerInput, @@ -64,22 +53,15 @@ export class RouteTriggerV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - workspaceId, - fromToAllFlatEntityMaps: { - flatRouteTriggerMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatRouteMaps, + allFlatEntityOperationByMetadataName: { + routeTrigger: { flatEntityToCreate: [flatRouteTriggerToCreate], flatEntityToDelete: [], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatServerlessFunctionMaps: - flatEntityMaps.flatServerlessFunctionMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, + workspaceId, + isSystemBuild: false, }, ); @@ -108,41 +90,32 @@ export class RouteTriggerV2Service { routeTriggerInput: UpdateRouteTriggerInput, workspaceId: string, ) { - const flatEntityMaps = + const { flatRouteTriggerMaps } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatMapsKeys: ['flatRouteTriggerMaps', 'flatServerlessFunctionMaps'], + flatMapsKeys: ['flatRouteTriggerMaps'], }, ); - const existingFlatRouteMaps = flatEntityMaps.flatRouteTriggerMaps; - const optimisticallyUpdatedFlatRouteTrigger = fromUpdateRouteTriggerInputToFlatRouteTriggerToUpdateOrThrow({ - flatRouteTriggerMaps: existingFlatRouteMaps, + flatRouteTriggerMaps, updateRouteTriggerInput: routeTriggerInput, }); const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - workspaceId, - fromToAllFlatEntityMaps: { - flatRouteTriggerMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatRouteMaps, + allFlatEntityOperationByMetadataName: { + routeTrigger: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [optimisticallyUpdatedFlatRouteTrigger], - }), - }, - dependencyAllFlatEntityMaps: { - flatServerlessFunctionMaps: - flatEntityMaps.flatServerlessFunctionMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, + workspaceId, + isSystemBuild: false, }, ); @@ -174,19 +147,16 @@ export class RouteTriggerV2Service { destroyRouteTriggerInput: RouteTriggerIdInput; workspaceId: string; }): Promise { - const { - flatRouteTriggerMaps: existingFlatRouteMaps, - flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, - } = + const { flatRouteTriggerMaps } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatMapsKeys: ['flatRouteTriggerMaps', 'flatServerlessFunctionMaps'], + flatMapsKeys: ['flatRouteTriggerMaps'], }, ); const existingFlatRoute = - existingFlatRouteMaps.byId[destroyRouteTriggerInput.id]; + flatRouteTriggerMaps.byId[destroyRouteTriggerInput.id]; if (!isDefined(existingFlatRoute)) { throw new RouteTriggerException( @@ -198,24 +168,15 @@ export class RouteTriggerV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatRouteTriggerMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatRouteMaps, + allFlatEntityOperationByMetadataName: { + routeTrigger: { flatEntityToCreate: [], flatEntityToDelete: [existingFlatRoute], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, - }, - buildOptions: { - isSystemBuild: false, - inferDeletionFromMissingEntities: { - routeTrigger: true, }, }, workspaceId, + isSystemBuild: false, }, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/serverless-function-v2.service.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/serverless-function-v2.service.ts index f5acda88a2..79ac472b5f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/serverless-function-v2.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/serverless-function-v2.service.ts @@ -4,7 +4,6 @@ import { isDefined } from 'twenty-shared/utils'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import type { CreateServerlessFunctionInput } from 'src/engine/metadata-modules/serverless-function/dtos/create-serverless-function.input'; import { ServerlessFunctionIdInput } from 'src/engine/metadata-modules/serverless-function/dtos/serverless-function-id.input'; @@ -49,17 +48,6 @@ export class ServerlessFunctionV2Service { }, ); - const flatEntityMaps = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatServerlessFunctionMaps'], - }, - ); - - const existingFlatServerlessFunctionMaps = - flatEntityMaps.flatServerlessFunctionMaps; - const flatServerlessFunctionToCreate = fromCreateServerlessFunctionInputToFlatServerlessFunction({ createServerlessFunctionInput, @@ -71,18 +59,15 @@ export class ServerlessFunctionV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - workspaceId, - fromToAllFlatEntityMaps: { - flatServerlessFunctionMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatServerlessFunctionMaps, + allFlatEntityOperationByMetadataName: { + serverlessFunction: { flatEntityToCreate: [flatServerlessFunctionToCreate], flatEntityToDelete: [], flatEntityToUpdate: [], - }), - }, - buildOptions: { - isSystemBuild: false, + }, }, + workspaceId, + isSystemBuild: false, }, ); @@ -113,7 +98,7 @@ export class ServerlessFunctionV2Service { serverlessFunctionInput: UpdateServerlessFunctionInput, workspaceId: string, ) { - const flatEntityMaps = + const { flatServerlessFunctionMaps } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, @@ -121,30 +106,24 @@ export class ServerlessFunctionV2Service { }, ); - const existingFlatServerlessFunctionMaps = - flatEntityMaps.flatServerlessFunctionMaps; - const optimisticallyUpdatedFlatServerlessFunction = fromUpdateServerlessFunctionInputToFlatServerlessFunctionToUpdateOrThrow({ - flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, + flatServerlessFunctionMaps, updateServerlessFunctionInput: serverlessFunctionInput, }); const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - workspaceId, - fromToAllFlatEntityMaps: { - flatServerlessFunctionMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatServerlessFunctionMaps, + allFlatEntityOperationByMetadataName: { + serverlessFunction: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [optimisticallyUpdatedFlatServerlessFunction], - }), - }, - buildOptions: { - isSystemBuild: false, + }, }, + workspaceId, + isSystemBuild: false, }, ); @@ -206,20 +185,17 @@ export class ServerlessFunctionV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatServerlessFunctionMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatServerlessFunctionMaps, + allFlatEntityOperationByMetadataName: { + serverlessFunction: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [ optimisticallyUpdatedFlatServerlessFunctionWithDeletedAt, ], - }), - }, - buildOptions: { - isSystemBuild, + }, }, workspaceId, + isSystemBuild, }, ); @@ -278,21 +254,15 @@ export class ServerlessFunctionV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatServerlessFunctionMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatServerlessFunctionMaps, + allFlatEntityOperationByMetadataName: { + serverlessFunction: { flatEntityToCreate: [], flatEntityToDelete: [existingFlatServerlessFunction], flatEntityToUpdate: [], - }), - }, - buildOptions: { - isSystemBuild, - inferDeletionFromMissingEntities: { - serverlessFunction: true, }, }, workspaceId, + isSystemBuild, }, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/view-field/services/view-field-v2.service.ts b/packages/twenty-server/src/engine/metadata-modules/view-field/services/view-field-v2.service.ts index 1b5db84daf..2d123c400d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view-field/services/view-field-v2.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view-field/services/view-field-v2.service.ts @@ -6,7 +6,6 @@ import { IsNull, Repository } from 'typeorm'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { fromCreateViewFieldInputToFlatViewFieldToCreate } from 'src/engine/metadata-modules/flat-view-field/utils/from-create-view-field-input-to-flat-view-field-to-create.util'; @@ -76,23 +75,6 @@ export class ViewFieldV2Service { }, ); - const { - flatViewFieldMaps: existingFlatViewFieldMaps, - flatViewMaps, - flatFieldMetadataMaps, - flatObjectMetadataMaps, - } = await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewFieldMaps', - 'flatViewMaps', - 'flatFieldMetadataMaps', - 'flatObjectMetadataMaps', - ], - }, - ); - const flatViewFieldsToCreate = createViewFieldInputs.map( (createViewFieldInput) => fromCreateViewFieldInputToFlatViewFieldToCreate({ @@ -105,23 +87,15 @@ export class ViewFieldV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewFieldMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewFieldMaps, + allFlatEntityOperationByMetadataName: { + viewField: { flatEntityToCreate: flatViewFieldsToCreate, flatEntityToDelete: [], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatFieldMetadataMaps, - flatViewMaps, - flatObjectMetadataMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -153,20 +127,13 @@ export class ViewFieldV2Service { workspaceId: string; updateViewFieldInput: UpdateViewFieldInput; }): Promise { - const { - flatViewFieldMaps: existingFlatViewFieldMaps, - flatObjectMetadataMaps, - flatViewMaps, - } = await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewFieldMaps', - 'flatObjectMetadataMaps', - 'flatViewMaps', - ], - }, - ); + const { flatViewFieldMaps: existingFlatViewFieldMaps } = + await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatViewFieldMaps'], + }, + ); const optimisticallyUpdatedFlatView = fromUpdateViewFieldInputToFlatViewFieldToUpdateOrThrow({ @@ -177,22 +144,15 @@ export class ViewFieldV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewFieldMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewFieldMaps, + allFlatEntityOperationByMetadataName: { + viewField: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [optimisticallyUpdatedFlatView], - }), - }, - dependencyAllFlatEntityMaps: { - flatObjectMetadataMaps, - flatViewMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -224,20 +184,13 @@ export class ViewFieldV2Service { deleteViewFieldInput: DeleteViewFieldInput; workspaceId: string; }): Promise { - const { - flatViewFieldMaps: existingFlatViewFieldMaps, - flatObjectMetadataMaps, - flatViewMaps, - } = await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewFieldMaps', - 'flatObjectMetadataMaps', - 'flatViewMaps', - ], - }, - ); + const { flatViewFieldMaps: existingFlatViewFieldMaps } = + await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatViewFieldMaps'], + }, + ); const optimisticallyUpdatedFlatViewWithDeletedAt = fromDeleteViewFieldInputToFlatViewFieldOrThrow({ @@ -248,22 +201,15 @@ export class ViewFieldV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewFieldMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewFieldMaps, + allFlatEntityOperationByMetadataName: { + viewField: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [optimisticallyUpdatedFlatViewWithDeletedAt], - }), - }, - dependencyAllFlatEntityMaps: { - flatObjectMetadataMaps, - flatViewMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -295,22 +241,13 @@ export class ViewFieldV2Service { destroyViewFieldInput: DestroyViewFieldInput; workspaceId: string; }): Promise { - const { - flatViewFieldMaps: existingFlatViewFieldMaps, - flatViewMaps: existingFlatViewMaps, - flatFieldMetadataMaps, - flatObjectMetadataMaps, - } = await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewFieldMaps', - 'flatViewMaps', - 'flatFieldMetadataMaps', - 'flatObjectMetadataMaps', - ], - }, - ); + const { flatViewFieldMaps: existingFlatViewFieldMaps } = + await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatViewFieldMaps'], + }, + ); const existingViewFieldToDelete = fromDestroyViewFieldInputToFlatViewFieldOrThrow({ @@ -321,26 +258,15 @@ export class ViewFieldV2Service { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewFieldMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewFieldMaps, + allFlatEntityOperationByMetadataName: { + viewField: { flatEntityToCreate: [], flatEntityToDelete: [existingViewFieldToDelete], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatViewMaps: existingFlatViewMaps, - flatFieldMetadataMaps, - flatObjectMetadataMaps, - }, - buildOptions: { - isSystemBuild: false, - inferDeletionFromMissingEntities: { - viewField: true, }, }, workspaceId, + isSystemBuild: false, }, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/view-filter/services/view-filter.service.ts b/packages/twenty-server/src/engine/metadata-modules/view-filter/services/view-filter.service.ts index 7d5447db51..559d40c2bc 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view-filter/services/view-filter.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view-filter/services/view-filter.service.ts @@ -6,7 +6,6 @@ import { IsNull, Repository } from 'typeorm'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { fromCreateViewFilterInputToFlatViewFilterToCreate } from 'src/engine/metadata-modules/flat-view-filter/utils/from-create-view-filter-input-to-flat-view-filter-to-create.util'; import { fromDeleteViewFilterInputToFlatViewFilterOrThrow } from 'src/engine/metadata-modules/flat-view-filter/utils/from-delete-view-filter-input-to-flat-view-filter-or-throw.util'; @@ -45,23 +44,6 @@ export class ViewFilterService { }, ); - const { - flatViewFilterMaps: existingFlatViewFilterMaps, - flatViewMaps, - flatFieldMetadataMaps, - flatObjectMetadataMaps, - } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewFilterMaps', - 'flatViewMaps', - 'flatFieldMetadataMaps', - 'flatObjectMetadataMaps', - ], - }, - ); - const flatViewFilterToCreate = fromCreateViewFilterInputToFlatViewFilterToCreate({ createViewFilterInput, @@ -72,23 +54,15 @@ export class ViewFilterService { const buildAndRunResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewFilterMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewFilterMaps, + allFlatEntityOperationByMetadataName: { + viewFilter: { flatEntityToCreate: [flatViewFilterToCreate], flatEntityToDelete: [], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatFieldMetadataMaps, - flatViewMaps, - flatObjectMetadataMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -125,20 +99,13 @@ export class ViewFilterService { workspaceId: string; updateViewFilterInput: UpdateViewFilterInput; }): Promise { - const { - flatViewFilterMaps: existingFlatViewFilterMaps, - flatViewMaps, - flatFieldMetadataMaps, - } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewFilterMaps', - 'flatViewMaps', - 'flatFieldMetadataMaps', - ], - }, - ); + const { flatViewFilterMaps: existingFlatViewFilterMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatViewFilterMaps'], + }, + ); const optimisticallyUpdatedFlatViewFilter = fromUpdateViewFilterInputToFlatViewFilterToUpdateOrThrow({ @@ -149,22 +116,15 @@ export class ViewFilterService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewFilterMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewFilterMaps, + allFlatEntityOperationByMetadataName: { + viewFilter: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [optimisticallyUpdatedFlatViewFilter], - }), - }, - dependencyAllFlatEntityMaps: { - flatViewMaps, - flatFieldMetadataMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -196,20 +156,13 @@ export class ViewFilterService { deleteViewFilterInput: DeleteViewFilterInput; workspaceId: string; }): Promise { - const { - flatViewFilterMaps: existingFlatViewFilterMaps, - flatViewMaps, - flatFieldMetadataMaps, - } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewFilterMaps', - 'flatViewMaps', - 'flatFieldMetadataMaps', - ], - }, - ); + const { flatViewFilterMaps: existingFlatViewFilterMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatViewFilterMaps'], + }, + ); const optimisticallyUpdatedFlatViewFilterWithDeletedAt = fromDeleteViewFilterInputToFlatViewFilterOrThrow({ @@ -220,24 +173,17 @@ export class ViewFilterService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewFilterMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewFilterMaps, + allFlatEntityOperationByMetadataName: { + viewFilter: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [ optimisticallyUpdatedFlatViewFilterWithDeletedAt, ], - }), - }, - dependencyAllFlatEntityMaps: { - flatFieldMetadataMaps, - flatViewMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -269,20 +215,13 @@ export class ViewFilterService { destroyViewFilterInput: DestroyViewFilterInput; workspaceId: string; }): Promise { - const { - flatViewFilterMaps: existingFlatViewFilterMaps, - flatViewMaps: existingFlatViewMaps, - flatFieldMetadataMaps: existingFlatFieldMetadataMaps, - } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewFilterMaps', - 'flatViewMaps', - 'flatFieldMetadataMaps', - ], - }, - ); + const { flatViewFilterMaps: existingFlatViewFilterMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatViewFilterMaps'], + }, + ); const existingViewFilterToDelete = fromDestroyViewFilterInputToFlatViewFilterOrThrow({ @@ -293,25 +232,15 @@ export class ViewFilterService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewFilterMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewFilterMaps, + allFlatEntityOperationByMetadataName: { + viewFilter: { flatEntityToCreate: [], flatEntityToDelete: [existingViewFilterToDelete], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatViewMaps: existingFlatViewMaps, - flatFieldMetadataMaps: existingFlatFieldMetadataMaps, - }, - buildOptions: { - isSystemBuild: false, - inferDeletionFromMissingEntities: { - viewFilter: true, }, }, workspaceId, + isSystemBuild: false, }, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/view-group/services/view-group.service.ts b/packages/twenty-server/src/engine/metadata-modules/view-group/services/view-group.service.ts index e442f90cb6..f654012cec 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view-group/services/view-group.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view-group/services/view-group.service.ts @@ -6,7 +6,6 @@ import { IsNull, Repository } from 'typeorm'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { fromCreateViewGroupInputToFlatViewGroupToCreate } from 'src/engine/metadata-modules/flat-view-group/utils/from-create-view-group-input-to-flat-view-group-to-create.util'; @@ -76,20 +75,13 @@ export class ViewGroupService { }, ); - const { - flatViewGroupMaps: existingFlatViewGroupMaps, - flatViewMaps, - flatFieldMetadataMaps, - } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewGroupMaps', - 'flatViewMaps', - 'flatFieldMetadataMaps', - ], - }, - ); + const { flatViewMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatViewMaps'], + }, + ); const flatViewGroupsToCreate = createViewGroupInputs.map( (createViewGroupInput) => { @@ -116,22 +108,15 @@ export class ViewGroupService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewGroupMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewGroupMaps, + allFlatEntityOperationByMetadataName: { + viewGroup: { flatEntityToCreate: flatViewGroupsToCreate, flatEntityToDelete: [], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatFieldMetadataMaps, - flatViewMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -163,20 +148,13 @@ export class ViewGroupService { workspaceId: string; updateViewGroupInput: UpdateViewGroupInput; }): Promise { - const { - flatViewGroupMaps: existingFlatViewGroupMaps, - flatViewMaps, - flatFieldMetadataMaps, - } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewGroupMaps', - 'flatViewMaps', - 'flatFieldMetadataMaps', - ], - }, - ); + const { flatViewGroupMaps: existingFlatViewGroupMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatViewGroupMaps'], + }, + ); const optimisticallyUpdatedFlatViewGroup = fromUpdateViewGroupInputToFlatViewGroupToUpdateOrThrow({ @@ -187,22 +165,15 @@ export class ViewGroupService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewGroupMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewGroupMaps, + allFlatEntityOperationByMetadataName: { + viewGroup: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [optimisticallyUpdatedFlatViewGroup], - }), - }, - dependencyAllFlatEntityMaps: { - flatViewMaps, - flatFieldMetadataMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -234,20 +205,13 @@ export class ViewGroupService { deleteViewGroupInput: DeleteViewGroupInput; workspaceId: string; }): Promise { - const { - flatViewGroupMaps: existingFlatViewGroupMaps, - flatViewMaps, - flatFieldMetadataMaps, - } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewGroupMaps', - 'flatViewMaps', - 'flatFieldMetadataMaps', - ], - }, - ); + const { flatViewGroupMaps: existingFlatViewGroupMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatViewGroupMaps'], + }, + ); const optimisticallyUpdatedFlatViewGroupWithDeletedAt = fromDeleteViewGroupInputToFlatViewGroupOrThrow({ @@ -258,24 +222,17 @@ export class ViewGroupService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewGroupMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewGroupMaps, + allFlatEntityOperationByMetadataName: { + viewGroup: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [ optimisticallyUpdatedFlatViewGroupWithDeletedAt, ], - }), - }, - dependencyAllFlatEntityMaps: { - flatFieldMetadataMaps, - flatViewMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -307,20 +264,13 @@ export class ViewGroupService { destroyViewGroupInput: DestroyViewGroupInput; workspaceId: string; }): Promise { - const { - flatViewGroupMaps: existingFlatViewGroupMaps, - flatViewMaps: existingFlatViewMaps, - flatFieldMetadataMaps: existingFlatFieldMetadataMaps, - } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatViewGroupMaps', - 'flatViewMaps', - 'flatFieldMetadataMaps', - ], - }, - ); + const { flatViewGroupMaps: existingFlatViewGroupMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatViewGroupMaps'], + }, + ); const existingViewGroupToDelete = fromDestroyViewGroupInputToFlatViewGroupOrThrow({ @@ -331,25 +281,15 @@ export class ViewGroupService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewGroupMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewGroupMaps, + allFlatEntityOperationByMetadataName: { + viewGroup: { flatEntityToCreate: [], flatEntityToDelete: [existingViewGroupToDelete], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatViewMaps: existingFlatViewMaps, - flatFieldMetadataMaps: existingFlatFieldMetadataMaps, - }, - buildOptions: { - isSystemBuild: false, - inferDeletionFromMissingEntities: { - viewGroup: true, }, }, workspaceId, + isSystemBuild: false, }, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/view/services/view.service.ts b/packages/twenty-server/src/engine/metadata-modules/view/services/view.service.ts index ae11a40da2..f7fae70788 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view/services/view.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view/services/view.service.ts @@ -9,7 +9,6 @@ import { ApplicationService } from 'src/engine/core-modules/application/applicat import { I18nService } from 'src/engine/core-modules/i18n/i18n.service'; import { generateMessageId } from 'src/engine/core-modules/i18n/utils/generateMessageId'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { fromCreateViewInputToFlatViewToCreate } from 'src/engine/metadata-modules/flat-view/utils/from-create-view-input-to-flat-view-to-create.util'; import { fromDeleteViewInputToFlatViewOrThrow } from 'src/engine/metadata-modules/flat-view/utils/from-delete-view-input-to-flat-view-or-throw.util'; @@ -52,22 +51,13 @@ export class ViewService { }, ); - const { - flatObjectMetadataMaps, - flatViewMaps: existingFlatViewMaps, - flatFieldMetadataMaps: existingFlatFieldMetadataMaps, - flatViewGroupMaps: existingFlatViewGroupMaps, - } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatObjectMetadataMaps', - 'flatViewMaps', - 'flatFieldMetadataMaps', - 'flatViewGroupMaps', - ], - }, - ); + const { flatFieldMetadataMaps: existingFlatFieldMetadataMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatFieldMetadataMaps'], + }, + ); const { flatViewToCreate, flatViewGroupsToCreate } = fromCreateViewInputToFlatViewToCreate({ @@ -81,28 +71,21 @@ export class ViewService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewMaps, + allFlatEntityOperationByMetadataName: { + view: { flatEntityToCreate: [flatViewToCreate], flatEntityToDelete: [], flatEntityToUpdate: [], - }), - flatViewGroupMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewGroupMaps, + }, + + viewGroup: { flatEntityToCreate: flatViewGroupsToCreate, flatEntityToDelete: [], flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatObjectMetadataMaps: flatObjectMetadataMaps, - flatFieldMetadataMaps: existingFlatFieldMetadataMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -163,30 +146,20 @@ export class ViewService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewMaps, + allFlatEntityOperationByMetadataName: { + view: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [flatViewToUpdate], - }), - flatViewGroupMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewGroupMaps, + }, + viewGroup: { flatEntityToCreate: flatViewGroupsToCreate, flatEntityToDelete: flatViewGroupsToDelete, flatEntityToUpdate: [], - }), - }, - dependencyAllFlatEntityMaps: { - flatFieldMetadataMaps: existingFlatFieldMetadataMaps, - }, - buildOptions: { - isSystemBuild: false, - inferDeletionFromMissingEntities: { - viewGroup: true, }, }, workspaceId, + isSystemBuild: false, }, ); @@ -218,14 +191,11 @@ export class ViewService { deleteViewInput: DeleteViewInput; workspaceId: string; }): Promise { - const { - flatViewMaps: existingFlatViewMaps, - flatFieldMetadataMaps: existingFlatFieldMetadataMaps, - } = + const { flatViewMaps: existingFlatViewMaps } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatMapsKeys: ['flatViewMaps', 'flatFieldMetadataMaps'], + flatMapsKeys: ['flatViewMaps'], }, ); @@ -238,21 +208,15 @@ export class ViewService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewMaps, + allFlatEntityOperationByMetadataName: { + view: { flatEntityToCreate: [], flatEntityToDelete: [], flatEntityToUpdate: [optimisticallyUpdatedFlatViewWithDeletedAt], - }), - }, - dependencyAllFlatEntityMaps: { - flatFieldMetadataMaps: existingFlatFieldMetadataMaps, - }, - buildOptions: { - isSystemBuild: false, + }, }, workspaceId, + isSystemBuild: false, }, ); @@ -284,14 +248,11 @@ export class ViewService { destroyViewInput: DestroyViewInput; workspaceId: string; }): Promise { - const { - flatViewMaps: existingFlatViewMaps, - flatFieldMetadataMaps: existingFlatFieldMetadataMaps, - } = + const { flatViewMaps: existingFlatViewMaps } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatMapsKeys: ['flatViewMaps', 'flatFieldMetadataMaps'], + flatMapsKeys: ['flatViewMaps'], }, ); @@ -303,24 +264,15 @@ export class ViewService { const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( { - fromToAllFlatEntityMaps: { - flatViewMaps: computeFlatEntityMapsFromTo({ - flatEntityMaps: existingFlatViewMaps, + allFlatEntityOperationByMetadataName: { + view: { flatEntityToCreate: [], flatEntityToDelete: [flatViewFromDestroyInput], flatEntityToUpdate: [], - }), - }, - buildOptions: { - isSystemBuild: false, - inferDeletionFromMissingEntities: { - view: true, }, }, - dependencyAllFlatEntityMaps: { - flatFieldMetadataMaps: existingFlatFieldMetadataMaps, - }, workspaceId, + isSystemBuild: false, }, ); diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/create-standard-flat-object-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/create-standard-flat-object-metadata.util.ts index 77f5b5b250..b9d524930a 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/create-standard-flat-object-metadata.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/utils/create-standard-flat-object-metadata.util.ts @@ -1,8 +1,8 @@ import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant'; import { type AllStandardObjectName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-name.type'; -import { type StandardFieldMetadataIdByObjectAndFieldName } from 'src/engine/workspace-manager/twenty-standard-application/utils/get-standard-field-metadata-id-by-object-and-field-name.util'; import { createStandardObjectFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/create-standard-object-flat-metadata.util'; +import { type StandardFieldMetadataIdByObjectAndFieldName } from 'src/engine/workspace-manager/twenty-standard-application/utils/get-standard-field-metadata-id-by-object-and-field-name.util'; export type BuildStandardFlatObjectMetadatasArgs = { createdAt: Date; @@ -14,11 +14,6 @@ export type StandardFlatObjectMetadataBuilder = ( args: BuildStandardFlatObjectMetadatasArgs, ) => FlatObjectMetadata; -/** - * Record mapping each standard object name to its corresponding object metadata builder. - * Using `satisfies` ensures type safety: if a new standard object is added to STANDARD_OBJECTS, - * TypeScript will error until a builder is added here. - */ export const STANDARD_FLAT_OBJECT_METADATA_BUILDERS_BY_OBJECT_NAME = { attachment: (args: BuildStandardFlatObjectMetadatasArgs) => createStandardObjectFlatMetadata({ diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service.ts index c30615e727..7b1dd8b8b2 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service.ts @@ -15,12 +15,12 @@ import { } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type'; import { aggregateOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/utils/aggregate-orchestrator-actions-report.util'; import { WorkspaceMigrationV2AgentActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/agent/workspace-migration-v2-agent-actions-builder.service'; -import { WorkspaceMigrationV2PageLayoutTabActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/page-layout-tab/workspace-migration-v2-page-layout-tab-actions-builder.service'; import { WorkspaceMigrationV2CronTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/workspace-migration-v2-cron-trigger-action-builder.service'; import { WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/workspace-migration-v2-database-event-trigger-actions-builder.service'; import { WorkspaceMigrationV2FieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/workspace-migration-v2-field-actions-builder.service'; import { WorkspaceMigrationV2IndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-actions-builder.service'; import { WorkspaceMigrationV2ObjectActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/workspace-migration-v2-object-actions-builder.service'; +import { WorkspaceMigrationV2PageLayoutTabActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/page-layout-tab/workspace-migration-v2-page-layout-tab-actions-builder.service'; import { WorkspaceMigrationV2RoleTargetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/role-target/workspace-migration-v2-role-target-actions-builder.service'; import { WorkspaceMigrationV2RoleActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/role/workspace-migration-v2-role-actions-builder.service'; import { WorkspaceMigrationV2RouteTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service'; @@ -65,7 +65,10 @@ export class WorkspaceMigrationBuildOrchestratorService { (allFlatEntityMaps, currFlatMaps) => { const fromToOccurence = fromToAllFlatEntityMaps[currFlatMaps]; - if (!isDefined(fromToOccurence)) { + if ( + !isDefined(fromToOccurence) || + isDefined(allFlatEntityMaps[currFlatMaps]) + ) { return allFlatEntityMaps; } diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service.ts index 02272a91ee..571ec62dc0 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service.ts @@ -1,15 +1,35 @@ import { Injectable, Logger } from '@nestjs/common'; -import { WorkspaceMigrationV2ExceptionCode } from 'twenty-shared/metadata'; +import { + AllMetadataName, + WorkspaceMigrationV2ExceptionCode, +} from 'twenty-shared/metadata'; +import { isDefined } from 'twenty-shared/utils'; +import { ALL_METADATA_REQUIRED_METADATA_FOR_VALIDATION } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-required-metadata-for-validation.constant'; +import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant'; +import { AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type'; +import { FlatEntityToCreateDeleteUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-to-create-delete-update.type'; +import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util'; +import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util'; +import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; import { WorkspaceMigrationBuildOrchestratorService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service'; import { WorkspaceMigrationOrchestratorBuildArgs, WorkspaceMigrationOrchestratorFailedResult, } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type'; +import { InferDeletionFromMissingEntities } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/infer-deletion-from-missing-entities.type'; import { WorkspaceMigrationRunnerV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/services/workspace-migration-runner-v2.service'; import { WorkspaceMigrationV2Exception } from 'src/engine/workspace-manager/workspace-migration.exception'; +type ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs = { + workspaceId: string; + allFlatEntityOperationByMetadataName: { + [P in AllMetadataName]?: FlatEntityToCreateDeleteUpdate

; + }; + isSystemBuild?: boolean; +}; + @Injectable() export class WorkspaceMigrationValidateBuildAndRunService { private readonly logger = new Logger( @@ -19,14 +39,144 @@ export class WorkspaceMigrationValidateBuildAndRunService { constructor( private readonly workspaceMigrationRunnerV2Service: WorkspaceMigrationRunnerV2Service, private readonly workspaceMigrationBuildOrchestratorService: WorkspaceMigrationBuildOrchestratorService, + private readonly workspaceCacheService: WorkspaceCacheService, ) {} - public async validateBuildAndRunWorkspaceMigration( - builderArgs: WorkspaceMigrationOrchestratorBuildArgs, - ): Promise { + private async computeAllRelatedFlatEntityMaps({ + allFlatEntityOperationByMetadataName, + workspaceId, + }: ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs) { + const allMetadataNameToCompare = Object.keys( + allFlatEntityOperationByMetadataName, + ) as AllMetadataName[]; + const allDependencyMetadataName = allMetadataNameToCompare.flatMap( + (metadataName) => + Object.keys( + ALL_METADATA_REQUIRED_METADATA_FOR_VALIDATION[metadataName], + ) as AllMetadataName[], + ); + const allMetadataNameCacheToCompute = [ + ...new Set([...allMetadataNameToCompare, ...allDependencyMetadataName]), + ]; + const allFlatEntityMapsCacheKeysToCompute = + allMetadataNameCacheToCompute.map(getMetadataFlatEntityMapsKey); + + const allRelatedFlatEntityMaps = + await this.workspaceCacheService.getOrRecompute( + workspaceId, + allFlatEntityMapsCacheKeysToCompute, + ); + + const initialAccumulator = allDependencyMetadataName.reduce< + Partial + >( + (allFlatEntityMaps, metadataName) => ({ + ...allFlatEntityMaps, + [getMetadataFlatEntityMapsKey(metadataName)]: + createEmptyFlatEntityMaps(), + }), + {}, + ); + const dependencyAllFlatEntityMaps = allDependencyMetadataName.reduce( + (allFlatEntityMaps, metadataName) => { + const metadataFlatEntityMapsKey = + getMetadataFlatEntityMapsKey(metadataName); + + return { + ...allFlatEntityMaps, + [metadataFlatEntityMapsKey]: + allRelatedFlatEntityMaps[metadataFlatEntityMapsKey], + }; + }, + initialAccumulator, + ); + + return { + allRelatedFlatEntityMaps, + dependencyAllFlatEntityMaps, + }; + } + + private async computeFromToAllFlatEntityMapsAndBuildOptions({ + allFlatEntityOperationByMetadataName, + workspaceId, + }: ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs): Promise<{ + fromToAllFlatEntityMaps: WorkspaceMigrationOrchestratorBuildArgs['fromToAllFlatEntityMaps']; + inferDeletionFromMissingEntities: InferDeletionFromMissingEntities; + dependencyAllFlatEntityMaps: Partial; + }> { + const { allRelatedFlatEntityMaps, dependencyAllFlatEntityMaps } = + await this.computeAllRelatedFlatEntityMaps({ + allFlatEntityOperationByMetadataName, + workspaceId, + }); + + const fromToAllFlatEntityMaps: WorkspaceMigrationOrchestratorBuildArgs['fromToAllFlatEntityMaps'] = + {}; + const inferDeletionFromMissingEntities: InferDeletionFromMissingEntities = + {}; + const allMetadataNameToCompare = Object.keys( + allFlatEntityOperationByMetadataName, + ) as AllMetadataName[]; + + for (const metadataName of allMetadataNameToCompare) { + const tmp = allFlatEntityOperationByMetadataName[metadataName]; + + if (!isDefined(tmp)) { + throw new Error('Should never occurs'); + } + const { flatEntityToCreate, flatEntityToDelete, flatEntityToUpdate } = + tmp; + const flatEntityMapsKey = getMetadataFlatEntityMapsKey(metadataName); + const flatEntityMaps = allRelatedFlatEntityMaps[flatEntityMapsKey]; + + // @ts-expect-error Metadata flat entity maps cache key and metadataName colliding + fromToAllFlatEntityMaps[flatEntityMapsKey] = computeFlatEntityMapsFromTo({ + flatEntityMaps, + flatEntityToCreate, + flatEntityToDelete, + flatEntityToUpdate, + }); + + if (flatEntityToDelete.length > 0) { + inferDeletionFromMissingEntities[metadataName] = true; + } + } + + return { + fromToAllFlatEntityMaps, + inferDeletionFromMissingEntities, + dependencyAllFlatEntityMaps, + }; + } + + public async validateBuildAndRunWorkspaceMigration({ + allFlatEntityOperationByMetadataName: allFlatEntities, + workspaceId, + isSystemBuild = false, + }: ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs): Promise< + WorkspaceMigrationOrchestratorFailedResult | undefined + > { + const { + fromToAllFlatEntityMaps, + inferDeletionFromMissingEntities, + dependencyAllFlatEntityMaps, + } = await this.computeFromToAllFlatEntityMapsAndBuildOptions({ + allFlatEntityOperationByMetadataName: allFlatEntities, + workspaceId, + }); + const validateAndBuildResult = await this.workspaceMigrationBuildOrchestratorService - .buildWorkspaceMigration(builderArgs) + .buildWorkspaceMigration({ + buildOptions: { + isSystemBuild, + inferDeletionFromMissingEntities, + }, + fromToAllFlatEntityMaps, + workspaceId, + dependencyAllFlatEntityMaps, + }) .catch((error) => { this.logger.error(error); throw new WorkspaceMigrationV2Exception( diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/infer-deletion-from-missing-entities.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/infer-deletion-from-missing-entities.type.ts new file mode 100644 index 0000000000..7c241bfd3a --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/infer-deletion-from-missing-entities.type.ts @@ -0,0 +1,6 @@ +import { type AllMetadataName } from 'twenty-shared/metadata'; + +export type InferDeletionFromMissingEntities = + | true + | Partial> + | undefined; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-builder-options.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-builder-options.type.ts index dfee2c42e4..7c95e09952 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-builder-options.type.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-builder-options.type.ts @@ -1,8 +1,6 @@ -import { type AllMetadataName } from 'twenty-shared/metadata'; +import { type InferDeletionFromMissingEntities } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/infer-deletion-from-missing-entities.type'; export type WorkspaceMigrationBuilderOptions = { - inferDeletionFromMissingEntities?: - | true - | Partial>; + inferDeletionFromMissingEntities?: InferDeletionFromMissingEntities; isSystemBuild: boolean; }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module.ts index 5616ce2fd1..e16ca23c6a 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module.ts @@ -1,5 +1,6 @@ import { Module } from '@nestjs/common'; +import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module'; import { WorkspaceMigrationBuildOrchestratorService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service'; import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service'; import { WorkspaceMigrationBuilderV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-builder-v2.module'; @@ -9,6 +10,7 @@ import { WorkspaceMigrationRunnerV2Module } from 'src/engine/workspace-manager/w imports: [ WorkspaceMigrationBuilderV2Module, WorkspaceMigrationRunnerV2Module, + WorkspaceCacheModule, ], providers: [ WorkspaceMigrationValidateBuildAndRunService,