From c8f541618d4310a7665ad6ff1624d12e8d1275f9 Mon Sep 17 00:00:00 2001 From: Paul Rastoin <45004772+prastoin@users.noreply.github.com> Date: Fri, 5 Dec 2025 16:41:56 +0100 Subject: [PATCH] Refactor validate build and run for configuration to be less verbose and more reliable (#16343) # Introduction Refactored the api `validateBuildAndRunWorkspaceMigration` to be require less configuration but to infer required args dynamically depending on provided metadata maps to compare ## `inferDeletionFromMissingEntities` Is not dynamically computed avoiding any miss configuration issue and any missleading devxp ## Maps computation Making only one call to redis to build both dependency and to be compared entity maps. It does not matter to avoid passing a about to compared flat entity maps to could also be a depedency, it's handled directly in the builder setup optimistic cache logic Please note that the flat maps used for the service input transpilation might differ from the one that we will dynamically compute and inject in the builder. Leading to do 2 redis calls but also race condition prone validation error We prefer that this occurs at the builder rather than at the runner level as the pg instance is not cache and reflect the real state of a given workspace In a nutshell, there's a possible race condition between cache invalidation and computation in both service input transpilers and builder but we're totally ok with that --- .../application/application-sync.service.ts | 47 ++--- .../ai/ai-agent/agent.service.ts | 76 +++------ .../services/cron-trigger-v2.service.ts | 77 +++------ .../database-event-trigger-v2.service.ts | 90 +++------- .../services/field-metadata.service.ts | 108 ++++-------- ...lat-entity-to-create-delete-update.type.ts | 9 + .../compute-flat-entity-maps-from-to.util.ts | 21 ++- .../object-metadata.service.ts | 148 +++++++--------- .../services/role-target.service.ts | 32 +--- .../metadata-modules/role/role.service.ts | 46 ++--- .../services/route-trigger-v2.service.ts | 77 +++------ .../serverless-function-v2.service.ts | 68 +++----- .../services/view-field-v2.service.ts | 146 ++++------------ .../services/view-filter.service.ts | 143 ++++------------ .../view-group/services/view-group.service.ts | 146 +++++----------- .../view/services/view.service.ts | 108 ++++-------- ...eate-standard-flat-object-metadata.util.ts | 7 +- ...ce-migration-build-orchestrator.service.ts | 7 +- ...igration-validate-build-and-run-service.ts | 160 +++++++++++++++++- ...fer-deletion-from-missing-entities.type.ts | 6 + ...orkspace-migration-builder-options.type.ts | 6 +- .../workspace-migration-v2.module.ts | 2 + 22 files changed, 554 insertions(+), 976 deletions(-) create mode 100644 packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-to-create-delete-update.type.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/infer-deletion-from-missing-entities.type.ts 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,