From d640b93096320a5c230d3174028108cd37932839 Mon Sep 17 00:00:00 2001
From: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Date: Fri, 31 Oct 2025 17:20:51 +0100
Subject: [PATCH] Improve v2 and cache invalidation perfs (#15467)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
# Introduction
Log are debug logs of
`packages/twenty-server/test/integration/metadata/suites/object-metadata/create-delete-and-create-object-metadata-v2.integration-spec.ts`run
ten times in a row on clean db reset
## Next
Will improve cache computation to lighter invalidation.
RelationLoad `query` does not seem to work with typeorm so I'll continue
the custom integration i've started in
https://github.com/twentyhq/twenty/tree/optimize-cache-read-v2
## Integration tests duration
Significant test duration improvement too
### Before
### After
## What's next
- The legacy cache invalidation removal
- Factorizing redis calls in only one operation
## Autogenerated performance comparison ( including mutation refactor
too )
[Before](https://gist.github.com/prastoin/3c1e21fa9e3b3ce4b0716902ff4a2dd6)
[After](https://gist.github.com/prastoin/7bfddd14bfded2e4991a9378970a026d)
The optimized implementation shows **dramatic performance improvements**
across all metrics:
- ๐ **Cache Invalidation**: 156.3ms โ 76.8ms (**50.9% faster**)
- ๐ **Builder Operations**: 21.3ms โ 14.2ms (**33.3% faster**)
- โก **Consistency**: 16.4% more predictable performance
---
## 1. Overall Performance Summary
| Component | Before (avg) | After (avg) | Best (After) | Worst (After)
| Improvement |
|-----------|-------------|-------------|--------------|---------------|-------------|
| **Total Execution Time** | 180.2ms | 110.5ms | 52.3ms | 585.9ms |
**38.7% faster** โกโก |
| **Cache Invalidation** | 156.3ms | 76.8ms | 47.8ms | 285.1ms | **50.9%
faster** โกโกโก |
| **Transaction Execution** | 22.4ms | 22.1ms | 0.99ms | 314.2ms |
Similar |
| **Initial Cache Retrieval** | 0.81ms | 2.08ms | 0.21ms | 8.24ms |
Similar |
| **Entity Builder (total)** | 21.3ms | 14.2ms | 0.36ms | 42.5ms |
**33.3% faster** โก |
### Total Execution Time Distribution
#### Before (Legacy Sequential)
```
Time (ms) Count Percentage Visualization
< 150 18 16% โโโโ
150-180 32 29% โโโโโโโ
180-210 35 32% โโโโโโโโ
210-250 17 15% โโโโ
250-350 6 5% โ
> 350 2 2% โ
```
#### After (Optimized Parallel)
```
Time (ms) Count Percentage Visualization
< 70 28 31% โโโโโโโโ
70-100 31 34% โโโโโโโโโ
100-150 18 20% โโโโโ
150-200 8 9% โโ
200-300 4 4% โ
> 300 2 2% โ
```
---
## 2. Builder Performance Breakdown
### Field Metadata Builder
| Operation | Before (avg) | After (avg) | Improvement |
|-----------|-------------|-------------|-------------|
| Matrix computation | 3.5ms | 3.4ms | Similar |
| Creation validation | 15.2ms | 2.1ms | **86% faster** โกโกโก |
| Deletion validation | 0.08ms | 0.06ms | Similar |
| Update validation | 1.3ms | 0.09ms | **93% faster** โกโกโก |
| Entity processing | 18.6ms | 11.8ms | **37% faster** โก |
| **Total validateAndBuild** | **21.3ms** | **14.2ms** | **33% faster**
โก |
#### Performance Distribution
```
Before: โโโโโโโโโโโโ (wide spread, 15-28ms range)
After: โโโโโโโโโโโ (tight clustering, 10-18ms range)
```
## 4. Cache Invalidation Performance Breakdown
### Cache Invalidation Summary
| Metric | Before (Legacy) | After (Optimized) | Improvement |
|--------|-----------------|-------------------|-------------|
| **Best Time** | 131.965ms | 47.833ms | **63.7% faster** โกโกโก |
| **10th Percentile** | 140.2ms | 51.7ms | **63.1% faster** โกโกโก |
| **25th Percentile** | 146.1ms | 54.4ms | **62.7% faster** โกโกโก |
| **Median (50th)** | 155.1ms | 63.4ms | **59.1% faster** โกโกโก |
| **Average** | 156.3ms | 76.8ms | **50.9% faster** โกโกโก |
| **75th Percentile** | 160.2ms | 90.2ms | **43.7% faster** โกโก |
| **90th Percentile** | 191.7ms | 100.2ms | **47.7% faster** โกโก |
| **95th Percentile** | 235.6ms | 110.3ms | **53.2% faster** โกโกโก |
| **99th Percentile** | 278.2ms | 224.9ms | **19.1% faster** โก |
| **Worst Time** | 383.914ms | 285.102ms | **25.7% faster** โก |
### Cache Invalidation Time Distribution
#### Before (Legacy Sequential)
```
Time (ms) Count Percentage Visualization
130-140 3 3% โ
140-150 15 14% โโโโ
150-160 48 44% โโโโโโโโโโโ
160-180 31 28% โโโโโโโ
180-220 8 7% โโ
220-280 3 3% โ
> 280 2 2% โ
```
#### After (Optimized Parallel + Intersection)
```
Time (ms) Count Percentage Visualization
< 50 3 3% โ
50-60 27 25% โโโโโโโ
60-70 25 23% โโโโโโ
70-90 25 23% โโโโโโ
90-100 15 14% โโโโ
100-120 8 7% โโ
120-150 3 3% โ
> 150 4 4% โ
```
## 6. Performance Consistency Analysis
### Standard Deviation & Variance
| Metric | Before | After | Improvement |
|--------|--------|-------|-------------|
| **Cache Invalidation Std Dev** | 42.1ms | 35.2ms | **16.4% more
consistent** โก |
| **Total Execution Std Dev** | 68.3ms | 89.1ms | Slightly more variable
|
| **Coefficient of Variation (Cache)** | 26.9% | 45.8% | More variance |
| **Outliers (> 2ฯ)** | 5 cases | 3 cases | **40% fewer outliers** โก |
---
---
.../application/application-sync.service.ts | 12 +-
...ace-flat-cron-trigger-map-cache.service.ts | 16 +-
...atabase-event-trigger-map-cache.service.ts | 39 ++--
...metadata-many-to-one-relations.constant.ts | 2 +-
...ate-empty-all-flat-entity-maps.constant.ts | 19 ++
...create-empty-flat-entity-maps.constant.ts} | 11 +-
.../empty-all-flat-entity-maps.constant.ts | 18 --
...y-or-all-flat-entity-maps-cache.service.ts | 41 ++--
.../metadata-many-to-one-join-column.type.ts | 6 +
...many-to-one-related-metadata-names.type.ts | 3 +-
.../get-sub-flat-entity-maps-or-throw.util.ts | 4 +-
...-to-flat-field-metadatas-to-create.spec.ts | 4 +-
...e-flat-field-metadata-map-cache.service.ts | 139 +++++++++----
...n-field-input-transpilations-error.util.ts | 2 +-
...ph-or-relation-flat-field-metadata.util.ts | 2 +-
.../workspace-flat-index-map-cache.service.ts | 17 +-
.../flat-object-metadata-maps.mock.ts | 4 +-
...-flat-object-metadata-map-cache.service.ts | 97 ++++++---
...space-flat-view-field-map-cache.service.ts | 16 +-
...pace-flat-view-filter-map-cache.service.ts | 16 +-
...space-flat-view-group-map-cache.service.ts | 16 +-
.../flat-view/flat-view.module.ts | 12 +-
.../workspace-flat-view-map-cache.service.ts | 86 +++++---
...ce-flat-route-trigger-map-cache.service.ts | 16 +-
...t-serverless-function-map-cache.service.ts | 39 ++--
.../regroup-entities-by-related-entity-id.ts | 39 ++++
.../workspace-flat-map-cache.module.ts | 4 +-
...ty-orchestrator-actions-report.constant.ts | 22 ++-
...ty-orchestrator-failure-report.constant.ts | 20 +-
...ce-migration-build-orchestrator.service.ts | 10 +-
...ject-and-create-field-actions.util.spec.ts | 14 +-
...ject-and-delete-field-actions.util.spec.ts | 12 +-
...ity-maps-through-mutation-or-throw.util.ts | 54 +++++
...ity-maps-through-mutation-or-throw.util.ts | 60 ++++++
...-created-updated-matrix-dispatcher.util.ts | 28 ++-
...ity-maps-through-mutation-or-throw.util.ts | 28 +++
...-v2-cron-trigger-action-builder.service.ts | 19 +-
...e-event-trigger-actions-builder.service.ts | 19 +-
...ration-v2-field-actions-builder.service.ts | 75 +++----
...ration-v2-index-actions-builder.service.ts | 98 +++++----
...ation-v2-object-actions-builder.service.ts | 19 +-
...2-route-trigger-actions-builder.service.ts | 19 +-
...erless-function-actions-builder.service.ts | 19 +-
...n-v2-view-field-actions-builder.service.ts | 110 +++++------
...-v2-view-filter-actions-builder.service.ts | 82 ++++----
...n-v2-view-group-actions-builder.service.ts | 108 +++++-----
...gration-v2-view-actions-builder.service.ts | 187 +++++++++---------
...ace-entity-migration-builder-v2.service.ts | 68 ++++---
.../types/flat-entity-validation-args.type.ts | 2 +-
.../flat-entity-validation-result.type.ts | 2 -
.../flat-cron-trigger-validator.service.ts | 13 +-
...atabase-event-trigger-validator.service.ts | 16 +-
.../flat-field-metadata-validator.service.ts | 28 +--
.../flat-index-metadata-validator.service.ts | 9 +-
.../flat-object-metadata-validator.service.ts | 8 +-
.../flat-route-trigger-validator.service.ts | 10 +-
.../flat-view-field-validator.service.ts | 21 +-
.../flat-view-filter-validator.service.ts | 14 +-
.../flat-view-group-validator.service.ts | 16 +-
.../services/flat-view-validator.service.ts | 6 +-
.../workspace-migration-runner-v2.service.ts | 70 ++++---
61 files changed, 1120 insertions(+), 846 deletions(-)
create mode 100644 packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-all-flat-entity-maps.constant.ts
rename packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/{empty-flat-entity-maps.constant.ts => create-empty-flat-entity-maps.constant.ts} (51%)
delete mode 100644 packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/empty-all-flat-entity-maps.constant.ts
create mode 100644 packages/twenty-server/src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-join-column.type.ts
create mode 100644 packages/twenty-server/src/engine/workspace-flat-map-cache/utils/regroup-entities-by-related-entity-id.ts
create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts
create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts
create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util.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 e10ed2c3a8..a8a2e9b4c5 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
@@ -2,8 +2,8 @@ import { Injectable, Logger } from '@nestjs/common';
import { parse } from 'path';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME, AllMetadataName } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
import {
@@ -18,12 +18,13 @@ import {
ServerlessFunctionTriggerManifest,
} from 'src/engine/core-modules/application/types/application.types';
import { ApplicationVariableEntityService } from 'src/engine/core-modules/applicationVariable/application-variable.service';
+import { Sources } from 'src/engine/core-modules/file-storage/types/source.type';
import { CronTriggerV2Service } from 'src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service';
import { FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { DatabaseEventTriggerV2Service } from 'src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service';
import { FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+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';
@@ -34,7 +35,6 @@ import { ServerlessFunctionLayerService } from 'src/engine/metadata-modules/serv
import { ServerlessFunctionV2Service } from 'src/engine/metadata-modules/serverless-function/services/serverless-function-v2.service';
import { FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service';
-import { Sources } from 'src/engine/core-modules/file-storage/types/source.type';
@Injectable()
export class ApplicationSyncService {
@@ -851,15 +851,15 @@ export class ApplicationSyncService {
fromToAllFlatEntityMaps: {
flatObjectMetadataMaps: {
from: fromFlatObjectMetadataMaps,
- to: EMPTY_FLAT_ENTITY_MAPS,
+ to: createEmptyFlatEntityMaps(),
},
flatIndexMaps: {
from: fromFlatIndexMetadataMaps,
- to: EMPTY_FLAT_ENTITY_MAPS,
+ to: createEmptyFlatEntityMaps(),
},
flatFieldMetadataMaps: {
from: fromFlatFieldMetadataMaps,
- to: EMPTY_FLAT_ENTITY_MAPS,
+ to: createEmptyFlatEntityMaps(),
},
},
workspaceId,
diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/workspace-flat-cron-trigger-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/workspace-flat-cron-trigger-map-cache.service.ts
index 041edc4f8a..3cdd4418f4 100644
--- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/workspace-flat-cron-trigger-map-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/workspace-flat-cron-trigger-map-cache.service.ts
@@ -12,11 +12,11 @@ import {
CronTriggerEntity,
} from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity';
import { FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/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 { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@Injectable()
@WorkspaceFlatMapCache('flatCronTriggerMaps')
@@ -43,7 +43,9 @@ export class WorkspaceFlatCronTriggerMapCacheService extends WorkspaceFlatMapCac
},
});
- return cronTriggers.reduce((flatCronTriggerMaps, cronTriggerEntity) => {
+ const flatCronTriggerMaps = createEmptyFlatEntityMaps();
+
+ for (const cronTriggerEntity of cronTriggers) {
const flatCronTrigger = {
...removePropertiesFromRecord(cronTriggerEntity, [
...CRON_TRIGGER_ENTITY_RELATION_PROPERTIES,
@@ -52,10 +54,12 @@ export class WorkspaceFlatCronTriggerMapCacheService extends WorkspaceFlatMapCac
cronTriggerEntity.universalIdentifier ?? cronTriggerEntity.id,
} satisfies FlatCronTrigger;
- return addFlatEntityToFlatEntityMapsOrThrow({
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
flatEntity: flatCronTrigger,
- flatEntityMaps: flatCronTriggerMaps,
+ flatEntityMapsToMutate: flatCronTriggerMaps,
});
- }, EMPTY_FLAT_ENTITY_MAPS);
+ }
+
+ return flatCronTriggerMaps;
}
}
diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/workspace-flat-database-event-trigger-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/workspace-flat-database-event-trigger-map-cache.service.ts
index a1640c09f6..1182277e3c 100644
--- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/workspace-flat-database-event-trigger-map-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/workspace-flat-database-event-trigger-map-cache.service.ts
@@ -12,11 +12,11 @@ import {
DatabaseEventTriggerEntity,
} from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity';
import { FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/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 { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@Injectable()
@WorkspaceFlatMapCache('flatDatabaseEventTriggerMaps')
@@ -44,23 +44,24 @@ export class WorkspaceFlatDatabaseEventTriggerMapCacheService extends WorkspaceF
},
});
- return databaseEventTriggers.reduce(
- (flatDatabaseEventTriggerMaps, databaseEventTriggerEntity) => {
- const flatDatabaseEventTrigger = {
- ...removePropertiesFromRecord(databaseEventTriggerEntity, [
- ...DATABASE_EVENT_TRIGGER_ENTITY_RELATION_PROPERTIES,
- ]),
- universalIdentifier:
- databaseEventTriggerEntity.universalIdentifier ??
- databaseEventTriggerEntity.id,
- } satisfies FlatDatabaseEventTrigger;
+ const flatDatabaseEventTriggerMaps = createEmptyFlatEntityMaps();
- return addFlatEntityToFlatEntityMapsOrThrow({
- flatEntity: flatDatabaseEventTrigger,
- flatEntityMaps: flatDatabaseEventTriggerMaps,
- });
- },
- EMPTY_FLAT_ENTITY_MAPS,
- );
+ for (const databaseEventTriggerEntity of databaseEventTriggers) {
+ const flatDatabaseEventTrigger = {
+ ...removePropertiesFromRecord(databaseEventTriggerEntity, [
+ ...DATABASE_EVENT_TRIGGER_ENTITY_RELATION_PROPERTIES,
+ ]),
+ universalIdentifier:
+ databaseEventTriggerEntity.universalIdentifier ??
+ databaseEventTriggerEntity.id,
+ } satisfies FlatDatabaseEventTrigger;
+
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: flatDatabaseEventTrigger,
+ flatEntityMapsToMutate: flatDatabaseEventTriggerMaps,
+ });
+ }
+
+ return flatDatabaseEventTriggerMaps;
}
}
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-many-to-one-relations.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-many-to-one-relations.constant.ts
index 6ec79a3658..67617a4f69 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-many-to-one-relations.constant.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-many-to-one-relations.constant.ts
@@ -1,5 +1,5 @@
-import { type ExtractPropertiesThatEndsWithId } from 'twenty-shared/types';
import { type AllMetadataName } from 'twenty-shared/metadata';
+import { type ExtractPropertiesThatEndsWithId } from 'twenty-shared/types';
import { type MetadataEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-entity.type';
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-all-flat-entity-maps.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-all-flat-entity-maps.constant.ts
new file mode 100644
index 0000000000..233b64772c
--- /dev/null
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-all-flat-entity-maps.constant.ts
@@ -0,0 +1,19 @@
+import {
+ ALL_METADATA_NAME,
+ type AllMetadataName,
+} from 'twenty-shared/metadata';
+
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
+import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
+import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
+
+export const createEmptyAllFlatEntityMaps = (): AllFlatEntityMaps =>
+ (
+ Object.keys(ALL_METADATA_NAME) as AllMetadataName[]
+ ).reduce(
+ (acc, metadataName) => ({
+ ...acc,
+ [getMetadataFlatEntityMapsKey(metadataName)]: createEmptyFlatEntityMaps(),
+ }),
+ {} as AllFlatEntityMaps,
+ );
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant.ts
similarity index 51%
rename from packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant.ts
rename to packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant.ts
index eaa7bf1bd5..9cff142b9d 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant.ts
@@ -1,8 +1,9 @@
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { type FlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
-export const EMPTY_FLAT_ENTITY_MAPS = {
- byId: {},
- idByUniversalIdentifier: {},
- universalIdentifiersByApplicationId: {},
-} as const satisfies FlatEntityMaps;
+export const createEmptyFlatEntityMaps = () =>
+ ({
+ byId: {},
+ idByUniversalIdentifier: {},
+ universalIdentifiersByApplicationId: {},
+ }) as const satisfies FlatEntityMaps;
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/empty-all-flat-entity-maps.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/empty-all-flat-entity-maps.constant.ts
deleted file mode 100644
index a75246485c..0000000000
--- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/empty-all-flat-entity-maps.constant.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import {
- ALL_METADATA_NAME,
- type AllMetadataName,
-} from 'twenty-shared/metadata';
-
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
-import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
-import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
-
-export const EMPTY_ALL_FLAT_ENTITY_MAPS = (
- Object.keys(ALL_METADATA_NAME) as AllMetadataName[]
-).reduce(
- (acc, metadataName) => ({
- ...acc,
- [getMetadataFlatEntityMapsKey(metadataName)]: EMPTY_FLAT_ENTITY_MAPS,
- }),
- {} as AllFlatEntityMaps,
-);
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service.ts
index b4fecb3616..bb89f2d72e 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service.ts
@@ -33,23 +33,32 @@ export class WorkspaceManyOrAllFlatEntityMapsCacheService {
? flatMapsKeys
: ALL_FLAT_ENTITY_MAPS_PROPERTIES;
- for (const flatMapKey of keysToProcess) {
- try {
- const service = this.cacheRegistry.getCacheServiceOrThrow(
- flatMapKey as K[number],
- );
+ const results = await Promise.allSettled(
+ keysToProcess.map(async (flatMapKey) => {
+ try {
+ const service = this.cacheRegistry.getCacheServiceOrThrow(
+ flatMapKey as K[number],
+ );
- await action({
- flatMapKey: flatMapKey,
- service,
- });
- } catch (error) {
- this.logger.error(
- `Failed to run action on flat entity maps of ${flatMapKey}`,
- error,
- );
- throw error;
- }
+ return await action({
+ flatMapKey: flatMapKey,
+ service,
+ });
+ } catch (error) {
+ this.logger.error(
+ `Failed to run action on flat entity maps of ${flatMapKey}`,
+ error,
+ );
+ throw error;
+ }
+ }),
+ );
+
+ const failures = results.filter((result) => result.status === 'rejected');
+
+ if (failures.length > 0) {
+ this.logger.error(`${failures.length} operations failed`);
+ throw new Error(`Failed to process ${failures.length} flat entity maps`);
}
}
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-join-column.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-join-column.type.ts
new file mode 100644
index 0000000000..77025ccdc3
--- /dev/null
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-join-column.type.ts
@@ -0,0 +1,6 @@
+import { type AllMetadataName } from 'twenty-shared/metadata';
+
+import { type ALL_METADATA_RELATED_METADATA_BY_FOREIGN_KEY } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-many-to-one-relations.constant';
+
+export type MetadataManyToOneJoinColumn =
+ keyof (typeof ALL_METADATA_RELATED_METADATA_BY_FOREIGN_KEY)[T];
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-related-metadata-names.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-related-metadata-names.type.ts
index efef68a37c..75c45a1688 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-related-metadata-names.type.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-related-metadata-names.type.ts
@@ -1,9 +1,10 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type ALL_METADATA_RELATED_METADATA_BY_FOREIGN_KEY } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-many-to-one-relations.constant';
+import { type MetadataManyToOneJoinColumn } from 'src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-join-column.type';
export type MetadataManyToOneRelatedMetadataNames =
Extract<
- (typeof ALL_METADATA_RELATED_METADATA_BY_FOREIGN_KEY)[T][keyof (typeof ALL_METADATA_RELATED_METADATA_BY_FOREIGN_KEY)[T]],
+ (typeof ALL_METADATA_RELATED_METADATA_BY_FOREIGN_KEY)[T][MetadataManyToOneJoinColumn],
AllMetadataName
>;
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util.ts
index abd615a90d..61427588d6 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util.ts
@@ -1,4 +1,4 @@
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { type FlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
@@ -21,5 +21,5 @@ export const getSubFlatEntityMapsOrThrow = ({
flatEntity,
flatEntityMaps: acc,
});
- }, EMPTY_FLAT_ENTITY_MAPS);
+ }, createEmptyFlatEntityMaps());
};
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts
index 9632fb11bf..d02761852e 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts
@@ -5,7 +5,7 @@ import { FieldMetadataType } from 'twenty-shared/types';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
import {
fromCreateFieldInputToFlatFieldMetadatasToCreate,
@@ -25,7 +25,7 @@ const flatObjectMetadataMaps = [
flatEntity: flatObjectMetadata,
flatEntityMaps: flatObjectMetadataMaps,
});
-}, EMPTY_FLAT_ENTITY_MAPS);
+}, createEmptyFlatEntityMaps());
type TestCase = EachTestingContext<{
input: FromCreateFieldInputToFlatObjectMetadataArgs;
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/services/workspace-flat-field-metadata-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/services/workspace-flat-field-metadata-map-cache.service.ts
index 40c592fa37..7408bfdd80 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/services/workspace-flat-field-metadata-map-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/services/workspace-flat-field-metadata-map-cache.service.ts
@@ -7,13 +7,18 @@ import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decora
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/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 { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { fromFieldMetadataEntityToFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/from-field-metadata-entity-to-flat-field-metadata.util';
+import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
+import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
+import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
+import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
+import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-flat-map-cache/utils/regroup-entities-by-related-entity-id';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@Injectable()
@WorkspaceFlatMapCache('flatFieldMetadataMaps')
@@ -25,6 +30,14 @@ export class WorkspaceFlatFieldMetadataMapCacheService extends WorkspaceFlatMapC
cacheStorageService: CacheStorageService,
@InjectRepository(FieldMetadataEntity)
private readonly fieldMetadataRepository: Repository,
+ @InjectRepository(ViewFieldEntity)
+ private readonly viewFieldRepository: Repository,
+ @InjectRepository(ViewFilterEntity)
+ private readonly viewFilterRepository: Repository,
+ @InjectRepository(ViewGroupEntity)
+ private readonly viewGroupRepository: Repository,
+ @InjectRepository(ViewEntity)
+ private readonly viewRepository: Repository,
) {
super(cacheStorageService);
}
@@ -34,48 +47,88 @@ export class WorkspaceFlatFieldMetadataMapCacheService extends WorkspaceFlatMapC
}: {
workspaceId: string;
}): Promise> {
- const fieldMetadatas = await this.fieldMetadataRepository.find({
- where: {
- workspaceId,
- },
- select: {
- viewFields: {
- id: true,
- },
- viewFilters: {
- id: true,
- },
- viewGroups: {
- id: true,
- },
- kanbanAggregateOperationViews: {
- id: true,
- },
- calendarViews: {
- id: true,
- },
- },
- withDeleted: true,
- relations: [
- 'viewFields',
- 'viewFilters',
- 'viewGroups',
- 'kanbanAggregateOperationViews',
- 'calendarViews',
- ],
- });
+ const [fieldMetadatas, viewFields, viewFilters, viewGroups, views] =
+ await Promise.all([
+ this.fieldMetadataRepository.find({
+ where: { workspaceId },
+ withDeleted: true,
+ }),
+ this.viewFieldRepository.find({
+ where: { workspaceId },
+ select: ['id', 'fieldMetadataId'],
+ withDeleted: true,
+ }),
+ this.viewFilterRepository.find({
+ where: { workspaceId },
+ select: ['id', 'fieldMetadataId'],
+ withDeleted: true,
+ }),
+ this.viewGroupRepository.find({
+ where: { workspaceId },
+ select: ['id', 'fieldMetadataId'],
+ withDeleted: true,
+ }),
+ this.viewRepository.find({
+ where: { workspaceId },
+ select: [
+ 'id',
+ 'kanbanAggregateOperationFieldMetadataId',
+ 'calendarFieldMetadataId',
+ ],
+ withDeleted: true,
+ }),
+ ]);
- return fieldMetadatas.reduce(
- (flatFieldMetadataMaps, fieldMetadataEntity) => {
- const flatFieldMetadata =
- fromFieldMetadataEntityToFlatFieldMetadata(fieldMetadataEntity);
+ const [
+ viewFieldsByFieldId,
+ viewFiltersByFieldId,
+ viewGroupsByFieldId,
+ calendarViewsByFieldId,
+ kanbanViewsByFieldId,
+ ] = (
+ [
+ {
+ entities: viewFields,
+ foreignKey: 'fieldMetadataId',
+ },
+ {
+ entities: viewFilters,
+ foreignKey: 'fieldMetadataId',
+ },
+ {
+ entities: viewGroups,
+ foreignKey: 'fieldMetadataId',
+ },
+ {
+ entities: views,
+ foreignKey: 'calendarFieldMetadataId',
+ },
+ {
+ entities: views,
+ foreignKey: 'kanbanAggregateOperationFieldMetadataId',
+ },
+ ] as const
+ ).map(regroupEntitiesByRelatedEntityId);
- return addFlatEntityToFlatEntityMapsOrThrow({
- flatEntity: flatFieldMetadata,
- flatEntityMaps: flatFieldMetadataMaps,
- });
- },
- EMPTY_FLAT_ENTITY_MAPS,
- );
+ const flatFieldMetadataMaps = createEmptyFlatEntityMaps();
+
+ for (const fieldMetadataEntity of fieldMetadatas) {
+ const flatFieldMetadata = fromFieldMetadataEntityToFlatFieldMetadata({
+ ...fieldMetadataEntity,
+ viewFields: viewFieldsByFieldId.get(fieldMetadataEntity.id) || [],
+ viewFilters: viewFiltersByFieldId.get(fieldMetadataEntity.id) || [],
+ viewGroups: viewGroupsByFieldId.get(fieldMetadataEntity.id) || [],
+ kanbanAggregateOperationViews:
+ kanbanViewsByFieldId.get(fieldMetadataEntity.id) || [],
+ calendarViews: calendarViewsByFieldId.get(fieldMetadataEntity.id) || [],
+ } as FieldMetadataEntity);
+
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: flatFieldMetadata,
+ flatEntityMapsToMutate: flatFieldMetadataMaps,
+ });
+ }
+
+ return flatFieldMetadataMaps;
}
}
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/throw-on-field-input-transpilations-error.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/throw-on-field-input-transpilations-error.util.ts
index d5c9773e07..b7840bd942 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/throw-on-field-input-transpilations-error.util.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/throw-on-field-input-transpilations-error.util.ts
@@ -25,7 +25,7 @@ export const throwOnFieldInputTranspilationsError: ThrowOnFieldInputTranspilatio
throw new WorkspaceMigrationBuilderExceptionV2(
{
report: {
- ...EMPTY_ORCHESTRATOR_FAILURE_REPORT,
+ ...EMPTY_ORCHESTRATOR_FAILURE_REPORT(),
objectMetadata: [
{
errors: failedInputTranspilationErrors,
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-or-relation-flat-field-metadata.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-or-relation-flat-field-metadata.util.ts
index 07842276d4..579da4a010 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-or-relation-flat-field-metadata.util.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-or-relation-flat-field-metadata.util.ts
@@ -7,7 +7,7 @@ import { type FlatFieldMetadataTypeValidationArgs } from 'src/engine/metadata-mo
import { type FlatFieldMetadataValidationError } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-validation-error.type';
export const validateMorphOrRelationFlatFieldMetadata = async ({
- dependencyOptimisticFlatEntityMaps: { flatObjectMetadataMaps },
+ mutableDependencyOptimisticFlatEntityMaps: { flatObjectMetadataMaps },
flatEntityToValidate: flatFieldMetadataToValidate,
optimisticFlatEntityMaps: optimisticFlatFieldMetadataMaps,
remainingFlatEntityMapsToValidate,
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-index-metadata/services/workspace-flat-index-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/flat-index-metadata/services/workspace-flat-index-map-cache.service.ts
index cbb35b170e..51e397010f 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-index-metadata/services/workspace-flat-index-map-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-index-metadata/services/workspace-flat-index-map-cache.service.ts
@@ -6,14 +6,14 @@ import { Repository } from 'typeorm';
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/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 { FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { fromIndexMetadataEntityToFlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/utils/from-index-metadata-entity-to-flat-index-metadata.util';
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@Injectable()
@WorkspaceFlatMapCache('flatIndexMaps')
@@ -39,6 +39,7 @@ export class WorkspaceFlatIndexMapCacheService extends WorkspaceFlatMapCacheServ
workspaceId,
},
withDeleted: true,
+ relationLoadStrategy: 'join',
select: {
// Note: We need all IndexFieldMetadataEntity in order to build a FlatIndex
indexFieldMetadatas: true,
@@ -46,13 +47,17 @@ export class WorkspaceFlatIndexMapCacheService extends WorkspaceFlatMapCacheServ
relations: ['indexFieldMetadatas'],
});
- return indexes.reduce((flatIndexMaps, indexEntity) => {
+ const flatIndexMaps = createEmptyFlatEntityMaps();
+
+ for (const indexEntity of indexes) {
const flatIndex = fromIndexMetadataEntityToFlatIndexMetadata(indexEntity);
- return addFlatEntityToFlatEntityMapsOrThrow({
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
flatEntity: flatIndex,
- flatEntityMaps: flatIndexMaps,
+ flatEntityMapsToMutate: flatIndexMaps,
});
- }, EMPTY_FLAT_ENTITY_MAPS);
+ }
+
+ return flatIndexMaps;
}
}
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/flat-object-metadata-maps.mock.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/flat-object-metadata-maps.mock.ts
index 22620f2cff..289dcaeb8e 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/flat-object-metadata-maps.mock.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/__mocks__/flat-object-metadata-maps.mock.ts
@@ -1,4 +1,4 @@
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
import { ALL_FLAT_OBJECT_METADATA_MOCKS } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/all-flat-object-metadatas.mock';
@@ -10,5 +10,5 @@ export const FLAT_OBJECT_METADATA_MAPS_MOCKS = [
flatEntity: flatObjectMetadata,
flatEntityMaps: flatObjectMaps,
}),
- EMPTY_FLAT_ENTITY_MAPS,
+ createEmptyFlatEntityMaps(),
);
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/services/workspace-flat-object-metadata-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/services/workspace-flat-object-metadata-map-cache.service.ts
index 98353da4c9..bc2f8da379 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/services/workspace-flat-object-metadata-map-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/services/workspace-flat-object-metadata-map-cache.service.ts
@@ -6,14 +6,18 @@ import { Repository } from 'typeorm';
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/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 { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { fromObjectMetadataEntityToFlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-object-metadata-entity-to-flat-object-metadata.util';
+import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
+import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
+import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-flat-map-cache/utils/regroup-entities-by-related-entity-id';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@Injectable()
@WorkspaceFlatMapCache('flatObjectMetadataMaps')
@@ -26,6 +30,12 @@ export class WorkspaceFlatObjectMetadataMapCacheService extends WorkspaceFlatMap
@InjectRepository(ObjectMetadataEntity)
private readonly objectMetadataRepository: Repository,
+ @InjectRepository(FieldMetadataEntity)
+ private readonly fieldMetadataRepository: Repository,
+ @InjectRepository(IndexMetadataEntity)
+ private readonly indexMetadataRepository: Repository,
+ @InjectRepository(ViewEntity)
+ private readonly viewRepository: Repository,
) {
super(cacheStorageService);
}
@@ -35,36 +45,61 @@ export class WorkspaceFlatObjectMetadataMapCacheService extends WorkspaceFlatMap
}: {
workspaceId: string;
}): Promise> {
- const objectMetadatas = await this.objectMetadataRepository.find({
- where: {
- workspaceId,
- },
- withDeleted: true,
- select: {
- fields: {
- id: true,
- },
- indexMetadatas: {
- id: true,
- },
- views: {
- id: true,
- },
- },
- relations: ['fields', 'indexMetadatas', 'views'],
- });
+ const [objectMetadatas, fields, indexMetadatas, views] = await Promise.all([
+ this.objectMetadataRepository.find({
+ where: { workspaceId },
+ withDeleted: true,
+ }),
+ this.fieldMetadataRepository.find({
+ where: { workspaceId },
+ select: ['id', 'objectMetadataId'],
+ withDeleted: true,
+ }),
+ this.indexMetadataRepository.find({
+ where: { workspaceId },
+ select: ['id', 'objectMetadataId'],
+ withDeleted: true,
+ }),
+ this.viewRepository.find({
+ where: { workspaceId },
+ select: ['id', 'objectMetadataId'],
+ withDeleted: true,
+ }),
+ ]);
- return objectMetadatas.reduce(
- (flatObjectMetadataMaps, objectMetadataEntity) => {
- const flatObjectMetadata =
- fromObjectMetadataEntityToFlatObjectMetadata(objectMetadataEntity);
+ const [fieldsByObjectId, indexesByObjectId, viewsByObjectId] = (
+ [
+ {
+ entities: fields,
+ foreignKey: 'objectMetadataId',
+ },
+ {
+ entities: indexMetadatas,
+ foreignKey: 'objectMetadataId',
+ },
+ {
+ entities: views,
+ foreignKey: 'objectMetadataId',
+ },
+ ] as const
+ ).map(regroupEntitiesByRelatedEntityId);
- return addFlatEntityToFlatEntityMapsOrThrow({
- flatEntity: flatObjectMetadata,
- flatEntityMaps: flatObjectMetadataMaps,
- });
- },
- EMPTY_FLAT_ENTITY_MAPS,
- );
+ const flatObjectMetadataMaps = createEmptyFlatEntityMaps();
+
+ for (const objectMetadataEntity of objectMetadatas) {
+ const flatObjectMetadata = fromObjectMetadataEntityToFlatObjectMetadata({
+ ...objectMetadataEntity,
+ fields: fieldsByObjectId.get(objectMetadataEntity.id) || [],
+ indexMetadatas: indexesByObjectId.get(objectMetadataEntity.id) || [],
+ views: viewsByObjectId.get(objectMetadataEntity.id) || [],
+ } as ObjectMetadataEntity);
+
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: flatObjectMetadata,
+ flatEntityMapsToMutate: flatObjectMetadataMaps,
+ });
+ }
+
+ return flatObjectMetadataMaps;
}
}
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-field/services/workspace-flat-view-field-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-field/services/workspace-flat-view-field-map-cache.service.ts
index 35b40e6187..9d52493455 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-view-field/services/workspace-flat-view-field-map-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-field/services/workspace-flat-view-field-map-cache.service.ts
@@ -6,13 +6,13 @@ import { Repository } from 'typeorm';
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
-import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FlatViewFieldMaps } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field-maps.type';
import { fromViewFieldEntityToFlatViewField } from 'src/engine/metadata-modules/flat-view-field/utils/from-view-field-entity-to-flat-view-field.util';
import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
import { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@Injectable()
@WorkspaceFlatMapCache('flatViewFieldMaps')
@@ -38,13 +38,17 @@ export class WorkspaceFlatViewFieldMapCacheService extends WorkspaceFlatMapCache
withDeleted: true,
});
- return existingViewFields.reduce((flatViewFieldMaps, viewFieldEntity) => {
+ const flatViewFieldMaps = createEmptyFlatEntityMaps();
+
+ for (const viewFieldEntity of existingViewFields) {
const flatViewField = fromViewFieldEntityToFlatViewField(viewFieldEntity);
- return addFlatEntityToFlatEntityMapsOrThrow({
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
flatEntity: flatViewField,
- flatEntityMaps: flatViewFieldMaps,
+ flatEntityMapsToMutate: flatViewFieldMaps,
});
- }, EMPTY_FLAT_ENTITY_MAPS);
+ }
+
+ return flatViewFieldMaps;
}
}
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/services/workspace-flat-view-filter-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/services/workspace-flat-view-filter-map-cache.service.ts
index 2069d0ff12..3639f69310 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/services/workspace-flat-view-filter-map-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/services/workspace-flat-view-filter-map-cache.service.ts
@@ -6,13 +6,13 @@ import { Repository } from 'typeorm';
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
-import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { type FlatViewFilterMaps } from 'src/engine/metadata-modules/flat-view-filter/types/flat-view-filter-maps.type';
import { fromViewFilterEntityToFlatViewFilter } from 'src/engine/metadata-modules/flat-view-filter/utils/from-view-filter-entity-to-flat-view-filter.util';
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
import { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@Injectable()
@WorkspaceFlatMapCache('flatViewFilterMaps')
@@ -38,14 +38,18 @@ export class WorkspaceFlatViewFilterMapCacheService extends WorkspaceFlatMapCach
withDeleted: true,
});
- return viewFilters.reduce((flatViewFilterMaps, viewFilterEntity) => {
+ const flatViewFilterMaps = createEmptyFlatEntityMaps();
+
+ for (const viewFilterEntity of viewFilters) {
const flatViewFilter =
fromViewFilterEntityToFlatViewFilter(viewFilterEntity);
- return addFlatEntityToFlatEntityMapsOrThrow({
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
flatEntity: flatViewFilter,
- flatEntityMaps: flatViewFilterMaps,
+ flatEntityMapsToMutate: flatViewFilterMaps,
});
- }, EMPTY_FLAT_ENTITY_MAPS);
+ }
+
+ return flatViewFilterMaps;
}
}
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/services/workspace-flat-view-group-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/services/workspace-flat-view-group-map-cache.service.ts
index 1b6a81e942..838c5770de 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/services/workspace-flat-view-group-map-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/services/workspace-flat-view-group-map-cache.service.ts
@@ -6,13 +6,13 @@ import { Repository } from 'typeorm';
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
-import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FlatViewGroupMaps } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group-maps.type';
import { fromViewGroupEntityToFlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/utils/from-view-group-entity-to-flat-view-group.util';
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
import { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@Injectable()
@WorkspaceFlatMapCache('flatViewGroupMaps')
@@ -38,13 +38,17 @@ export class WorkspaceFlatViewGroupMapCacheService extends WorkspaceFlatMapCache
withDeleted: true,
});
- return existingViewGroups.reduce((flatViewGroupMaps, viewGroupEntity) => {
+ const flatViewGroupMaps = createEmptyFlatEntityMaps();
+
+ for (const viewGroupEntity of existingViewGroups) {
const flatViewGroup = fromViewGroupEntityToFlatViewGroup(viewGroupEntity);
- return addFlatEntityToFlatEntityMapsOrThrow({
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
flatEntity: flatViewGroup,
- flatEntityMaps: flatViewGroupMaps,
+ flatEntityMapsToMutate: flatViewGroupMaps,
});
- }, EMPTY_FLAT_ENTITY_MAPS);
+ }
+
+ return flatViewGroupMaps;
}
}
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view/flat-view.module.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view/flat-view.module.ts
index 7d44ec14a0..e3d728c121 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-view/flat-view.module.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-view/flat-view.module.ts
@@ -2,10 +2,20 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { WorkspaceFlatViewMapCacheService } from 'src/engine/metadata-modules/flat-view/services/workspace-flat-view-map-cache.service';
+import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
+import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
+import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
@Module({
- imports: [TypeOrmModule.forFeature([ViewEntity])],
+ imports: [
+ TypeOrmModule.forFeature([
+ ViewEntity,
+ ViewFieldEntity,
+ ViewFilterEntity,
+ ViewGroupEntity,
+ ]),
+ ],
providers: [WorkspaceFlatViewMapCacheService],
exports: [WorkspaceFlatViewMapCacheService],
})
diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view/services/workspace-flat-view-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view/services/workspace-flat-view-map-cache.service.ts
index 7ec8f35491..d96f193e38 100644
--- a/packages/twenty-server/src/engine/metadata-modules/flat-view/services/workspace-flat-view-map-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/flat-view/services/workspace-flat-view-map-cache.service.ts
@@ -6,13 +6,17 @@ import { Repository } from 'typeorm';
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
-import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { type FlatViewMaps } from 'src/engine/metadata-modules/flat-view/types/flat-view-maps.type';
import { fromViewEntityToFlatView } from 'src/engine/metadata-modules/flat-view/utils/from-view-entity-to-flat-view.util';
+import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
+import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
+import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
+import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-flat-map-cache/utils/regroup-entities-by-related-entity-id';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@Injectable()
@WorkspaceFlatMapCache('flatViewMaps')
@@ -22,6 +26,12 @@ export class WorkspaceFlatViewMapCacheService extends WorkspaceFlatMapCacheServi
cacheStorageService: CacheStorageService,
@InjectRepository(ViewEntity)
private readonly viewRepository: Repository,
+ @InjectRepository(ViewFieldEntity)
+ private readonly viewFieldRepository: Repository,
+ @InjectRepository(ViewFilterEntity)
+ private readonly viewFilterRepository: Repository,
+ @InjectRepository(ViewGroupEntity)
+ private readonly viewGroupRepository: Repository,
) {
super(cacheStorageService);
}
@@ -31,29 +41,61 @@ export class WorkspaceFlatViewMapCacheService extends WorkspaceFlatMapCacheServi
}: {
workspaceId: string;
}): Promise {
- const views = await this.viewRepository.find({
- where: {
- workspaceId,
- },
- select: {
- viewFields: {
- id: true,
- },
- viewFilters: {
- id: true,
- },
- },
- relations: ['viewFields', 'viewFilters', 'viewGroups'],
- withDeleted: true,
- });
+ const [views, viewFields, viewFilters, viewGroups] = await Promise.all([
+ this.viewRepository.find({
+ where: { workspaceId },
+ withDeleted: true,
+ }),
+ this.viewFieldRepository.find({
+ where: { workspaceId },
+ select: ['id', 'viewId'],
+ withDeleted: true,
+ }),
+ this.viewFilterRepository.find({
+ where: { workspaceId },
+ select: ['id', 'viewId'],
+ withDeleted: true,
+ }),
+ this.viewGroupRepository.find({
+ where: { workspaceId },
+ select: ['id', 'viewId'],
+ withDeleted: true,
+ }),
+ ]);
- return views.reduce((flatViewMaps, viewEntity) => {
- const flatView = fromViewEntityToFlatView(viewEntity);
+ const [viewFieldsByViewId, viewFiltersByViewId, viewGroupsByViewId] = (
+ [
+ {
+ entities: viewFields,
+ foreignKey: 'viewId',
+ },
+ {
+ entities: viewFilters,
+ foreignKey: 'viewId',
+ },
+ {
+ entities: viewGroups,
+ foreignKey: 'viewId',
+ },
+ ] as const
+ ).map(regroupEntitiesByRelatedEntityId);
- return addFlatEntityToFlatEntityMapsOrThrow({
+ const flatViewMaps = createEmptyFlatEntityMaps();
+
+ for (const viewEntity of views) {
+ const flatView = fromViewEntityToFlatView({
+ ...viewEntity,
+ viewFields: viewFieldsByViewId.get(viewEntity.id) || [],
+ viewFilters: viewFiltersByViewId.get(viewEntity.id) || [],
+ viewGroups: viewGroupsByViewId.get(viewEntity.id) || [],
+ } as ViewEntity);
+
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
flatEntity: flatView,
- flatEntityMaps: flatViewMaps,
+ flatEntityMapsToMutate: flatViewMaps,
});
- }, EMPTY_FLAT_ENTITY_MAPS);
+ }
+
+ return flatViewMaps;
}
}
diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service.ts
index 5793a19289..2105d57252 100644
--- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service.ts
@@ -7,9 +7,8 @@ import { Repository } from 'typeorm';
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/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 {
ROUTE_TRIGGER_ENTITY_RELATION_PROPERTIES,
RouteTriggerEntity,
@@ -17,6 +16,7 @@ import {
import { FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
import { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@Injectable()
@WorkspaceFlatMapCache('flatRouteTriggerMaps')
@@ -43,7 +43,9 @@ export class WorkspaceFlatRouteTriggerMapCacheService extends WorkspaceFlatMapCa
},
});
- return routeTriggers.reduce((flatRouteTriggerMaps, routeTriggerEntity) => {
+ const flatRouteTriggerMaps = createEmptyFlatEntityMaps();
+
+ for (const routeTriggerEntity of routeTriggers) {
const flatRouteTrigger = {
...removePropertiesFromRecord(routeTriggerEntity, [
...ROUTE_TRIGGER_ENTITY_RELATION_PROPERTIES,
@@ -52,10 +54,12 @@ export class WorkspaceFlatRouteTriggerMapCacheService extends WorkspaceFlatMapCa
routeTriggerEntity.universalIdentifier ?? routeTriggerEntity.id,
} satisfies FlatRouteTrigger;
- return addFlatEntityToFlatEntityMapsOrThrow({
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
flatEntity: flatRouteTrigger,
- flatEntityMaps: flatRouteTriggerMaps,
+ flatEntityMapsToMutate: flatRouteTriggerMaps,
});
- }, EMPTY_FLAT_ENTITY_MAPS);
+ }
+
+ return flatRouteTriggerMaps;
}
}
diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/workspace-flat-serverless-function-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/workspace-flat-serverless-function-map-cache.service.ts
index d7416e1600..5631d2c712 100644
--- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/workspace-flat-serverless-function-map-cache.service.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/workspace-flat-serverless-function-map-cache.service.ts
@@ -7,9 +7,8 @@ import { Repository } from 'typeorm';
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/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 {
SERVERLESS_FUNCTION_ENTITY_RELATION_PROPERTIES,
ServerlessFunctionEntity,
@@ -17,6 +16,7 @@ import {
import { FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
import { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
@Injectable()
@WorkspaceFlatMapCache('flatServerlessFunctionMaps')
@@ -44,23 +44,24 @@ export class WorkspaceFlatServerlessFunctionMapCacheService extends WorkspaceFla
withDeleted: true,
});
- return serverlessFunctions.reduce(
- (flatServerlessFunctionMaps, serverlessFunctionEntity) => {
- const flatServerlessFunction = {
- ...removePropertiesFromRecord(serverlessFunctionEntity, [
- ...SERVERLESS_FUNCTION_ENTITY_RELATION_PROPERTIES,
- ]),
- universalIdentifier:
- serverlessFunctionEntity.universalIdentifier ??
- serverlessFunctionEntity.id,
- } satisfies FlatServerlessFunction;
+ const flatServerlessFunctionMaps = createEmptyFlatEntityMaps();
- return addFlatEntityToFlatEntityMapsOrThrow({
- flatEntity: flatServerlessFunction,
- flatEntityMaps: flatServerlessFunctionMaps,
- });
- },
- EMPTY_FLAT_ENTITY_MAPS,
- );
+ for (const serverlessFunctionEntity of serverlessFunctions) {
+ const flatServerlessFunction = {
+ ...removePropertiesFromRecord(serverlessFunctionEntity, [
+ ...SERVERLESS_FUNCTION_ENTITY_RELATION_PROPERTIES,
+ ]),
+ universalIdentifier:
+ serverlessFunctionEntity.universalIdentifier ??
+ serverlessFunctionEntity.id,
+ } satisfies FlatServerlessFunction;
+
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: flatServerlessFunction,
+ flatEntityMapsToMutate: flatServerlessFunctionMaps,
+ });
+ }
+
+ return flatServerlessFunctionMaps;
}
}
diff --git a/packages/twenty-server/src/engine/workspace-flat-map-cache/utils/regroup-entities-by-related-entity-id.ts b/packages/twenty-server/src/engine/workspace-flat-map-cache/utils/regroup-entities-by-related-entity-id.ts
new file mode 100644
index 0000000000..a23ada1c0f
--- /dev/null
+++ b/packages/twenty-server/src/engine/workspace-flat-map-cache/utils/regroup-entities-by-related-entity-id.ts
@@ -0,0 +1,39 @@
+import { isDefined } from 'class-validator';
+import { type AllMetadataName } from 'twenty-shared/metadata';
+
+import { type MetadataEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-entity.type';
+import { type MetadataManyToOneJoinColumn } from 'src/engine/metadata-modules/flat-entity/types/metadata-many-to-one-join-column.type';
+
+export type RegroupEntitiesByRelatedEntityIdArgs =
+ MetadataManyToOneJoinColumn extends never
+ ? never
+ : {
+ entities: MetadataEntity[];
+ foreignKey: MetadataManyToOneJoinColumn;
+ };
+export const regroupEntitiesByRelatedEntityId = ({
+ entities,
+ foreignKey,
+}: RegroupEntitiesByRelatedEntityIdArgs) => {
+ const entitiesByRelatedEntityId = new Map();
+
+ for (const entity of entities) {
+ const currentRelatedEntityId = entity[
+ foreignKey as keyof MetadataEntity
+ ] as string;
+
+ if (!isDefined(currentRelatedEntityId)) {
+ continue;
+ }
+
+ if (!entitiesByRelatedEntityId.has(currentRelatedEntityId)) {
+ entitiesByRelatedEntityId.set(currentRelatedEntityId, []);
+ }
+
+ entitiesByRelatedEntityId
+ .get(currentRelatedEntityId)!
+ .push({ id: entity.id });
+ }
+
+ return entitiesByRelatedEntityId;
+};
diff --git a/packages/twenty-server/src/engine/workspace-flat-map-cache/workspace-flat-map-cache.module.ts b/packages/twenty-server/src/engine/workspace-flat-map-cache/workspace-flat-map-cache.module.ts
index 6808ad106b..710b0cae80 100644
--- a/packages/twenty-server/src/engine/workspace-flat-map-cache/workspace-flat-map-cache.module.ts
+++ b/packages/twenty-server/src/engine/workspace-flat-map-cache/workspace-flat-map-cache.module.ts
@@ -10,6 +10,7 @@ import { WorkspaceFlatViewFieldMapCacheService } from 'src/engine/metadata-modul
import { WorkspaceFlatViewFilterMapCacheService } from 'src/engine/metadata-modules/flat-view-filter/services/workspace-flat-view-filter-map-cache.service';
import { WorkspaceFlatViewGroupMapCacheService } from 'src/engine/metadata-modules/flat-view-group/services/workspace-flat-view-group-map-cache.service';
import { WorkspaceFlatViewMapCacheService } from 'src/engine/metadata-modules/flat-view/services/workspace-flat-view-map-cache.service';
+import { IndexFieldMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-field-metadata.entity';
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
@@ -31,10 +32,11 @@ import { WorkspaceFlatMapCacheRegistryService } from 'src/engine/workspace-flat-
ViewEntity,
ViewFieldEntity,
ViewFilterEntity,
+ ViewGroupEntity,
IndexMetadataEntity,
+ IndexFieldMetadataEntity,
FieldMetadataEntity,
ObjectMetadataEntity,
- ViewGroupEntity,
]),
],
providers: [
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant.ts
index 03599b150c..41e1dfcf12 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant.ts
@@ -3,13 +3,15 @@ import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
import { getMetadataEmptyWorkspaceMigrationActionRecord } from 'src/engine/workspace-manager/workspace-migration-v2/utils/get-metadata-empty-workspace-migration-action-record.util';
-export const EMPTY_ORCHESTRATOR_ACTIONS_REPORT = (
- Object.keys(ALL_METADATA_NAME) as (keyof typeof ALL_METADATA_NAME)[]
-).reduce(
- (orchestratorReport, metadataName) => ({
- ...orchestratorReport,
- [metadataName]:
- getMetadataEmptyWorkspaceMigrationActionRecord(metadataName),
- }),
- {} as OrchestratorActionsReport,
-);
+export const createEmptyOrchestratorActionsReport =
+ (): OrchestratorActionsReport =>
+ (
+ Object.keys(ALL_METADATA_NAME) as (keyof typeof ALL_METADATA_NAME)[]
+ ).reduce(
+ (orchestratorReport, metadataName) => ({
+ ...orchestratorReport,
+ [metadataName]:
+ getMetadataEmptyWorkspaceMigrationActionRecord(metadataName),
+ }),
+ {} as OrchestratorActionsReport,
+ );
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-failure-report.constant.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-failure-report.constant.ts
index 031fb04ac2..748e3a3f63 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-failure-report.constant.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-failure-report.constant.ts
@@ -2,12 +2,14 @@ import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { type OrchestratorFailureReport } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
-export const EMPTY_ORCHESTRATOR_FAILURE_REPORT = (
- Object.keys(ALL_METADATA_NAME) as (keyof typeof ALL_METADATA_NAME)[]
-).reduce(
- (orchestratorReport, metadataName) => ({
- ...orchestratorReport,
- [metadataName]: [],
- }),
- {} as OrchestratorFailureReport,
-);
+export const EMPTY_ORCHESTRATOR_FAILURE_REPORT =
+ (): OrchestratorFailureReport =>
+ (
+ Object.keys(ALL_METADATA_NAME) as (keyof typeof ALL_METADATA_NAME)[]
+ ).reduce(
+ (orchestratorReport, metadataName) => ({
+ ...orchestratorReport,
+ [metadataName]: [],
+ }),
+ {} as OrchestratorFailureReport,
+ );
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 01abd98e7e..ea05af1f0f 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
@@ -2,9 +2,9 @@ import { Injectable } from '@nestjs/common';
import { isDefined } from 'twenty-shared/utils';
-import { EMPTY_ALL_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-all-flat-entity-maps.constant';
+import { createEmptyAllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-all-flat-entity-maps.constant';
import { AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
-import { EMPTY_ORCHESTRATOR_ACTIONS_REPORT } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant';
+import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant';
import { EMPTY_ORCHESTRATOR_FAILURE_REPORT } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-failure-report.constant';
import {
WorkspaceMigrationOrchestratorBuildArgs,
@@ -65,7 +65,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
};
},
{
- ...EMPTY_ALL_FLAT_ENTITY_MAPS,
+ ...createEmptyAllFlatEntityMaps(),
...dependencyAllFlatEntityMaps,
},
);
@@ -81,10 +81,10 @@ export class WorkspaceMigrationBuildOrchestratorService {
| WorkspaceMigrationOrchestratorSuccessfulResult
> {
const orchestratorActionsReport = structuredClone({
- ...EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ ...createEmptyOrchestratorActionsReport(),
});
const orchestratorFailureReport = structuredClone(
- EMPTY_ORCHESTRATOR_FAILURE_REPORT,
+ EMPTY_ORCHESTRATOR_FAILURE_REPORT(),
);
const optimisticAllFlatEntityMaps = this.setupOptimisticCache({
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/__tests__/aggregate-orchestrator-actions-report-create-object-and-create-field-actions.util.spec.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/__tests__/aggregate-orchestrator-actions-report-create-object-and-create-field-actions.util.spec.ts
index 8bc07a6da8..7fe5dd2895 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/__tests__/aggregate-orchestrator-actions-report-create-object-and-create-field-actions.util.spec.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/__tests__/aggregate-orchestrator-actions-report-create-object-and-create-field-actions.util.spec.ts
@@ -6,7 +6,7 @@ import { FieldMetadataType } from 'twenty-shared/types';
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock';
-import { EMPTY_ORCHESTRATOR_ACTIONS_REPORT } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant';
+import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
import { aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions } from 'src/engine/workspace-manager/workspace-migration-v2/utils/aggregate-orchestrator-actions-report-create-object-and-create-field-actions.util';
import { type CreateFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/types/workspace-migration-field-action-v2';
@@ -26,7 +26,7 @@ describe('aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions',
'should aggregate single object with multiple fields into one object action',
context: {
input: {
- ...EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ ...createEmptyOrchestratorActionsReport(),
objectMetadata: {
created: [
{
@@ -83,7 +83,7 @@ describe('aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions',
'should keep separate field actions when no matching object action exists',
context: {
input: {
- ...EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ ...createEmptyOrchestratorActionsReport(),
objectMetadata: {
created: [],
updated: [],
@@ -147,7 +147,7 @@ describe('aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions',
title: 'should handle multiple objects with their respective fields',
context: {
input: {
- ...EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ ...createEmptyOrchestratorActionsReport(),
objectMetadata: {
created: [
{
@@ -228,7 +228,7 @@ describe('aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions',
'should handle mixed scenario with some fields merged and some kept separate',
context: {
input: {
- ...EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ ...createEmptyOrchestratorActionsReport(),
objectMetadata: {
created: [
{
@@ -293,7 +293,7 @@ describe('aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions',
'should aggregate multiple field actions for the same object when no create object action exists',
context: {
input: {
- ...EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ ...createEmptyOrchestratorActionsReport(),
objectMetadata: {
created: [],
updated: [],
@@ -356,7 +356,7 @@ describe('aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions',
{
title: 'should handle empty actions report',
context: {
- input: EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ input: createEmptyOrchestratorActionsReport(),
expected: {
expectCreateFieldActionPerObjectMetadataId: {},
expectCreateObjectActionPerObjectMetadataId: {},
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/__tests__/aggregate-orchestrator-actions-report-delete-object-and-delete-field-actions.util.spec.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/__tests__/aggregate-orchestrator-actions-report-delete-object-and-delete-field-actions.util.spec.ts
index d5ad48964a..1841aa4520 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/__tests__/aggregate-orchestrator-actions-report-delete-object-and-delete-field-actions.util.spec.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/__tests__/aggregate-orchestrator-actions-report-delete-object-and-delete-field-actions.util.spec.ts
@@ -3,7 +3,7 @@ import {
type EachTestingContext,
} from 'twenty-shared/testing';
-import { EMPTY_ORCHESTRATOR_ACTIONS_REPORT } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant';
+import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant';
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
import { aggregateOrchestratorActionsReportDeleteObjectAndDeleteFieldActions } from 'src/engine/workspace-manager/workspace-migration-v2/utils/aggregate-orchestrator-actions-report-delete-object-and-delete-field.util';
import { type DeleteFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/types/workspace-migration-field-action-v2';
@@ -23,7 +23,7 @@ describe('aggregateOrchestratorActionsReportDeleteObjectAndDeleteFieldActions',
title: 'should remove field actions when parent object is being deleted',
context: {
input: {
- ...EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ ...createEmptyOrchestratorActionsReport(),
objectMetadata: {
created: [],
updated: [],
@@ -63,7 +63,7 @@ describe('aggregateOrchestratorActionsReportDeleteObjectAndDeleteFieldActions',
title: 'should keep field actions when no parent object is being deleted',
context: {
input: {
- ...EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ ...createEmptyOrchestratorActionsReport(),
objectMetadata: {
created: [],
updated: [],
@@ -94,7 +94,7 @@ describe('aggregateOrchestratorActionsReportDeleteObjectAndDeleteFieldActions',
'should handle mixed scenario with some fields removed and some kept',
context: {
input: {
- ...EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ ...createEmptyOrchestratorActionsReport(),
objectMetadata: {
created: [],
updated: [],
@@ -136,7 +136,7 @@ describe('aggregateOrchestratorActionsReportDeleteObjectAndDeleteFieldActions',
title: 'should handle multiple objects with mixed field deletions',
context: {
input: {
- ...EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ ...createEmptyOrchestratorActionsReport(),
objectMetadata: {
created: [],
updated: [],
@@ -187,7 +187,7 @@ describe('aggregateOrchestratorActionsReportDeleteObjectAndDeleteFieldActions',
{
title: 'should handle empty actions report',
context: {
- input: EMPTY_ORCHESTRATOR_ACTIONS_REPORT,
+ input: createEmptyOrchestratorActionsReport(),
expected: {
expectDeleteFieldActionPerObjectMetadataId: {},
expectDeleteObjectActionPerObjectMetadataId: {},
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts
new file mode 100644
index 0000000000..29815d3649
--- /dev/null
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts
@@ -0,0 +1,54 @@
+import { isDefined } from 'twenty-shared/utils';
+
+import {
+ FlatEntityMapsException,
+ FlatEntityMapsExceptionCode,
+} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
+import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
+import { type FlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
+
+type AddFlatEntityToFlatEntityMapsThroughMutationOrThrowArgs<
+ T extends FlatEntity,
+> = {
+ flatEntity: T;
+ flatEntityMapsToMutate: FlatEntityMaps;
+};
+
+export const addFlatEntityToFlatEntityMapsThroughMutationOrThrow = <
+ T extends FlatEntity,
+>({
+ flatEntity,
+ flatEntityMapsToMutate,
+}: AddFlatEntityToFlatEntityMapsThroughMutationOrThrowArgs): void => {
+ if (isDefined(flatEntityMapsToMutate.byId[flatEntity.id])) {
+ throw new FlatEntityMapsException(
+ 'addFlatEntityToFlatEntityMapsThroughMutationOrThrow: flat entity to add already exists',
+ FlatEntityMapsExceptionCode.ENTITY_ALREADY_EXISTS,
+ );
+ }
+
+ flatEntityMapsToMutate.byId[flatEntity.id] = flatEntity;
+
+ flatEntityMapsToMutate.idByUniversalIdentifier[
+ flatEntity.universalIdentifier
+ ] = flatEntity.id;
+
+ if (isDefined(flatEntity.applicationId)) {
+ const existingUniversalIdentifiers =
+ flatEntityMapsToMutate.universalIdentifiersByApplicationId[
+ flatEntity.applicationId
+ ];
+
+ if (isDefined(existingUniversalIdentifiers)) {
+ if (
+ !existingUniversalIdentifiers.includes(flatEntity.universalIdentifier)
+ ) {
+ existingUniversalIdentifiers.push(flatEntity.universalIdentifier);
+ }
+ } else {
+ flatEntityMapsToMutate.universalIdentifiersByApplicationId[
+ flatEntity.applicationId
+ ] = [flatEntity.universalIdentifier];
+ }
+ }
+};
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts
new file mode 100644
index 0000000000..8b24c39666
--- /dev/null
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts
@@ -0,0 +1,60 @@
+import { isDefined } from 'twenty-shared/utils';
+
+import {
+ FlatEntityMapsException,
+ FlatEntityMapsExceptionCode,
+} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
+import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
+import { type FlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
+
+export type DeleteFlatEntityFromFlatEntityMapsThroughMutationOrThrowArgs<
+ T extends FlatEntity,
+> = {
+ entityToDeleteId: string;
+ flatEntityMapsToMutate: FlatEntityMaps;
+};
+
+export const deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow = <
+ T extends FlatEntity,
+>({
+ flatEntityMapsToMutate,
+ entityToDeleteId,
+}: DeleteFlatEntityFromFlatEntityMapsThroughMutationOrThrowArgs): void => {
+ const entityToDelete = flatEntityMapsToMutate.byId[entityToDeleteId];
+
+ if (!isDefined(entityToDelete)) {
+ throw new FlatEntityMapsException(
+ 'deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow: entity to delete not found',
+ FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
+ );
+ }
+
+ delete flatEntityMapsToMutate.byId[entityToDeleteId];
+
+ delete flatEntityMapsToMutate.idByUniversalIdentifier[
+ entityToDelete.universalIdentifier
+ ];
+
+ if (isDefined(entityToDelete.applicationId)) {
+ const universalIdentifiers =
+ flatEntityMapsToMutate.universalIdentifiersByApplicationId[
+ entityToDelete.applicationId
+ ];
+
+ if (isDefined(universalIdentifiers)) {
+ const index = universalIdentifiers.indexOf(
+ entityToDelete.universalIdentifier,
+ );
+
+ if (index !== -1) {
+ universalIdentifiers.splice(index, 1);
+ }
+
+ if (universalIdentifiers.length === 0) {
+ delete flatEntityMapsToMutate.universalIdentifiersByApplicationId[
+ entityToDelete.applicationId
+ ];
+ }
+ }
+ }
+};
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util.ts
index 315906b51c..84c1a4c3e4 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util.ts
@@ -1,16 +1,16 @@
+import { type AllMetadataName } from 'twenty-shared/metadata';
import { type FromTo } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
-import { type AllMetadataName } from 'twenty-shared/metadata';
import { ALL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY } from 'src/engine/metadata-modules/flat-entity/constant/all-flat-entity-properties-to-compare-and-stringify.constant';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { type FlatEntityPropertiesToCompare } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-compare.type';
import { type FlatEntityPropertiesToStringify } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-stringify.type';
import { type FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
-import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
import { compareTwoFlatEntity } from 'src/engine/metadata-modules/flat-entity/utils/compare-two-flat-entity.util';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-builder-options.type';
export type DeletedCreatedUpdatedMatrix = {
@@ -46,8 +46,8 @@ export const flatEntityDeletedCreatedUpdatedMatrixDispatcher = <
buildOptions,
}: FlatEntityDeletedCreatedUpdatedMatrixDispatcherArgs): DeletedCreatedUpdatedMatrix => {
const initialDispatcher: DeletedCreatedUpdatedMatrix = {
- createdFlatEntityMaps: EMPTY_FLAT_ENTITY_MAPS,
- deletedFlatEntityMaps: EMPTY_FLAT_ENTITY_MAPS,
+ createdFlatEntityMaps: createEmptyFlatEntityMaps(),
+ deletedFlatEntityMaps: createEmptyFlatEntityMaps(),
updatedFlatEntityMaps: { byId: {} },
};
@@ -59,11 +59,10 @@ export const flatEntityDeletedCreatedUpdatedMatrixDispatcher = <
if (toMap.has(universalIdentifier)) {
continue;
}
- initialDispatcher.deletedFlatEntityMaps =
- addFlatEntityToFlatEntityMapsOrThrow({
- flatEntity: fromEntity,
- flatEntityMaps: initialDispatcher.deletedFlatEntityMaps,
- });
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: fromEntity,
+ flatEntityMapsToMutate: initialDispatcher.deletedFlatEntityMaps,
+ });
}
}
@@ -71,11 +70,10 @@ export const flatEntityDeletedCreatedUpdatedMatrixDispatcher = <
if (fromMap.has(universalIdentifier)) {
continue;
}
- initialDispatcher.createdFlatEntityMaps =
- addFlatEntityToFlatEntityMapsOrThrow({
- flatEntity: toFlatEntity,
- flatEntityMaps: initialDispatcher.createdFlatEntityMaps,
- });
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: toFlatEntity,
+ flatEntityMapsToMutate: initialDispatcher.createdFlatEntityMaps,
+ });
}
const { propertiesToCompare, propertiesToStringify } =
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util.ts
new file mode 100644
index 0000000000..80eaa7175f
--- /dev/null
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util.ts
@@ -0,0 +1,28 @@
+import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
+import { type FlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
+import { deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util';
+
+export type ReplaceFlatEntityInFlatEntityMapsThroughMutationOrThrowArgs<
+ T extends FlatEntity,
+> = {
+ flatEntity: T;
+ flatEntityMapsToMutate: FlatEntityMaps;
+};
+
+export const replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow = <
+ T extends FlatEntity,
+>({
+ flatEntity,
+ flatEntityMapsToMutate,
+}: ReplaceFlatEntityInFlatEntityMapsThroughMutationOrThrowArgs): void => {
+ deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow({
+ flatEntityMapsToMutate,
+ entityToDeleteId: flatEntity.id,
+ });
+
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
+ flatEntity,
+ flatEntityMapsToMutate,
+ });
+};
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/workspace-migration-v2-cron-trigger-action-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/workspace-migration-v2-cron-trigger-action-builder.service.ts
index 06329ef53d..eca52d8a8e 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/workspace-migration-v2-cron-trigger-action-builder.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/workspace-migration-v2-cron-trigger-action-builder.service.ts
@@ -39,10 +39,7 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
};
}
- const {
- dependencyOptimisticFlatEntityMaps,
- flatEntityToValidate: flatCronTriggerToValidate,
- } = args;
+ const { flatEntityToValidate: flatCronTriggerToValidate } = args;
return {
status: 'success',
@@ -50,7 +47,6 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
type: 'create_cron_trigger',
cronTrigger: flatCronTriggerToValidate,
},
- dependencyOptimisticFlatEntityMaps,
};
}
@@ -74,10 +70,7 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
};
}
- const {
- flatEntityToValidate: flatCronTriggerToValidate,
- dependencyOptimisticFlatEntityMaps,
- } = args;
+ const { flatEntityToValidate: flatCronTriggerToValidate } = args;
return {
status: 'success',
@@ -85,7 +78,6 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
type: 'delete_cron_trigger',
cronTriggerId: flatCronTriggerToValidate.id,
},
- dependencyOptimisticFlatEntityMaps,
};
}
@@ -106,11 +98,7 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
...validationResult,
};
}
- const {
- dependencyOptimisticFlatEntityMaps,
- flatEntityId,
- flatEntityUpdates,
- } = args;
+ const { flatEntityId, flatEntityUpdates } = args;
const updateCronTriggerAction: UpdateCronTriggerAction = {
type: 'update_cron_trigger',
@@ -121,7 +109,6 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
return {
status: 'success',
action: updateCronTriggerAction,
- dependencyOptimisticFlatEntityMaps,
};
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/workspace-migration-v2-database-event-trigger-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/workspace-migration-v2-database-event-trigger-actions-builder.service.ts
index 60d983dd04..550b25215d 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/workspace-migration-v2-database-event-trigger-actions-builder.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/workspace-migration-v2-database-event-trigger-actions-builder.service.ts
@@ -41,10 +41,7 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
};
}
- const {
- flatEntityToValidate: flatDatabaseEventTriggerToValidate,
- dependencyOptimisticFlatEntityMaps,
- } = args;
+ const { flatEntityToValidate: flatDatabaseEventTriggerToValidate } = args;
return {
status: 'success',
@@ -52,7 +49,6 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
type: 'create_database_event_trigger',
databaseEventTrigger: flatDatabaseEventTriggerToValidate,
},
- dependencyOptimisticFlatEntityMaps,
};
}
@@ -78,10 +74,7 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
};
}
- const {
- flatEntityToValidate: flatDatabaseEventTriggerToValidate,
- dependencyOptimisticFlatEntityMaps,
- } = args;
+ const { flatEntityToValidate: flatDatabaseEventTriggerToValidate } = args;
return {
status: 'success',
@@ -89,7 +82,6 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
type: 'delete_database_event_trigger',
databaseEventTriggerId: flatDatabaseEventTriggerToValidate.id,
},
- dependencyOptimisticFlatEntityMaps,
};
}
@@ -115,11 +107,7 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
};
}
- const {
- dependencyOptimisticFlatEntityMaps,
- flatEntityId,
- flatEntityUpdates,
- } = args;
+ const { flatEntityId, flatEntityUpdates } = args;
const updateDatabaseEventTriggerAction: UpdateDatabaseEventTriggerAction = {
type: 'update_database_event_trigger',
@@ -130,7 +118,6 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
return {
status: 'success',
action: updateDatabaseEventTriggerAction,
- dependencyOptimisticFlatEntityMaps,
};
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/workspace-migration-v2-field-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/workspace-migration-v2-field-actions-builder.service.ts
index f259cb474d..6eca5b4fa6 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/workspace-migration-v2-field-actions-builder.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/workspace-migration-v2-field-actions-builder.service.ts
@@ -1,11 +1,11 @@
import { Injectable } from '@nestjs/common';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
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 { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
+import { replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util';
import { UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/types/workspace-migration-field-action-v2';
import { WorkspaceEntityMigrationBuilderV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
@@ -45,26 +45,26 @@ export class WorkspaceMigrationV2FieldActionsBuilderService extends WorkspaceEnt
const {
flatEntityToValidate: flatFieldMetadataToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatFieldMetadataToValidate.objectMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
});
- const updatedFlatObjectMetadataMaps =
- replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatObjectMetadata,
- fieldMetadataIds: [
- ...flatObjectMetadata.fieldMetadataIds,
- flatFieldMetadataToValidate.id,
- ],
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
- });
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatObjectMetadata,
+ fieldMetadataIds: [
+ ...flatObjectMetadata.fieldMetadataIds,
+ flatFieldMetadataToValidate.id,
+ ],
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ });
return {
status: 'success',
@@ -73,9 +73,6 @@ export class WorkspaceMigrationV2FieldActionsBuilderService extends WorkspaceEnt
objectMetadataId: flatFieldMetadataToValidate.objectMetadataId,
flatFieldMetadatas: [flatFieldMetadataToValidate],
},
- dependencyOptimisticFlatEntityMaps: {
- flatObjectMetadataMaps: updatedFlatObjectMetadataMaps,
- },
};
}
@@ -99,26 +96,27 @@ export class WorkspaceMigrationV2FieldActionsBuilderService extends WorkspaceEnt
const {
flatEntityToValidate: flatFieldMetadataToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatFieldMetadataToValidate.objectMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
});
- const updatedFlatObjectMetadataMaps = isDefined(flatObjectMetadata)
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatObjectMetadata,
- fieldMetadataIds: flatObjectMetadata.fieldMetadataIds.filter(
- (id) => id !== flatFieldMetadataToValidate.id,
- ),
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
- })
- : dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps;
+ if (isDefined(flatObjectMetadata)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatObjectMetadata,
+ fieldMetadataIds: flatObjectMetadata.fieldMetadataIds.filter(
+ (id) => id !== flatFieldMetadataToValidate.id,
+ ),
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ });
+ }
return {
status: 'success',
@@ -127,9 +125,6 @@ export class WorkspaceMigrationV2FieldActionsBuilderService extends WorkspaceEnt
fieldMetadataId: flatFieldMetadataToValidate.id,
objectMetadataId: flatFieldMetadataToValidate.objectMetadataId,
},
- dependencyOptimisticFlatEntityMaps: {
- flatObjectMetadataMaps: updatedFlatObjectMetadataMaps,
- },
};
}
@@ -155,12 +150,7 @@ export class WorkspaceMigrationV2FieldActionsBuilderService extends WorkspaceEnt
};
}
- const {
- dependencyOptimisticFlatEntityMaps,
- flatEntityId,
- flatEntityUpdates,
- optimisticFlatEntityMaps,
- } = args;
+ const { flatEntityId, flatEntityUpdates, optimisticFlatEntityMaps } = args;
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatEntityId,
@@ -177,7 +167,6 @@ export class WorkspaceMigrationV2FieldActionsBuilderService extends WorkspaceEnt
return {
status: 'success',
action: updateFieldAction,
- dependencyOptimisticFlatEntityMaps,
};
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-actions-builder.service.ts
index cce05d6d2c..b004e16e9c 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-actions-builder.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-actions-builder.service.ts
@@ -1,15 +1,15 @@
import { Injectable } from '@nestjs/common';
import { t } from '@lingui/core/macro';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FlatEntityMapsExceptionCode } from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
-import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.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 { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
+import { deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util';
+import { replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util';
import { WorkspaceEntityMigrationBuilderV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type';
@@ -44,26 +44,26 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
const {
flatEntityToValidate: flatIndexToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatIndexToValidate.objectMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
});
- const updatedFlatObjectMetadataMaps =
- replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatObjectMetadata,
- indexMetadataIds: [
- ...flatObjectMetadata.indexMetadataIds,
- flatIndexToValidate.id,
- ],
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
- });
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatObjectMetadata,
+ indexMetadataIds: [
+ ...flatObjectMetadata.indexMetadataIds,
+ flatIndexToValidate.id,
+ ],
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ });
return {
status: 'success',
@@ -71,10 +71,6 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
type: 'create_index',
flatIndexMetadata: flatIndexToValidate,
},
- dependencyOptimisticFlatEntityMaps: {
- ...dependencyOptimisticFlatEntityMaps,
- flatObjectMetadataMaps: updatedFlatObjectMetadataMaps,
- },
};
}
@@ -95,26 +91,27 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
const {
flatEntityToValidate: flatIndexToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatIndexToValidate.objectMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
});
- const updatedFlatObjectMetadataMaps = isDefined(flatObjectMetadata)
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatObjectMetadata,
- indexMetadataIds: flatObjectMetadata.indexMetadataIds.filter(
- (id) => id !== flatIndexToValidate.id,
- ),
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
- })
- : dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps;
+ if (isDefined(flatObjectMetadata)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatObjectMetadata,
+ indexMetadataIds: flatObjectMetadata.indexMetadataIds.filter(
+ (id) => id !== flatIndexToValidate.id,
+ ),
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ });
+ }
return {
status: 'success',
@@ -122,10 +119,6 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
type: 'delete_index',
flatIndexMetadataId: flatIndexToValidate.id,
},
- dependencyOptimisticFlatEntityMaps: {
- ...dependencyOptimisticFlatEntityMaps,
- flatObjectMetadataMaps: updatedFlatObjectMetadataMaps,
- },
};
}
@@ -133,7 +126,7 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
flatEntityId,
flatEntityUpdates,
optimisticFlatEntityMaps: optimisticFlatIndexMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
buildOptions,
workspaceId,
}: FlatEntityUpdateValidationArgs): Promise<
@@ -160,11 +153,11 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
const deletionValidationResult =
this.flatIndexValidatorService.validateFlatIndexDeletion({
buildOptions,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
optimisticFlatEntityMaps: optimisticFlatIndexMaps,
workspaceId,
flatEntityToValidate: flatEntity,
- remainingFlatEntityMapsToValidate: EMPTY_FLAT_ENTITY_MAPS,
+ remainingFlatEntityMapsToValidate: createEmptyFlatEntityMaps(),
});
if (deletionValidationResult.errors.length > 0) {
@@ -181,17 +174,23 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
}),
};
+ const tempOptimisticFlatIndexMaps = structuredClone(
+ optimisticFlatIndexMaps,
+ );
+
+ deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow({
+ entityToDeleteId: flatEntity.id,
+ flatEntityMapsToMutate: tempOptimisticFlatIndexMaps,
+ });
+
const creationValidationResult =
this.flatIndexValidatorService.validateFlatIndexCreation({
buildOptions,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
workspaceId,
flatEntityToValidate: updatedFlatIndex,
- optimisticFlatEntityMaps: deleteFlatEntityFromFlatEntityMapsOrThrow({
- entityToDeleteId: flatEntity.id,
- flatEntityMaps: optimisticFlatIndexMaps,
- }),
- remainingFlatEntityMapsToValidate: EMPTY_FLAT_ENTITY_MAPS,
+ optimisticFlatEntityMaps: tempOptimisticFlatIndexMaps,
+ remainingFlatEntityMapsToValidate: createEmptyFlatEntityMaps(),
});
if (creationValidationResult.errors.length > 0) {
@@ -213,7 +212,6 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
flatIndexMetadata: updatedFlatIndex,
},
],
- dependencyOptimisticFlatEntityMaps,
};
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/workspace-migration-v2-object-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/workspace-migration-v2-object-actions-builder.service.ts
index 9f8fa839c5..31f13aa7fa 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/workspace-migration-v2-object-actions-builder.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/workspace-migration-v2-object-actions-builder.service.ts
@@ -39,10 +39,7 @@ export class WorkspaceMigrationV2ObjectActionsBuilderService extends WorkspaceEn
};
}
- const {
- flatEntityToValidate: flatObjectMetadataToValidate,
- dependencyOptimisticFlatEntityMaps,
- } = args;
+ const { flatEntityToValidate: flatObjectMetadataToValidate } = args;
return {
status: 'success',
@@ -51,7 +48,6 @@ export class WorkspaceMigrationV2ObjectActionsBuilderService extends WorkspaceEn
flatFieldMetadatas: [],
flatObjectMetadata: flatObjectMetadataToValidate,
},
- dependencyOptimisticFlatEntityMaps,
};
}
@@ -73,10 +69,7 @@ export class WorkspaceMigrationV2ObjectActionsBuilderService extends WorkspaceEn
};
}
- const {
- flatEntityToValidate: flatObjectMetadataToValidate,
- dependencyOptimisticFlatEntityMaps,
- } = args;
+ const { flatEntityToValidate: flatObjectMetadataToValidate } = args;
return {
status: 'success',
@@ -84,7 +77,6 @@ export class WorkspaceMigrationV2ObjectActionsBuilderService extends WorkspaceEn
type: 'delete_object',
objectMetadataId: flatObjectMetadataToValidate.id,
},
- dependencyOptimisticFlatEntityMaps,
};
}
@@ -108,11 +100,7 @@ export class WorkspaceMigrationV2ObjectActionsBuilderService extends WorkspaceEn
};
}
- const {
- dependencyOptimisticFlatEntityMaps,
- flatEntityId,
- flatEntityUpdates,
- } = args;
+ const { flatEntityId, flatEntityUpdates } = args;
const updateObjectAction: UpdateObjectAction = {
type: 'update_object',
@@ -123,7 +111,6 @@ export class WorkspaceMigrationV2ObjectActionsBuilderService extends WorkspaceEn
return {
status: 'success',
action: updateObjectAction,
- dependencyOptimisticFlatEntityMaps,
};
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service.ts
index ae9dab46a3..3888f16174 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service.ts
@@ -39,10 +39,7 @@ export class WorkspaceMigrationV2RouteTriggerActionsBuilderService extends Works
};
}
- const {
- flatEntityToValidate: flatRouteTriggerToValidate,
- dependencyOptimisticFlatEntityMaps,
- } = args;
+ const { flatEntityToValidate: flatRouteTriggerToValidate } = args;
return {
status: 'success',
@@ -50,7 +47,6 @@ export class WorkspaceMigrationV2RouteTriggerActionsBuilderService extends Works
type: 'create_route_trigger',
routeTrigger: flatRouteTriggerToValidate,
},
- dependencyOptimisticFlatEntityMaps,
};
}
@@ -74,10 +70,7 @@ export class WorkspaceMigrationV2RouteTriggerActionsBuilderService extends Works
};
}
- const {
- flatEntityToValidate: flatRouteTriggerToValidate,
- dependencyOptimisticFlatEntityMaps,
- } = args;
+ const { flatEntityToValidate: flatRouteTriggerToValidate } = args;
return {
status: 'success',
@@ -85,7 +78,6 @@ export class WorkspaceMigrationV2RouteTriggerActionsBuilderService extends Works
type: 'delete_route_trigger',
routeTriggerId: flatRouteTriggerToValidate.id,
},
- dependencyOptimisticFlatEntityMaps,
};
}
@@ -109,11 +101,7 @@ export class WorkspaceMigrationV2RouteTriggerActionsBuilderService extends Works
};
}
- const {
- dependencyOptimisticFlatEntityMaps,
- flatEntityId,
- flatEntityUpdates,
- } = args;
+ const { flatEntityId, flatEntityUpdates } = args;
const updateRouteTriggerAction: UpdateRouteTriggerAction = {
type: 'update_route_trigger',
@@ -124,7 +112,6 @@ export class WorkspaceMigrationV2RouteTriggerActionsBuilderService extends Works
return {
status: 'success',
action: updateRouteTriggerAction,
- dependencyOptimisticFlatEntityMaps,
};
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/workspace-migration-v2-serverless-function-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/workspace-migration-v2-serverless-function-actions-builder.service.ts
index bd8bb42e61..08fe87d2a9 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/workspace-migration-v2-serverless-function-actions-builder.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/workspace-migration-v2-serverless-function-actions-builder.service.ts
@@ -81,10 +81,7 @@ export class WorkspaceMigrationV2ServerlessFunctionActionsBuilderService extends
};
}
- const {
- flatEntityToValidate: flatServerlessFunctionToValidate,
- dependencyOptimisticFlatEntityMaps,
- } = args;
+ const { flatEntityToValidate: flatServerlessFunctionToValidate } = args;
return {
status: 'success',
@@ -92,7 +89,6 @@ export class WorkspaceMigrationV2ServerlessFunctionActionsBuilderService extends
type: 'create_serverless_function',
serverlessFunction: flatServerlessFunctionToValidate,
},
- dependencyOptimisticFlatEntityMaps,
};
}
@@ -116,10 +112,7 @@ export class WorkspaceMigrationV2ServerlessFunctionActionsBuilderService extends
};
}
- const {
- flatEntityToValidate: flatServerlessFunctionToValidate,
- dependencyOptimisticFlatEntityMaps,
- } = args;
+ const { flatEntityToValidate: flatServerlessFunctionToValidate } = args;
return {
status: 'success',
@@ -127,7 +120,6 @@ export class WorkspaceMigrationV2ServerlessFunctionActionsBuilderService extends
type: 'delete_serverless_function',
serverlessFunctionId: flatServerlessFunctionToValidate.id,
},
- dependencyOptimisticFlatEntityMaps,
};
}
@@ -153,11 +145,7 @@ export class WorkspaceMigrationV2ServerlessFunctionActionsBuilderService extends
};
}
- const {
- dependencyOptimisticFlatEntityMaps,
- flatEntityId,
- flatEntityUpdates,
- } = args;
+ const { flatEntityId, flatEntityUpdates } = args;
const updateServerlessFunctionAction: UpdateServerlessFunctionAction = {
type: 'update_serverless_function',
@@ -168,7 +156,6 @@ export class WorkspaceMigrationV2ServerlessFunctionActionsBuilderService extends
return {
status: 'success',
action: updateServerlessFunctionAction,
- dependencyOptimisticFlatEntityMaps,
};
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service.ts
index b0cc2b35bc..372e0726ae 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service.ts
@@ -1,11 +1,11 @@
import { Injectable } from '@nestjs/common';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
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 { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
+import { replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util';
import { UpdateViewFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/types/workspace-migration-view-field-action-v2.type';
import { WorkspaceEntityMigrationBuilderV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
@@ -43,38 +43,39 @@ export class WorkspaceMigrationV2ViewFieldActionsBuilderService extends Workspac
const {
flatEntityToValidate: flatViewFieldToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatViewFieldToValidate.fieldMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
- const updatedFlatFieldMetadataMaps =
- replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatFieldMetadata,
- viewFieldIds: [
- ...flatFieldMetadata.viewFieldIds,
- flatViewFieldToValidate.id,
- ],
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
- });
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatFieldMetadata,
+ viewFieldIds: [
+ ...flatFieldMetadata.viewFieldIds,
+ flatViewFieldToValidate.id,
+ ],
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ });
const flatView = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatViewFieldToValidate.viewId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMaps: mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
- const updatedFlatViewMaps = replaceFlatEntityInFlatEntityMapsOrThrow({
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
flatEntity: {
...flatView,
viewFieldIds: [...flatView.viewFieldIds, flatViewFieldToValidate.id],
},
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
return {
@@ -83,11 +84,6 @@ export class WorkspaceMigrationV2ViewFieldActionsBuilderService extends Workspac
type: 'create_view_field',
viewField: flatViewFieldToValidate,
},
- dependencyOptimisticFlatEntityMaps: {
- ...dependencyOptimisticFlatEntityMaps,
- flatViewMaps: updatedFlatViewMaps,
- flatFieldMetadataMaps: updatedFlatFieldMetadataMaps,
- },
};
}
@@ -111,43 +107,45 @@ export class WorkspaceMigrationV2ViewFieldActionsBuilderService extends Workspac
const {
flatEntityToValidate: flatViewFieldToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewFieldToValidate.fieldMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
- const updatedFlatFieldMetadataMaps = isDefined(flatFieldMetadata)
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatFieldMetadata,
- viewFieldIds: flatFieldMetadata.viewFieldIds.filter(
- (id) => id !== flatViewFieldToValidate.id,
- ),
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
- })
- : dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps;
+ if (isDefined(flatFieldMetadata)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatFieldMetadata,
+ viewFieldIds: flatFieldMetadata.viewFieldIds.filter(
+ (id) => id !== flatViewFieldToValidate.id,
+ ),
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ });
+ }
const flatView = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewFieldToValidate.viewId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMaps: mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
- const updatedFlatViewMaps = isDefined(flatView)
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatView,
- viewFieldIds: flatView.viewFieldIds.filter(
- (id) => id !== flatViewFieldToValidate.id,
- ),
- },
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
- })
- : dependencyOptimisticFlatEntityMaps.flatViewMaps;
+ if (isDefined(flatView)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatView,
+ viewFieldIds: flatView.viewFieldIds.filter(
+ (id) => id !== flatViewFieldToValidate.id,
+ ),
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
+ });
+ }
return {
status: 'success',
@@ -155,11 +153,6 @@ export class WorkspaceMigrationV2ViewFieldActionsBuilderService extends Workspac
type: 'delete_view_field',
viewFieldId: flatViewFieldToValidate.id,
},
- dependencyOptimisticFlatEntityMaps: {
- ...dependencyOptimisticFlatEntityMaps,
- flatViewMaps: updatedFlatViewMaps,
- flatFieldMetadataMaps: updatedFlatFieldMetadataMaps,
- },
};
}
@@ -181,11 +174,7 @@ export class WorkspaceMigrationV2ViewFieldActionsBuilderService extends Workspac
};
}
- const {
- dependencyOptimisticFlatEntityMaps,
- flatEntityId,
- flatEntityUpdates,
- } = args;
+ const { flatEntityId, flatEntityUpdates } = args;
const updateViewFieldAction: UpdateViewFieldAction = {
type: 'update_view_field',
@@ -196,7 +185,6 @@ export class WorkspaceMigrationV2ViewFieldActionsBuilderService extends Workspac
return {
status: 'success',
action: updateViewFieldAction,
- dependencyOptimisticFlatEntityMaps,
};
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-filter/workspace-migration-v2-view-filter-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-filter/workspace-migration-v2-view-filter-actions-builder.service.ts
index b78ad8dad3..163ebb3137 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-filter/workspace-migration-v2-view-filter-actions-builder.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-filter/workspace-migration-v2-view-filter-actions-builder.service.ts
@@ -1,11 +1,11 @@
import { Injectable } from '@nestjs/common';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
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 { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
+import { replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util';
import { UpdateViewFilterAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-filter/types/workspace-migration-view-filter-action-v2.type';
import { WorkspaceEntityMigrationBuilderV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
@@ -43,38 +43,40 @@ export class WorkspaceMigrationV2ViewFilterActionsBuilderService extends Workspa
const {
flatEntityToValidate: flatViewFilterToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatView = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatViewFilterToValidate.viewId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMaps: mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
- const updatedFlatViewMaps = replaceFlatEntityInFlatEntityMapsOrThrow({
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
flatEntity: {
...flatView,
viewFilterIds: [...flatView.viewFilterIds, flatViewFilterToValidate.id],
},
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatViewFilterToValidate.fieldMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ });
+
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatFieldMetadata,
+ viewFilterIds: [
+ ...flatFieldMetadata.viewFilterIds,
+ flatViewFilterToValidate.id,
+ ],
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
- const updatedFlatFieldMetadataMaps =
- replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatFieldMetadata,
- viewFilterIds: [
- ...flatFieldMetadata.viewFilterIds,
- flatViewFilterToValidate.id,
- ],
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
- });
return {
status: 'success',
@@ -82,10 +84,6 @@ export class WorkspaceMigrationV2ViewFilterActionsBuilderService extends Workspa
type: 'create_view_filter',
viewFilter: flatViewFilterToValidate,
},
- dependencyOptimisticFlatEntityMaps: {
- flatFieldMetadataMaps: updatedFlatFieldMetadataMaps,
- flatViewMaps: updatedFlatViewMaps,
- },
};
}
@@ -109,25 +107,26 @@ export class WorkspaceMigrationV2ViewFilterActionsBuilderService extends Workspa
const {
flatEntityToValidate: flatViewFilterToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatView = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewFilterToValidate.viewId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMaps: mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
- const updatedFlatViewMaps = isDefined(flatView)
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatView,
- viewFilterIds: flatView.viewFilterIds.filter(
- (id) => id !== flatViewFilterToValidate.id,
- ),
- },
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
- })
- : dependencyOptimisticFlatEntityMaps.flatViewMaps;
+ if (isDefined(flatView)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatView,
+ viewFilterIds: flatView.viewFilterIds.filter(
+ (id) => id !== flatViewFilterToValidate.id,
+ ),
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
+ });
+ }
return {
status: 'success',
@@ -135,10 +134,6 @@ export class WorkspaceMigrationV2ViewFilterActionsBuilderService extends Workspa
type: 'delete_view_filter',
viewFilterId: flatViewFilterToValidate.id,
},
- dependencyOptimisticFlatEntityMaps: {
- ...dependencyOptimisticFlatEntityMaps,
- flatViewMaps: updatedFlatViewMaps,
- },
};
}
@@ -160,11 +155,7 @@ export class WorkspaceMigrationV2ViewFilterActionsBuilderService extends Workspa
};
}
- const {
- dependencyOptimisticFlatEntityMaps,
- flatEntityId,
- flatEntityUpdates,
- } = args;
+ const { flatEntityId, flatEntityUpdates } = args;
const updateViewFilterAction: UpdateViewFilterAction = {
type: 'update_view_filter',
@@ -175,7 +166,6 @@ export class WorkspaceMigrationV2ViewFilterActionsBuilderService extends Workspa
return {
status: 'success',
action: updateViewFilterAction,
- dependencyOptimisticFlatEntityMaps,
};
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-group/workspace-migration-v2-view-group-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-group/workspace-migration-v2-view-group-actions-builder.service.ts
index 3b1ac05279..0a5cd69713 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-group/workspace-migration-v2-view-group-actions-builder.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-group/workspace-migration-v2-view-group-actions-builder.service.ts
@@ -1,11 +1,11 @@
import { Injectable } from '@nestjs/common';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
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 { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
+import { replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util';
import { UpdateViewGroupAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-group/types/workspace-migration-view-group-action-v2.type';
import { WorkspaceEntityMigrationBuilderV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
@@ -43,39 +43,40 @@ export class WorkspaceMigrationV2ViewGroupActionsBuilderService extends Workspac
const {
flatEntityToValidate: flatViewGroupToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatView = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatViewGroupToValidate.viewId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMaps: mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
- const updatedFlatViewMaps = replaceFlatEntityInFlatEntityMapsOrThrow({
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
flatEntity: {
...flatView,
viewGroupIds: [...flatView.viewGroupIds, flatViewGroupToValidate.id],
},
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatViewGroupToValidate.fieldMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
- const updatedFlatFieldMetadataMaps =
- replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatFieldMetadata,
- viewGroupIds: [
- ...flatFieldMetadata.viewGroupIds,
- flatViewGroupToValidate.id,
- ],
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
- });
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatFieldMetadata,
+ viewGroupIds: [
+ ...flatFieldMetadata.viewGroupIds,
+ flatViewGroupToValidate.id,
+ ],
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ });
return {
status: 'success',
@@ -83,10 +84,6 @@ export class WorkspaceMigrationV2ViewGroupActionsBuilderService extends Workspac
type: 'create_view_group',
viewGroup: flatViewGroupToValidate,
},
- dependencyOptimisticFlatEntityMaps: {
- flatFieldMetadataMaps: updatedFlatFieldMetadataMaps,
- flatViewMaps: updatedFlatViewMaps,
- },
};
}
@@ -110,43 +107,45 @@ export class WorkspaceMigrationV2ViewGroupActionsBuilderService extends Workspac
const {
flatEntityToValidate: flatViewGroupToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatView = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewGroupToValidate.viewId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMaps: mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
- const updatedFlatViewMaps = isDefined(flatView)
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatView,
- viewGroupIds: flatView.viewGroupIds.filter(
- (id) => id !== flatViewGroupToValidate.id,
- ),
- },
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
- })
- : dependencyOptimisticFlatEntityMaps.flatViewMaps;
+ if (isDefined(flatView)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatView,
+ viewGroupIds: flatView.viewGroupIds.filter(
+ (id) => id !== flatViewGroupToValidate.id,
+ ),
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
+ });
+ }
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewGroupToValidate.fieldMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
- const updatedFlatFieldMetadataMaps = isDefined(flatFieldMetadata)
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatFieldMetadata,
- viewGroupIds: flatFieldMetadata.viewGroupIds.filter(
- (id) => id !== flatViewGroupToValidate.id,
- ),
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
- })
- : dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps;
+ if (isDefined(flatFieldMetadata)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatFieldMetadata,
+ viewGroupIds: flatFieldMetadata.viewGroupIds.filter(
+ (id) => id !== flatViewGroupToValidate.id,
+ ),
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ });
+ }
return {
status: 'success',
@@ -154,10 +153,6 @@ export class WorkspaceMigrationV2ViewGroupActionsBuilderService extends Workspac
type: 'delete_view_group',
viewGroupId: flatViewGroupToValidate.id,
},
- dependencyOptimisticFlatEntityMaps: {
- flatFieldMetadataMaps: updatedFlatFieldMetadataMaps,
- flatViewMaps: updatedFlatViewMaps,
- },
};
}
@@ -179,11 +174,7 @@ export class WorkspaceMigrationV2ViewGroupActionsBuilderService extends Workspac
};
}
- const {
- dependencyOptimisticFlatEntityMaps,
- flatEntityId,
- flatEntityUpdates,
- } = args;
+ const { flatEntityId, flatEntityUpdates } = args;
const updateViewGroupAction: UpdateViewGroupAction = {
type: 'update_view_group',
@@ -194,7 +185,6 @@ export class WorkspaceMigrationV2ViewGroupActionsBuilderService extends Workspac
return {
status: 'success',
action: updateViewGroupAction,
- dependencyOptimisticFlatEntityMaps,
};
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view/workspace-migration-v2-view-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view/workspace-migration-v2-view-actions-builder.service.ts
index 1c99021bbe..06324244c3 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view/workspace-migration-v2-view-actions-builder.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view/workspace-migration-v2-view-actions-builder.service.ts
@@ -1,11 +1,11 @@
import { Injectable } from '@nestjs/common';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
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 { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
+import { replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util';
import { UpdateViewAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view/types/workspace-migration-view-action-v2.type';
import { WorkspaceEntityMigrationBuilderV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
@@ -40,22 +40,23 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
const {
flatEntityToValidate: flatViewToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatViewToValidate.objectMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ });
+
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatObjectMetadata,
+ viewIds: [...flatObjectMetadata.viewIds, flatViewToValidate.id],
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
});
- const updatedFlatObjectMetadataMaps =
- replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatObjectMetadata,
- viewIds: [...flatObjectMetadata.viewIds, flatViewToValidate.id],
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
- });
const kanbanFieldMetadata = isDefined(
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
@@ -64,45 +65,47 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
flatEntityId:
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
})
: undefined;
- const updatedFlatFieldMetadataMapsWithKanban = isDefined(
- kanbanFieldMetadata,
- )
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...kanbanFieldMetadata,
- kanbanAggregateOperationViewIds: [
- ...kanbanFieldMetadata.kanbanAggregateOperationViewIds,
- flatViewToValidate.id,
- ],
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
- })
- : dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps;
+
+ if (isDefined(kanbanFieldMetadata)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...kanbanFieldMetadata,
+ kanbanAggregateOperationViewIds: [
+ ...kanbanFieldMetadata.kanbanAggregateOperationViewIds,
+ flatViewToValidate.id,
+ ],
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ });
+ }
const calendarFieldMetadata = isDefined(
flatViewToValidate.calendarFieldMetadataId,
)
? findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatViewToValidate.calendarFieldMetadataId,
- flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
})
: undefined;
- const updatedFlatFieldMetadataMaps = isDefined(calendarFieldMetadata)
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...calendarFieldMetadata,
- calendarViewIds: [
- ...calendarFieldMetadata.calendarViewIds,
- flatViewToValidate.id,
- ],
- },
- flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
- })
- : updatedFlatFieldMetadataMapsWithKanban;
+
+ if (isDefined(calendarFieldMetadata)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...calendarFieldMetadata,
+ calendarViewIds: [
+ ...calendarFieldMetadata.calendarViewIds,
+ flatViewToValidate.id,
+ ],
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ });
+ }
return {
status: 'success',
@@ -110,10 +113,6 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
type: 'create_view',
view: flatViewToValidate,
},
- dependencyOptimisticFlatEntityMaps: {
- flatFieldMetadataMaps: updatedFlatFieldMetadataMaps,
- flatObjectMetadataMaps: updatedFlatObjectMetadataMaps,
- },
};
}
@@ -134,26 +133,27 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
const {
flatEntityToValidate: flatViewToValidate,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
} = args;
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewToValidate.objectMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
});
- const updatedFlatObjectMetadataMaps = isDefined(flatObjectMetadata)
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...flatObjectMetadata,
- viewIds: flatObjectMetadata.viewIds.filter(
- (id) => id !== flatViewToValidate.id,
- ),
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
- })
- : dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps;
+ if (isDefined(flatObjectMetadata)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...flatObjectMetadata,
+ viewIds: flatObjectMetadata.viewIds.filter(
+ (id) => id !== flatViewToValidate.id,
+ ),
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ });
+ }
const kanbanFieldMetadata = isDefined(
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
@@ -162,46 +162,46 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
flatEntityId:
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
})
: undefined;
- const updatedFlatFieldMetadataMapsWithKanban = isDefined(
- kanbanFieldMetadata,
- )
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...kanbanFieldMetadata,
- kanbanAggregateOperationViewIds:
- kanbanFieldMetadata.kanbanAggregateOperationViewIds.filter(
- (id) => id !== flatViewToValidate.id,
- ),
- },
- flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
- })
- : dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps;
+ if (isDefined(kanbanFieldMetadata)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...kanbanFieldMetadata,
+ kanbanAggregateOperationViewIds:
+ kanbanFieldMetadata.kanbanAggregateOperationViewIds.filter(
+ (id) => id !== flatViewToValidate.id,
+ ),
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ });
+ }
const calendarFieldMetadata = isDefined(
flatViewToValidate.calendarFieldMetadataId,
)
? findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewToValidate.calendarFieldMetadataId,
- flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
})
: undefined;
- const updatedFlatFieldMetadataMaps = isDefined(calendarFieldMetadata)
- ? replaceFlatEntityInFlatEntityMapsOrThrow({
- flatEntity: {
- ...calendarFieldMetadata,
- calendarViewIds: calendarFieldMetadata.calendarViewIds.filter(
- (id) => id !== flatViewToValidate.id,
- ),
- },
- flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
- })
- : updatedFlatFieldMetadataMapsWithKanban;
+ if (isDefined(calendarFieldMetadata)) {
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
+ flatEntity: {
+ ...calendarFieldMetadata,
+ calendarViewIds: calendarFieldMetadata.calendarViewIds.filter(
+ (id) => id !== flatViewToValidate.id,
+ ),
+ },
+ flatEntityMapsToMutate:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ });
+ }
return {
status: 'success',
@@ -209,10 +209,6 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
type: 'delete_view',
viewId: flatViewToValidate.id,
},
- dependencyOptimisticFlatEntityMaps: {
- flatFieldMetadataMaps: updatedFlatFieldMetadataMaps,
- flatObjectMetadataMaps: updatedFlatObjectMetadataMaps,
- },
};
}
@@ -231,11 +227,7 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
};
}
- const {
- dependencyOptimisticFlatEntityMaps,
- flatEntityId,
- flatEntityUpdates,
- } = args;
+ const { flatEntityId, flatEntityUpdates } = args;
const updateViewAction: UpdateViewAction = {
type: 'update_view',
@@ -246,7 +238,6 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
return {
status: 'success',
action: updateViewAction,
- dependencyOptimisticFlatEntityMaps,
};
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service.ts
index 0b66fa445e..781baae499 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service.ts
@@ -1,8 +1,8 @@
import { Inject } from '@nestjs/common';
+import { AllMetadataName } from 'twenty-shared/metadata';
import { type FromTo } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
-import { AllMetadataName } from 'twenty-shared/metadata';
import { LoggerService } from 'src/engine/core-modules/logger/logger.service';
import {
@@ -11,12 +11,12 @@ import {
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
import { MetadataValidationRelatedFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.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 { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
-import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
+import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
+import { deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util';
import { flatEntityDeletedCreatedUpdatedMatrixDispatcher } from 'src/engine/workspace-manager/workspace-migration-v2/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util';
import { getMetadataEmptyWorkspaceMigrationActionRecord } from 'src/engine/workspace-manager/workspace-migration-v2/utils/get-metadata-empty-workspace-migration-action-record.util';
+import { replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util';
import { FailedFlatEntityValidateAndBuild } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/failed-flat-entity-validate-and-build.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type';
@@ -48,11 +48,15 @@ export abstract class WorkspaceEntityMigrationBuilderV2Service<
public async validateAndBuild({
buildOptions,
- dependencyOptimisticFlatEntityMaps,
+ dependencyOptimisticFlatEntityMaps: inputDependencyOptimisticFlatEntityMaps,
from: fromFlatEntityMaps,
to: toFlatEntityMaps,
workspaceId,
}: ValidateAndBuildArgs): Promise> {
+ const mutableDependencyOptimisticFlatEntityMaps = structuredClone(
+ inputDependencyOptimisticFlatEntityMaps,
+ );
+
this.logger.time(`EntityBuilder ${this.metadataName}`, 'validateAndBuild');
this.logger.time(
`EntityBuilder ${this.metadataName}`,
@@ -83,13 +87,13 @@ export abstract class WorkspaceEntityMigrationBuilderV2Service<
);
this.logger.time(`EntityBuilder ${this.metadataName}`, 'entity processing');
- let optimisticFlatEntityMaps = structuredClone(fromFlatEntityMaps);
+ const optimisticFlatEntityMaps = structuredClone(fromFlatEntityMaps);
const actionsResult = getMetadataEmptyWorkspaceMigrationActionRecord(
this.metadataName,
);
const allValidationResult: FailedFlatEntityValidateAndBuild['errors'] =
[];
- let remainingFlatEntityMapsToCreate = structuredClone(
+ const remainingFlatEntityMapsToCreate = structuredClone(
createdFlatEntityMaps,
);
@@ -108,14 +112,13 @@ export abstract class WorkspaceEntityMigrationBuilderV2Service<
);
}
- remainingFlatEntityMapsToCreate =
- deleteFlatEntityFromFlatEntityMapsOrThrow({
- entityToDeleteId: flatEntityToCreateId,
- flatEntityMaps: remainingFlatEntityMapsToCreate,
- });
+ deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow({
+ entityToDeleteId: flatEntityToCreateId,
+ flatEntityMapsToMutate: remainingFlatEntityMapsToCreate,
+ });
const validationResult = await this.validateFlatEntityCreation({
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
flatEntityToValidate: flatEntityToCreate,
optimisticFlatEntityMaps,
workspaceId,
@@ -128,12 +131,10 @@ export abstract class WorkspaceEntityMigrationBuilderV2Service<
continue;
}
- optimisticFlatEntityMaps = addFlatEntityToFlatEntityMapsOrThrow({
+ addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
flatEntity: flatEntityToCreate,
- flatEntityMaps: optimisticFlatEntityMaps,
+ flatEntityMapsToMutate: optimisticFlatEntityMaps,
});
- dependencyOptimisticFlatEntityMaps =
- validationResult.dependencyOptimisticFlatEntityMaps;
actionsResult.created.push(
...(Array.isArray(validationResult.action)
@@ -151,7 +152,7 @@ export abstract class WorkspaceEntityMigrationBuilderV2Service<
'deletion validation',
);
- let remainingFlatEntityMapsToDelete = structuredClone(
+ const remainingFlatEntityMapsToDelete = structuredClone(
deletedFlatEntityMaps,
);
@@ -169,14 +170,13 @@ export abstract class WorkspaceEntityMigrationBuilderV2Service<
);
}
- remainingFlatEntityMapsToDelete =
- deleteFlatEntityFromFlatEntityMapsOrThrow({
- entityToDeleteId: flatEntityToDeleteId,
- flatEntityMaps: remainingFlatEntityMapsToDelete,
- });
+ deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow({
+ entityToDeleteId: flatEntityToDeleteId,
+ flatEntityMapsToMutate: remainingFlatEntityMapsToDelete,
+ });
const validationResult = await this.validateFlatEntityDeletion({
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
flatEntityToValidate: flatEntityToDelete,
optimisticFlatEntityMaps: optimisticFlatEntityMaps,
workspaceId,
@@ -189,12 +189,10 @@ export abstract class WorkspaceEntityMigrationBuilderV2Service<
continue;
}
- optimisticFlatEntityMaps = deleteFlatEntityFromFlatEntityMapsOrThrow({
+ deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow({
entityToDeleteId: flatEntityToDelete.id,
- flatEntityMaps: optimisticFlatEntityMaps,
+ flatEntityMapsToMutate: optimisticFlatEntityMaps,
});
- dependencyOptimisticFlatEntityMaps =
- validationResult.dependencyOptimisticFlatEntityMaps;
actionsResult.deleted.push(
...(Array.isArray(validationResult.action)
@@ -223,7 +221,7 @@ export abstract class WorkspaceEntityMigrationBuilderV2Service<
const validationResult = await this.validateFlatEntityUpdate({
flatEntityUpdates: flatEntityToUpdate.updates,
flatEntityId: flatEntityToUpdateId,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
optimisticFlatEntityMaps: optimisticFlatEntityMaps,
workspaceId,
buildOptions,
@@ -253,12 +251,10 @@ export abstract class WorkspaceEntityMigrationBuilderV2Service<
}),
};
- optimisticFlatEntityMaps = replaceFlatEntityInFlatEntityMapsOrThrow({
+ replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
flatEntity: updatedFlatEntity,
- flatEntityMaps: optimisticFlatEntityMaps,
+ flatEntityMapsToMutate: optimisticFlatEntityMaps,
});
- dependencyOptimisticFlatEntityMaps =
- validationResult.dependencyOptimisticFlatEntityMaps;
actionsResult.updated.push(
...(Array.isArray(validationResult.action)
@@ -281,7 +277,8 @@ export abstract class WorkspaceEntityMigrationBuilderV2Service<
status: 'fail',
errors: allValidationResult,
optimisticFlatEntityMaps,
- dependencyOptimisticFlatEntityMaps,
+ dependencyOptimisticFlatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps,
};
}
@@ -294,7 +291,8 @@ export abstract class WorkspaceEntityMigrationBuilderV2Service<
status: 'success',
actions: actionsResult,
optimisticFlatEntityMaps,
- dependencyOptimisticFlatEntityMaps,
+ dependencyOptimisticFlatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps,
};
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type.ts
index 43bd0516f1..4a22d573cb 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type.ts
@@ -8,7 +8,7 @@ import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-mana
export type FlatEntityValidationArgs = {
flatEntityToValidate: MetadataFlatEntity;
optimisticFlatEntityMaps: MetadataFlatEntityMaps;
- dependencyOptimisticFlatEntityMaps: MetadataValidationRelatedFlatEntityMaps;
+ mutableDependencyOptimisticFlatEntityMaps: MetadataValidationRelatedFlatEntityMaps;
workspaceId: string;
remainingFlatEntityMapsToValidate: MetadataFlatEntityMaps;
buildOptions: WorkspaceMigrationBuilderOptions;
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-result.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-result.type.ts
index 82b8b2c509..95a54731e3 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-result.type.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-result.type.ts
@@ -1,7 +1,6 @@
import { type AllMetadataName } from 'twenty-shared/metadata';
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
-import { type MetadataValidationRelatedFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
import { type MetadataWorkspaceMigrationAction } from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
@@ -14,7 +13,6 @@ export type FlatEntityValidationReturnType<
action:
| MetadataWorkspaceMigrationAction
| MetadataWorkspaceMigrationAction[];
- dependencyOptimisticFlatEntityMaps: MetadataValidationRelatedFlatEntityMaps;
}
| ({
status: 'fail';
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-cron-trigger-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-cron-trigger-validator.service.ts
index 961388be0a..ee9c00167b 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-cron-trigger-validator.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-cron-trigger-validator.service.ts
@@ -1,8 +1,8 @@
import { Injectable } from '@nestjs/common';
import { msg, t } from '@lingui/core/macro';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
import { CronTriggerExceptionCode } from 'src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception';
import { FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type';
@@ -19,7 +19,7 @@ export class FlatCronTriggerValidatorService {
flatEntityId,
flatEntityUpdates,
optimisticFlatEntityMaps: optimisticFlatCronTriggerMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.cronTrigger
>): FailedFlatEntityValidation {
@@ -52,7 +52,7 @@ export class FlatCronTriggerValidatorService {
};
const serverlessFunction =
- dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps.byId[
+ mutableDependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps.byId[
updatedFlatCronTrigger.serverlessFunctionId
];
@@ -98,7 +98,7 @@ export class FlatCronTriggerValidatorService {
public async validateFlatCronTriggerCreation({
flatEntityToValidate: flatCronTriggerToValidate,
optimisticFlatEntityMaps: optimisticFlatCronTriggerMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityValidationArgs): Promise<
FailedFlatEntityValidation
> {
@@ -123,9 +123,8 @@ export class FlatCronTriggerValidatorService {
}
const serverlessFunction =
- dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps?.byId?.[
- flatCronTriggerToValidate.serverlessFunctionId
- ];
+ mutableDependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps
+ ?.byId?.[flatCronTriggerToValidate.serverlessFunctionId];
if (!isDefined(serverlessFunction)) {
validationResult.errors.push({
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-database-event-trigger-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-database-event-trigger-validator.service.ts
index 17e4a247b9..9b3a6e289f 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-database-event-trigger-validator.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-database-event-trigger-validator.service.ts
@@ -1,8 +1,8 @@
import { Injectable } from '@nestjs/common';
import { msg, t } from '@lingui/core/macro';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
import { DatabaseEventTriggerExceptionCode } from 'src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception';
import { FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type';
@@ -20,7 +20,7 @@ export class FlatDatabaseEventTriggerValidatorService {
flatEntityId,
flatEntityUpdates,
optimisticFlatEntityMaps: optimisticFlatDatabaseEventTriggerMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.databaseEventTrigger
>): FailedFlatEntityValidation {
@@ -54,9 +54,8 @@ export class FlatDatabaseEventTriggerValidatorService {
};
const serverlessFunction =
- dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps?.byId?.[
- updatedFlatDatabaseEventTrigger.serverlessFunctionId
- ];
+ mutableDependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps
+ ?.byId?.[updatedFlatDatabaseEventTrigger.serverlessFunctionId];
if (!isDefined(serverlessFunction)) {
validationResult.errors.push({
@@ -103,7 +102,7 @@ export class FlatDatabaseEventTriggerValidatorService {
public async validateFlatDatabaseEventTriggerCreation({
flatEntityToValidate: flatDatabaseEventTriggerToValidate,
optimisticFlatEntityMaps: optimisticFlatDatabaseEventTriggerMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityValidationArgs<
typeof ALL_METADATA_NAME.databaseEventTrigger
>): Promise> {
@@ -131,9 +130,8 @@ export class FlatDatabaseEventTriggerValidatorService {
}
const serverlessFunction =
- dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps?.byId?.[
- flatDatabaseEventTriggerToValidate.serverlessFunctionId
- ];
+ mutableDependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps
+ ?.byId?.[flatDatabaseEventTriggerToValidate.serverlessFunctionId];
if (!isDefined(serverlessFunction)) {
validationResult.errors.push({
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-field-metadata-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-field-metadata-validator.service.ts
index b4d571178e..afb65413dd 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-field-metadata-validator.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-field-metadata-validator.service.ts
@@ -1,11 +1,11 @@
import { Injectable } from '@nestjs/common';
import { msg } from '@lingui/core/macro';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
-import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/metadata-modules/flat-entity/constant/empty-flat-entity-maps.constant';
+import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { FLAT_FIELD_METADATA_RELATION_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-relation-properties-to-compare.constant';
import { FlatFieldMetadataTypeValidatorService } from 'src/engine/metadata-modules/flat-field-metadata/services/flat-field-metadata-type-validator.service';
import { FlatFieldMetadataRelationPropertiesToCompare } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-relation-properties-to-compare.type';
@@ -31,7 +31,7 @@ export class FlatFieldMetadataValidatorService {
flatEntityId,
flatEntityUpdates: updates,
optimisticFlatEntityMaps: optimisticFlatFieldMetadataMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
workspaceId,
buildOptions,
}: FlatEntityUpdateValidationArgs<
@@ -70,7 +70,7 @@ export class FlatFieldMetadataValidatorService {
};
const flatObjectMetadata =
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
flatFieldMetadataToValidate.objectMetadataId
];
@@ -152,14 +152,14 @@ export class FlatFieldMetadataValidatorService {
const fieldMetadataTypeValidationErrors =
await this.flatFieldMetadataTypeValidatorService.validateFlatFieldMetadataTypeSpecificities(
{
- dependencyOptimisticFlatEntityMaps: {
+ mutableDependencyOptimisticFlatEntityMaps: {
flatObjectMetadataMaps:
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
},
optimisticFlatEntityMaps: optimisticFlatFieldMetadataMaps,
flatEntityToValidate: flatFieldMetadataToValidate,
buildOptions,
- remainingFlatEntityMapsToValidate: EMPTY_FLAT_ENTITY_MAPS,
+ remainingFlatEntityMapsToValidate: createEmptyFlatEntityMaps(),
workspaceId,
},
);
@@ -174,7 +174,7 @@ export class FlatFieldMetadataValidatorService {
validateFlatFieldMetadataDeletion({
flatEntityToValidate: { id: flatFieldMetadataToDeleteId },
optimisticFlatEntityMaps: optimisticFlatFieldMetadataMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityValidationArgs<
typeof ALL_METADATA_NAME.fieldMetadata
>): FailedFlatEntityValidation {
@@ -205,7 +205,7 @@ export class FlatFieldMetadataValidatorService {
};
const relatedFlatObjectMetadata =
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
flatFieldMetadataToDelete.objectMetadataId
];
@@ -225,12 +225,12 @@ export class FlatFieldMetadataValidatorService {
const relationTargetObjectMetadataHasBeenDeleted =
isMorphOrRelationFlatFieldMetadata(flatFieldMetadataToDelete) &&
!isDefined(
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
flatFieldMetadataToDelete.relationTargetObjectMetadataId
],
);
const parentObjectMetadataHasBeenDeleted = !isDefined(
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
flatFieldMetadataToDelete.objectMetadataId
],
);
@@ -265,7 +265,7 @@ export class FlatFieldMetadataValidatorService {
async validateFlatFieldMetadataCreation({
flatEntityToValidate: flatFieldMetadataToValidate,
optimisticFlatEntityMaps: optimisticFlatFieldMetadataMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
workspaceId,
buildOptions,
remainingFlatEntityMapsToValidate,
@@ -283,7 +283,7 @@ export class FlatFieldMetadataValidatorService {
};
const parentFlatObjectMetadata =
- dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
flatFieldMetadataToValidate.objectMetadataId
];
@@ -343,7 +343,7 @@ export class FlatFieldMetadataValidatorService {
validationResult.errors.push(
...(await this.flatFieldMetadataTypeValidatorService.validateFlatFieldMetadataTypeSpecificities(
{
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
flatEntityToValidate: flatFieldMetadataToValidate,
buildOptions,
optimisticFlatEntityMaps: optimisticFlatFieldMetadataMaps,
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-index-metadata-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-index-metadata-validator.service.ts
index 27e0bf778f..707b7fc67f 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-index-metadata-validator.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-index-metadata-validator.service.ts
@@ -1,9 +1,9 @@
import { Injectable } from '@nestjs/common';
import { msg, t } from '@lingui/core/macro';
+import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FieldMetadataType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
-import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types';
import { isValidUniqueFieldDefaultValueCombination } from 'src/engine/metadata-modules/field-metadata/utils/is-valid-unique-input.util';
@@ -49,7 +49,7 @@ export class FlatIndexValidatorService {
public validateFlatIndexCreation({
flatEntityToValidate: flatIndexToValidate,
optimisticFlatEntityMaps: optimisticFlatIndexMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityValidationArgs<
typeof ALL_METADATA_NAME.index
>): FailedFlatEntityValidation {
@@ -77,7 +77,8 @@ export class FlatIndexValidatorService {
const relatedObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatIndexToValidate.objectMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
});
if (!isDefined(relatedObjectMetadata)) {
@@ -117,7 +118,7 @@ export class FlatIndexValidatorService {
const relatedFlatField = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatIndexField.fieldMetadataId,
flatEntityMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
if (!isDefined(relatedFlatField)) {
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-object-metadata-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-object-metadata-validator.service.ts
index d9250c5dd5..2b17b077fc 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-object-metadata-validator.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-object-metadata-validator.service.ts
@@ -20,7 +20,7 @@ export class FlatObjectMetadataValidatorService {
flatEntityId,
flatEntityUpdates,
optimisticFlatEntityMaps: optimisticFlatObjectMetadataMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.objectMetadata
>): FailedFlatEntityValidation {
@@ -83,7 +83,7 @@ export class FlatObjectMetadataValidatorService {
...validateFlatObjectMetadataIdentifiers({
flatObjectMetadata: updatedFlatObjectMetadata,
flatFieldMetadataMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
}),
);
}
@@ -156,7 +156,7 @@ export class FlatObjectMetadataValidatorService {
public async validateFlatObjectMetadataCreation({
flatEntityToValidate: flatObjectMetadataToValidate,
optimisticFlatEntityMaps: optimisticFlatObjectMetadataMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityValidationArgs<
typeof ALL_METADATA_NAME.objectMetadata
>): Promise> {
@@ -195,7 +195,7 @@ export class FlatObjectMetadataValidatorService {
...validateFlatObjectMetadataIdentifiers({
flatObjectMetadata: flatObjectMetadataToValidate,
flatFieldMetadataMaps:
- dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
}),
);
objectValidationResult.errors.push(
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service.ts
index 3a56ec4c51..981d796ad6 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service.ts
@@ -1,8 +1,8 @@
import { Injectable } from '@nestjs/common';
import { msg, t } from '@lingui/core/macro';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
import { RouteTriggerExceptionCode } from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception';
import { FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
@@ -19,7 +19,7 @@ export class FlatRouteTriggerValidatorService {
flatEntityId,
flatEntityUpdates,
optimisticFlatEntityMaps: optimisticFlatRouteTriggerMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.routeTrigger
>): FailedFlatEntityValidation {
@@ -52,7 +52,7 @@ export class FlatRouteTriggerValidatorService {
};
const serverlessFunction =
- dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps.byId[
+ mutableDependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps.byId[
updatedFlatRouteTrigger.serverlessFunctionId
];
@@ -98,7 +98,7 @@ export class FlatRouteTriggerValidatorService {
public async validateFlatRouteTriggerCreation({
flatEntityToValidate: flatRouteTriggerToValidate,
optimisticFlatEntityMaps: optimisticFlatRouteTriggerMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityValidationArgs): Promise<
FailedFlatEntityValidation
> {
@@ -140,7 +140,7 @@ export class FlatRouteTriggerValidatorService {
}
const serverlessFunction =
- dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps.byId[
+ mutableDependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps.byId[
flatRouteTriggerToValidate.serverlessFunctionId
];
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service.ts
index a5b4fc8236..87eb17562b 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service.ts
@@ -1,8 +1,8 @@
import { Injectable } from '@nestjs/common';
import { msg, t } from '@lingui/core/macro';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
@@ -23,7 +23,7 @@ export class FlatViewFieldValidatorService {
flatEntityId,
flatEntityUpdates,
optimisticFlatEntityMaps: optimisticFlatViewFieldMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.viewField
>): FailedFlatEntityValidation {
@@ -63,7 +63,7 @@ export class FlatViewFieldValidatorService {
const flatView = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: updatedFlatViewField.viewId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMaps: mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
if (!isDefined(flatView)) {
@@ -78,7 +78,8 @@ export class FlatViewFieldValidatorService {
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatView.objectMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
});
if (!isDefined(flatObjectMetadata)) {
@@ -118,7 +119,7 @@ export class FlatViewFieldValidatorService {
public validateFlatViewFieldDeletion({
flatEntityToValidate: { id: viewFieldIdToDelete },
optimisticFlatEntityMaps: optimisticFlatViewFieldMaps,
- dependencyOptimisticFlatEntityMaps: {
+ mutableDependencyOptimisticFlatEntityMaps: {
flatFieldMetadataMaps,
flatObjectMetadataMaps,
},
@@ -181,7 +182,7 @@ export class FlatViewFieldValidatorService {
public validateFlatViewFieldCreation({
flatEntityToValidate: flatViewFieldToValidate,
optimisticFlatEntityMaps: optimisticFlatViewFieldMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityValidationArgs<
typeof ALL_METADATA_NAME.viewField
>): FailedFlatEntityValidation {
@@ -210,7 +211,8 @@ export class FlatViewFieldValidatorService {
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewFieldToValidate.fieldMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
if (!isDefined(flatFieldMetadata)) {
@@ -222,7 +224,7 @@ export class FlatViewFieldValidatorService {
}
const flatView =
- dependencyOptimisticFlatEntityMaps.flatViewMaps.byId[
+ mutableDependencyOptimisticFlatEntityMaps.flatViewMaps.byId[
flatViewFieldToValidate.viewId
];
@@ -256,7 +258,8 @@ export class FlatViewFieldValidatorService {
}
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
flatEntityId: flatView.objectMetadataId,
});
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-filter-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-filter-validator.service.ts
index 4d380e618f..03ce9fbb98 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-filter-validator.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-filter-validator.service.ts
@@ -1,8 +1,8 @@
import { Injectable } from '@nestjs/common';
import { msg, t } from '@lingui/core/macro';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { type FlatViewFilter } from 'src/engine/metadata-modules/flat-view-filter/types/flat-view-filter.type';
@@ -19,7 +19,7 @@ export class FlatViewFilterValidatorService {
validateFlatViewFilterCreation({
flatEntityToValidate: flatViewFilterToValidate,
optimisticFlatEntityMaps: optimisticFlatViewFilterMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityValidationArgs<
typeof ALL_METADATA_NAME.viewFilter
>): FailedFlatEntityValidation {
@@ -46,7 +46,7 @@ export class FlatViewFilterValidatorService {
const referencedView = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewFilterToValidate.viewId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMaps: mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
if (!isDefined(referencedView)) {
@@ -59,7 +59,8 @@ export class FlatViewFilterValidatorService {
const referencedFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewFilterToValidate.fieldMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
if (!isDefined(referencedFieldMetadata)) {
@@ -109,7 +110,7 @@ export class FlatViewFilterValidatorService {
flatEntityId,
flatEntityUpdates,
optimisticFlatEntityMaps: optimisticFlatViewFilterMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.viewFilter
>): FailedFlatEntityValidation {
@@ -142,7 +143,8 @@ export class FlatViewFilterValidatorService {
const referencedFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: updatedFlatViewFilter.fieldMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
if (!isDefined(referencedFieldMetadata)) {
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-group-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-group-validator.service.ts
index 5c80bffa2b..a843ab405b 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-group-validator.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-group-validator.service.ts
@@ -1,8 +1,8 @@
import { Injectable } from '@nestjs/common';
import { msg, t } from '@lingui/core/macro';
-import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type';
@@ -18,7 +18,7 @@ export class FlatViewGroupValidatorService {
flatEntityId,
flatEntityUpdates,
optimisticFlatEntityMaps: optimisticFlatViewGroupMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.viewGroup
>): FailedFlatEntityValidation {
@@ -58,7 +58,7 @@ export class FlatViewGroupValidatorService {
const flatView = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: updatedFlatViewGroup.viewId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatViewMaps,
+ flatEntityMaps: mutableDependencyOptimisticFlatEntityMaps.flatViewMaps,
});
if (!isDefined(flatView)) {
@@ -71,7 +71,8 @@ export class FlatViewGroupValidatorService {
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: updatedFlatViewGroup.fieldMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
if (!isDefined(flatFieldMetadata)) {
@@ -116,7 +117,7 @@ export class FlatViewGroupValidatorService {
public validateFlatViewGroupCreation({
flatEntityToValidate: flatViewGroupToValidate,
optimisticFlatEntityMaps: optimisticFlatViewGroupMaps,
- dependencyOptimisticFlatEntityMaps,
+ mutableDependencyOptimisticFlatEntityMaps,
}: FlatEntityValidationArgs<
typeof ALL_METADATA_NAME.viewGroup
>): FailedFlatEntityValidation {
@@ -145,7 +146,8 @@ export class FlatViewGroupValidatorService {
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewGroupToValidate.fieldMetadataId,
- flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
+ flatEntityMaps:
+ mutableDependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
if (!isDefined(flatFieldMetadata)) {
@@ -157,7 +159,7 @@ export class FlatViewGroupValidatorService {
}
const flatView =
- dependencyOptimisticFlatEntityMaps.flatViewMaps.byId[
+ mutableDependencyOptimisticFlatEntityMaps.flatViewMaps.byId[
flatViewGroupToValidate.viewId
];
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-validator.service.ts
index 6c7a2deb35..6990336acf 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-validator.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-validator.service.ts
@@ -1,6 +1,6 @@
import { msg, t } from '@lingui/core/macro';
-import { isDefined } from 'twenty-shared/utils';
import { type ALL_METADATA_NAME } from 'twenty-shared/metadata';
+import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
@@ -17,7 +17,7 @@ export class FlatViewValidatorService {
flatEntityId,
flatEntityUpdates,
optimisticFlatEntityMaps: optimisticFlatViewMaps,
- dependencyOptimisticFlatEntityMaps: { flatFieldMetadataMaps },
+ mutableDependencyOptimisticFlatEntityMaps: { flatFieldMetadataMaps },
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.view
>): FailedFlatEntityValidation {
@@ -95,7 +95,7 @@ export class FlatViewValidatorService {
public async validateFlatViewCreation({
flatEntityToValidate: flatViewToValidate,
optimisticFlatEntityMaps: optimisticFlatViewMaps,
- dependencyOptimisticFlatEntityMaps: {
+ mutableDependencyOptimisticFlatEntityMaps: {
flatFieldMetadataMaps,
flatObjectMetadataMaps,
},
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/services/workspace-migration-runner-v2.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/services/workspace-migration-runner-v2.service.ts
index d7734ee22f..b48345c7a5 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/services/workspace-migration-runner-v2.service.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/services/workspace-migration-runner-v2.service.ts
@@ -30,11 +30,12 @@ export class WorkspaceMigrationRunnerV2Service {
private readonly logger: LoggerService,
) {}
- private async invalidateLegacyCache({
+ private getLegacyCacheInvalidationPromises({
workspaceMigration: { actions, workspaceId },
}: {
workspaceMigration: WorkspaceMigrationV2;
- }) {
+ }): Promise[] {
+ const asyncOperations: Promise[] = [];
const shouldIncrementMetadataGraphqlSchemaVersion = actions.some(
(action) => {
switch (action.type) {
@@ -54,13 +55,15 @@ export class WorkspaceMigrationRunnerV2Service {
);
if (shouldIncrementMetadataGraphqlSchemaVersion) {
- await this.workspaceMetadataVersionService.incrementMetadataVersion(
- workspaceId,
- );
- await this.workspacePermissionsCacheService.recomputeRolesPermissionsCache(
- {
+ asyncOperations.push(
+ this.workspaceMetadataVersionService.incrementMetadataVersion(
workspaceId,
- },
+ ),
+ );
+ asyncOperations.push(
+ this.workspacePermissionsCacheService.recomputeRolesPermissionsCache({
+ workspaceId,
+ }),
);
}
@@ -92,11 +95,15 @@ export class WorkspaceMigrationRunnerV2Service {
shouldInvalidFindCoreViewsGraphqlCacheOperation ||
shouldIncrementMetadataGraphqlSchemaVersion
) {
- await this.workspaceCacheStorageService.flushGraphQLOperation({
- operationName: FIND_ALL_CORE_VIEWS_GRAPHQL_OPERATION,
- workspaceId,
- });
+ asyncOperations.push(
+ this.workspaceCacheStorageService.flushGraphQLOperation({
+ operationName: FIND_ALL_CORE_VIEWS_GRAPHQL_OPERATION,
+ workspaceId,
+ }),
+ );
}
+
+ return asyncOperations;
}
run = async ({
@@ -170,19 +177,34 @@ export class WorkspaceMigrationRunnerV2Service {
`Cache invalidation ${flatEntitiesCacheToInvalidate.join()}`,
);
- await this.flatEntityMapsCacheService.invalidateFlatEntityMaps({
- workspaceId,
- flatMapsKeys: [
- ...new Set([
- ...flatEntityMapsToInvalidate,
- ...(relatedFlatEntityMapsKeys ?? []),
- ]),
- ],
- });
+ const invalidationResults = await Promise.allSettled([
+ this.flatEntityMapsCacheService.invalidateFlatEntityMaps({
+ workspaceId,
+ flatMapsKeys: [
+ ...new Set([
+ ...flatEntityMapsToInvalidate,
+ ...(relatedFlatEntityMapsKeys ?? []),
+ ]),
+ ],
+ }),
+ ...this.getLegacyCacheInvalidationPromises({
+ workspaceMigration: {
+ actions,
+ workspaceId,
+ relatedFlatEntityMapsKeys,
+ },
+ }),
+ ]);
- await this.invalidateLegacyCache({
- workspaceMigration: { actions, workspaceId, relatedFlatEntityMapsKeys },
- });
+ const invalidationFailures = invalidationResults.filter(
+ (result) => result.status === 'rejected',
+ );
+
+ if (invalidationFailures.length > 0) {
+ throw new Error(
+ `Failed to invalidate ${invalidationFailures.length} cache operations`,
+ );
+ }
this.logger.timeEnd(
'Runner',