diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-17/1-17-migrate-attachment-to-morph-relations.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-17/1-17-migrate-attachment-to-morph-relations.command.ts index 89c1ad0306d..9a7550d7977 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-17/1-17-migrate-attachment-to-morph-relations.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-17/1-17-migrate-attachment-to-morph-relations.command.ts @@ -18,9 +18,11 @@ import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/service import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util'; +import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util'; import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util'; import { getMetadataRelatedMetadataNames } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-related-metadata-names.util'; +import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service'; @@ -131,7 +133,10 @@ export class MigrateAttachmentToMorphRelationsCommand extends ActiveOrSuspendedW const attachmentTargetRelationFields = attachmentFieldMetadatas .filter(isMorphOrRelationFlatFieldMetadata) - .filter((field) => field.type === FieldMetadataType.RELATION) + .filter( + (field): field is FlatFieldMetadata => + field.type === FieldMetadataType.RELATION, + ) .filter((field) => { const isStandardAppField = this.isTwentyStandardApplicationField({ field, @@ -143,9 +148,11 @@ export class MigrateAttachmentToMorphRelationsCommand extends ActiveOrSuspendedW attachmentTargetFieldUniversalIdentifiers.has( field.universalIdentifier, ); - const targetObjectMetadata = field.relationTargetObjectMetadataId - ? flatObjectMetadataMaps.byId[field.relationTargetObjectMetadataId] - : undefined; + const targetObjectMetadata = + findFlatEntityByIdInFlatEntityMapsOrThrow({ + flatEntityId: field.relationTargetObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); const isCustomTarget = !isStandardAppField && targetObjectMetadata?.isCustom === true; diff --git a/packages/twenty-server/src/engine/api/common/common-args-handlers/common-query-selected-fields/common-selected-fields.handler.ts b/packages/twenty-server/src/engine/api/common/common-args-handlers/common-query-selected-fields/common-selected-fields.handler.ts index f3fb0639f3e..7cac55b2245 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-handlers/common-query-selected-fields/common-selected-fields.handler.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-handlers/common-query-selected-fields/common-selected-fields.handler.ts @@ -14,6 +14,7 @@ import { MAX_DEPTH } from 'src/engine/api/rest/input-request-parsers/constants/m import { Depth } from 'src/engine/api/rest/input-request-parsers/types/depth.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; 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 { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -100,8 +101,10 @@ export class CommonSelectedFieldsHandler { if (!field.relationTargetObjectMetadataId) continue; - const relationTargetObjectMetadata = - flatObjectMetadataMaps.byId[field.relationTargetObjectMetadataId]; + const relationTargetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: field.relationTargetObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(relationTargetObjectMetadata)) { throw new CommonQueryRunnerException( diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg.processor.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg.processor.ts index 9e4c365e9c8..1cf6d3916f8 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg.processor.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/data-arg.processor.ts @@ -55,6 +55,7 @@ import { transformPhonesValue } from 'src/engine/core-modules/record-transformer import { transformRichTextV2Value } from 'src/engine/core-modules/record-transformer/utils/transform-rich-text-v2.util'; import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception'; import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -119,7 +120,10 @@ export class DataArgProcessor { ); } - const fieldMetadata = flatFieldMetadataMaps.byId[fieldMetadataId]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!fieldMetadata) { throw new CommonQueryRunnerException( diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/query-runner-args.factory.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/query-runner-args.factory.ts index 084a0139391..10be2a71ebe 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/query-runner-args.factory.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/query-runner-args.factory.ts @@ -7,6 +7,7 @@ import { type ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query- import { RecordInputTransformerService } from 'src/engine/core-modules/record-transformer/services/record-input-transformer.service'; import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -69,7 +70,10 @@ export class QueryRunnerArgsFactory { ) { const fieldMetadataId = fieldIdByName[key]; const fieldMetadata = fieldMetadataId - ? flatFieldMetadataMaps.byId[fieldMetadataId] + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }) : undefined; if (!fieldMetadata) { @@ -103,7 +107,10 @@ export class QueryRunnerArgsFactory { flatObjectMetadata: FlatObjectMetadata, flatFieldMetadataMaps: FlatEntityMaps, ) { - const fieldMetadata = flatFieldMetadataMaps.byId[fieldIdByName[key]]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldIdByName[key], + flatEntityMaps: flatFieldMetadataMaps, + }); if (!fieldMetadata) { return value; diff --git a/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/common-create-many-query-runner.service.ts b/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/common-create-many-query-runner.service.ts index 91a587c43e8..50cae7de4e7 100644 --- a/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/common-create-many-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/common-create-many-query-runner.service.ts @@ -32,6 +32,7 @@ import { getAllSelectableColumnNames } from 'src/engine/api/utils/get-all-select import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -468,8 +469,10 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer flatObjectMetadata, ); - const createdByFieldMetadata = - flatFieldMetadataMaps.byId[fieldIdByName['createdBy']]; + const createdByFieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldIdByName['createdBy'], + flatEntityMaps: flatFieldMetadataMaps, + }); if (!isDefined(createdByFieldMetadata)) { throw new CommonQueryRunnerException( diff --git a/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/__tests__/get-conflicting-fields.util.spec.ts b/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/__tests__/get-conflicting-fields.util.spec.ts index ad3215575fd..9d72bc0e650 100644 --- a/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/__tests__/get-conflicting-fields.util.spec.ts +++ b/packages/twenty-server/src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/__tests__/get-conflicting-fields.util.spec.ts @@ -94,17 +94,17 @@ describe('getConflictingFields', () => { const buildFlatFieldMetadataMaps = ( fields: FlatFieldMetadata[], ): FlatEntityMaps => ({ - byId: fields.reduce( + byUniversalIdentifier: fields.reduce( (acc, field) => { - acc[field.id] = field; + acc[field.universalIdentifier] = field; return acc; }, {} as Record, ), - idByUniversalIdentifier: fields.reduce( + universalIdentifierById: fields.reduce( (acc, field) => { - acc[field.universalIdentifier] = field.id; + acc[field.id] = field.universalIdentifier; return acc; }, diff --git a/packages/twenty-server/src/engine/api/common/common-query-runners/common-group-by-query-runner.service.ts b/packages/twenty-server/src/engine/api/common/common-query-runners/common-group-by-query-runner.service.ts index 20ecfcdd849..7e82a1aaf39 100644 --- a/packages/twenty-server/src/engine/api/common/common-query-runners/common-group-by-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/common/common-query-runners/common-group-by-query-runner.service.ts @@ -17,7 +17,6 @@ import { ObjectLiteral } from 'typeorm'; import { ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface'; -import { WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type'; import { CommonBaseQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-base-query-runner.service'; import { CommonQueryRunnerException, @@ -46,7 +45,9 @@ import { GroupByWithRecordsService } from 'src/engine/api/graphql/graphql-query- import { getGroupLimit } from 'src/engine/api/graphql/graphql-query-runner/group-by/utils/get-group-limit.util'; import { ProcessAggregateHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-aggregate.helper'; import { getFlatFieldsFromFlatObjectMetadata } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util'; +import { WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type'; import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util'; import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -208,8 +209,10 @@ export class CommonGroupByQueryRunnerService extends CommonBaseQueryRunnerServic ); const recordFilters = viewFilters.map((viewFilter) => { - const fieldMetadata = - flatFieldMetadataMaps.byId[viewFilter.fieldMetadataId]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFilter.fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!fieldMetadata) { throw new CommonQueryRunnerException( diff --git a/packages/twenty-server/src/engine/api/common/common-query-runners/common-merge-many-query-runner.service.ts b/packages/twenty-server/src/engine/api/common/common-query-runners/common-merge-many-query-runner.service.ts index b82e5ea3b8c..63088bdaaad 100644 --- a/packages/twenty-server/src/engine/api/common/common-query-runners/common-merge-many-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/common/common-query-runners/common-merge-many-query-runner.service.ts @@ -15,7 +15,6 @@ import { isDefined } from 'twenty-shared/utils'; import { FindOptionsRelations, In, ObjectLiteral } from 'typeorm'; import { v4 as uuidv4 } from 'uuid'; -import { WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type'; import { CommonBaseQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-base-query-runner.service'; import { CommonQueryRunnerException, @@ -34,7 +33,9 @@ import { buildColumnsToReturn } from 'src/engine/api/graphql/graphql-query-runne import { buildColumnsToSelect } from 'src/engine/api/graphql/graphql-query-runner/utils/build-columns-to-select'; import { hasRecordFieldValue } from 'src/engine/api/graphql/graphql-query-runner/utils/has-record-field-value.util'; import { mergeFieldValues } from 'src/engine/api/graphql/graphql-query-runner/utils/merge-field-values.util'; +import { WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type'; import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util'; @@ -246,8 +247,10 @@ export class CommonMergeManyQueryRunnerService extends CommonBaseQueryRunnerServ flatFieldMetadataMaps, flatObjectMetadata, ); - const fieldMetadata = - flatFieldMetadataMaps.byId[fieldIdByName[fieldName]]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldIdByName[fieldName], + flatEntityMaps: flatFieldMetadataMaps, + }); if (!fieldMetadata) { return; @@ -282,7 +285,10 @@ export class CommonMergeManyQueryRunnerService extends CommonBaseQueryRunnerServ flatFieldMetadataMaps, flatObjectMetadata, ); - const fieldMetadata = flatFieldMetadataMaps.byId[fieldIdByName[fieldName]]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldIdByName[fieldName], + flatEntityMaps: flatFieldMetadataMaps, + }); return fieldMetadata?.isSystem ?? false; } @@ -364,9 +370,9 @@ export class CommonMergeManyQueryRunnerService extends CommonBaseQueryRunnerServ joinColumnName: string | undefined; }> = []; - for (const field of Object.values(flatFieldMetadataMaps.byId).filter( - isDefined, - )) { + for (const field of Object.values( + flatFieldMetadataMaps.byUniversalIdentifier, + ).filter(isDefined)) { if ( !isFlatFieldMetadataOfType(field, FieldMetadataType.RELATION) || field.relationTargetObjectMetadataId !== flatObjectMetadata.id || @@ -386,7 +392,10 @@ export class CommonMergeManyQueryRunnerService extends CommonBaseQueryRunnerServ continue; } - const objMetadata = flatObjectMetadataMaps.byId[field.objectMetadataId]; + const objMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: field.objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!objMetadata) { continue; diff --git a/packages/twenty-server/src/engine/api/common/common-result-getters/common-result-getters.service.ts b/packages/twenty-server/src/engine/api/common/common-result-getters/common-result-getters.service.ts index 293f03acf72..478237d396f 100644 --- a/packages/twenty-server/src/engine/api/common/common-result-getters/common-result-getters.service.ts +++ b/packages/twenty-server/src/engine/api/common/common-result-getters/common-result-getters.service.ts @@ -18,6 +18,7 @@ import { WorkspaceMemberQueryResultGetterHandler } from 'src/engine/api/graphql/ import { FilesFieldService } from 'src/engine/core-modules/file/files-field/files-field.service'; import { FileService } from 'src/engine/core-modules/file/services/file.service'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { @@ -118,9 +119,11 @@ export class CommonResultGettersService { const handlers = [ this.getObjectHandler(flatObjectMetadata.nameSingular), ...Object.keys(record) - .map( - (recordFieldName) => - flatFieldMetadataMaps.byId[fieldIdByName[recordFieldName]], + .map((recordFieldName) => + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldIdByName[recordFieldName], + flatEntityMaps: flatFieldMetadataMaps, + }), ) .filter(isDefined) .map((fieldMetadata) => this.fieldHandlers.get(fieldMetadata.type)) @@ -128,9 +131,11 @@ export class CommonResultGettersService { ]; const relationFields = Object.keys(record) - .map( - (recordFieldName) => - flatFieldMetadataMaps.byId[fieldIdByName[recordFieldName]], + .map((recordFieldName) => + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldIdByName[recordFieldName], + flatEntityMaps: flatFieldMetadataMaps, + }), ) .filter(isDefined) .filter((fieldMetadata) => @@ -178,9 +183,11 @@ export class CommonResultGettersService { } const fieldMetadata = Object.keys(record) - .map( - (recordFieldName) => - flatFieldMetadataMaps.byId[fieldIdByName[recordFieldName]], + .map((recordFieldName) => + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldIdByName[recordFieldName], + flatEntityMaps: flatFieldMetadataMaps, + }), ) .filter(isDefined); diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/__mocks__/mockPersonObjectMetadata.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/__mocks__/mockPersonObjectMetadata.ts index 59242f8bab8..221659a4d85 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/__mocks__/mockPersonObjectMetadata.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/__mocks__/mockPersonObjectMetadata.ts @@ -95,17 +95,17 @@ const mockFieldMetadatas: FlatFieldMetadata[] = [ export const mockPersonFlatFieldMetadataMaps = (): FlatEntityMaps => ({ - byId: mockFieldMetadatas.reduce( + byUniversalIdentifier: mockFieldMetadatas.reduce( (acc, field) => { - acc[field.id] = field; + acc[field.universalIdentifier] = field; return acc; }, {} as Record, ), - idByUniversalIdentifier: mockFieldMetadatas.reduce( + universalIdentifierById: mockFieldMetadatas.reduce( (acc, field) => { - acc[field.universalIdentifier] = field.id; + acc[field.id] = field.universalIdentifier; return acc; }, @@ -120,11 +120,11 @@ export const mockPersonFlatObjectMetadataMaps = ( const flatObjectMetadata = mockPersonFlatObjectMetadata(duplicateCriteria); return { - byId: { - [flatObjectMetadata.id]: flatObjectMetadata, + byUniversalIdentifier: { + [flatObjectMetadata.universalIdentifier as string]: flatObjectMetadata, }, - idByUniversalIdentifier: { - [flatObjectMetadata.universalIdentifier as string]: flatObjectMetadata.id, + universalIdentifierById: { + [flatObjectMetadata.id]: flatObjectMetadata.universalIdentifier as string, }, universalIdentifiersByApplicationId: {}, }; diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-filter/graphql-query-filter-field.parser.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-filter/graphql-query-filter-field.parser.ts index 65c0ad5fbe3..55910b16809 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-filter/graphql-query-filter-field.parser.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-filter/graphql-query-filter-field.parser.ts @@ -11,6 +11,7 @@ import { computeWhereConditionParts } from 'src/engine/api/graphql/graphql-query import { type CompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/composite-field-metadata-type.type'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -18,7 +19,6 @@ import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object const ARRAY_OPERATORS = ['in', 'contains', 'notContains']; export class GraphqlQueryFilterFieldParser { - private flatObjectMetadata: FlatObjectMetadata; private flatFieldMetadataMaps: FlatEntityMaps; private fieldIdByName: Record; private fieldIdByJoinColumnName: Record; @@ -27,7 +27,6 @@ export class GraphqlQueryFilterFieldParser { flatObjectMetadata: FlatObjectMetadata, flatFieldMetadataMaps: FlatEntityMaps, ) { - this.flatObjectMetadata = flatObjectMetadata; this.flatFieldMetadataMaps = flatFieldMetadataMaps; const fieldMaps = buildFieldMapsFromFlatObjectMetadata( @@ -51,7 +50,10 @@ export class GraphqlQueryFilterFieldParser { const fieldMetadataId = this.fieldIdByName[`${key}`] || this.fieldIdByJoinColumnName[`${key}`]; - const fieldMetadata = this.flatFieldMetadataMaps.byId[fieldMetadataId]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: this.flatFieldMetadataMaps, + }); if (!isDefined(fieldMetadata)) { throw new Error(`Field metadata not found for field: ${key}`); diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/graphql-query-order-group-by.parser.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/graphql-query-order-group-by.parser.ts index 06738d28ceb..9f0c47e869e 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/graphql-query-order-group-by.parser.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/graphql-query-order-group-by.parser.ts @@ -30,11 +30,13 @@ import { import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { formatColumnNamesFromCompositeFieldAndSubfields } from 'src/engine/twenty-orm/utils/format-column-names-from-composite-field-and-subfield.util'; +import { findManyFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps.util'; import { type OrderByClause } from './types/order-by-condition.type'; @@ -70,9 +72,10 @@ export class GraphqlQueryOrderGroupByParser { }): Record[] { const parsedOrderBy: Record[] = []; - const fields = this.flatObjectMetadata.fieldIds - .map((id) => this.flatFieldMetadataMaps.byId[id]) - .filter(isDefined); + const fields = findManyFlatEntityByIdInFlatEntityMaps({ + flatEntityIds: this.flatObjectMetadata.fieldIds, + flatEntityMaps: this.flatFieldMetadataMaps, + }); const availableAggregations: Record = getAvailableAggregationsFromObjectFields(fields); @@ -97,7 +100,10 @@ export class GraphqlQueryOrderGroupByParser { const fieldName = Object.keys(orderByArg)[0]; const fieldMetadataId = this.fieldIdByName[fieldName]; - const fieldMetadata = this.flatFieldMetadataMaps.byId[fieldMetadataId]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: this.flatFieldMetadataMaps, + }); if (!isDefined(fieldMetadata)) { throw new UserInputError(`Cannot orderBy unknown field: ${fieldName}.`); diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/graphql-query-order.parser.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/graphql-query-order.parser.ts index 1520798949d..5af7e1510cb 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/graphql-query-order.parser.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/graphql-query-order.parser.ts @@ -18,6 +18,7 @@ import { isOrderByDirection } from 'src/engine/api/graphql/graphql-query-runner/ import { parseCompositeFieldForOrder } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/utils/parse-composite-field-for-order.util'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util'; @@ -71,7 +72,10 @@ export class GraphqlQueryOrderFieldParser { const fieldMetadataId = this.fieldIdByName[fieldName] || this.fieldIdByJoinColumnName[fieldName]; - const fieldMetadata = this.flatFieldMetadataMaps.byId[fieldMetadataId]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: this.flatFieldMetadataMaps, + }); if (!fieldMetadata || orderByDirection === undefined) { throw new GraphqlQueryRunnerException( @@ -173,10 +177,10 @@ export class GraphqlQueryOrderFieldParser { return null; } - const targetObjectMetadata = - this.flatObjectMetadataMaps.byId[ - fieldMetadata.relationTargetObjectMetadataId - ]; + const targetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadata.relationTargetObjectMetadataId, + flatEntityMaps: this.flatObjectMetadataMaps, + }); if (!isDefined(targetObjectMetadata)) { return null; @@ -205,8 +209,10 @@ export class GraphqlQueryOrderFieldParser { ); } - const nestedFieldMetadata = - this.flatFieldMetadataMaps.byId[nestedFieldMetadataId]; + const nestedFieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: nestedFieldMetadataId, + flatEntityMaps: this.flatFieldMetadataMaps, + }); if (!isDefined(nestedFieldMetadata)) { return null; diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/utils/prepare-for-order-by-relation-field-parsing.util.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/utils/prepare-for-order-by-relation-field-parsing.util.ts index 3c65fa47d61..4cb4d45f587 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/utils/prepare-for-order-by-relation-field-parsing.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/utils/prepare-for-order-by-relation-field-parsing.util.ts @@ -10,6 +10,7 @@ import { isGroupByRelationField } from 'src/engine/api/graphql/graphql-query-run import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -56,8 +57,10 @@ export const prepareForOrderByRelationFieldParsing = ({ ); } - const targetObjectMetadata = - flatObjectMetadataMaps.byId[fieldMetadata.relationTargetObjectMetadataId]; + const targetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadata.relationTargetObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(targetObjectMetadata)) { throw new UserInputError( @@ -79,7 +82,10 @@ export const prepareForOrderByRelationFieldParsing = ({ ); } - const nestedFieldMetadata = flatFieldMetadataMaps.byId[nestedFieldMetadataId]; + const nestedFieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: nestedFieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!isDefined(nestedFieldMetadata) || !isDefined(nestedFieldMetadataId)) { throw new UserInputError( diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-selected-fields/graphql-selected-fields-aggregate.parser.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-selected-fields/graphql-selected-fields-aggregate.parser.ts index 8c6af9489d0..3f74321d6bf 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-selected-fields/graphql-selected-fields-aggregate.parser.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-selected-fields/graphql-selected-fields-aggregate.parser.ts @@ -6,6 +6,7 @@ import { getAvailableAggregationsFromObjectFields, } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-available-aggregations-from-object-fields.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -18,7 +19,12 @@ export class GraphqlQuerySelectedFieldsAggregateParser { accumulator: GraphqlQuerySelectedFieldsResult, ): void { const fields = flatObjectMetadata.fieldIds - .map((id) => flatFieldMetadataMaps.byId[id]) + .map((id) => + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: id, + flatEntityMaps: flatFieldMetadataMaps, + }), + ) .filter(isDefined); const availableAggregations: Record = diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-selected-fields/graphql-selected-fields.parser.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-selected-fields/graphql-selected-fields.parser.ts index a111c181947..0fdf2d40183 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-selected-fields/graphql-selected-fields.parser.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-selected-fields/graphql-selected-fields.parser.ts @@ -9,6 +9,7 @@ import { GraphqlQuerySelectedFieldsRelationParser } from 'src/engine/api/graphql import { type CompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/composite-field-metadata-type.type'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util'; @@ -136,10 +137,10 @@ export class GraphqlQuerySelectedFieldsParser { FieldMetadataType.MORPH_RELATION, ) ) { - const targetObjectMetadata = - this.flatObjectMetadataMaps.byId[ - fieldMetadata.relationTargetObjectMetadataId - ]; + const targetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadata.relationTargetObjectMetadataId, + flatEntityMaps: this.flatObjectMetadataMaps, + }); if ( !fieldMetadata.settings?.relationType || diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/parse-group-by-args.util.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/parse-group-by-args.util.ts index 1b1faf65758..e60a2d90a23 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/parse-group-by-args.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/parse-group-by-args.util.ts @@ -8,6 +8,7 @@ import { isGroupByDateFieldDefinition } from 'src/engine/api/graphql/graphql-que import { parseGroupByRelationField } from 'src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/parse-group-by-relation-field.util'; import { validateSingleKeyForGroupByOrThrow } from 'src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/validate-single-key-for-group-by-or-throw.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util'; @@ -40,7 +41,10 @@ export const parseGroupByArgs = ( const fieldMetadataId = fieldIdByName[fieldName] || fieldIdByJoinColumnName[fieldName]; const fieldMetadata = fieldMetadataId - ? flatFieldMetadataMaps.byId[fieldMetadataId] + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }) : undefined; if (!isDefined(fieldMetadata) || !isDefined(fieldMetadataId)) { diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/parse-group-by-relation-field.util.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/parse-group-by-relation-field.util.ts index 48edf3206ac..56337d447ce 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/parse-group-by-relation-field.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/parse-group-by-relation-field.util.ts @@ -14,6 +14,7 @@ import { validateSingleKeyForGroupByOrThrow } from 'src/engine/api/graphql/graph import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; @@ -63,7 +64,10 @@ const getNestedFieldMetadataDetails = ({ ); const nestedFieldMetadataId = fieldIdByName[nestedFieldName]; - const nestedFieldMetadata = flatFieldMetadataMaps.byId[nestedFieldMetadataId]; + const nestedFieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: nestedFieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!isDefined(nestedFieldMetadata) || !isDefined(nestedFieldMetadataId)) { throw new GraphqlQueryRunnerException( diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper.ts index 1551e509650..3ca822cadc9 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper.ts @@ -21,6 +21,7 @@ import { type CompositeFieldMetadataType } from 'src/engine/metadata-modules/fie import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; 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 { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -193,10 +194,10 @@ export class ObjectRecordsToGraphqlConnectionHelper { } if (isMorphOrRelationFlatFieldMetadata(fieldMetadata)) { - const targetObjectMetadata = - this.flatObjectMetadataMaps.byId[ - fieldMetadata.relationTargetObjectMetadataId - ]; + const targetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadata.relationTargetObjectMetadataId, + flatEntityMaps: this.flatObjectMetadataMaps, + }); if (!isDefined(targetObjectMetadata)) { continue; diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations-v2.helper.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations-v2.helper.ts index 24902cf5d32..80601fc3677 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations-v2.helper.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations-v2.helper.ts @@ -293,10 +293,10 @@ export class ProcessNestedRelationsV2Helper { ); } - const targetRelation = - flatFieldMetadataMaps.byId[ - targetFieldMetadata.relationTargetFieldMetadataId - ]; + const targetRelation = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: targetFieldMetadata.relationTargetFieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); const targetRelationName = targetRelation?.name; diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/build-columns-to-select.spec.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/build-columns-to-select.spec.ts index e3bced57438..63ba14a2b6f 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/build-columns-to-select.spec.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/__tests__/build-columns-to-select.spec.ts @@ -115,17 +115,17 @@ describe('buildColumnsToSelect', () => { const buildFlatFieldMetadataMaps = ( fields: FlatFieldMetadata[], ): FlatEntityMaps => ({ - byId: fields.reduce( + byUniversalIdentifier: fields.reduce( (acc, field) => { - acc[field.id] = field; + acc[field.universalIdentifier] = field; return acc; }, {} as Record, ), - idByUniversalIdentifier: fields.reduce( + universalIdentifierById: fields.reduce( (acc, field) => { - acc[field.universalIdentifier] = field.id; + acc[field.id] = field.universalIdentifier; return acc; }, @@ -137,18 +137,18 @@ describe('buildColumnsToSelect', () => { const buildFlatObjectMetadataMaps = ( objects: FlatObjectMetadata[], ): FlatEntityMaps => ({ - byId: objects.reduce( + byUniversalIdentifier: objects.reduce( (acc, obj) => { - acc[obj.id] = obj; + acc[obj.universalIdentifier as string] = obj; return acc; }, {} as Record, ), - idByUniversalIdentifier: objects.reduce( + universalIdentifierById: objects.reduce( (acc, obj) => { if (obj.universalIdentifier) { - acc[obj.universalIdentifier] = obj.id; + acc[obj.id] = obj.universalIdentifier; } return acc; diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/build-columns-to-select.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/build-columns-to-select.ts index 37079f5a274..0381a851891 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/build-columns-to-select.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/build-columns-to-select.ts @@ -4,6 +4,7 @@ import { isDefined } from 'twenty-shared/utils'; import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util'; @@ -74,9 +75,10 @@ const getRequiredRelationColumns = ( isFlatFieldMetadataOfType(fieldMetadata, FieldMetadataType.MORPH_RELATION) ) { const targetObjectMetadata = fieldMetadata.relationTargetObjectMetadataId - ? flatObjectMetadataMaps.byId[ - fieldMetadata.relationTargetObjectMetadataId - ] + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadata.relationTargetObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }) : undefined; if ( diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/get-field-metadata-from-graphql-field.util.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/get-field-metadata-from-graphql-field.util.ts index 1c6bfb479e4..79a37233c78 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/get-field-metadata-from-graphql-field.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/get-field-metadata-from-graphql-field.util.ts @@ -4,6 +4,7 @@ import { isDefined } from 'twenty-shared/utils'; import { getTargetObjectMetadataOrThrow } from 'src/engine/api/graphql/graphql-query-runner/utils/get-target-object-metadata.util'; import { getFlatFieldsFromFlatObjectMetadata } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util'; @@ -29,7 +30,10 @@ export function getFieldMetadataFromGraphQLField({ const sourceFieldMetadataId = fieldIdByName[graphQLField]; let sourceFieldMetadata = sourceFieldMetadataId - ? flatFieldMetadataMaps.byId[sourceFieldMetadataId] + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: sourceFieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }) : undefined; // If empty, it could be a morph relation diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/get-target-object-metadata.util.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/get-target-object-metadata.util.ts index a0c8a814476..24352429026 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/get-target-object-metadata.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/get-target-object-metadata.util.ts @@ -4,6 +4,7 @@ import { GraphqlQueryRunnerExceptionCode, } from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -19,8 +20,10 @@ export const getTargetObjectMetadataOrThrow = ( ); } - const targetObjectMetadata = - flatObjectMetadataMaps.byId[fieldMetadata.relationTargetObjectMetadataId]; + const targetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadata.relationTargetObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!targetObjectMetadata) { throw new GraphqlQueryRunnerException( diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts index d206f3a1f73..2d622082a13 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-resolver-builder/workspace-resolver.factory.ts @@ -85,7 +85,7 @@ export class WorkspaceResolverFactory { }; for (const flatObjectMetadata of Object.values( - flatObjectMetadataMaps.byId, + flatObjectMetadataMaps.byUniversalIdentifier, ).filter(isDefined)) { // Generate query resolvers for (const methodName of workspaceResolverBuilderMethods.queries) { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts index 97dbd9086e1..595014f998d 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts @@ -81,7 +81,7 @@ export class GqlTypeGenerator { ) { const { flatObjectMetadataMaps, flatFieldMetadataMaps } = context; const objectMetadataCollection = Object.values( - flatObjectMetadataMaps.byId, + flatObjectMetadataMaps.byUniversalIdentifier, ).filter(isDefined); this.logger.log( diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/relation-connect-gql-input-type.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/relation-connect-gql-input-type.generator.ts index 46fb87b6410..79146dc9b48 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/relation-connect-gql-input-type.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/relation-connect-gql-input-type.generator.ts @@ -9,16 +9,13 @@ import { } from 'graphql'; import { RELATION_NESTED_QUERY_KEYWORDS } from 'twenty-shared/constants'; import { compositeTypeDefinitions } from 'twenty-shared/types'; -import { - getUniqueConstraintsFields, - isDefined, - pascalCase, -} from 'twenty-shared/utils'; +import { getUniqueConstraintsFields, pascalCase } from 'twenty-shared/utils'; import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage'; import { type SchemaGenerationContext } from 'src/engine/api/graphql/workspace-schema-builder/types/schema-generation-context.type'; import { computeRelationConnectInputTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-relation-connect-input-type-key.util'; +import { findManyFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps.util'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -79,14 +76,14 @@ export class RelationConnectGqlInputTypeGenerator { ): Record { const { flatIndexMaps } = context; - const indexMetadatas = flatObjectMetadata.indexMetadataIds - .map((indexId) => flatIndexMaps.byId[indexId]) - .filter(isDefined) - .map((flatIndex) => ({ - id: flatIndex.id, - isUnique: flatIndex.isUnique, - indexFieldMetadatas: flatIndex.flatIndexFieldMetadatas, - })); + const indexMetadatas = findManyFlatEntityByIdInFlatEntityMaps({ + flatEntityIds: flatObjectMetadata.indexMetadataIds, + flatEntityMaps: flatIndexMaps, + }).map((flatIndex) => ({ + id: flatIndex.id, + isUnique: flatIndex.isUnique, + indexFieldMetadatas: flatIndex.flatIndexFieldMetadatas, + })); const objectWithIndexes = { id: flatObjectMetadata.id, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/relation-field-metadata-gql-type.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/relation-field-metadata-gql-type.generator.ts index 6157bfa73bb..d37e2d70a1c 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/relation-field-metadata-gql-type.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/relation-field-metadata-gql-type.generator.ts @@ -18,6 +18,7 @@ import { type SchemaGenerationContext } from 'src/engine/api/graphql/workspace-s import { computeObjectMetadataInputTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-object-metadata-input-type.util'; import { computeRelationConnectInputTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-relation-connect-input-type-key.util'; import { extractGraphQLRelationFieldNames } from 'src/engine/api/graphql/workspace-schema-builder/utils/extract-graphql-relation-field-names.util'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; @Injectable() @@ -162,10 +163,10 @@ export class RelationFieldMetadataGqlInputTypeGenerator { isDefined(fieldMetadata.relationTargetObjectMetadataId) && isDefined(context) ) { - const targetObjectMetadata = - context.flatObjectMetadataMaps.byId[ - fieldMetadata.relationTargetObjectMetadataId - ]; + const targetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadata.relationTargetObjectMetadataId, + flatEntityMaps: context.flatObjectMetadataMaps, + }); if (isDefined(targetObjectMetadata)) { const targetOrderByInputTypeKey = computeObjectMetadataInputTypeKey( @@ -212,10 +213,10 @@ export class RelationFieldMetadataGqlInputTypeGenerator { isDefined(fieldMetadata.relationTargetObjectMetadataId) && isDefined(context) ) { - const targetObjectMetadata = - context.flatObjectMetadataMaps.byId[ - fieldMetadata.relationTargetObjectMetadataId - ]; + const targetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadata.relationTargetObjectMetadataId, + flatEntityMaps: context.flatObjectMetadataMaps, + }); if (isDefined(targetObjectMetadata)) { const targetGroupByInputTypeKey = computeObjectMetadataInputTypeKey( diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/object-metadata-with-relations-gql-object-type.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/object-metadata-with-relations-gql-object-type.generator.ts index 7f7fcf9ba83..ab534cc64f5 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/object-metadata-with-relations-gql-object-type.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/object-metadata-with-relations-gql-object-type.generator.ts @@ -18,6 +18,7 @@ import { GraphQLOutputTypeFieldConfigMap } from 'src/engine/api/graphql/workspac import { type SchemaGenerationContext } from 'src/engine/api/graphql/workspace-schema-builder/types/schema-generation-context.type'; import { computeObjectMetadataObjectTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-object-metadata-object-type-key.util'; import { getResolverArgs } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-resolver-args.util'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -110,10 +111,10 @@ export class ObjectMetadataWithRelationsGqlObjectTypeGenerator { ); } - const objectMetadataTarget = - context.flatObjectMetadataMaps.byId[ - flatFieldMetadata.relationTargetObjectMetadataId - ]; + const objectMetadataTarget = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatFieldMetadata.relationTargetObjectMetadataId, + flatEntityMaps: context.flatObjectMetadataMaps, + }); if (!isDefined(objectMetadataTarget)) { throw new Error( diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/root-type.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/root-type.generator.ts index e5e660227ad..0ac1354db02 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/root-type.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/root-type.generator.ts @@ -49,7 +49,7 @@ export class RootTypeGenerator { } const objectMetadataCollection = Object.values( - context.flatObjectMetadataMaps.byId, + context.flatObjectMetadataMaps.byUniversalIdentifier, ).filter(isDefined); this.gqlTypesStorage.addGqlType( diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util.ts index 958434dc9aa..97ac2670f0d 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util.ts @@ -1,6 +1,5 @@ -import { isDefined } from 'twenty-shared/utils'; - import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findManyFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -8,7 +7,8 @@ export const getFlatFieldsFromFlatObjectMetadata = ( flatObjectMetadata: FlatObjectMetadata, flatFieldMetadataMaps: FlatEntityMaps, ): FlatFieldMetadata[] => { - return flatObjectMetadata.fieldIds - .map((fieldId) => flatFieldMetadataMaps.byId[fieldId]) - .filter(isDefined); + return findManyFlatEntityByIdInFlatEntityMaps({ + flatEntityIds: flatObjectMetadata.fieldIds, + flatEntityMaps: flatFieldMetadataMaps, + }); }; diff --git a/packages/twenty-server/src/engine/api/rest/core/handlers/rest-api-base.handler.ts b/packages/twenty-server/src/engine/api/rest/core/handlers/rest-api-base.handler.ts index 9bbcef3b0e1..1b2a3da2179 100644 --- a/packages/twenty-server/src/engine/api/rest/core/handlers/rest-api-base.handler.ts +++ b/packages/twenty-server/src/engine/api/rest/core/handlers/rest-api-base.handler.ts @@ -25,6 +25,7 @@ import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/service import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -226,13 +227,19 @@ export abstract class RestApiBaseHandler { let objectId = idByNamePlural[parsedObject]; let flatObjectMetadataItem = objectId - ? flatObjectMetadataMaps.byId[objectId] + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectId, + flatEntityMaps: flatObjectMetadataMaps, + }) : undefined; if (!flatObjectMetadataItem) { const wrongObjectId = idByNameSingular[parsedObject]; const wrongFlatObjectMetadataItem = wrongObjectId - ? flatObjectMetadataMaps.byId[wrongObjectId] + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: wrongObjectId, + flatEntityMaps: flatObjectMetadataMaps, + }) : undefined; let hint = 'eg: companies'; diff --git a/packages/twenty-server/src/engine/api/rest/core/rest-to-common-args-handlers/utils/__tests__/get-all-selectable-fields.util.spec.ts b/packages/twenty-server/src/engine/api/rest/core/rest-to-common-args-handlers/utils/__tests__/get-all-selectable-fields.util.spec.ts index 0bba3266126..fa92fe7b7ff 100644 --- a/packages/twenty-server/src/engine/api/rest/core/rest-to-common-args-handlers/utils/__tests__/get-all-selectable-fields.util.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/core/rest-to-common-args-handlers/utils/__tests__/get-all-selectable-fields.util.spec.ts @@ -33,17 +33,17 @@ describe('getAllSelectableFields', () => { const buildFlatFieldMetadataMaps = ( fields: FlatFieldMetadata[], ): FlatEntityMaps => ({ - byId: fields.reduce( + byUniversalIdentifier: fields.reduce( (acc, field) => { - acc[field.id] = field; + acc[field.universalIdentifier] = field; return acc; }, {} as Record, ), - idByUniversalIdentifier: fields.reduce( + universalIdentifierById: fields.reduce( (acc, field) => { - acc[field.universalIdentifier] = field.id; + acc[field.id] = field.universalIdentifier; return acc; }, diff --git a/packages/twenty-server/src/engine/api/utils/__tests__/compute-cursor-arg-filter.utils.spec.ts b/packages/twenty-server/src/engine/api/utils/__tests__/compute-cursor-arg-filter.utils.spec.ts index f840ac14c07..6a37348d73f 100644 --- a/packages/twenty-server/src/engine/api/utils/__tests__/compute-cursor-arg-filter.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/utils/__tests__/compute-cursor-arg-filter.utils.spec.ts @@ -58,17 +58,17 @@ describe('computeCursorArgFilter', () => { const buildFlatFieldMetadataMaps = ( fields: FlatFieldMetadata[], ): FlatEntityMaps => ({ - byId: fields.reduce( + byUniversalIdentifier: fields.reduce( (acc, field) => { - acc[field.id] = field; + acc[field.universalIdentifier] = field; return acc; }, {} as Record, ), - idByUniversalIdentifier: fields.reduce( + universalIdentifierById: fields.reduce( (acc, field) => { - acc[field.universalIdentifier] = field.id; + acc[field.id] = field.universalIdentifier; return acc; }, diff --git a/packages/twenty-server/src/engine/api/utils/validate-and-get-order-by.utils.ts b/packages/twenty-server/src/engine/api/utils/validate-and-get-order-by.utils.ts index 1a85d9d5a66..6ebc47337d6 100644 --- a/packages/twenty-server/src/engine/api/utils/validate-and-get-order-by.utils.ts +++ b/packages/twenty-server/src/engine/api/utils/validate-and-get-order-by.utils.ts @@ -15,6 +15,7 @@ import { GraphqlQueryRunnerExceptionCode, } from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; const isOrderByDirection = (value: unknown): value is OrderByDirection => { @@ -103,7 +104,10 @@ export const countRelationFieldsInOrderBy = ( return orderBy.filter((orderByItem) => { const fieldName = Object.keys(orderByItem)[0]; const fieldMetadataId = fieldIdByName[fieldName]; - const fieldMetadata = flatFieldMetadataMaps.byId[fieldMetadataId]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); return fieldMetadata?.type === FieldMetadataType.RELATION; }).length; diff --git a/packages/twenty-server/src/engine/core-modules/__mocks__/mockFlatObjectMetadatas.ts b/packages/twenty-server/src/engine/core-modules/__mocks__/mockFlatObjectMetadatas.ts index 6c90b26c227..d16178a9347 100644 --- a/packages/twenty-server/src/engine/core-modules/__mocks__/mockFlatObjectMetadatas.ts +++ b/packages/twenty-server/src/engine/core-modules/__mocks__/mockFlatObjectMetadatas.ts @@ -87,8 +87,8 @@ export const mockFlatObjectMetadatas: FlatObjectMetadata[] = [ ]; export const mockFlatFieldMetadataMaps: FlatEntityMaps = { - byId: { - [personNameFieldId]: getFlatFieldMetadataMock({ + byUniversalIdentifier: { + 'person-name-field-universal-id': getFlatFieldMetadataMock({ id: personNameFieldId, type: FieldMetadataType.FULL_NAME, icon: 'test-field-icon', @@ -102,7 +102,7 @@ export const mockFlatFieldMetadataMaps: FlatEntityMaps = { universalIdentifier: 'person-name-field-universal-id', applicationId: workspaceId, }), - [companyNameFieldId]: getFlatFieldMetadataMock({ + 'company-name-field-universal-id': getFlatFieldMetadataMock({ id: companyNameFieldId, type: FieldMetadataType.TEXT, icon: 'test-field-icon', @@ -116,7 +116,7 @@ export const mockFlatFieldMetadataMaps: FlatEntityMaps = { universalIdentifier: 'company-name-field-universal-id', applicationId: workspaceId, }), - [companyDomainNameFieldId]: getFlatFieldMetadataMock({ + 'company-domain-name-field-universal-id': getFlatFieldMetadataMock({ id: companyDomainNameFieldId, type: FieldMetadataType.LINKS, icon: 'test-field-icon', @@ -134,7 +134,7 @@ export const mockFlatFieldMetadataMaps: FlatEntityMaps = { universalIdentifier: 'company-domain-name-field-universal-id', applicationId: workspaceId, }), - [customObjectNameFieldId]: getFlatFieldMetadataMock({ + 'custom-object-name-field-universal-id': getFlatFieldMetadataMock({ id: customObjectNameFieldId, type: FieldMetadataType.TEXT, icon: 'test-field-icon', @@ -148,7 +148,7 @@ export const mockFlatFieldMetadataMaps: FlatEntityMaps = { universalIdentifier: 'custom-object-name-field-universal-id', applicationId: workspaceId, }), - [customObjectImageFieldId]: getFlatFieldMetadataMock({ + 'custom-object-image-field-universal-id': getFlatFieldMetadataMock({ id: customObjectImageFieldId, type: FieldMetadataType.TEXT, icon: 'test-field-icon', @@ -163,6 +163,12 @@ export const mockFlatFieldMetadataMaps: FlatEntityMaps = { applicationId: workspaceId, }), }, - idByUniversalIdentifier: {}, + universalIdentifierById: { + [personNameFieldId]: 'person-name-field-universal-id', + [companyNameFieldId]: 'company-name-field-universal-id', + [companyDomainNameFieldId]: 'company-domain-name-field-universal-id', + [customObjectNameFieldId]: 'custom-object-name-field-universal-id', + [customObjectImageFieldId]: 'custom-object-image-field-universal-id', + }, universalIdentifiersByApplicationId: {}, }; diff --git a/packages/twenty-server/src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts b/packages/twenty-server/src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts index 57cb49197f6..8e46077384e 100644 --- a/packages/twenty-server/src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts +++ b/packages/twenty-server/src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps.ts @@ -2,10 +2,11 @@ import { FieldMetadataType } from 'twenty-shared/types'; 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 FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock'; -import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; +import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; +import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { type ObjectMetadataInfo } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service'; const workspaceId = '20202020-0000-0000-0000-000000000000'; @@ -219,13 +220,13 @@ export const mockFlatObjectMetadataMaps: FlatEntityMaps = ALL_FLAT_OBJECTS.reduce( (acc, object) => ({ ...acc, - byId: { - ...acc.byId, - [object.id]: object, + byUniversalIdentifier: { + ...acc.byUniversalIdentifier, + [object.universalIdentifier]: object, }, - idByUniversalIdentifier: { - ...acc.idByUniversalIdentifier, - [object.universalIdentifier]: object.id, + universalIdentifierById: { + ...acc.universalIdentifierById, + [object.id]: object.universalIdentifier, }, }), createEmptyFlatEntityMaps() as FlatEntityMaps, @@ -235,13 +236,13 @@ export const mockFlatFieldMetadataMaps: FlatEntityMaps = ALL_FLAT_FIELDS.reduce( (acc, field) => ({ ...acc, - byId: { - ...acc.byId, - [field.id]: field, + byUniversalIdentifier: { + ...acc.byUniversalIdentifier, + [field.universalIdentifier]: field, }, - idByUniversalIdentifier: { - ...acc.idByUniversalIdentifier, - [field.universalIdentifier]: field.id, + universalIdentifierById: { + ...acc.universalIdentifierById, + [field.id]: field.universalIdentifier, }, }), createEmptyFlatEntityMaps() as FlatEntityMaps, @@ -260,7 +261,10 @@ export const getMockObjectMetadataInfo = ( nameSingular: string, ): ObjectMetadataInfo => { const objectId = mockObjectIdByNameSingular[nameSingular]; - const flatObjectMetadata = mockFlatObjectMetadataMaps.byId[objectId]; + const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectId, + flatEntityMaps: mockFlatObjectMetadataMaps, + }); if (!flatObjectMetadata) { throw new Error( diff --git a/packages/twenty-server/src/engine/core-modules/actor/services/__tests__/actor-from-auth-context.service.spec.ts b/packages/twenty-server/src/engine/core-modules/actor/services/__tests__/actor-from-auth-context.service.spec.ts index 8c93ff16cdb..bfcc5f02682 100644 --- a/packages/twenty-server/src/engine/core-modules/actor/services/__tests__/actor-from-auth-context.service.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/actor/services/__tests__/actor-from-auth-context.service.spec.ts @@ -67,25 +67,37 @@ describe('ActorFromAuthContextService', () => { useValue: { getOrRecomputeManyOrAllFlatEntityMaps: jest.fn().mockResolvedValue({ flatObjectMetadataMaps: { - byId: { - 'person-id': { + byUniversalIdentifier: { + 'person-universal-id': { id: 'person-id', nameSingular: 'person', fieldIds: ['createdBy-id'], + universalIdentifier: 'person-universal-id', }, }, + universalIdentifierById: { + 'person-id': 'person-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: { - 'createdBy-id': { + byUniversalIdentifier: { + 'createdBy-universal-id': { id: 'createdBy-id', name: 'createdBy', objectMetadataId: 'person-id', + universalIdentifier: 'createdBy-universal-id', }, }, + universalIdentifierById: { + 'createdBy-id': 'createdBy-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, flatIndexMaps: { - byId: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, + universalIdentifiersByApplicationId: {}, }, }), }, diff --git a/packages/twenty-server/src/engine/core-modules/actor/services/actor-from-auth-context.service.ts b/packages/twenty-server/src/engine/core-modules/actor/services/actor-from-auth-context.service.ts index b87c7784278..22b45549423 100644 --- a/packages/twenty-server/src/engine/core-modules/actor/services/actor-from-auth-context.service.ts +++ b/packages/twenty-server/src/engine/core-modules/actor/services/actor-from-auth-context.service.ts @@ -10,6 +10,7 @@ import { buildCreatedByFromFullNameMetadata } from 'src/engine/core-modules/acto import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { buildObjectIdByNameMaps } from 'src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util'; import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @@ -103,7 +104,10 @@ export class ActorFromAuthContextService { ); const objectId = idByNameSingular[objectMetadataNameSingular]; const objectMetadata = objectId - ? flatObjectMetadataMaps.byId[objectId] + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectId, + flatEntityMaps: flatObjectMetadataMaps, + }) : undefined; const fieldIdByName = objectMetadata diff --git a/packages/twenty-server/src/engine/core-modules/application/services/application-sync.service.ts b/packages/twenty-server/src/engine/core-modules/application/services/application-sync.service.ts index e6fc4317840..aa41239e722 100644 --- a/packages/twenty-server/src/engine/core-modules/application/services/application-sync.service.ts +++ b/packages/twenty-server/src/engine/core-modules/application/services/application-sync.service.ts @@ -29,8 +29,11 @@ import { DataSourceService } from 'src/engine/metadata-modules/data-source/data- import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input'; import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/services/field-metadata.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { findFlatEntitiesByApplicationId } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util'; +import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; +import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { LogicFunctionService } from 'src/engine/metadata-modules/logic-function/services/logic-function.service'; import { FlatLogicFunction } from 'src/engine/metadata-modules/logic-function/types/flat-logic-function.type'; import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; @@ -286,13 +289,24 @@ export class ApplicationSyncService { ); const formattedObjectPermissions = role.objectPermissions - ?.map((perm) => ({ - ...perm, - objectMetadataId: - flatObjectMetadataMaps.idByUniversalIdentifier[ - perm.objectUniversalIdentifier - ], - })) + ?.map((perm) => { + const flatObjectMetadata = findFlatEntityByUniversalIdentifier({ + flatEntityMaps: flatObjectMetadataMaps, + universalIdentifier: perm.objectUniversalIdentifier, + }); + + if (!isDefined(flatObjectMetadata)) { + throw new ApplicationException( + `Failed to find object with universalIdentifier ${perm.objectUniversalIdentifier}`, + ApplicationExceptionCode.OBJECT_NOT_FOUND, + ); + } + + return { + ...perm, + objectMetadataId: flatObjectMetadata.id, + }; + }) .filter((perm): perm is typeof perm & { objectMetadataId: string } => isDefined(perm.objectMetadataId), ); @@ -309,20 +323,34 @@ export class ApplicationSyncService { const formattedFieldPermissions = role?.fieldPermissions ?.map((perm) => { - const objectMetadataId = - flatObjectMetadataMaps.idByUniversalIdentifier[ - perm.objectUniversalIdentifier - ]; + const flatObjectMetadata = findFlatEntityByUniversalIdentifier({ + flatEntityMaps: flatObjectMetadataMaps, + universalIdentifier: perm.objectUniversalIdentifier, + }); - const fieldMetadataId = - flatFieldMetadataMaps.idByUniversalIdentifier[ - perm.fieldUniversalIdentifier - ]; + if (!isDefined(flatObjectMetadata)) { + throw new ApplicationException( + `Failed to find object with universalIdentifier ${perm.objectUniversalIdentifier}`, + ApplicationExceptionCode.OBJECT_NOT_FOUND, + ); + } + + const flatFieldMetadata = findFlatEntityByUniversalIdentifier({ + flatEntityMaps: flatFieldMetadataMaps, + universalIdentifier: perm.fieldUniversalIdentifier, + }); + + if (!isDefined(flatFieldMetadata)) { + throw new ApplicationException( + `Failed to find field with universalIdentifier ${perm.fieldUniversalIdentifier}`, + ApplicationExceptionCode.FIELD_NOT_FOUND, + ); + } return { ...perm, - objectMetadataId, - fieldMetadataId, + objectMetadataId: flatObjectMetadata.id, + fieldMetadataId: flatFieldMetadata.id, }; }) .filter( @@ -395,7 +423,7 @@ export class ApplicationSyncService { ); const existingFields = Object.values( - existingFlatFieldMetadataMaps.byId, + existingFlatFieldMetadataMaps.byUniversalIdentifier, ).filter( (field) => isDefined(field) && @@ -514,9 +542,7 @@ export class ApplicationSyncService { fieldsToSync: ObjectFieldManifest[]; workspaceId: string; ownerFlatApplication: FlatApplication; - flatObjectMetadataMaps: { - idByUniversalIdentifier: Partial>; - }; + flatObjectMetadataMaps: FlatEntityMaps; }) { const relationFields = fieldsToSync.filter((field) => this.isRelationFieldManifest(field), @@ -532,7 +558,7 @@ export class ApplicationSyncService { for (const relation of relationFields) { const existingRelationField = Object.values( - flatFieldMetadataMaps.byId, + flatFieldMetadataMaps.byUniversalIdentifier, ).find( (field) => isDefined(field) && @@ -543,12 +569,12 @@ export class ApplicationSyncService { continue; } - const targetObjectId = - flatObjectMetadataMaps.idByUniversalIdentifier[ - relation.targetObjectUniversalIdentifier - ]; + const targetObjectMetadata = findFlatEntityByUniversalIdentifier({ + flatEntityMaps: flatObjectMetadataMaps, + universalIdentifier: relation.targetObjectUniversalIdentifier, + }); - if (!isDefined(targetObjectId)) { + if (!isDefined(targetObjectMetadata)) { throw new ApplicationException( `Failed to find target object with universalIdentifier ${relation.targetObjectUniversalIdentifier}`, ApplicationExceptionCode.OBJECT_NOT_FOUND, @@ -568,7 +594,7 @@ export class ApplicationSyncService { workspaceId, relationCreationPayload: { type: relation.relationType, - targetObjectMetadataId: targetObjectId, + targetObjectMetadataId: targetObjectMetadata.id, targetFieldLabel: relation.targetFieldLabel, targetFieldIcon: relation.targetFieldIcon ?? 'IconRelationOneToMany', }, @@ -600,7 +626,7 @@ export class ApplicationSyncService { ); const applicationObjects = Object.values( - existingFlatObjectMetadataMaps.byId, + existingFlatObjectMetadataMaps.byUniversalIdentifier, ).filter( (obj) => isDefined(obj) && obj.applicationId === ownerFlatApplication.id, // TODO handle when migrating to trinite usage @@ -732,12 +758,12 @@ export class ApplicationSyncService { ); for (const objectToSync of objectsToSync) { - const sourceObjectId = - flatObjectMetadataMaps.idByUniversalIdentifier[ - objectToSync.universalIdentifier - ]; + const sourceObjectMetadata = findFlatEntityByUniversalIdentifier({ + flatEntityMaps: flatObjectMetadataMaps, + universalIdentifier: objectToSync.universalIdentifier, + }); - if (!isDefined(sourceObjectId)) { + if (!isDefined(sourceObjectMetadata)) { throw new ApplicationException( `Failed to find source object with universalIdentifier ${objectToSync.universalIdentifier}`, ApplicationExceptionCode.OBJECT_NOT_FOUND, @@ -745,7 +771,7 @@ export class ApplicationSyncService { } await this.syncObjectFieldsRelationOnly({ - objectId: sourceObjectId, + objectId: sourceObjectMetadata.id, fieldsToSync: objectToSync.fields, workspaceId, ownerFlatApplication, @@ -772,12 +798,12 @@ export class ApplicationSyncService { ); for (const fieldToSync of fieldsToSync) { - const targetObjectId = - flatObjectMetadataMaps.idByUniversalIdentifier[ - fieldToSync.objectUniversalIdentifier - ]; + const targetObjectMetadata = findFlatEntityByUniversalIdentifier({ + flatEntityMaps: flatObjectMetadataMaps, + universalIdentifier: fieldToSync.objectUniversalIdentifier, + }); - if (!isDefined(targetObjectId)) { + if (!isDefined(targetObjectMetadata)) { throw new ApplicationException( 'Object extension must specify either nameSingular or universalIdentifier in targetObject', ApplicationExceptionCode.INVALID_INPUT, @@ -785,14 +811,14 @@ export class ApplicationSyncService { } await this.syncObjectFieldsWithoutRelations({ - objectId: targetObjectId, + objectId: targetObjectMetadata.id, fieldsToSync: [fieldToSync], workspaceId, ownerFlatApplication, }); await this.syncObjectFieldsRelationOnly({ - objectId: targetObjectId, + objectId: targetObjectMetadata.id, fieldsToSync: [fieldToSync], workspaceId, ownerFlatApplication, @@ -823,7 +849,7 @@ export class ApplicationSyncService { ); const applicationLogicFunctions = Object.values( - flatLogicFunctionMaps.byId, + flatLogicFunctionMaps.byUniversalIdentifier, ).filter( (logicFunction) => isDefined(logicFunction) && diff --git a/packages/twenty-server/src/engine/core-modules/event-emitter/utils/__tests__/object-record-changed-values.spec.ts b/packages/twenty-server/src/engine/core-modules/event-emitter/utils/__tests__/object-record-changed-values.spec.ts index 87bc33d43a3..f4e35a6bf37 100644 --- a/packages/twenty-server/src/engine/core-modules/event-emitter/utils/__tests__/object-record-changed-values.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/event-emitter/utils/__tests__/object-record-changed-values.spec.ts @@ -42,8 +42,8 @@ const mockObjectMetadata: FlatObjectMetadata = { }; const mockFlatFieldMetadataMaps: FlatEntityMaps = { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }; diff --git a/packages/twenty-server/src/engine/core-modules/event-emitter/utils/object-record-changed-values.ts b/packages/twenty-server/src/engine/core-modules/event-emitter/utils/object-record-changed-values.ts index 3286a8323f7..905f5b41d04 100644 --- a/packages/twenty-server/src/engine/core-modules/event-emitter/utils/object-record-changed-values.ts +++ b/packages/twenty-server/src/engine/core-modules/event-emitter/utils/object-record-changed-values.ts @@ -4,6 +4,7 @@ import { fastDeepEqual } from 'twenty-shared/utils'; import { STANDARD_OBJECTS } from 'twenty-shared/metadata'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -42,7 +43,12 @@ export const objectRecordChangedValues = ( return Object.keys(newRecord).reduce( (acc, key) => { const fieldId = fieldIdByName[key]; - const field = fieldId ? flatFieldMetadataMaps.byId[fieldId] : undefined; + const field = fieldId + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldId, + flatEntityMaps: flatFieldMetadataMaps, + }) + : undefined; const oldRecordValue = oldRecord[key]; const newRecordValue = newRecord[key]; diff --git a/packages/twenty-server/src/engine/core-modules/file/files-field/listeners/files-field-deletion.listener.ts b/packages/twenty-server/src/engine/core-modules/file/files-field/listeners/files-field-deletion.listener.ts index c7db1e7d641..58dbae12ae0 100644 --- a/packages/twenty-server/src/engine/core-modules/file/files-field/listeners/files-field-deletion.listener.ts +++ b/packages/twenty-server/src/engine/core-modules/file/files-field/listeners/files-field-deletion.listener.ts @@ -15,6 +15,7 @@ import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decora import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants'; import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { buildObjectIdByNameMaps } from 'src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util'; import { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event-batch.type'; @@ -57,7 +58,10 @@ export class FilesFieldDeletionListener { return; } - const flatObjectMetadata = flatObjectMetadataMaps.byId[objectId]; + const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(flatObjectMetadata)) { return; diff --git a/packages/twenty-server/src/engine/core-modules/open-api/open-api.service.ts b/packages/twenty-server/src/engine/core-modules/open-api/open-api.service.ts index 171c7ef4a7b..8d8d8903d48 100644 --- a/packages/twenty-server/src/engine/core-modules/open-api/open-api.service.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/open-api.service.ts @@ -80,7 +80,7 @@ export class OpenApiService { ); const flatObjectMetadataArray = Object.values( - flatObjectMetadataMaps.byId, + flatObjectMetadataMaps.byUniversalIdentifier, ).filter(isDefined); flatObjectMetadataArray.sort((a, b) => diff --git a/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts index ae94efc3c65..c84304c15cd 100644 --- a/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts @@ -17,10 +17,18 @@ describe('computeSchemaComponents', () => { } as any; const flatFieldMetadataMaps = { - byId: Object.fromEntries( - objectMetadataItemMock.fields.map((f) => [f.id, f as any]), + byUniversalIdentifier: Object.fromEntries( + objectMetadataItemMock.fields.map((f) => [ + f.universalIdentifier || f.id, + f as any, + ]), + ), + universalIdentifierById: Object.fromEntries( + objectMetadataItemMock.fields.map((f) => [ + f.id, + f.universalIdentifier || f.id, + ]), ), - idByUniversalIdentifier: {}, universalIdentifiersByApplicationId: {}, }; @@ -33,11 +41,17 @@ describe('computeSchemaComponents', () => { } as any; const flatObjectMetadataMaps = { - byId: { - [flatObjectMetadata.id]: flatObjectMetadata, - [relationTargetObjectMetadata.id]: relationTargetObjectMetadata, + byUniversalIdentifier: { + [flatObjectMetadata.universalIdentifier as string]: flatObjectMetadata, + [relationTargetObjectMetadata.universalIdentifier as string]: + relationTargetObjectMetadata, + }, + universalIdentifierById: { + [flatObjectMetadata.id]: + flatObjectMetadata.universalIdentifier as string, + [relationTargetObjectMetadata.id]: + relationTargetObjectMetadata.universalIdentifier as string, }, - idByUniversalIdentifier: {}, universalIdentifiersByApplicationId: {}, }; @@ -814,7 +828,7 @@ describe('computeSchemaComponents', () => { Pick< FieldMetadataEntity, 'id' | 'name' | 'type' | 'isNullable' | 'defaultValue' | 'settings' - > + > & { universalIdentifier: string } >[] = [ { title: 'Integer dataType with decimals', @@ -825,6 +839,7 @@ describe('computeSchemaComponents', () => { isNullable: false, defaultValue: null, settings: { type: 'number', decimals: 1, dataType: NumberDataType.INT }, + universalIdentifier: 'number1', }, }, { @@ -836,6 +851,7 @@ describe('computeSchemaComponents', () => { isNullable: false, defaultValue: null, settings: { type: 'number', dataType: NumberDataType.FLOAT }, + universalIdentifier: 'number2', }, }, { @@ -847,6 +863,7 @@ describe('computeSchemaComponents', () => { isNullable: false, defaultValue: null, settings: { type: 'number', decimals: 0, dataType: NumberDataType.INT }, + universalIdentifier: 'number3', }, }, ]; @@ -862,18 +879,23 @@ describe('computeSchemaComponents', () => { } as any; const flatFieldMetadataMaps = { - byId: { - [field.id]: field as any, + byUniversalIdentifier: { + [field.universalIdentifier || field.id]: field as any, + }, + universalIdentifierById: { + [field.id]: field.universalIdentifier || field.id, }, - idByUniversalIdentifier: {}, universalIdentifiersByApplicationId: {}, }; const flatObjectMetadataMaps = { - byId: { - [flatObjectMetadata.id]: flatObjectMetadata, + byUniversalIdentifier: { + [flatObjectMetadata.universalIdentifier as string]: flatObjectMetadata, + }, + universalIdentifierById: { + [flatObjectMetadata.id]: + flatObjectMetadata.universalIdentifier as string, }, - idByUniversalIdentifier: {}, universalIdentifiersByApplicationId: {}, }; diff --git a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts index 3caf54cd987..87b5dbfa832 100644 --- a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts @@ -25,6 +25,7 @@ import { computeViewIdParameters, } from 'src/engine/core-modules/open-api/utils/parameters.utils'; import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type'; +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'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -105,8 +106,10 @@ const getSchemaComponentsRelationProperties = ( let itemProperty = {} as Property; if (isFieldMetadataEntityOfType(field, FieldMetadataType.RELATION)) { - const targetObjectMetadata = - flatObjectMetadataMaps.byId[field.relationTargetObjectMetadataId]; + const targetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: field.relationTargetObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!targetObjectMetadata) { return node; diff --git a/packages/twenty-server/src/engine/core-modules/record-crud/services/common-api-context-builder.service.ts b/packages/twenty-server/src/engine/core-modules/record-crud/services/common-api-context-builder.service.ts index dddf6e81226..3ba21f46a69 100644 --- a/packages/twenty-server/src/engine/core-modules/record-crud/services/common-api-context-builder.service.ts +++ b/packages/twenty-server/src/engine/core-modules/record-crud/services/common-api-context-builder.service.ts @@ -16,6 +16,7 @@ import { RecordCrudExceptionCode, } from 'src/engine/core-modules/record-crud/exceptions/record-crud.exception'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -77,7 +78,10 @@ export class CommonApiContextBuilderService { ); } - const flatObjectMetadata = flatObjectMetadataMaps.byId[objectId]; + const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(flatObjectMetadata)) { throw new RecordCrudException( diff --git a/packages/twenty-server/src/engine/core-modules/record-transformer/services/record-input-transformer.service.ts b/packages/twenty-server/src/engine/core-modules/record-transformer/services/record-input-transformer.service.ts index 75d5f222024..1989fd745e8 100644 --- a/packages/twenty-server/src/engine/core-modules/record-transformer/services/record-input-transformer.service.ts +++ b/packages/twenty-server/src/engine/core-modules/record-transformer/services/record-input-transformer.service.ts @@ -12,6 +12,7 @@ import { transformLinksValue } from 'src/engine/core-modules/record-transformer/ import { transformPhonesValue } from 'src/engine/core-modules/record-transformer/utils/transform-phones-value.util'; import { transformRichTextV2Value } from 'src/engine/core-modules/record-transformer/utils/transform-rich-text-v2.util'; import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -37,7 +38,10 @@ export class RecordInputTransformerService { for (const [key, value] of Object.entries(recordInput)) { const fieldMetadataId = fieldIdByName[key]; const fieldMetadata = fieldMetadataId - ? flatFieldMetadataMaps.byId[fieldMetadataId] + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }) : undefined; if (!fieldMetadata) { diff --git a/packages/twenty-server/src/engine/core-modules/search/search.resolver.ts b/packages/twenty-server/src/engine/core-modules/search/search.resolver.ts index 6e15bf6b50c..dda315f8db9 100644 --- a/packages/twenty-server/src/engine/core-modules/search/search.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/search/search.resolver.ts @@ -57,7 +57,7 @@ export class SearchResolver { ); const flatObjectMetadatas = Object.values( - flatObjectMetadataMaps.byId, + flatObjectMetadataMaps.byUniversalIdentifier, ).filter(isDefined); const filteredObjectMetadataItems = diff --git a/packages/twenty-server/src/engine/core-modules/search/services/search.service.ts b/packages/twenty-server/src/engine/core-modules/search/services/search.service.ts index 5fe51669d94..ffbd026d5b2 100644 --- a/packages/twenty-server/src/engine/core-modules/search/services/search.service.ts +++ b/packages/twenty-server/src/engine/core-modules/search/services/search.service.ts @@ -26,6 +26,7 @@ import { } from 'src/engine/core-modules/search/exceptions/search.exception'; import { type RecordsWithObjectMetadataItem } from 'src/engine/core-modules/search/types/records-with-object-metadata-item'; import { formatSearchTerms } from 'src/engine/core-modules/search/utils/format-search-terms'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -308,10 +309,10 @@ export class SearchService { ); } - const labelIdentifierField = - flatFieldMetadataMaps.byId[ - flatObjectMetadata.labelIdentifierFieldMetadataId - ]; + const labelIdentifierField = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatObjectMetadata.labelIdentifierFieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!isDefined(labelIdentifierField)) { throw new SearchException( @@ -355,10 +356,10 @@ export class SearchService { return null; } - const imageIdentifierField = - flatFieldMetadataMaps.byId[ - flatObjectMetadata.imageIdentifierFieldMetadataId - ]; + const imageIdentifierField = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatObjectMetadata.imageIdentifierFieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!isDefined(imageIdentifierField)) { return null; diff --git a/packages/twenty-server/src/engine/core-modules/tool-generator/services/per-object-tool-generator.service.ts b/packages/twenty-server/src/engine/core-modules/tool-generator/services/per-object-tool-generator.service.ts index bfcd3037437..01f82342703 100644 --- a/packages/twenty-server/src/engine/core-modules/tool-generator/services/per-object-tool-generator.service.ts +++ b/packages/twenty-server/src/engine/core-modules/tool-generator/services/per-object-tool-generator.service.ts @@ -90,7 +90,9 @@ export class PerObjectToolGeneratorService { }, ); - const allFlatObjects = Object.values(flatObjectMetadataMaps.byId) + const allFlatObjects = Object.values( + flatObjectMetadataMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter((obj) => obj.isActive && !obj.isSystem); diff --git a/packages/twenty-server/src/engine/core-modules/tool-provider/providers/database-tool.provider.ts b/packages/twenty-server/src/engine/core-modules/tool-provider/providers/database-tool.provider.ts index d7a2a56d9e2..927f2b3a752 100644 --- a/packages/twenty-server/src/engine/core-modules/tool-provider/providers/database-tool.provider.ts +++ b/packages/twenty-server/src/engine/core-modules/tool-provider/providers/database-tool.provider.ts @@ -123,7 +123,9 @@ export class DatabaseToolProvider implements ToolProvider { }, ); - const allFlatObjects = Object.values(flatObjectMetadataMaps.byId) + const allFlatObjects = Object.values( + flatObjectMetadataMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter((obj) => obj.isActive && !obj.isSystem); diff --git a/packages/twenty-server/src/engine/core-modules/tool-provider/providers/logic-function-tool.provider.ts b/packages/twenty-server/src/engine/core-modules/tool-provider/providers/logic-function-tool.provider.ts index 6aa6b05620f..067da7227c2 100644 --- a/packages/twenty-server/src/engine/core-modules/tool-provider/providers/logic-function-tool.provider.ts +++ b/packages/twenty-server/src/engine/core-modules/tool-provider/providers/logic-function-tool.provider.ts @@ -39,7 +39,7 @@ export class LogicFunctionToolProvider implements ToolProvider { // Filter logic functions that are marked as tools const logicFunctionsWithSchema = Object.values( - flatLogicFunctionMaps.byId, + flatLogicFunctionMaps.byUniversalIdentifier, ).filter( (fn): fn is FlatLogicFunction => isDefined(fn) && fn.isTool === true && fn.deletedAt === null, diff --git a/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts b/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts index 787304182cc..4bd093a38d2 100644 --- a/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts @@ -420,7 +420,9 @@ export class WorkspaceService extends TypeOrmQueryService { }, ); - const fields = Object.values(flatFieldMetadataMaps.byId).filter(isDefined); + const fields = Object.values( + flatFieldMetadataMaps.byUniversalIdentifier, + ).filter(isDefined); if (fields.length === 0) { return 0; diff --git a/packages/twenty-server/src/engine/dataloaders/dataloader.service.ts b/packages/twenty-server/src/engine/dataloaders/dataloader.service.ts index 24e399f2e83..76b83fefeab 100644 --- a/packages/twenty-server/src/engine/dataloaders/dataloader.service.ts +++ b/packages/twenty-server/src/engine/dataloaders/dataloader.service.ts @@ -16,6 +16,7 @@ import { RelationDTO } from 'src/engine/metadata-modules/field-metadata/dtos/rel import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { resolveFieldMetadataStandardOverride } from 'src/engine/metadata-modules/field-metadata/utils/resolve-field-metadata-standard-override.util'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { findAllOthersMorphRelationFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-all-others-morph-relation-flat-field-metadatas-or-throw.util'; @@ -458,7 +459,10 @@ export class DataloaderService { return dataLoaderParams.map( ({ indexMetadata: { id: indexMetadataId } }) => { - const indexMetadataEntity = flatIndexMaps.byId[indexMetadataId]; + const indexMetadataEntity = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: indexMetadataId, + flatEntityMaps: flatIndexMaps, + }); if (!isDefined(indexMetadataEntity)) { return []; @@ -498,8 +502,10 @@ export class DataloaderService { ); return dataLoaderParams.map((dataLoaderParam) => { - const flatObjectMetadata = - flatObjectMetadataMaps.byId[dataLoaderParam.objectMetadataId]; + const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: dataLoaderParam.objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(flatObjectMetadata)) { return null; diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.service.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.service.ts index 9a39ec23425..af69638447c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.service.ts @@ -37,7 +37,7 @@ export class AgentService { 'flatRoleTargetByAgentIdMaps', ]); - return Object.values(flatAgentMaps.byId) + return Object.values(flatAgentMaps.byUniversalIdentifier) .filter(isDefined) .map((flatAgent) => { const roleId = flatRoleTargetByAgentIdMaps[flatAgent.id]?.roleId; diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-update-agent-input-to-flat-agent-to-update.util.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-update-agent-input-to-flat-agent-to-update.util.ts index 93c0b625b54..e0ae6d9c279 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-update-agent-input-to-flat-agent-to-update.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-update-agent-input-to-flat-agent-to-update.util.ts @@ -13,6 +13,7 @@ import { import { type UpdateAgentInput } from 'src/engine/metadata-modules/ai/ai-agent/dtos/update-agent.input'; import { FLAT_AGENT_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-agent/constants/flat-agent-editable-properties.constant'; import { type FlatAgentMaps } from 'src/engine/metadata-modules/flat-agent/types/flat-agent-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatAgent } from 'src/engine/metadata-modules/flat-agent/types/flat-agent.type'; import { type FlatRoleTargetByAgentIdMaps } from 'src/engine/metadata-modules/flat-agent/types/flat-role-target-by-agent-id-maps.type'; import { type FlatRoleTarget } from 'src/engine/metadata-modules/flat-role-target/types/flat-role-target.type'; @@ -95,7 +96,10 @@ export const fromUpdateAgentInputToFlatAgentToUpdate = ({ ['id'], ); - const existingFlatAgent = flatAgentMaps.byId[agentIdToUpdate]; + const existingFlatAgent = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: agentIdToUpdate, + flatEntityMaps: flatAgentMaps, + }); if (!isDefined(existingFlatAgent)) { throw new AgentException( diff --git a/packages/twenty-server/src/engine/metadata-modules/command-menu-item/command-menu-item.service.ts b/packages/twenty-server/src/engine/metadata-modules/command-menu-item/command-menu-item.service.ts index 7e5fa5008a9..f1890999e13 100644 --- a/packages/twenty-server/src/engine/metadata-modules/command-menu-item/command-menu-item.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/command-menu-item/command-menu-item.service.ts @@ -38,7 +38,7 @@ export class CommandMenuItemService { }, ); - return Object.values(flatCommandMenuItemMaps.byId) + return Object.values(flatCommandMenuItemMaps.byUniversalIdentifier) .filter(isDefined) .sort((a, b) => a.label.localeCompare(b.label)) .map(fromFlatCommandMenuItemToCommandMenuItemDto); @@ -263,7 +263,7 @@ export class CommandMenuItemService { }, ); - return Object.values(flatCommandMenuItemMaps.byId) + return Object.values(flatCommandMenuItemMaps.byUniversalIdentifier) .filter(isDefined) .sort((a, b) => a.label.localeCompare(b.label)); } @@ -281,7 +281,7 @@ export class CommandMenuItemService { ); const flatCommandMenuItem = Object.values( - flatCommandMenuItemMaps.byId, + flatCommandMenuItemMaps.byUniversalIdentifier, ).find( (item) => isDefined(item) && item.workflowVersionId === workflowVersionId, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant.ts index ec66537c50c..3ca9e484fd1 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant.ts @@ -3,7 +3,7 @@ import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/typ export const createEmptyFlatEntityMaps = () => ({ - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }) as const satisfies FlatEntityMaps; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type.ts index d5f0f26e67b..4020f354147 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type.ts @@ -1,7 +1,10 @@ import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; +import { type UniversalSyncableFlatEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type'; -export type FlatEntityMaps = { - byId: Partial>; - idByUniversalIdentifier: Partial>; +export type FlatEntityMaps< + T extends SyncableFlatEntity | UniversalSyncableFlatEntity, +> = { + byUniversalIdentifier: Partial>; + universalIdentifierById: Partial>; universalIdentifiersByApplicationId: Partial>; }; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/add-flat-entity-to-flat-entity-and-related-entity-maps-through-mutation-or-throw.spec.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/add-flat-entity-to-flat-entity-and-related-entity-maps-through-mutation-or-throw.spec.ts index b74a35aa927..df894d22906 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/add-flat-entity-to-flat-entity-and-related-entity-maps-through-mutation-or-throw.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/add-flat-entity-to-flat-entity-and-related-entity-maps-through-mutation-or-throw.spec.ts @@ -4,6 +4,7 @@ import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-enti import { type MetadataFlatEntityAndRelatedFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type'; import { addFlatEntityToFlatEntityAndRelatedEntityMapsThroughMutationOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-and-related-entity-maps-through-mutation-or-throw.util'; import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-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 { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; @@ -72,21 +73,26 @@ describe('addFlatEntityToFlatEntityAndRelatedEntityMapsThroughMutationOrThrow', }); expect( - flatEntityAndRelatedMapsToMutate.flatViewMaps.byId[mockView.id], + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: mockView.id, + flatEntityMaps: flatEntityAndRelatedMapsToMutate.flatViewMaps, + }), ).toMatchObject(mockView); expect( - flatEntityAndRelatedMapsToMutate.flatObjectMetadataMaps.byId[ - objectMetadataId - ], + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectMetadataId, + flatEntityMaps: flatEntityAndRelatedMapsToMutate.flatObjectMetadataMaps, + }), ).toMatchObject>({ viewIds: [mockView.id], }); expect( - flatEntityAndRelatedMapsToMutate.flatFieldMetadataMaps.byId[ - mockFieldMetadata.id - ], + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: mockFieldMetadata.id, + flatEntityMaps: flatEntityAndRelatedMapsToMutate.flatFieldMetadataMaps, + }), ).toMatchObject>({ calendarViewIds: [mockView.id], }); diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/delete-flat-entity-from-flat-entity-and-related-entity-maps-through-mutation-or-throw.spec.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/delete-flat-entity-from-flat-entity-and-related-entity-maps-through-mutation-or-throw.spec.ts index 1f7d1ca1e8f..504850802b9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/delete-flat-entity-from-flat-entity-and-related-entity-maps-through-mutation-or-throw.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/delete-flat-entity-from-flat-entity-and-related-entity-maps-through-mutation-or-throw.spec.ts @@ -4,6 +4,7 @@ import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-enti import { type MetadataFlatEntityAndRelatedFlatEntityMaps } 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 { deleteFlatEntityFromFlatEntityAndRelatedEntityMapsThroughMutationOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-and-related-entity-maps-through-mutation-or-throw.util'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; @@ -82,21 +83,26 @@ describe('deleteFlatEntityFromFlatEntityAndRelatedEntityMapsThroughMutationOrThr }); expect( - flatEntityAndRelatedMapsToMutate.flatViewMaps.byId[viewId], + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewId, + flatEntityMaps: flatEntityAndRelatedMapsToMutate.flatViewMaps, + }), ).toBeUndefined(); expect( - flatEntityAndRelatedMapsToMutate.flatObjectMetadataMaps.byId[ - objectMetadataId - ], + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectMetadataId, + flatEntityMaps: flatEntityAndRelatedMapsToMutate.flatObjectMetadataMaps, + }), ).toMatchObject>({ viewIds: ['something-else'], }); expect( - flatEntityAndRelatedMapsToMutate.flatFieldMetadataMaps.byId[ - mockFieldMetadata.id - ], + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: mockFieldMetadata.id, + flatEntityMaps: flatEntityAndRelatedMapsToMutate.flatFieldMetadataMaps, + }), ).toMatchObject>({ calendarViewIds: [], }); diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util.ts index 1633f15f3eb..d2800a88bda 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util.ts @@ -18,7 +18,11 @@ export const addFlatEntityToFlatEntityMapsOrThrow = < flatEntity, flatEntityMaps, }: AddFlatEntityToFlatEntityMapsOrThrowArgs): FlatEntityMaps => { - if (isDefined(flatEntityMaps.byId[flatEntity.id])) { + if ( + isDefined( + flatEntityMaps.byUniversalIdentifier[flatEntity.universalIdentifier], + ) + ) { throw new FlatEntityMapsException( 'addFlatEntityToFlatEntityMapsOrThrow: flat entity to add already exists', FlatEntityMapsExceptionCode.ENTITY_ALREADY_EXISTS, @@ -26,13 +30,13 @@ export const addFlatEntityToFlatEntityMapsOrThrow = < } return { - byId: { - ...flatEntityMaps.byId, - [flatEntity.id]: flatEntity, + byUniversalIdentifier: { + ...flatEntityMaps.byUniversalIdentifier, + [flatEntity.universalIdentifier]: flatEntity, }, - idByUniversalIdentifier: { - ...flatEntityMaps.idByUniversalIdentifier, - [flatEntity.universalIdentifier]: flatEntity.id, + universalIdentifierById: { + ...flatEntityMaps.universalIdentifierById, + [flatEntity.id]: flatEntity.universalIdentifier, }, universalIdentifiersByApplicationId: { ...flatEntityMaps.universalIdentifiersByApplicationId, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util.ts index c5a9bc222d9..5bd6c4daebd 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util.ts @@ -4,7 +4,7 @@ import { type FlatEntityToCreateDeleteUpdate } from 'src/engine/metadata-modules import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type'; import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util'; import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util'; -import { getSubFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util'; +import { getSubFlatEntityByIdsMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-by-ids-maps-or-throw.util'; import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util'; export type ComputeFlatEntityMapsFromToArgs = { @@ -21,7 +21,7 @@ export const computeFlatEntityMapsFromTo = ({ } => { const fromFlatEntityMaps = flatEntityToDelete.length > 0 - ? getSubFlatEntityMapsOrThrow({ + ? getSubFlatEntityByIdsMapsOrThrow({ flatEntityIds: [...flatEntityToDelete, ...flatEntityToUpdate].map( ({ id }) => id, ), diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util.ts index cf6cddb85ac..7753ff91aa8 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util.ts @@ -21,16 +21,19 @@ export const deleteFlatEntityFromFlatEntityMapsOrThrow = < flatEntityMaps, entityToDeleteId, }: DeleteFlatEntityFromFlatEntityMapsOrThrowArgs): FlatEntityMaps => { - if (!isDefined(flatEntityMaps.byId[entityToDeleteId])) { + const universalIdentifierToDelete = + flatEntityMaps.universalIdentifierById[entityToDeleteId]; + + if (!isDefined(universalIdentifierToDelete)) { throw new FlatEntityMapsException( 'deleteFlatEntityFromFlatEntityMapsOrThrow: entity to delete not found', FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND, ); } - const updatedIdByUniversalIdentifierEntries = Object.entries( - flatEntityMaps.idByUniversalIdentifier, - ).filter(([_universalIdentifier, id]) => id !== entityToDeleteId); + const updatedUniversalIdentifierByIdEntries = Object.entries( + flatEntityMaps.universalIdentifierById, + ).filter(([id]) => id !== entityToDeleteId); const updatedUniversalIdentifiersByApplicationIdEntries = Object.entries( flatEntityMaps.universalIdentifiersByApplicationId, @@ -38,10 +41,7 @@ export const deleteFlatEntityFromFlatEntityMapsOrThrow = < .map(([applicationId, universalIdentifiers]) => { const stillPresentUniversalIdentifiers = universalIdentifiers?.filter( (universalIdentifier) => - updatedIdByUniversalIdentifierEntries.some( - ([existingUniversalIdentifier]) => - existingUniversalIdentifier === universalIdentifier, - ), + universalIdentifier !== universalIdentifierToDelete, ); if ( @@ -56,9 +56,12 @@ export const deleteFlatEntityFromFlatEntityMapsOrThrow = < .filter(isDefined); return { - byId: removePropertiesFromRecord(flatEntityMaps.byId, [entityToDeleteId]), - idByUniversalIdentifier: Object.fromEntries( - updatedIdByUniversalIdentifierEntries, + byUniversalIdentifier: removePropertiesFromRecord( + flatEntityMaps.byUniversalIdentifier, + [universalIdentifierToDelete], + ), + universalIdentifierById: Object.fromEntries( + updatedUniversalIdentifierByIdEntries, ), universalIdentifiersByApplicationId: Object.fromEntries( updatedUniversalIdentifiersByApplicationIdEntries, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util.ts index a213bcfa9ba..dc871c79ad5 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util.ts @@ -19,13 +19,7 @@ export const findFlatEntitiesByApplicationId = ({ return universalIdentifiers .map((universalId) => { - const id = flatEntityMaps.idByUniversalIdentifier[universalId]; - - if (!isDefined(id)) { - return undefined; - } - - const entity = flatEntityMaps.byId[id]; + const entity = flatEntityMaps.byUniversalIdentifier[universalId]; if (!isDefined(entity)) { return undefined; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts index d7ea89ca185..f6a79da9437 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts @@ -20,7 +20,17 @@ export const findFlatEntityByIdInFlatEntityMapsOrThrow = < flatEntityMaps, flatEntityId, }: FindFlatEntityByIdInFlatEntityMapsOrThrowArgs): T => { - const flatEntity = flatEntityMaps.byId[flatEntityId]; + const universalIdentifier = + flatEntityMaps.universalIdentifierById[flatEntityId]; + + if (!isDefined(universalIdentifier)) { + throw new FlatEntityMapsException( + t`Could not find flat entity in maps`, + FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND, + ); + } + + const flatEntity = flatEntityMaps.byUniversalIdentifier[universalIdentifier]; if (!isDefined(flatEntity)) { throw new FlatEntityMapsException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util.ts index b152d9bfc5c..734ca3bff68 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util.ts @@ -1,5 +1,3 @@ -import { isDefined } from 'twenty-shared/utils'; - import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; @@ -11,20 +9,6 @@ export const findFlatEntityByUniversalIdentifier = < }: { flatEntityMaps: FlatEntityMaps; universalIdentifier: string; -}): (T & { id: string }) | undefined => { - const flatEntityId = - flatEntityMaps.idByUniversalIdentifier[universalIdentifier]; - - if (!isDefined(flatEntityId)) { - return; - } - - const result = flatEntityMaps.byId[flatEntityId]; - - return isDefined(result) - ? { - ...result, - id: flatEntityId, - } - : undefined; +}): T | undefined => { + return flatEntityMaps.byUniversalIdentifier[universalIdentifier]; }; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts index 29b8f04c5d4..db3e3bd99fd 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util.ts @@ -2,7 +2,7 @@ import { isDefined } from 'twenty-shared/utils'; import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { getSubFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util'; +import { getSubFlatEntityByIdsMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-by-ids-maps-or-throw.util'; export type FindManyFlatEntityByIdInFlatEntityMapsOrThrowArgs< T extends SyncableFlatEntity, @@ -16,10 +16,12 @@ export const findManyFlatEntityByIdInFlatEntityMapsOrThrow = < flatEntityMaps, flatEntityIds, }: FindManyFlatEntityByIdInFlatEntityMapsOrThrowArgs): T[] => { - const subFlatEntityMaps = getSubFlatEntityMapsOrThrow({ + const subFlatEntityMaps = getSubFlatEntityByIdsMapsOrThrow({ flatEntityIds, flatEntityMaps, }); - return Object.values(subFlatEntityMaps.byId).filter(isDefined); + return Object.values(subFlatEntityMaps.byUniversalIdentifier).filter( + isDefined, + ); }; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps.util.ts new file mode 100644 index 00000000000..66bb5d7d519 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps.util.ts @@ -0,0 +1,28 @@ +import { isDefined } from 'twenty-shared/utils'; + +import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; +import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; + +export type FindManyFlatEntityByIdInFlatEntityMapsArgs< + T extends SyncableFlatEntity, +> = { + flatEntityMaps: FlatEntityMaps; + flatEntityIds: string[]; +}; + +export const findManyFlatEntityByIdInFlatEntityMaps = < + T extends SyncableFlatEntity, +>({ + flatEntityMaps, + flatEntityIds, +}: FindManyFlatEntityByIdInFlatEntityMapsArgs): T[] => { + return flatEntityIds + .map((flatEntityId) => + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps, + }), + ) + .filter(isDefined); +}; 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-by-ids-maps-or-throw.util.ts similarity index 93% rename from packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util.ts rename to packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-by-ids-maps-or-throw.util.ts index 333a2b11429..99c01abda86 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-by-ids-maps-or-throw.util.ts @@ -4,7 +4,7 @@ import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/typ import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-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'; -export const getSubFlatEntityMapsOrThrow = ({ +export const getSubFlatEntityByIdsMapsOrThrow = ({ flatEntityIds, flatEntityMaps, }: { diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-by-application-id-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-by-application-id-or-throw.util.ts index 581c959615f..ec4709ce1d7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-by-application-id-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-by-application-id-or-throw.util.ts @@ -1,7 +1,7 @@ import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { findFlatEntitiesByApplicationId } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util'; -import { getSubFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util'; +import { getSubFlatEntityByIdsMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-by-ids-maps-or-throw.util'; export const getSubFlatEntityMapsByApplicationIdOrThrow = < T extends SyncableFlatEntity, @@ -17,7 +17,7 @@ export const getSubFlatEntityMapsByApplicationIdOrThrow = < flatEntityMaps, }); - return getSubFlatEntityMapsOrThrow({ + return getSubFlatEntityByIdsMapsOrThrow({ flatEntityIds: allApplicationFlatEntity.map((flatEntity) => flatEntity.id), flatEntityMaps, }); diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/compute-flat-field-to-update-from-morph-relation-update-payload.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/compute-flat-field-to-update-from-morph-relation-update-payload.util.ts index a14e692aaeb..b46754b10b3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/compute-flat-field-to-update-from-morph-relation-update-payload.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/compute-flat-field-to-update-from-morph-relation-update-payload.util.ts @@ -7,6 +7,7 @@ import { computeMorphRelationFieldName, isDefined } from 'twenty-shared/utils'; import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type'; import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { extractJunctionTargetSettingsFromSettings } from 'src/engine/metadata-modules/flat-field-metadata/utils/extract-junction-target-settings-from-settings.util'; @@ -74,7 +75,10 @@ export const computeFlatFieldToUpdateFromMorphRelationUpdatePayload = ({ fieldMetadataToUpdate.settings, ); const junctionTargetFlatFieldMetadata = isDefined(junctionTargetFieldId) - ? flatFieldMetadataMaps.byId[junctionTargetFieldId] + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: junctionTargetFieldId, + flatEntityMaps: flatFieldMetadataMaps, + }) : undefined; morphRelationsUpdatePayload.forEach((morphRelationUpdatePayload) => { diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-all-others-morph-relation-flat-field-metadatas-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-all-others-morph-relation-flat-field-metadatas-or-throw.util.ts index 1e9469569ce..63ca2162f35 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-all-others-morph-relation-flat-field-metadatas-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-all-others-morph-relation-flat-field-metadatas-or-throw.util.ts @@ -6,6 +6,7 @@ import { 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 { 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'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util'; @@ -22,7 +23,12 @@ export const findAllOthersMorphRelationFlatFieldMetadatasOrThrow = ({ flatFieldMetadata: morphRelationFlatFieldMetadata, }: FindAllMorphRelationFlatFieldMetadatasOrThrowArgs): FlatFieldMetadata[] => { if ( - !isDefined(flatFieldMetadataMaps.byId[morphRelationFlatFieldMetadata.id]) + !isDefined( + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: morphRelationFlatFieldMetadata.id, + flatEntityMaps: flatFieldMetadataMaps, + }), + ) ) { throw new FlatEntityMapsException( 'Morph relation field not found in flat field metadata maps', diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util.ts index c6e67bd4913..58e8f915dde 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util.ts @@ -6,6 +6,7 @@ import { } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception'; import { type MorphOrRelationFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/morph-or-relation-field-metadata-type.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util'; @@ -20,8 +21,10 @@ export const findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow = ({ }: GetRelationFlatFieldMetadatasUtilArgs): FlatFieldMetadata => { const { relationTargetFieldMetadataId } = flatFieldMetadata; - const relatedFlatFieldMetadata = - flatFieldMetadataMaps.byId[relationTargetFieldMetadataId]; + const relatedFlatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: relationTargetFieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!isDefined(relatedFlatFieldMetadata)) { throw new FieldMetadataException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-create-field-input-to-flat-field-metadatas-to-create.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-create-field-input-to-flat-field-metadatas-to-create.util.ts index c544467a6ac..864a13c2be9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-create-field-input-to-flat-field-metadatas-to-create.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-create-field-input-to-flat-field-metadatas-to-create.util.ts @@ -15,6 +15,7 @@ import { type CreateFieldInput } from 'src/engine/metadata-modules/field-metadat import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception'; import { generateRatingOptions } from 'src/engine/metadata-modules/field-metadata/utils/generate-rating-optionts.util'; import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FieldInputTranspilationResult } from 'src/engine/metadata-modules/flat-field-metadata/types/field-input-transpilation-result.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { fromMorphRelationCreateFieldInputToFlatFieldMetadatas } from 'src/engine/metadata-modules/flat-field-metadata/utils/from-morph-relation-create-field-input-to-flat-field-metadatas.util'; @@ -58,8 +59,10 @@ export const fromCreateFieldInputToFlatFieldMetadatasToCreate = async ({ rawCreateFieldInput, ['description', 'icon', 'label', 'name', 'objectMetadataId', 'type'], ); - const parentFlatObjectMetadata = - existingFlatObjectMetadataMaps.byId[createFieldInput.objectMetadataId]; + const parentFlatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: createFieldInput.objectMetadataId, + flatEntityMaps: existingFlatObjectMetadataMaps, + }); if (!isDefined(parentFlatObjectMetadata)) { return { diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-delete-field-input-to-flat-field-metadatas-to-delete.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-delete-field-input-to-flat-field-metadatas-to-delete.util.ts index 394ca12a0c3..1279e424791 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-delete-field-input-to-flat-field-metadatas-to-delete.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-delete-field-input-to-flat-field-metadatas-to-delete.util.ts @@ -77,9 +77,9 @@ export const fromDeleteFieldInputToFlatFieldMetadatasToDelete = ({ ]; const flatIndexMap = new Map(); - const allFlatIndexes = Object.values(existingFlatIndexMaps.byId).filter( - isDefined, - ); + const allFlatIndexes = Object.values( + existingFlatIndexMaps.byUniversalIdentifier, + ).filter(isDefined); for (const flatFieldMetadata of flatFieldMetadatasToDelete) { allFlatIndexes.forEach((flatIndex) => { diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-morph-relation-create-field-input-to-flat-field-metadatas.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-morph-relation-create-field-input-to-flat-field-metadatas.util.ts index cfb25597e32..b9d3a5f1002 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-morph-relation-create-field-input-to-flat-field-metadatas.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-morph-relation-create-field-input-to-flat-field-metadatas.util.ts @@ -8,6 +8,7 @@ import { type CreateFieldInput } from 'src/engine/metadata-modules/field-metadat import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception'; import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FieldInputTranspilationResult } from 'src/engine/metadata-modules/flat-field-metadata/types/field-input-transpilation-result.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { extractJunctionTargetSettingsFromSettings } from 'src/engine/metadata-modules/flat-field-metadata/utils/extract-junction-target-settings-from-settings.util'; @@ -74,7 +75,10 @@ export const fromMorphRelationCreateFieldInputToFlatFieldMetadatas = async ({ createFieldInput.settings, ); const junctionTargetFlatFieldMetadata = isDefined(junctionTargetFieldId) - ? existingFlatFieldMetadataMaps.byId[junctionTargetFieldId] + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: junctionTargetFieldId, + flatEntityMaps: existingFlatFieldMetadataMaps, + }) : undefined; const morphRelationCreationPayload = diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-relation-create-field-input-to-flat-field-metadatas.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-relation-create-field-input-to-flat-field-metadatas.util.ts index ef0fd7c9b1a..910a7c1cbe7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-relation-create-field-input-to-flat-field-metadatas.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/from-relation-create-field-input-to-flat-field-metadatas.util.ts @@ -7,6 +7,7 @@ import { type CreateFieldInput } from 'src/engine/metadata-modules/field-metadat import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception'; import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FieldInputTranspilationResult } from 'src/engine/metadata-modules/flat-field-metadata/types/field-input-transpilation-result.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { extractJunctionTargetSettingsFromSettings } from 'src/engine/metadata-modules/flat-field-metadata/utils/extract-junction-target-settings-from-settings.util'; @@ -68,7 +69,10 @@ export const fromRelationCreateFieldInputToFlatFieldMetadatas = async ({ createFieldInput.settings, ); const junctionTargetFlatFieldMetadata = isDefined(junctionTargetFieldId) - ? existingFlatFieldMetadataMaps.byId[junctionTargetFieldId] + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: junctionTargetFieldId, + flatEntityMaps: existingFlatFieldMetadataMaps, + }) : undefined; const generateResult = generateMorphOrRelationFlatFieldMetadataPair({ 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 bec5666d5eb..282e7691e73 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 @@ -115,7 +115,12 @@ export const validateMorphOrRelationFlatFieldMetadata = ({ }); const targetFlatFieldMetadata = - remainingFlatEntityMapsToValidate?.byId[relationTargetFieldMetadataId] ?? + (remainingFlatEntityMapsToValidate + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: relationTargetFieldMetadataId, + flatEntityMaps: remainingFlatEntityMapsToValidate, + }) + : undefined) ?? findFlatEntityByIdInFlatEntityMaps({ flatEntityId: relationTargetFieldMetadataId, flatEntityMaps: flatFieldMetadataMaps, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-relation-flat-field-metadata.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-relation-flat-field-metadata.util.ts index 6d65ac31a82..48bc160f11d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-relation-flat-field-metadata.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-relation-flat-field-metadata.util.ts @@ -24,7 +24,12 @@ export const validateMorphRelationFlatFieldMetadata = ( errors.push(...validateMorphOrRelationFlatFieldMetadata(args)); const targetFlatFieldMetadata = - remainingFlatEntityMapsToValidate?.byId[relationTargetFieldMetadataId] ?? + (remainingFlatEntityMapsToValidate + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: relationTargetFieldMetadataId, + flatEntityMaps: remainingFlatEntityMapsToValidate, + }) + : undefined) ?? findFlatEntityByIdInFlatEntityMaps({ flatEntityId: relationTargetFieldMetadataId, flatEntityMaps: flatFieldMetadataMaps, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-relation-creation-payload.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-relation-creation-payload.util.ts index f9578b0664b..767946a542c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-relation-creation-payload.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-relation-creation-payload.util.ts @@ -11,6 +11,7 @@ import { } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception'; import { validateRelationCreationPayloadOrThrow } from 'src/engine/metadata-modules/field-metadata/utils/validate-relation-creation-payload-or-throw.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FieldInputTranspilationResult } from 'src/engine/metadata-modules/flat-field-metadata/types/field-input-transpilation-result.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -53,10 +54,10 @@ export const validateRelationCreationPayload = async ({ } } - const targetFlatObjectMetadata = - existingFlatObjectMetadataMaps.byId[ - relationCreationPayload.targetObjectMetadataId - ]; + const targetFlatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: relationCreationPayload.targetObjectMetadataId, + flatEntityMaps: existingFlatObjectMetadataMaps, + }); if (!isDefined(targetFlatObjectMetadata)) { return { diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util.ts index e4d30b47293..ea6f9fa4f95 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util.ts @@ -12,15 +12,15 @@ export const buildObjectIdByNameMaps = ( const idByNameSingular: Record = {}; const idByNamePlural: Record = {}; - for (const [objectId, objectMetadata] of Object.entries( - flatObjectMetadataMaps.byId, + for (const objectMetadata of Object.values( + flatObjectMetadataMaps.byUniversalIdentifier, )) { if (!isDefined(objectMetadata)) { continue; } - idByNameSingular[objectMetadata.nameSingular] = objectId; - idByNamePlural[objectMetadata.namePlural] = objectId; + idByNameSingular[objectMetadata.nameSingular] = objectMetadata.id; + idByNamePlural[objectMetadata.namePlural] = objectMetadata.id; } return { idByNameSingular, idByNamePlural }; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-delete-object-input-to-flat-field-metadatas-to-delete.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-delete-object-input-to-flat-field-metadatas-to-delete.util.ts index 97bc5ae29e3..a38f85707dc 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-delete-object-input-to-flat-field-metadatas-to-delete.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-delete-object-input-to-flat-field-metadatas-to-delete.util.ts @@ -78,7 +78,9 @@ export const fromDeleteObjectInputToFlatFieldMetadatasToDelete = ({ ); // TODO We should maintain a idsByObjectMetadataId in the flatIndexMaps - const flatIndexMetadataToDelete = Object.values(flatIndexMaps.byId).filter( + const flatIndexMetadataToDelete = Object.values( + flatIndexMaps.byUniversalIdentifier, + ).filter( (flatIndex): flatIndex is FlatIndexMetadata => isDefined(flatIndex) && flatIndex.objectMetadataId === flatObjectMetadataToDelete.id, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/validators/utils/validate-flat-object-metadata-name-and-labels.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/validators/utils/validate-flat-object-metadata-name-and-labels.util.ts index bce80c72470..10063124131 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/validators/utils/validate-flat-object-metadata-name-and-labels.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/validators/utils/validate-flat-object-metadata-name-and-labels.util.ts @@ -23,7 +23,7 @@ export const doesOtherObjectWithSameNameExists = ({ objectMetadataNameSingular, existingObjectMetadataId, }: ValidateNoOtherObjectWithSameNameExistsOrThrowsParams) => - Object.values(objectMetadataMaps.byId) + Object.values(objectMetadataMaps.byUniversalIdentifier) .filter(isDefined) .some( (objectMetadata) => diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/from-destroy-page-layout-tab-input-to-flat-page-layout-tab-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/from-destroy-page-layout-tab-input-to-flat-page-layout-tab-or-throw.util.ts index 34dbdb43c38..a655bae0ac5 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/from-destroy-page-layout-tab-input-to-flat-page-layout-tab-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/from-destroy-page-layout-tab-input-to-flat-page-layout-tab-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { type FlatPageLayoutTabMaps } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatPageLayoutTab } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type'; import { PageLayoutTabException, @@ -27,8 +28,12 @@ export const fromDestroyPageLayoutTabInputToFlatPageLayoutTabOrThrow = ({ ['id'], ); - const existingFlatPageLayoutTabToDestroy = - flatPageLayoutTabMaps.byId[pageLayoutTabId]; + const existingFlatPageLayoutTabToDestroy = findFlatEntityByIdInFlatEntityMaps( + { + flatEntityId: pageLayoutTabId, + flatEntityMaps: flatPageLayoutTabMaps, + }, + ); if (!isDefined(existingFlatPageLayoutTabToDestroy)) { throw new PageLayoutTabException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/from-update-page-layout-tab-input-to-flat-page-layout-tab-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/from-update-page-layout-tab-input-to-flat-page-layout-tab-to-update-or-throw.util.ts index c93dbd181f7..498775e3523 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/from-update-page-layout-tab-input-to-flat-page-layout-tab-to-update-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/from-update-page-layout-tab-input-to-flat-page-layout-tab-to-update-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { FLAT_PAGE_LAYOUT_TAB_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-page-layout-tab/constants/flat-page-layout-tab-editable-properties.constant'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatPageLayoutTabMaps } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab-maps.type'; import { type FlatPageLayoutTab } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type'; import { type UpdatePageLayoutTabInput } from 'src/engine/metadata-modules/page-layout-tab/dtos/inputs/update-page-layout-tab.input'; @@ -31,8 +32,10 @@ export const fromUpdatePageLayoutTabInputToFlatPageLayoutTabToUpdateOrThrow = ({ ['id'], ); - const existingFlatPageLayoutTabToUpdate = - flatPageLayoutTabMaps.byId[pageLayoutTabToUpdateId]; + const existingFlatPageLayoutTabToUpdate = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: pageLayoutTabToUpdateId, + flatEntityMaps: flatPageLayoutTabMaps, + }); if (!isDefined(existingFlatPageLayoutTabToUpdate)) { throw new PageLayoutTabException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/reconstruct-flat-page-layout-tab-with-widgets.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/reconstruct-flat-page-layout-tab-with-widgets.util.ts index befdef9cb4f..c20fd18eb97 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/reconstruct-flat-page-layout-tab-with-widgets.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-tab/utils/reconstruct-flat-page-layout-tab-with-widgets.util.ts @@ -15,7 +15,9 @@ export const reconstructFlatPageLayoutTabWithWidgets = ({ tab: FlatPageLayoutTab; flatPageLayoutWidgetMaps: FlatPageLayoutWidgetMaps; }): FlatPageLayoutTabWithWidgets => { - const widgets = Object.values(flatPageLayoutWidgetMaps.byId).filter( + const widgets = Object.values( + flatPageLayoutWidgetMaps.byUniversalIdentifier, + ).filter( (widget): widget is FlatPageLayoutWidget => isDefined(widget) && widget.pageLayoutTabId === tab.id && diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-destroy-page-layout-widget-input-to-flat-page-layout-widget-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-destroy-page-layout-widget-input-to-flat-page-layout-widget-or-throw.util.ts index 42d75340e99..6a4de715f2d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-destroy-page-layout-widget-input-to-flat-page-layout-widget-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-destroy-page-layout-widget-input-to-flat-page-layout-widget-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { type FlatPageLayoutWidgetMaps } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatPageLayoutWidget } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type'; import { type DestroyPageLayoutWidgetInput } from 'src/engine/metadata-modules/page-layout-widget/dtos/inputs/destroy-page-layout-widget.input'; import { @@ -25,7 +26,10 @@ export const fromDestroyPageLayoutWidgetInputToFlatPageLayoutWidgetOrThrow = ({ ); const existingFlatPageLayoutWidgetToDestroy = - flatPageLayoutWidgetMaps.byId[pageLayoutWidgetId]; + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: pageLayoutWidgetId, + flatEntityMaps: flatPageLayoutWidgetMaps, + }); if (!isDefined(existingFlatPageLayoutWidgetToDestroy)) { throw new PageLayoutWidgetException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-update-page-layout-widget-input-to-flat-page-layout-widget-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-update-page-layout-widget-input-to-flat-page-layout-widget-to-update-or-throw.util.ts index d76bc733991..bf67867ece7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-update-page-layout-widget-input-to-flat-page-layout-widget-to-update-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-update-page-layout-widget-input-to-flat-page-layout-widget-to-update-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { FLAT_PAGE_LAYOUT_WIDGET_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-page-layout-widget/constants/flat-page-layout-widget-editable-properties.constant'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatPageLayoutWidgetMaps } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-maps.type'; import { type FlatPageLayoutWidget } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type'; import { type UpdatePageLayoutWidgetInput } from 'src/engine/metadata-modules/page-layout-widget/dtos/inputs/update-page-layout-widget.input'; @@ -34,7 +35,10 @@ export const fromUpdatePageLayoutWidgetInputToFlatPageLayoutWidgetToUpdateOrThro ]); const existingFlatPageLayoutWidgetToUpdate = - flatPageLayoutWidgetMaps.byId[pageLayoutWidgetToUpdateId]; + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: pageLayoutWidgetToUpdateId, + flatEntityMaps: flatPageLayoutWidgetMaps, + }); if (!isDefined(existingFlatPageLayoutWidgetToUpdate)) { throw new PageLayoutWidgetException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/from-destroy-page-layout-input-to-flat-page-layout-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/from-destroy-page-layout-input-to-flat-page-layout-or-throw.util.ts index dbe8029fdd9..dfe5202c87c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/from-destroy-page-layout-input-to-flat-page-layout-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/from-destroy-page-layout-input-to-flat-page-layout-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { type FlatPageLayoutMaps } from 'src/engine/metadata-modules/flat-page-layout/types/flat-page-layout-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatPageLayout } from 'src/engine/metadata-modules/flat-page-layout/types/flat-page-layout.type'; import { PageLayoutException, @@ -27,7 +28,10 @@ export const fromDestroyPageLayoutInputToFlatPageLayoutOrThrow = ({ ['id'], ); - const existingFlatPageLayoutToDestroy = flatPageLayoutMaps.byId[pageLayoutId]; + const existingFlatPageLayoutToDestroy = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: pageLayoutId, + flatEntityMaps: flatPageLayoutMaps, + }); if (!isDefined(existingFlatPageLayoutToDestroy)) { throw new PageLayoutException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/from-update-page-layout-input-to-flat-page-layout-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/from-update-page-layout-input-to-flat-page-layout-to-update-or-throw.util.ts index 20ffc1c56a5..4ac5c259eb4 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/from-update-page-layout-input-to-flat-page-layout-to-update-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/from-update-page-layout-input-to-flat-page-layout-to-update-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { FLAT_PAGE_LAYOUT_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-page-layout/constants/flat-page-layout-editable-properties.constant'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatPageLayoutMaps } from 'src/engine/metadata-modules/flat-page-layout/types/flat-page-layout-maps.type'; import { type FlatPageLayout } from 'src/engine/metadata-modules/flat-page-layout/types/flat-page-layout.type'; import { type UpdatePageLayoutInput } from 'src/engine/metadata-modules/page-layout/dtos/inputs/update-page-layout.input'; @@ -31,8 +32,10 @@ export const fromUpdatePageLayoutInputToFlatPageLayoutToUpdateOrThrow = ({ ['id'], ); - const existingFlatPageLayoutToUpdate = - flatPageLayoutMaps.byId[pageLayoutToUpdateId]; + const existingFlatPageLayoutToUpdate = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: pageLayoutToUpdateId, + flatEntityMaps: flatPageLayoutMaps, + }); if (!isDefined(existingFlatPageLayoutToUpdate)) { throw new PageLayoutException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/reconstruct-flat-page-layout-with-tabs-and-widgets.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/reconstruct-flat-page-layout-with-tabs-and-widgets.util.ts index da843627290..d799495a0e1 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/reconstruct-flat-page-layout-with-tabs-and-widgets.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-page-layout/utils/reconstruct-flat-page-layout-with-tabs-and-widgets.util.ts @@ -23,7 +23,7 @@ export const reconstructFlatPageLayoutWithTabsAndWidgets = ({ flatPageLayoutTabMaps: FlatPageLayoutTabMaps; flatPageLayoutWidgetMaps: FlatPageLayoutWidgetMaps; }): FlatPageLayoutWithTabsAndWidgets => { - const tabs = Object.values(flatPageLayoutTabMaps.byId) + const tabs = Object.values(flatPageLayoutTabMaps.byUniversalIdentifier) .filter(isDefined) .filter( (tab) => tab.pageLayoutId === layout.id && !isDefined(tab.deletedAt), @@ -31,7 +31,9 @@ export const reconstructFlatPageLayoutWithTabsAndWidgets = ({ .sort((a, b) => (a.position ?? 0) - (b.position ?? 0)); const tabsWithWidgets: FlatPageLayoutTabWithWidgets[] = tabs.map((tab) => { - const widgets = Object.values(flatPageLayoutWidgetMaps.byId) + const widgets = Object.values( + flatPageLayoutWidgetMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter( (widget) => diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-role-target/utils/find-flat-role-target-from-foreign-key.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-role-target/utils/find-flat-role-target-from-foreign-key.util.ts index 9ffad08bdd0..af38c114abd 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-role-target/utils/find-flat-role-target-from-foreign-key.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-role-target/utils/find-flat-role-target-from-foreign-key.util.ts @@ -13,9 +13,9 @@ export const findFlatRoleTargetFromForeignKey = ({ targetMetadataForeignKey, targetId, }: FindAllFlatRoleTargetOfArgs): FlatRoleTarget | undefined => { - const allRoleTargets = Object.values(flatRoleTargetMaps.byId).filter( - isDefined, - ); + const allRoleTargets = Object.values( + flatRoleTargetMaps.byUniversalIdentifier, + ).filter(isDefined); return allRoleTargets.find( (roleTarget) => roleTarget[targetMetadataForeignKey] === targetId, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-delete-view-field-input-to-flat-view-field-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-delete-view-field-input-to-flat-view-field-or-throw.util.ts index 07ab8ed43ba..47c42b74aa9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-delete-view-field-input-to-flat-view-field-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-delete-view-field-input-to-flat-view-field-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { type FlatViewFieldMaps } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatViewField } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field.type'; import { type DeleteViewFieldInput } from 'src/engine/metadata-modules/view-field/dtos/inputs/delete-view-field.input'; import { @@ -24,7 +25,10 @@ export const fromDeleteViewFieldInputToFlatViewFieldOrThrow = ({ ['id'], ); - const existingFlatViewFieldToDelete = flatViewFieldMaps.byId[viewFieldId]; + const existingFlatViewFieldToDelete = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFieldId, + flatEntityMaps: flatViewFieldMaps, + }); if (!isDefined(existingFlatViewFieldToDelete)) { throw new ViewFieldException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-destroy-view-field-input-to-flat-view-field-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-destroy-view-field-input-to-flat-view-field-or-throw.util.ts index 79e1da3726f..6aa632f5d50 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-destroy-view-field-input-to-flat-view-field-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-destroy-view-field-input-to-flat-view-field-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { type FlatViewFieldMaps } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatViewField } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field.type'; import { type DestroyViewFieldInput } from 'src/engine/metadata-modules/view-field/dtos/inputs/destroy-view-field.input'; import { @@ -24,7 +25,10 @@ export const fromDestroyViewFieldInputToFlatViewFieldOrThrow = ({ ['id'], ); - const existingFlatViewFieldToDestroy = flatViewFieldMaps.byId[viewFieldId]; + const existingFlatViewFieldToDestroy = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFieldId, + flatEntityMaps: flatViewFieldMaps, + }); if (!isDefined(existingFlatViewFieldToDestroy)) { throw new ViewFieldException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-update-view-field-input-to-flat-view-field-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-update-view-field-input-to-flat-view-field-to-update-or-throw.util.ts index fd6df76e308..7802df57841 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-update-view-field-input-to-flat-view-field-to-update-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-field/utils/from-update-view-field-input-to-flat-view-field-to-update-or-throw.util.ts @@ -6,6 +6,7 @@ import { } from 'twenty-shared/utils'; import { FLAT_VIEW_FIELD_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-view-field/constants/flat-view-field-editable-properties.constant'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatViewFieldMaps } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field-maps.type'; import { type FlatViewField } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field.type'; import { type UpdateViewFieldInput } from 'src/engine/metadata-modules/view-field/dtos/inputs/update-view-field.input'; @@ -28,8 +29,10 @@ export const fromUpdateViewFieldInputToFlatViewFieldToUpdateOrThrow = ({ ['id'], ); - const existingFlatViewFieldToUpdate = - flatViewFieldMaps.byId[viewFieldToUpdateId]; + const existingFlatViewFieldToUpdate = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFieldToUpdateId, + flatEntityMaps: flatViewFieldMaps, + }); if (!isDefined(existingFlatViewFieldToUpdate)) { throw new ViewFieldException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-delete-view-filter-group-input-to-flat-view-filter-group-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-delete-view-filter-group-input-to-flat-view-filter-group-or-throw.util.ts index 6152bfd758b..7d1dea47276 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-delete-view-filter-group-input-to-flat-view-filter-group-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-delete-view-filter-group-input-to-flat-view-filter-group-or-throw.util.ts @@ -4,6 +4,7 @@ import { } from 'twenty-shared/utils'; import { type FlatViewFilterGroupMaps } from 'src/engine/metadata-modules/flat-view-filter-group/types/flat-view-filter-group-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatViewFilterGroup } from 'src/engine/metadata-modules/flat-view-filter-group/types/flat-view-filter-group.type'; import { type DeleteViewFilterGroupInput } from 'src/engine/metadata-modules/view-filter-group/dtos/inputs/delete-view-filter-group.input'; import { @@ -24,7 +25,10 @@ export const fromDeleteViewFilterGroupInputToFlatViewFilterGroupOrThrow = ({ ); const existingFlatViewFilterGroupToDelete = - flatViewFilterGroupMaps.byId[viewFilterGroupId]; + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFilterGroupId, + flatEntityMaps: flatViewFilterGroupMaps, + }); if (!isDefined(existingFlatViewFilterGroupToDelete)) { throw new ViewFilterGroupException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-destroy-view-filter-group-input-to-flat-view-filter-group-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-destroy-view-filter-group-input-to-flat-view-filter-group-or-throw.util.ts index a4b1b647812..6fd04ac8dbd 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-destroy-view-filter-group-input-to-flat-view-filter-group-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-destroy-view-filter-group-input-to-flat-view-filter-group-or-throw.util.ts @@ -4,6 +4,7 @@ import { } from 'twenty-shared/utils'; import { type FlatViewFilterGroupMaps } from 'src/engine/metadata-modules/flat-view-filter-group/types/flat-view-filter-group-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatViewFilterGroup } from 'src/engine/metadata-modules/flat-view-filter-group/types/flat-view-filter-group.type'; import { type DestroyViewFilterGroupInput } from 'src/engine/metadata-modules/view-filter-group/dtos/inputs/destroy-view-filter-group.input'; import { @@ -24,7 +25,10 @@ export const fromDestroyViewFilterGroupInputToFlatViewFilterGroupOrThrow = ({ ); const existingFlatViewFilterGroupToDestroy = - flatViewFilterGroupMaps.byId[viewFilterGroupId]; + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFilterGroupId, + flatEntityMaps: flatViewFilterGroupMaps, + }); if (!isDefined(existingFlatViewFilterGroupToDestroy)) { throw new ViewFilterGroupException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-update-view-filter-group-input-to-flat-view-filter-group-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-update-view-filter-group-input-to-flat-view-filter-group-to-update-or-throw.util.ts index 93a7dff9e92..308c3bb7879 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-update-view-filter-group-input-to-flat-view-filter-group-to-update-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter-group/utils/from-update-view-filter-group-input-to-flat-view-filter-group-to-update-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { FLAT_VIEW_FILTER_GROUP_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-view-filter-group/constants/flat-view-filter-group-editable-properties.constant'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatViewFilterGroupMaps } from 'src/engine/metadata-modules/flat-view-filter-group/types/flat-view-filter-group-maps.type'; import { type FlatViewFilterGroup } from 'src/engine/metadata-modules/flat-view-filter-group/types/flat-view-filter-group.type'; import { type UpdateViewFilterGroupInput } from 'src/engine/metadata-modules/view-filter-group/dtos/inputs/update-view-filter-group.input'; @@ -29,7 +30,10 @@ export const fromUpdateViewFilterGroupInputToFlatViewFilterGroupToUpdateOrThrow ); const existingFlatViewFilterGroupToUpdate = - flatViewFilterGroupMaps.byId[viewFilterGroupToUpdateId]; + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFilterGroupToUpdateId, + flatEntityMaps: flatViewFilterGroupMaps, + }); if (!isDefined(existingFlatViewFilterGroupToUpdate)) { throw new ViewFilterGroupException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-delete-view-filter-input-to-flat-view-filter-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-delete-view-filter-input-to-flat-view-filter-or-throw.util.ts index 4c338859673..e2045a64a95 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-delete-view-filter-input-to-flat-view-filter-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-delete-view-filter-input-to-flat-view-filter-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { type FlatViewFilterMaps } from 'src/engine/metadata-modules/flat-view-filter/types/flat-view-filter-maps.type'; +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'; import { type DeleteViewFilterInput } from 'src/engine/metadata-modules/view-filter/dtos/inputs/delete-view-filter.input'; import { @@ -24,7 +25,10 @@ export const fromDeleteViewFilterInputToFlatViewFilterOrThrow = ({ ['id'], ); - const existingFlatViewFilterToDelete = flatViewFilterMaps.byId[viewFilterId]; + const existingFlatViewFilterToDelete = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFilterId, + flatEntityMaps: flatViewFilterMaps, + }); if (!isDefined(existingFlatViewFilterToDelete)) { throw new ViewFilterException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-destroy-view-filter-input-to-flat-view-filter-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-destroy-view-filter-input-to-flat-view-filter-or-throw.util.ts index b2cc19fc3cb..25a635d8964 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-destroy-view-filter-input-to-flat-view-filter-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-destroy-view-filter-input-to-flat-view-filter-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { type FlatViewFilterMaps } from 'src/engine/metadata-modules/flat-view-filter/types/flat-view-filter-maps.type'; +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'; import { type DestroyViewFilterInput } from 'src/engine/metadata-modules/view-filter/dtos/inputs/destroy-view-filter.input'; import { @@ -24,7 +25,10 @@ export const fromDestroyViewFilterInputToFlatViewFilterOrThrow = ({ ['id'], ); - const existingFlatViewFilterToDestroy = flatViewFilterMaps.byId[viewFilterId]; + const existingFlatViewFilterToDestroy = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFilterId, + flatEntityMaps: flatViewFilterMaps, + }); if (!isDefined(existingFlatViewFilterToDestroy)) { throw new ViewFilterException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-update-view-filter-input-to-flat-view-filter-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-update-view-filter-input-to-flat-view-filter-to-update-or-throw.util.ts index e55a20bc3ad..97d6244cce7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-update-view-filter-input-to-flat-view-filter-to-update-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-filter/utils/from-update-view-filter-input-to-flat-view-filter-to-update-or-throw.util.ts @@ -6,6 +6,7 @@ import { } from 'twenty-shared/utils'; import { FLAT_VIEW_FILTER_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-view-filter/constants/flat-view-filter-editable-properties.constant'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatViewFilterMaps } from 'src/engine/metadata-modules/flat-view-filter/types/flat-view-filter-maps.type'; import { type FlatViewFilter } from 'src/engine/metadata-modules/flat-view-filter/types/flat-view-filter.type'; import { type UpdateViewFilterInput } from 'src/engine/metadata-modules/view-filter/dtos/inputs/update-view-filter.input'; @@ -28,8 +29,10 @@ export const fromUpdateViewFilterInputToFlatViewFilterToUpdateOrThrow = ({ ['id'], ); - const existingFlatViewFilterToUpdate = - flatViewFilterMaps.byId[viewFilterToUpdateId]; + const existingFlatViewFilterToUpdate = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFilterToUpdateId, + flatEntityMaps: flatViewFilterMaps, + }); if (!isDefined(existingFlatViewFilterToUpdate)) { throw new ViewFilterException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/compute-flat-view-groups-on-view-create.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/compute-flat-view-groups-on-view-create.util.ts index 23acf58c86f..cc55c5bf554 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/compute-flat-view-groups-on-view-create.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/compute-flat-view-groups-on-view-create.util.ts @@ -7,6 +7,7 @@ import { FlatEntityMapsExceptionCode, } from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception'; import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type'; type ComputeFlatViewGroupsOnViewCreateArgs = { @@ -19,8 +20,10 @@ export const computeFlatViewGroupsOnViewCreate = ({ mainGroupByFieldMetadataId, flatFieldMetadataMaps, }: ComputeFlatViewGroupsOnViewCreateArgs): FlatViewGroup[] => { - const mainGroupByFieldMetadata = - flatFieldMetadataMaps.byId[mainGroupByFieldMetadataId]; + const mainGroupByFieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: mainGroupByFieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!isDefined(mainGroupByFieldMetadata)) { throw new FlatEntityMapsException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-delete-view-group-input-to-flat-view-group-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-delete-view-group-input-to-flat-view-group-or-throw.util.ts index f8da0ab6484..4b1626e5277 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-delete-view-group-input-to-flat-view-group-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-delete-view-group-input-to-flat-view-group-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { type FlatViewGroupMaps } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type'; import { type DeleteViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/delete-view-group.input'; import { @@ -24,7 +25,10 @@ export const fromDeleteViewGroupInputToFlatViewGroupOrThrow = ({ ['id'], ); - const existingFlatViewGroupToDelete = flatViewGroupMaps.byId[viewGroupId]; + const existingFlatViewGroupToDelete = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewGroupId, + flatEntityMaps: flatViewGroupMaps, + }); if (!isDefined(existingFlatViewGroupToDelete)) { throw new ViewGroupException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-destroy-view-group-input-to-flat-view-group-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-destroy-view-group-input-to-flat-view-group-or-throw.util.ts index 316292e52df..7392806acd7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-destroy-view-group-input-to-flat-view-group-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-destroy-view-group-input-to-flat-view-group-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { type FlatViewGroupMaps } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type'; import { type DestroyViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/destroy-view-group.input'; import { @@ -24,7 +25,10 @@ export const fromDestroyViewGroupInputToFlatViewGroupOrThrow = ({ ['id'], ); - const existingFlatViewGroupToDestroy = flatViewGroupMaps.byId[viewGroupId]; + const existingFlatViewGroupToDestroy = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewGroupId, + flatEntityMaps: flatViewGroupMaps, + }); if (!isDefined(existingFlatViewGroupToDestroy)) { throw new ViewGroupException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-update-view-group-input-to-flat-view-group-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-update-view-group-input-to-flat-view-group-to-update-or-throw.util.ts index be1225296db..431b032a10a 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-update-view-group-input-to-flat-view-group-to-update-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/from-update-view-group-input-to-flat-view-group-to-update-or-throw.util.ts @@ -7,6 +7,7 @@ import { import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { FLAT_VIEW_GROUP_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-view-group/constants/flat-view-group-editable-properties.constant'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type'; import { type UpdateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/update-view-group.input'; import { @@ -28,8 +29,10 @@ export const fromUpdateViewGroupInputToFlatViewGroupToUpdateOrThrow = ({ ['id'], ); - const existingFlatViewGroupToUpdate = - flatViewGroupMaps.byId[viewGroupToUpdateId]; + const existingFlatViewGroupToUpdate = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewGroupToUpdateId, + flatEntityMaps: flatViewGroupMaps, + }); if (!isDefined(existingFlatViewGroupToUpdate)) { throw new ViewGroupException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-delete-view-input-to-flat-view-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-delete-view-input-to-flat-view-or-throw.util.ts index d47bbf837ac..cd90f0d10d2 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-delete-view-input-to-flat-view-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-delete-view-input-to-flat-view-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { type FlatViewMaps } from 'src/engine/metadata-modules/flat-view/types/flat-view-maps.type'; +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'; import { type DeleteViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/delete-view.input'; import { @@ -24,7 +25,10 @@ export const fromDeleteViewInputToFlatViewOrThrow = ({ ['id'], ); - const existingFlatViewToDelete = flatViewMaps.byId[viewId]; + const existingFlatViewToDelete = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewId, + flatEntityMaps: flatViewMaps, + }); if (!isDefined(existingFlatViewToDelete)) { throw new ViewException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-destroy-view-input-to-flat-view-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-destroy-view-input-to-flat-view-or-throw.util.ts index ba5cbcf1639..ead2d7aee2e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-destroy-view-input-to-flat-view-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-destroy-view-input-to-flat-view-or-throw.util.ts @@ -5,6 +5,7 @@ import { } from 'twenty-shared/utils'; import { type FlatViewMaps } from 'src/engine/metadata-modules/flat-view/types/flat-view-maps.type'; +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'; import { type DestroyViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/destroy-view.input'; import { @@ -24,7 +25,10 @@ export const fromDestroyViewInputToFlatViewOrThrow = ({ ['id'], ); - const existingFlatViewToDestroy = flatViewMaps.byId[viewId]; + const existingFlatViewToDestroy = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewId, + flatEntityMaps: flatViewMaps, + }); if (!isDefined(existingFlatViewToDestroy)) { throw new ViewException( diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-update-view-input-to-flat-view-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-update-view-input-to-flat-view-to-update-or-throw.util.ts index 03bbbf1703c..e1025745d66 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-update-view-input-to-flat-view-to-update-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-view/utils/from-update-view-input-to-flat-view-to-update-or-throw.util.ts @@ -6,6 +6,7 @@ import { } from 'twenty-shared/utils'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatViewGroupMaps } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group-maps.type'; import { type FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type'; @@ -43,7 +44,10 @@ export const fromUpdateViewInputToFlatViewToUpdateOrThrow = ({ ['id'], ); - const existingFlatViewToUpdate = flatViewMaps.byId[viewToUpdateId]; + const existingFlatViewToUpdate = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewToUpdateId, + flatEntityMaps: flatViewMaps, + }); if (!isDefined(existingFlatViewToUpdate)) { throw new ViewException( diff --git a/packages/twenty-server/src/engine/metadata-modules/front-component/front-component.service.ts b/packages/twenty-server/src/engine/metadata-modules/front-component/front-component.service.ts index d7b6f0991f0..370e3e23262 100644 --- a/packages/twenty-server/src/engine/metadata-modules/front-component/front-component.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/front-component/front-component.service.ts @@ -37,7 +37,7 @@ export class FrontComponentService { }, ); - return Object.values(flatFrontComponentMaps.byId) + return Object.values(flatFrontComponentMaps.byUniversalIdentifier) .filter(isDefined) .sort((a, b) => a.name.localeCompare(b.name)) .map(fromFlatFrontComponentToFrontComponentDto); diff --git a/packages/twenty-server/src/engine/metadata-modules/logic-function/logic-function.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/logic-function/logic-function.resolver.ts index a61eeed2165..31fe2256d8c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/logic-function/logic-function.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/logic-function/logic-function.resolver.ts @@ -87,7 +87,7 @@ export class LogicFunctionResolver { }, ); - return Object.values(flatLogicFunctionMaps.byId) + return Object.values(flatLogicFunctionMaps.byUniversalIdentifier) .filter( (flatLogicFunction): flatLogicFunction is FlatLogicFunction => isDefined(flatLogicFunction) && diff --git a/packages/twenty-server/src/engine/metadata-modules/logic-function/services/logic-function.service.ts b/packages/twenty-server/src/engine/metadata-modules/logic-function/services/logic-function.service.ts index 0e1ca8ec9a7..6f5e4597d7d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/logic-function/services/logic-function.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/logic-function/services/logic-function.service.ts @@ -9,6 +9,7 @@ import { FileStorageService } from 'src/engine/core-modules/file-storage/file-st import { getLogicFunctionBaseFolderPath } from 'src/engine/core-modules/logic-function/logic-function-build/utils/get-logic-function-base-folder-path.util'; import { LogicFunctionLayerService } from 'src/engine/core-modules/logic-function/logic-function-layer/services/logic-function-layer.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import type { CreateLogicFunctionInput } from 'src/engine/metadata-modules/logic-function/dtos/create-logic-function.input'; import type { UpdateLogicFunctionInput } from 'src/engine/metadata-modules/logic-function/dtos/update-logic-function.input'; @@ -223,7 +224,10 @@ export class LogicFunctionService { }, ); - const existingFlatLogicFunction = existingFlatLogicFunctionMaps.byId[id]; + const existingFlatLogicFunction = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: id, + flatEntityMaps: existingFlatLogicFunctionMaps, + }); if (!isDefined(existingFlatLogicFunction)) { throw new LogicFunctionException( diff --git a/packages/twenty-server/src/engine/metadata-modules/navigation-menu-item/navigation-menu-item.service.ts b/packages/twenty-server/src/engine/metadata-modules/navigation-menu-item/navigation-menu-item.service.ts index d694aea6473..c4235b09a05 100644 --- a/packages/twenty-server/src/engine/metadata-modules/navigation-menu-item/navigation-menu-item.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/navigation-menu-item/navigation-menu-item.service.ts @@ -64,7 +64,7 @@ export class NavigationMenuItemService { }, ); - return Object.values(flatNavigationMenuItemMaps.byId) + return Object.values(flatNavigationMenuItemMaps.byUniversalIdentifier) .filter( (item): item is NonNullable => isDefined(item) && @@ -424,7 +424,10 @@ export class NavigationMenuItemService { }, ); - const objectMetadata = flatObjectMetadataMaps.byId[targetObjectMetadataId]; + const objectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: targetObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(objectMetadata)) { return null; diff --git a/packages/twenty-server/src/engine/metadata-modules/navigation-menu-item/services/navigation-menu-item-deletion.service.ts b/packages/twenty-server/src/engine/metadata-modules/navigation-menu-item/services/navigation-menu-item-deletion.service.ts index e3ce8bbbed6..8064f7acdd9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/navigation-menu-item/services/navigation-menu-item-deletion.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/navigation-menu-item/services/navigation-menu-item-deletion.service.ts @@ -36,7 +36,7 @@ export class NavigationMenuItemDeletionService { const deletedRecordIdsSet = new Set(deletedRecordIds); const navigationMenuItemsToDelete = Object.values( - flatNavigationMenuItemMaps.byId, + flatNavigationMenuItemMaps.byUniversalIdentifier, ).filter( (item): item is NonNullable => isDefined(item) && diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts index 653669bffff..80caddf96e9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts @@ -12,6 +12,7 @@ import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadat import { AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type'; import { MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type'; import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util'; +import { 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'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type'; @@ -156,8 +157,10 @@ export class ObjectMetadataService extends TypeOrmQueryService((flatObjectMetadata) => ({ - id: flatObjectMetadata.id, + .map((id) => ({ + id, })); await this.deleteManyObjectMetadatas({ diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util.ts index 5d5ff4ceb53..07d2ce116b9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util.ts @@ -71,7 +71,7 @@ export const buildDefaultRelationFlatFieldMetadatasForCustomObject = ({ flatApplication, }: BuildDefaultRelationFieldsForCustomObjectArgs): SourceAndTargetFlatFieldMetadatasRecord => { const objectIdByNameSingular = Object.values( - existingFlatObjectMetadataMaps.byId, + existingFlatObjectMetadataMaps.byUniversalIdentifier, ).reduce>((acc, flatObject) => { if (!isDefined(flatObject)) { return acc; diff --git a/packages/twenty-server/src/engine/metadata-modules/object-permission/__tests__/object-permission.service.spec.ts b/packages/twenty-server/src/engine/metadata-modules/object-permission/__tests__/object-permission.service.spec.ts index 5fd1ed91fa5..7e877082796 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-permission/__tests__/object-permission.service.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-permission/__tests__/object-permission.service.spec.ts @@ -110,7 +110,7 @@ describe('ObjectPermissionService', () => { workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue( { flatObjectMetadataMaps: { - byId: { + byUniversalIdentifier: { [systemObjectMetadataId]: { id: systemObjectMetadataId, isSystem: true, @@ -122,7 +122,9 @@ describe('ObjectPermissionService', () => { applicationId: null, } as any, }, - idByUniversalIdentifier: {}, + universalIdentifierById: { + [systemObjectMetadataId]: systemObjectMetadataId, + }, universalIdentifiersByApplicationId: {}, }, } as any, @@ -167,7 +169,7 @@ describe('ObjectPermissionService', () => { workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue( { flatObjectMetadataMaps: { - byId: { + byUniversalIdentifier: { [customObjectMetadataId]: { id: customObjectMetadataId, isSystem: false, @@ -179,7 +181,9 @@ describe('ObjectPermissionService', () => { applicationId: null, } as any, }, - idByUniversalIdentifier: {}, + universalIdentifierById: { + [customObjectMetadataId]: customObjectMetadataId, + }, universalIdentifiersByApplicationId: {}, }, } as any, @@ -254,8 +258,8 @@ describe('ObjectPermissionService', () => { workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue( { flatObjectMetadataMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, } as any, diff --git a/packages/twenty-server/src/engine/metadata-modules/object-permission/field-permission/__tests__/field-permissions.service.spec.ts b/packages/twenty-server/src/engine/metadata-modules/object-permission/field-permission/__tests__/field-permissions.service.spec.ts index 2dafceda889..e8b7e59fd13 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-permission/field-permission/__tests__/field-permissions.service.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-permission/field-permission/__tests__/field-permissions.service.spec.ts @@ -150,7 +150,7 @@ describe('FieldPermissionService', () => { workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue( { flatObjectMetadataMaps: { - byId: { + byUniversalIdentifier: { [testObjectMetadataId]: { ...objectMetadataItemMock, id: testObjectMetadataId, @@ -170,15 +170,22 @@ describe('FieldPermissionService', () => { applicationId: null, } as any, }, - idByUniversalIdentifier: {}, + universalIdentifierById: { + [testObjectMetadataId]: testObjectMetadataId, + [fieldRelationMock.objectMetadataId]: + fieldRelationMock.objectMetadataId, + }, universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: { - [testFieldMetadataId]: testFieldMetadata as any, - [fieldRelationMock.id]: fieldRelationMock as any, + byUniversalIdentifier: { + [testFieldMetadata.universalIdentifier]: testFieldMetadata as any, + [fieldRelationMock.universalIdentifier]: fieldRelationMock as any, + }, + universalIdentifierById: { + [testFieldMetadataId]: testFieldMetadata.universalIdentifier, + [fieldRelationMock.id]: fieldRelationMock.universalIdentifier, }, - idByUniversalIdentifier: {}, universalIdentifiersByApplicationId: {}, }, } as any, @@ -398,13 +405,13 @@ describe('FieldPermissionService', () => { workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue( { flatObjectMetadataMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, } as any, @@ -440,7 +447,7 @@ describe('FieldPermissionService', () => { workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue( { flatObjectMetadataMaps: { - byId: { + byUniversalIdentifier: { [testObjectMetadataId]: { ...systemObjectMetadata, id: testObjectMetadataId, @@ -451,12 +458,14 @@ describe('FieldPermissionService', () => { applicationId: null, } as any, }, - idByUniversalIdentifier: {}, + universalIdentifierById: { + [testObjectMetadataId]: testObjectMetadataId, + }, universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, } as any, @@ -486,7 +495,7 @@ describe('FieldPermissionService', () => { workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue( { flatObjectMetadataMaps: { - byId: { + byUniversalIdentifier: { [testObjectMetadataId]: { ...objectMetadataItemMock, id: testObjectMetadataId, @@ -497,12 +506,14 @@ describe('FieldPermissionService', () => { applicationId: null, } as any, }, - idByUniversalIdentifier: {}, + universalIdentifierById: { + [testObjectMetadataId]: testObjectMetadataId, + }, universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, } as any, diff --git a/packages/twenty-server/src/engine/metadata-modules/object-permission/field-permission/field-permission.service.ts b/packages/twenty-server/src/engine/metadata-modules/object-permission/field-permission/field-permission.service.ts index 6cc0123f6ae..c1c5791f29c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-permission/field-permission/field-permission.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-permission/field-permission/field-permission.service.ts @@ -15,6 +15,7 @@ import { import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { isFieldMetadataTypeRelation } from 'src/engine/metadata-modules/field-metadata/utils/is-field-metadata-type-relation.util'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -220,8 +221,10 @@ export class FieldPermissionService { ); } - const flatObjectMetadata = - flatObjectMetadataMaps.byId[fieldPermission.objectMetadataId]; + const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldPermission.objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(flatObjectMetadata)) { throw new PermissionsException( @@ -243,8 +246,10 @@ export class FieldPermissionService { ); } - const flatFieldMetadata = - flatFieldMetadataMaps.byId[fieldPermission.fieldMetadataId]; + const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldPermission.fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!isDefined(flatFieldMetadata)) { throw new PermissionsException( diff --git a/packages/twenty-server/src/engine/metadata-modules/object-permission/object-permission.service.ts b/packages/twenty-server/src/engine/metadata-modules/object-permission/object-permission.service.ts index 25a1e5a2732..6d1e7c30db7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-permission/object-permission.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-permission/object-permission.service.ts @@ -5,6 +5,7 @@ import { isDefined } from 'twenty-shared/utils'; import { In, Repository } from 'typeorm'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { type ObjectPermissionInput, @@ -63,7 +64,10 @@ export class ObjectPermissionService { input.objectPermissions.forEach((objectPermission) => { const objectMetadataForObjectPermission = - flatObjectMetadataMaps.byId[objectPermission.objectMetadataId]; + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectPermission.objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(objectMetadataForObjectPermission)) { throw new PermissionsException( diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-tab/services/page-layout-tab.service.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-tab/services/page-layout-tab.service.ts index 92077cf1228..be85ffef7d8 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-tab/services/page-layout-tab.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-tab/services/page-layout-tab.service.ts @@ -4,6 +4,7 @@ import { isDefined } from 'twenty-shared/utils'; import { ApplicationService } from 'src/engine/core-modules/application/services/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { FlatPageLayoutTabMaps } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab-maps.type'; import { fromCreatePageLayoutTabInputToFlatPageLayoutTabToCreate } from 'src/engine/metadata-modules/flat-page-layout-tab/utils/from-create-page-layout-tab-input-to-flat-page-layout-tab-to-create.util'; @@ -48,7 +49,7 @@ export class PageLayoutTabService { const { flatPageLayoutTabMaps, flatPageLayoutWidgetMaps } = await this.getPageLayoutTabFlatEntityMaps(workspaceId); - return Object.values(flatPageLayoutTabMaps.byId) + return Object.values(flatPageLayoutTabMaps.byUniversalIdentifier) .filter(isDefined) .filter( (tab) => tab.pageLayoutId === pageLayoutId && !isDefined(tab.deletedAt), @@ -74,7 +75,10 @@ export class PageLayoutTabService { const { flatPageLayoutTabMaps, flatPageLayoutWidgetMaps } = await this.getPageLayoutTabFlatEntityMaps(workspaceId); - const flatTab = flatPageLayoutTabMaps.byId[id]; + const flatTab = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: id, + flatEntityMaps: flatPageLayoutTabMaps, + }); if (!isDefined(flatTab) || isDefined(flatTab.deletedAt)) { throw new PageLayoutTabException( diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/services/page-layout-widget.service.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/services/page-layout-widget.service.ts index 7a347da834c..620909715ef 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/services/page-layout-widget.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/services/page-layout-widget.service.ts @@ -4,6 +4,7 @@ import { isDefined } from 'twenty-shared/utils'; import { ApplicationService } from 'src/engine/core-modules/application/services/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { FlatPageLayoutWidgetMaps } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-maps.type'; import { FlatPageLayoutWidget } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type'; @@ -101,7 +102,7 @@ export class PageLayoutWidgetService { const flatPageLayoutWidgetMaps = await this.getFlatPageLayoutWidgetMaps(workspaceId); - return Object.values(flatPageLayoutWidgetMaps.byId) + return Object.values(flatPageLayoutWidgetMaps.byUniversalIdentifier) .filter(isDefined) .filter( (widget) => @@ -126,7 +127,10 @@ export class PageLayoutWidgetService { const flatPageLayoutWidgetMaps = await this.getFlatPageLayoutWidgetMaps(workspaceId); - const flatWidget = flatPageLayoutWidgetMaps.byId[id]; + const flatWidget = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: id, + flatEntityMaps: flatPageLayoutWidgetMaps, + }); if (!isDefined(flatWidget) || isDefined(flatWidget.deletedAt)) { throw new PageLayoutWidgetException( @@ -245,7 +249,10 @@ export class PageLayoutWidgetService { id: string, flatPageLayoutWidgetMaps: FlatPageLayoutWidgetMaps, ): FlatPageLayoutWidget { - const existingWidget = flatPageLayoutWidgetMaps.byId[id]; + const existingWidget = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: id, + flatEntityMaps: flatPageLayoutWidgetMaps, + }); if (!isDefined(existingWidget) || isDefined(existingWidget.deletedAt)) { throw new PageLayoutWidgetException( diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-duplication.service.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-duplication.service.ts index 11e6cc8efb2..54ade398eee 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-duplication.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-duplication.service.ts @@ -5,6 +5,7 @@ import { isDefined } from 'twenty-shared/utils'; import { ApplicationService } from 'src/engine/core-modules/application/services/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; 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 { type FlatPageLayoutTabMaps } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab-maps.type'; import { type FlatPageLayoutTab } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type'; import { fromCreatePageLayoutTabInputToFlatPageLayoutTabToCreate } from 'src/engine/metadata-modules/flat-page-layout-tab/utils/from-create-page-layout-tab-input-to-flat-page-layout-tab-to-create.util'; @@ -166,7 +167,10 @@ export class PageLayoutDuplicationService { pageLayoutId: string, flatPageLayoutMaps: FlatPageLayoutMaps, ): FlatPageLayout { - const flatLayout = flatPageLayoutMaps.byId[pageLayoutId]; + const flatLayout = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: pageLayoutId, + flatEntityMaps: flatPageLayoutMaps, + }); if (!isDefined(flatLayout) || isDefined(flatLayout.deletedAt)) { throw new PageLayoutException( @@ -188,7 +192,9 @@ export class PageLayoutDuplicationService { ): { tab: FlatPageLayoutTab; widgets: FlatPageLayoutWidget[] }[] { const widgetsByTabId = new Map(); - for (const widget of Object.values(flatPageLayoutWidgetMaps.byId)) { + for (const widget of Object.values( + flatPageLayoutWidgetMaps.byUniversalIdentifier, + )) { if (!isDefined(widget) || isDefined(widget.deletedAt)) { continue; } @@ -199,7 +205,7 @@ export class PageLayoutDuplicationService { widgetsByTabId.set(widget.pageLayoutTabId, existingWidgets); } - const tabs = Object.values(flatPageLayoutTabMaps.byId) + const tabs = Object.values(flatPageLayoutTabMaps.byUniversalIdentifier) .filter( (tab): tab is FlatPageLayoutTab => isDefined(tab) && diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts index 726572463bb..a787ce288e0 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts @@ -7,6 +7,7 @@ import { v4 } from 'uuid'; import { ApplicationService } from 'src/engine/core-modules/application/services/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; 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 { FLAT_PAGE_LAYOUT_TAB_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-page-layout-tab/constants/flat-page-layout-tab-editable-properties.constant'; import { type FlatPageLayoutTabMaps } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab-maps.type'; import { type FlatPageLayoutTab } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type'; @@ -66,7 +67,10 @@ export class PageLayoutUpdateService { }, ); - const existingPageLayout = flatPageLayoutMaps.byId[id]; + const existingPageLayout = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: id, + flatEntityMaps: flatPageLayoutMaps, + }); // TODO move in validator if ( @@ -203,7 +207,9 @@ export class PageLayoutUpdateService { tabsToUpdate: FlatPageLayoutTab[]; tabsToDelete: FlatPageLayoutTab[]; } { - const existingTabs = Object.values(flatPageLayoutTabMaps.byId) + const existingTabs = Object.values( + flatPageLayoutTabMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter((tab) => tab.pageLayoutId === existingPageLayout.id); @@ -279,7 +285,10 @@ export class PageLayoutUpdateService { const tabsToDelete: FlatPageLayoutTab[] = idsToDelete .map((tabId) => { - const existingTab = flatPageLayoutTabMaps.byId[tabId]; + const existingTab = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: tabId, + flatEntityMaps: flatPageLayoutTabMaps, + }); if (!isDefined(existingTab)) { return null; @@ -359,7 +368,9 @@ export class PageLayoutUpdateService { widgetsToCreate: FlatPageLayoutWidget[]; widgetsToUpdate: FlatPageLayoutWidget[]; } { - const existingWidgets = Object.values(flatPageLayoutWidgetMaps.byId) + const existingWidgets = Object.values( + flatPageLayoutWidgetMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter((widget) => widget.pageLayoutTabId === tabId); @@ -447,7 +458,10 @@ export class PageLayoutUpdateService { const widgetsToDelete: FlatPageLayoutWidget[] = idsToDelete .map((widgetId) => { - const existingWidget = flatPageLayoutWidgetMaps.byId[widgetId]; + const existingWidget = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: widgetId, + flatEntityMaps: flatPageLayoutWidgetMaps, + }); if (!isDefined(existingWidget)) { return null; diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout.service.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout.service.ts index fb4eda8565e..477be69decf 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout.service.ts @@ -5,6 +5,7 @@ import { isDefined } from 'twenty-shared/utils'; import { ApplicationService } from 'src/engine/core-modules/application/services/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { type FlatPageLayoutTabMaps } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab-maps.type'; import { type FlatPageLayoutWidgetMaps } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-maps.type'; @@ -51,7 +52,9 @@ export class PageLayoutService { flatPageLayoutWidgetMaps, } = await this.getPageLayoutFlatEntityMaps(workspaceId); - const activeLayouts = Object.values(flatPageLayoutMaps.byId) + const activeLayouts = Object.values( + flatPageLayoutMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter((layout) => !isDefined(layout.deletedAt)); @@ -79,7 +82,9 @@ export class PageLayoutService { flatPageLayoutWidgetMaps, } = await this.getPageLayoutFlatEntityMaps(workspaceId); - const activeLayouts = Object.values(flatPageLayoutMaps.byId) + const activeLayouts = Object.values( + flatPageLayoutMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter( (layout) => @@ -111,7 +116,10 @@ export class PageLayoutService { flatPageLayoutWidgetMaps, } = await this.getPageLayoutFlatEntityMaps(workspaceId); - const flatLayout = flatPageLayoutMaps.byId[id]; + const flatLayout = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: id, + flatEntityMaps: flatPageLayoutMaps, + }); const isLayoutNotFound = !isDefined(flatLayout) || isDefined(flatLayout.deletedAt); diff --git a/packages/twenty-server/src/engine/metadata-modules/role-target/services/role-target.service.ts b/packages/twenty-server/src/engine/metadata-modules/role-target/services/role-target.service.ts index b747a52b468..6e4bc119440 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role-target/services/role-target.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role-target/services/role-target.service.ts @@ -4,6 +4,7 @@ import { isDefined } from 'twenty-shared/utils'; import { ApplicationService } from 'src/engine/core-modules/application/services/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { FlatRoleTarget } from 'src/engine/metadata-modules/flat-role-target/types/flat-role-target.type'; import { CreateRoleTargetInput } from 'src/engine/metadata-modules/role-target/types/create-role-target.input'; @@ -191,7 +192,10 @@ export class RoleTargetService { }, ); - const roleTarget = flatRoleTargetMaps.byId[id]; + const roleTarget = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: id, + flatEntityMaps: flatRoleTargetMaps, + }); return roleTarget ?? null; } diff --git a/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/services/row-level-permission-predicate-group.service.ts b/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/services/row-level-permission-predicate-group.service.ts index 6c63955441a..34e70d9bb54 100644 --- a/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/services/row-level-permission-predicate-group.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/services/row-level-permission-predicate-group.service.ts @@ -45,7 +45,9 @@ export class RowLevelPermissionPredicateGroupService { }, ); - return Object.values(flatRowLevelPermissionPredicateGroupMaps.byId) + return Object.values( + flatRowLevelPermissionPredicateGroupMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter((group) => group.deletedAt === null) .sort( @@ -75,7 +77,9 @@ export class RowLevelPermissionPredicateGroupService { }, ); - return Object.values(flatRowLevelPermissionPredicateGroupMaps.byId) + return Object.values( + flatRowLevelPermissionPredicateGroupMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter((group) => group.deletedAt === null && group.roleId === roleId) .sort( diff --git a/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/services/row-level-permission-predicate.service.ts b/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/services/row-level-permission-predicate.service.ts index 5da47d5044b..ea47897cbe7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/services/row-level-permission-predicate.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/row-level-permission-predicate/services/row-level-permission-predicate.service.ts @@ -60,7 +60,9 @@ export class RowLevelPermissionPredicateService { }, ); - return Object.values(flatRowLevelPermissionPredicateMaps.byId) + return Object.values( + flatRowLevelPermissionPredicateMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter((predicate) => predicate.deletedAt === null) .sort( @@ -91,7 +93,9 @@ export class RowLevelPermissionPredicateService { }, ); - return Object.values(flatRowLevelPermissionPredicateMaps.byId) + return Object.values( + flatRowLevelPermissionPredicateMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter( (predicate) => @@ -173,7 +177,7 @@ export class RowLevelPermissionPredicateService { ); const existingPredicates = Object.values( - flatRowLevelPermissionPredicateMaps.byId, + flatRowLevelPermissionPredicateMaps.byUniversalIdentifier, ) .filter(isDefined) .filter( @@ -184,7 +188,7 @@ export class RowLevelPermissionPredicateService { ); const existingGroups = Object.values( - flatRowLevelPermissionPredicateGroupMaps.byId, + flatRowLevelPermissionPredicateGroupMaps.byUniversalIdentifier, ) .filter(isDefined) .filter( @@ -239,7 +243,9 @@ export class RowLevelPermissionPredicateService { }, ); - const resultPredicates = Object.values(updatedPredicateMaps.byId) + const resultPredicates = Object.values( + updatedPredicateMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter( (predicate) => @@ -249,7 +255,7 @@ export class RowLevelPermissionPredicateService { ) .map(fromFlatRowLevelPermissionPredicateToDto); - const resultGroups = Object.values(updatedGroupMaps.byId) + const resultGroups = Object.values(updatedGroupMaps.byUniversalIdentifier) .filter(isDefined) .filter( (group) => @@ -295,8 +301,10 @@ export class RowLevelPermissionPredicateService { inputGroupIds.add(groupId); - const existingGroup = - flatRowLevelPermissionPredicateGroupMaps.byId[groupId]; + const existingGroup = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: groupId, + flatEntityMaps: flatRowLevelPermissionPredicateGroupMaps, + }); if (isDefined(existingGroup) && existingGroup.deletedAt === null) { groupsToUpdate.push({ @@ -377,8 +385,10 @@ export class RowLevelPermissionPredicateService { inputPredicateIds.add(predicateId); - const existingPredicate = - flatRowLevelPermissionPredicateMaps.byId[predicateId]; + const existingPredicate = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: predicateId, + flatEntityMaps: flatRowLevelPermissionPredicateMaps, + }); if ( isDefined(existingPredicate) && diff --git a/packages/twenty-server/src/engine/metadata-modules/skill/skill.service.ts b/packages/twenty-server/src/engine/metadata-modules/skill/skill.service.ts index 28f4c1611e8..f51e2755761 100644 --- a/packages/twenty-server/src/engine/metadata-modules/skill/skill.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/skill/skill.service.ts @@ -38,7 +38,7 @@ export class SkillService { }, ); - return Object.values(flatSkillMaps.byId) + return Object.values(flatSkillMaps.byUniversalIdentifier) .filter(isDefined) .sort((a, b) => a.label.localeCompare(b.label)) .map(fromFlatSkillToSkillDto); @@ -237,7 +237,7 @@ export class SkillService { }, ); - return Object.values(flatSkillMaps.byId) + return Object.values(flatSkillMaps.byUniversalIdentifier) .filter(isDefined) .filter((flatSkill) => flatSkill.isActive) .sort((a, b) => a.label.localeCompare(b.label)); @@ -259,7 +259,7 @@ export class SkillService { }, ); - return Object.values(flatSkillMaps.byId) + return Object.values(flatSkillMaps.byUniversalIdentifier) .filter(isDefined) .filter( (flatSkill) => names.includes(flatSkill.name) && flatSkill.isActive, diff --git a/packages/twenty-server/src/engine/metadata-modules/view-group/services/view-group.service.ts b/packages/twenty-server/src/engine/metadata-modules/view-group/services/view-group.service.ts index 421a53e9204..dd1c57b5ee3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view-group/services/view-group.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view-group/services/view-group.service.ts @@ -7,6 +7,7 @@ import { IsNull, Repository } from 'typeorm'; import { ApplicationService } from 'src/engine/core-modules/application/services/application.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; 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 { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { fromCreateViewGroupInputToFlatViewGroupToCreate } from 'src/engine/metadata-modules/flat-view-group/utils/from-create-view-group-input-to-flat-view-group-to-create.util'; import { fromDeleteViewGroupInputToFlatViewGroupOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-delete-view-group-input-to-flat-view-group-or-throw.util'; @@ -86,9 +87,10 @@ export class ViewGroupService { const flatViewGroupsToCreate = createViewGroupInputs.map( (createViewGroupInput) => { - const mainGroupByFieldMetadataId = - flatViewMaps.byId[createViewGroupInput.viewId] - ?.mainGroupByFieldMetadataId; + const mainGroupByFieldMetadataId = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: createViewGroupInput.viewId, + flatEntityMaps: flatViewMaps, + })?.mainGroupByFieldMetadataId; if (!isDefined(mainGroupByFieldMetadataId)) { throw new ViewGroupException( diff --git a/packages/twenty-server/src/engine/metadata-modules/view/controllers/view.controller.ts b/packages/twenty-server/src/engine/metadata-modules/view/controllers/view.controller.ts index 4142df18f91..ca33c029189 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view/controllers/view.controller.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view/controllers/view.controller.ts @@ -23,6 +23,7 @@ import { CustomPermissionGuard } from 'src/engine/guards/custom-permission.guard import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { resolveObjectMetadataStandardOverride } from 'src/engine/metadata-modules/object-metadata/utils/resolve-object-metadata-standard-override.util'; import { CreateViewPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/create-view-permission.guard'; import { DeleteViewPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/delete-view-permission.guard'; @@ -189,8 +190,10 @@ export class ViewController { let processedName = view.name; if (view.name.includes('{objectLabelPlural}')) { - const objectMetadata = - flatObjectMetadataMaps.byId[view.objectMetadataId]; + const objectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: view.objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (objectMetadata) { const i18n = this.i18nService.getI18nInstance(locale ?? 'en'); diff --git a/packages/twenty-server/src/engine/metadata-modules/view/services/__tests__/view-query-params.service.spec.ts b/packages/twenty-server/src/engine/metadata-modules/view/services/__tests__/view-query-params.service.spec.ts index acea4ccd526..b86ea538970 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view/services/__tests__/view-query-params.service.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view/services/__tests__/view-query-params.service.spec.ts @@ -21,30 +21,37 @@ describe('ViewQueryParamsService', () => { const mockFieldMetadataId = 'field-metadata-id'; const mockFlatObjectMetadataMaps = { - byId: { - [mockObjectMetadataId]: { + byUniversalIdentifier: { + 'object-universal-id': { id: mockObjectMetadataId, nameSingular: 'company', namePlural: 'companies', labelSingular: 'Company', labelPlural: 'Companies', + universalIdentifier: 'object-universal-id', }, }, - byNameSingular: {}, - byNamePlural: {}, + universalIdentifierById: { + [mockObjectMetadataId]: 'object-universal-id', + }, + universalIdentifiersByApplicationId: {}, }; const mockFlatFieldMetadataMaps = { - byId: { - [mockFieldMetadataId]: { + byUniversalIdentifier: { + 'field-universal-id': { id: mockFieldMetadataId, name: 'name', type: FieldMetadataType.TEXT, label: 'Name', options: null, + universalIdentifier: 'field-universal-id', }, }, - byNameAndObjectId: {}, + universalIdentifierById: { + [mockFieldMetadataId]: 'field-universal-id', + }, + universalIdentifiersByApplicationId: {}, }; beforeEach(async () => { diff --git a/packages/twenty-server/src/engine/metadata-modules/view/services/view-query-params.service.ts b/packages/twenty-server/src/engine/metadata-modules/view/services/view-query-params.service.ts index d66a6375808..eddcccd1cba 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view/services/view-query-params.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view/services/view-query-params.service.ts @@ -16,6 +16,7 @@ import { type ObjectRecordOrderBy } from 'src/engine/api/graphql/workspace-query import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; 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 { ViewFilterGroupLogicalOperator } from 'src/engine/metadata-modules/view-filter-group/enums/view-filter-group-logical-operator'; import { ViewSortDirection } from 'src/engine/metadata-modules/view-sort/enums/view-sort-direction'; import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum'; @@ -62,7 +63,10 @@ export class ViewQueryParamsService { const recordFilters: RecordFilter[] = (view.viewFilters ?? []) .map((viewFilter) => { - const field = flatFieldMetadataMaps.byId[viewFilter.fieldMetadataId]; + const field = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFilter.fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!field) return null; @@ -91,7 +95,10 @@ export class ViewQueryParamsService { const fields = recordFilters .map((filter) => { - const field = flatFieldMetadataMaps.byId[filter.fieldMetadataId]; + const field = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: filter.fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!field) return null; @@ -120,7 +127,10 @@ export class ViewQueryParamsService { const orderBy: ObjectRecordOrderBy = (view.viewSorts ?? []) .map((sort) => { - const field = flatFieldMetadataMaps.byId[sort.fieldMetadataId]; + const field = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: sort.fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!field) return null; diff --git a/packages/twenty-server/src/engine/metadata-modules/view/tools/__tests__/view-tools.factory.spec.ts b/packages/twenty-server/src/engine/metadata-modules/view/tools/__tests__/view-tools.factory.spec.ts index f0ae0444db5..9d159bd630b 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view/tools/__tests__/view-tools.factory.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view/tools/__tests__/view-tools.factory.spec.ts @@ -33,16 +33,19 @@ describe('ViewToolsFactory', () => { }; const mockFlatObjectMetadataMaps = { - byId: { - [mockObjectMetadataId]: { + byUniversalIdentifier: { + 'object-universal-id': { id: mockObjectMetadataId, nameSingular: mockObjectNameSingular, namePlural: 'companies', labelSingular: 'Company', labelPlural: 'Companies', + universalIdentifier: 'object-universal-id', }, }, - idByUniversalIdentifier: {}, + universalIdentifierById: { + [mockObjectMetadataId]: 'object-universal-id', + }, universalIdentifiersByApplicationId: {}, }; diff --git a/packages/twenty-server/src/engine/metadata-modules/view/tools/view-tools.factory.ts b/packages/twenty-server/src/engine/metadata-modules/view/tools/view-tools.factory.ts index 8e62ea1b792..72850dff2e7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view/tools/view-tools.factory.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view/tools/view-tools.factory.ts @@ -88,9 +88,9 @@ export class ViewToolsFactory { }, ); - const objectMetadata = Object.values(flatObjectMetadataMaps.byId).find( - (obj) => obj?.nameSingular === objectNameSingular, - ); + const objectMetadata = Object.values( + flatObjectMetadataMaps.byUniversalIdentifier, + ).find((obj) => obj?.nameSingular === objectNameSingular); if (!objectMetadata) { throw new Error( diff --git a/packages/twenty-server/src/engine/trash-cleanup/services/__tests__/trash-cleanup.service.spec.ts b/packages/twenty-server/src/engine/trash-cleanup/services/__tests__/trash-cleanup.service.spec.ts index 11944d0a795..26c4d37d3ad 100644 --- a/packages/twenty-server/src/engine/trash-cleanup/services/__tests__/trash-cleanup.service.spec.ts +++ b/packages/twenty-server/src/engine/trash-cleanup/services/__tests__/trash-cleanup.service.spec.ts @@ -69,13 +69,18 @@ describe('TrashCleanupService', () => { }; const setObjectMetadataCache = ( - entries: Array<{ id: string; nameSingular: string }>, + entries: Array<{ + id: string; + nameSingular: string; + universalIdentifier: string; + }>, ) => { - const byId = entries.reduce>( - (acc, { id, nameSingular }) => { - acc[id] = { + const byUniversalIdentifier = entries.reduce>( + (acc, { id, nameSingular, universalIdentifier }) => { + acc[universalIdentifier] = { id, nameSingular, + universalIdentifier, }; return acc; @@ -83,11 +88,21 @@ describe('TrashCleanupService', () => { {}, ); + const universalIdentifierById = entries.reduce>( + (acc, { id, universalIdentifier }) => { + acc[id] = universalIdentifier; + + return acc; + }, + {}, + ); + mockFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue( { flatObjectMetadataMaps: { - byId, - idByUniversalIdentifier: {}, + byUniversalIdentifier, + universalIdentifierById, + universalIdentifiersByApplicationId: {}, }, }, ); @@ -95,8 +110,16 @@ describe('TrashCleanupService', () => { it('should return deleted count when cleanup succeeds', async () => { setObjectMetadataCache([ - { id: 'obj-company', nameSingular: 'company' }, - { id: 'obj-person', nameSingular: 'person' }, + { + id: 'obj-company', + nameSingular: 'company', + universalIdentifier: 'uni-company', + }, + { + id: 'obj-person', + nameSingular: 'person', + universalIdentifier: 'uni-person', + }, ]); const companyRepository = createRepositoryMock('company', 2); @@ -141,8 +164,16 @@ describe('TrashCleanupService', () => { (service as any).maxRecordsPerWorkspace = 3; (service as any).batchSize = 3; setObjectMetadataCache([ - { id: 'obj-company', nameSingular: 'company' }, - { id: 'obj-person', nameSingular: 'person' }, + { + id: 'obj-company', + nameSingular: 'company', + universalIdentifier: 'uni-company', + }, + { + id: 'obj-person', + nameSingular: 'person', + universalIdentifier: 'uni-person', + }, ]); const companyRepository = createRepositoryMock('company', 2); @@ -169,7 +200,13 @@ describe('TrashCleanupService', () => { }); it('should ignore objects without soft deleted records', async () => { - setObjectMetadataCache([{ id: 'obj-company', nameSingular: 'company' }]); + setObjectMetadataCache([ + { + id: 'obj-company', + nameSingular: 'company', + universalIdentifier: 'uni-company', + }, + ]); const companyRepository = createRepositoryMock('company', 0); @@ -187,7 +224,13 @@ describe('TrashCleanupService', () => { }); it('should delete records across multiple batches', async () => { - setObjectMetadataCache([{ id: 'obj-company', nameSingular: 'company' }]); + setObjectMetadataCache([ + { + id: 'obj-company', + nameSingular: 'company', + universalIdentifier: 'uni-company', + }, + ]); const companyRepository = createRepositoryMock('company', 5); diff --git a/packages/twenty-server/src/engine/trash-cleanup/services/trash-cleanup.service.ts b/packages/twenty-server/src/engine/trash-cleanup/services/trash-cleanup.service.ts index 04f38bf5ce1..eaafcb3613e 100644 --- a/packages/twenty-server/src/engine/trash-cleanup/services/trash-cleanup.service.ts +++ b/packages/twenty-server/src/engine/trash-cleanup/services/trash-cleanup.service.ts @@ -37,7 +37,9 @@ export class TrashCleanupService { }, ); - const objectNames = Object.values(flatObjectMetadataMaps.byId ?? {}) + const objectNames = Object.values( + flatObjectMetadataMaps.byUniversalIdentifier ?? {}, + ) .map((metadata) => metadata?.nameSingular) .filter(isDefined); diff --git a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts index a51e4d8f741..97cfe828c3c 100644 --- a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts @@ -179,20 +179,20 @@ describe('WorkspaceEntityManager', () => { }; const flatObjectMetadataMaps: FlatEntityMaps = { - byId: { + byUniversalIdentifier: { 'test-entity-id': mockFlatObjectMetadata, }, - idByUniversalIdentifier: { + universalIdentifierById: { 'test-entity-id': 'test-entity-id', }, universalIdentifiersByApplicationId: {}, }; const flatFieldMetadataMaps: FlatEntityMaps = { - byId: { + byUniversalIdentifier: { 'field-id': mockFlatFieldMetadata, }, - idByUniversalIdentifier: { + universalIdentifierById: { 'field-id': 'field-id', }, universalIdentifiersByApplicationId: {}, @@ -203,18 +203,18 @@ describe('WorkspaceEntityManager', () => { flatObjectMetadataMaps, flatFieldMetadataMaps, flatIndexMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, flatRowLevelPermissionPredicateMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, flatRowLevelPermissionPredicateGroupMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, objectIdByNameSingular: { diff --git a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.ts b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.ts index 98b13c5cf95..f89e8ea89c2 100644 --- a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.ts +++ b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.ts @@ -36,10 +36,11 @@ import { InstanceChecker } from 'typeorm/util/InstanceChecker'; import { type FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; import { type WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface'; -import { type WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type'; import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action'; import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; +import { type WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type'; import { InternalServerError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { PermissionsException, @@ -1390,8 +1391,10 @@ export class WorkspaceEntityManager extends EntityManager { Object.entries(restrictedFields) .filter(([_, fieldPermissions]) => fieldPermissions.canRead === false) .map(([fieldMetadataId]) => { - const fieldMetadata = - this.internalContext.flatFieldMetadataMaps.byId[fieldMetadataId]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: this.internalContext.flatFieldMetadataMaps, + }); if (!isDefined(fieldMetadata)) { throw new InternalServerError( diff --git a/packages/twenty-server/src/engine/twenty-orm/field-operations/files-field-sync/files-field-sync.ts b/packages/twenty-server/src/engine/twenty-orm/field-operations/files-field-sync/files-field-sync.ts index 7f7336dc6fe..a32d127a64c 100644 --- a/packages/twenty-server/src/engine/twenty-orm/field-operations/files-field-sync/files-field-sync.ts +++ b/packages/twenty-server/src/engine/twenty-orm/field-operations/files-field-sync/files-field-sync.ts @@ -19,6 +19,7 @@ import { type WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/ import { STANDARD_ERROR_MESSAGE } from 'src/engine/api/common/common-query-runners/errors/standard-error-message.constant'; import { getFlatFieldsFromFlatObjectMetadata } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util'; import { FileEntity } from 'src/engine/core-modules/file/entities/file.entity'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { TwentyORMException, @@ -597,8 +598,10 @@ export class FilesFieldSync { } private getFilesFields(objectMetadataId: string): FlatFieldMetadata[] { - const objectMetadata = - this.internalContext.flatObjectMetadataMaps.byId[objectMetadataId]; + const objectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectMetadataId, + flatEntityMaps: this.internalContext.flatObjectMetadataMaps, + }); if (!objectMetadata) { return []; diff --git a/packages/twenty-server/src/engine/twenty-orm/repository/__tests__/workspace.repository.spec.ts b/packages/twenty-server/src/engine/twenty-orm/repository/__tests__/workspace.repository.spec.ts index 366494f6dc6..d4466da527b 100644 --- a/packages/twenty-server/src/engine/twenty-orm/repository/__tests__/workspace.repository.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/repository/__tests__/workspace.repository.spec.ts @@ -111,30 +111,32 @@ describe('WorkspaceRepository', () => { mockInternalContext = { workspaceId: 'test-workspace-id', flatObjectMetadataMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: { - 'test-field-id': mockFieldMetadata, + byUniversalIdentifier: { + 'id-field-universal-id': mockFieldMetadata, + }, + universalIdentifierById: { + 'test-field-id': 'id-field-universal-id', }, - idByUniversalIdentifier: {}, universalIdentifiersByApplicationId: {}, }, flatIndexMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, flatRowLevelPermissionPredicateMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, flatRowLevelPermissionPredicateGroupMaps: { - byId: {}, - idByUniversalIdentifier: {}, + byUniversalIdentifier: {}, + universalIdentifierById: {}, universalIdentifiersByApplicationId: {}, }, objectIdByNameSingular: {}, diff --git a/packages/twenty-server/src/engine/twenty-orm/repository/permissions.utils.ts b/packages/twenty-server/src/engine/twenty-orm/repository/permissions.utils.ts index cfc68558895..8099eb49203 100644 --- a/packages/twenty-server/src/engine/twenty-orm/repository/permissions.utils.ts +++ b/packages/twenty-server/src/engine/twenty-orm/repository/permissions.utils.ts @@ -10,6 +10,7 @@ import { type QueryExpressionMap } from 'typeorm/query-builder/QueryExpressionMa import { ProcessAggregateHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-aggregate.helper'; import { InternalServerError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { @@ -96,7 +97,10 @@ export const validateOperationIsPermittedOrThrow = ({ ); } - const objectMetadata = flatObjectMetadataMaps.byId[objectMetadataIdForEntity]; + const objectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectMetadataIdForEntity, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(objectMetadata)) { throw new PermissionsException( diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/compute-relation-connect-query-configs.util.spec.ts b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/compute-relation-connect-query-configs.util.spec.ts index d3932f338ff..8d81cd2c61d 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/compute-relation-connect-query-configs.util.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/compute-relation-connect-query-configs.util.spec.ts @@ -183,17 +183,17 @@ describe('computeRelationConnectQueryConfigs', () => { const allFields = [...personFields, ...companyFields]; const flatFieldMetadataMaps: FlatEntityMaps = { - byId: allFields.reduce( + byUniversalIdentifier: allFields.reduce( (acc, field) => { - acc[field.id] = field; + acc[field.universalIdentifier] = field; return acc; }, {} as Record, ), - idByUniversalIdentifier: allFields.reduce( + universalIdentifierById: allFields.reduce( (acc, field) => { - acc[field.universalIdentifier] = field.id; + acc[field.id] = field.universalIdentifier; return acc; }, @@ -258,11 +258,11 @@ describe('computeRelationConnectQueryConfigs', () => { }); const flatObjectMetadataMaps: FlatEntityMaps = { - byId: { + byUniversalIdentifier: { 'person-object-metadata-id': personMetadata, 'company-object-metadata-id': companyMetadata, }, - idByUniversalIdentifier: { + universalIdentifierById: { 'person-object-metadata-id': 'person-object-metadata-id', 'company-object-metadata-id': 'company-object-metadata-id', }, @@ -284,7 +284,7 @@ describe('computeRelationConnectQueryConfigs', () => { }); const flatIndexMaps: FlatEntityMaps = { - byId: { + byUniversalIdentifier: { 'company-id-index-metadata-id': { id: 'company-id-index-metadata-id', name: 'company-id-index-metadata-name', @@ -337,7 +337,7 @@ describe('computeRelationConnectQueryConfigs', () => { ], } as unknown as FlatIndexMetadata, }, - idByUniversalIdentifier: { + universalIdentifierById: { 'company-id-index-metadata-id': 'company-id-index-metadata-id', 'company-domain-index-metadata-id': 'company-domain-index-metadata-id', 'company-composite-index-metadata-id': diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/format-twenty-orm-event-to-database-batch-event.util.spec.ts b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/format-twenty-orm-event-to-database-batch-event.util.spec.ts index 627a44ab593..e5a196ad4cb 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/format-twenty-orm-event-to-database-batch-event.util.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/format-twenty-orm-event-to-database-batch-event.util.spec.ts @@ -48,10 +48,10 @@ describe('formatTwentyOrmEventToDatabaseBatchEvent', () => { }); const flatFieldMetadataMaps: FlatEntityMaps = { - byId: { + byUniversalIdentifier: { 'name-id': nameField, }, - idByUniversalIdentifier: { + universalIdentifierById: { 'name-id': 'name-id', }, universalIdentifiersByApplicationId: {}, diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-column-name-to-field-metadata-id.util.spec.ts b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-column-name-to-field-metadata-id.util.spec.ts index ac800a0d108..a811c66b7c9 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-column-name-to-field-metadata-id.util.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-column-name-to-field-metadata-id.util.spec.ts @@ -75,17 +75,17 @@ describe('getColumnNameToFieldMetadataIdMap', () => { const buildFlatFieldMetadataMaps = ( fields: FlatFieldMetadata[], ): FlatEntityMaps => ({ - byId: fields.reduce( + byUniversalIdentifier: fields.reduce( (acc, field) => { - acc[field.id] = field; + acc[field.universalIdentifier] = field; return acc; }, {} as Record, ), - idByUniversalIdentifier: fields.reduce( + universalIdentifierById: fields.reduce( (acc, field) => { - acc[field.universalIdentifier] = field.id; + acc[field.id] = field.universalIdentifier; return acc; }, diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-field-metadata-id-to-column-names-map.util.spec.ts b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-field-metadata-id-to-column-names-map.util.spec.ts index 1cc78c84138..64a313a9fc8 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-field-metadata-id-to-column-names-map.util.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/get-field-metadata-id-to-column-names-map.util.spec.ts @@ -73,17 +73,17 @@ describe('getFieldMetadataIdToColumnNamesMap', () => { const buildFlatFieldMetadataMaps = ( fields: FlatFieldMetadata[], ): FlatEntityMaps => ({ - byId: fields.reduce( + byUniversalIdentifier: fields.reduce( (acc, field) => { - acc[field.id] = field; + acc[field.universalIdentifier] = field; return acc; }, {} as Record, ), - idByUniversalIdentifier: fields.reduce( + universalIdentifierById: fields.reduce( (acc, field) => { - acc[field.universalIdentifier] = field.id; + acc[field.id] = field.universalIdentifier; return acc; }, diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/is-record-matching-rls-row-level-permission-predicate.util.spec.ts b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/is-record-matching-rls-row-level-permission-predicate.util.spec.ts index 354dc50b243..83d8d37f9a0 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/is-record-matching-rls-row-level-permission-predicate.util.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/__tests__/is-record-matching-rls-row-level-permission-predicate.util.spec.ts @@ -75,17 +75,17 @@ describe('isRecordMatchingRLSRowLevelPermissionPredicate', () => { const buildFlatFieldMetadataMaps = ( fields: FlatFieldMetadata[], ): FlatEntityMaps => ({ - byId: fields.reduce( + byUniversalIdentifier: fields.reduce( (accumulator, field) => { - accumulator[field.id] = field; + accumulator[field.universalIdentifier] = field; return accumulator; }, {} as Record, ), - idByUniversalIdentifier: fields.reduce( + universalIdentifierById: fields.reduce( (accumulator, field) => { - accumulator[field.universalIdentifier] = field.id; + accumulator[field.id] = field.universalIdentifier; return accumulator; }, diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/build-row-level-permission-record-filter.util.ts b/packages/twenty-server/src/engine/twenty-orm/utils/build-row-level-permission-record-filter.util.ts index ed37a584842..66ca53921f3 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/build-row-level-permission-record-filter.util.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/build-row-level-permission-record-filter.util.ts @@ -21,6 +21,7 @@ import { import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { @@ -52,7 +53,9 @@ export const buildRowLevelPermissionRecordFilter = ({ return null; } - const predicates = Object.values(flatRowLevelPermissionPredicateMaps.byId) + const predicates = Object.values( + flatRowLevelPermissionPredicateMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter( (predicate) => @@ -65,13 +68,14 @@ export const buildRowLevelPermissionRecordFilter = ({ return null; } - const fieldMetadataMapById = flatFieldMetadataMaps.byId; - const workspaceMember = authContext.workspaceMember; const recordFilters = predicates .map((predicate) => { - const fieldMetadata = fieldMetadataMapById[predicate.fieldMetadataId]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: predicate.fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!isDefined(fieldMetadata)) { throw new PermissionsException( @@ -85,8 +89,12 @@ export const buildRowLevelPermissionRecordFilter = ({ let predicateValue: RowLevelPermissionPredicateValue = predicate.value; if (isDefined(workspaceMemberFieldMetadataId)) { - const workspaceMemberFieldMetadata = - fieldMetadataMapById[workspaceMemberFieldMetadataId]; + const workspaceMemberFieldMetadata = findFlatEntityByIdInFlatEntityMaps( + { + flatEntityId: workspaceMemberFieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }, + ); if (!isDefined(workspaceMemberFieldMetadata)) { throw new PermissionsException( @@ -162,29 +170,34 @@ export const buildRowLevelPermissionRecordFilter = ({ }) .filter(isDefined); - const predicateGroupsById = flatRowLevelPermissionPredicateGroupMaps.byId; - const relevantGroupIds = new Set(); for (const predicate of predicates) { if (isDefined(predicate.rowLevelPermissionPredicateGroupId)) { relevantGroupIds.add(predicate.rowLevelPermissionPredicateGroupId); - let parentGroupId = - predicateGroupsById[predicate.rowLevelPermissionPredicateGroupId] - ?.parentRowLevelPermissionPredicateGroupId; + let parentGroupId = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: predicate.rowLevelPermissionPredicateGroupId, + flatEntityMaps: flatRowLevelPermissionPredicateGroupMaps, + })?.parentRowLevelPermissionPredicateGroupId; while (isDefined(parentGroupId) && !relevantGroupIds.has(parentGroupId)) { relevantGroupIds.add(parentGroupId); - parentGroupId = - predicateGroupsById[parentGroupId] - ?.parentRowLevelPermissionPredicateGroupId; + parentGroupId = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: parentGroupId, + flatEntityMaps: flatRowLevelPermissionPredicateGroupMaps, + })?.parentRowLevelPermissionPredicateGroupId; } } } const recordFilterGroups: RecordFilterGroup[] = [...relevantGroupIds] - .map((groupId) => predicateGroupsById[groupId]) + .map((groupId) => + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: groupId, + flatEntityMaps: flatRowLevelPermissionPredicateGroupMaps, + }), + ) .filter(isDefined) .filter( (predicateGroup) => @@ -203,7 +216,12 @@ export const buildRowLevelPermissionRecordFilter = ({ })); const fieldMetadataItems = predicates - .map((predicate) => fieldMetadataMapById[predicate.fieldMetadataId]) + .map((predicate) => + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: predicate.fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }), + ) .filter(isDefined) .map((field) => ({ id: field.id, diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/compute-relation-connect-query-configs.util.ts b/packages/twenty-server/src/engine/twenty-orm/utils/compute-relation-connect-query-configs.util.ts index b0fa4b7eec3..6913a9badc2 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/compute-relation-connect-query-configs.util.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/compute-relation-connect-query-configs.util.ts @@ -8,6 +8,8 @@ import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfa import { getFlatFieldsFromFlatObjectMetadata } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; +import { findManyFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata, @@ -147,8 +149,10 @@ const computeRecordToConnectCondition = ( uniqueConstraintFields: FlatFieldMetadata[]; targetObjectNameSingular: string; } => { - const field = - flatFieldMetadataMaps.byId[fieldMaps.fieldIdByName[connectFieldName]]; + const field = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMaps.fieldIdByName[connectFieldName], + flatEntityMaps: flatFieldMetadataMaps, + }); if ( !isDefined(field) || @@ -168,8 +172,12 @@ const computeRecordToConnectCondition = ( } checkNoRelationFieldConflictOrThrow(entity, connectFieldName); - const targetObjectMetadata = - flatObjectMetadataMaps.byId[field.relationTargetObjectMetadataId || '']; + const targetObjectMetadata = field.relationTargetObjectMetadataId + ? findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: field.relationTargetObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }) + : undefined; if (!isDefined(targetObjectMetadata)) { throw new TwentyORMException( @@ -211,18 +219,16 @@ const checkUniqueConstraintFullyPopulated = ( flatFieldMetadataMaps, ); - const indexMetadatas = flatObjectMetadata.indexMetadataIds - .map((indexId) => flatIndexMaps.byId[indexId]) - .filter(isDefined) - .map((index) => ({ - id: index.id, - isUnique: index.isUnique, - indexFieldMetadatas: index.flatIndexFieldMetadatas.map( - (fieldMetadata) => ({ - fieldMetadataId: fieldMetadata.fieldMetadataId, - }), - ), - })); + const indexMetadatas = findManyFlatEntityByIdInFlatEntityMaps({ + flatEntityIds: flatObjectMetadata.indexMetadataIds, + flatEntityMaps: flatIndexMaps, + }).map((index) => ({ + id: index.id, + isUnique: index.isUnique, + indexFieldMetadatas: index.flatIndexFieldMetadatas.map((fieldMetadata) => ({ + fieldMetadataId: fieldMetadata.fieldMetadataId, + })), + })); const uniqueConstraintsFields = getUniqueConstraintsFields< FlatFieldMetadata, diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/format-data.util.ts b/packages/twenty-server/src/engine/twenty-orm/utils/format-data.util.ts index 4d1d8e9c2ad..8aef2a601c2 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/format-data.util.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/format-data.util.ts @@ -7,6 +7,7 @@ import { capitalize } from 'twenty-shared/utils'; import { type CompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/composite-field-metadata-type.type'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata, @@ -45,7 +46,10 @@ export function formatData( for (const [key, value] of Object.entries(data)) { const fieldMetadataId = fieldIdByName[key] || fieldIdByJoinColumnName[key]; - const fieldMetadata = flatFieldMetadataMaps.byId[fieldMetadataId]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!fieldMetadata) { throw new Error( diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/format-result.util.ts b/packages/twenty-server/src/engine/twenty-orm/utils/format-result.util.ts index 690dce80f57..e7bafe5f8f7 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/format-result.util.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/format-result.util.ts @@ -16,6 +16,7 @@ import { import { getFlatFieldsFromFlatObjectMetadata } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util'; import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata, @@ -80,9 +81,10 @@ export function formatResult( fieldIdByName[key] || fieldIdByName[compositePropertyArgs?.parentField ?? '']; - const fieldMetadata = flatFieldMetadataMaps.byId[fieldMetadataId] as - | FlatFieldMetadata - | undefined; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); const isRelation = fieldMetadata ? isFieldMetadataEntityOfType(fieldMetadata, FieldMetadataType.RELATION) @@ -116,10 +118,10 @@ export function formatResult( ); } - const targetObjectMetadata = - flatObjectMetadataMaps.byId[ - fieldMetadata.relationTargetObjectMetadataId - ]; + const targetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadata.relationTargetObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!targetObjectMetadata) { throw new Error( diff --git a/packages/twenty-server/src/engine/twenty-orm/utils/get-object-metadata-from-entity-target.util.ts b/packages/twenty-server/src/engine/twenty-orm/utils/get-object-metadata-from-entity-target.util.ts index 8e764f0d10f..44c1e69b628 100644 --- a/packages/twenty-server/src/engine/twenty-orm/utils/get-object-metadata-from-entity-target.util.ts +++ b/packages/twenty-server/src/engine/twenty-orm/utils/get-object-metadata-from-entity-target.util.ts @@ -2,6 +2,7 @@ import { type EntityTarget, type ObjectLiteral } from 'typeorm'; import { type WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { TwentyORMException, @@ -35,8 +36,10 @@ export const getObjectMetadataFromEntityTarget = ( ); } - const objectMetadata = - internalContext.flatObjectMetadataMaps.byId[objectMetadataId]; + const objectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectMetadataId, + flatEntityMaps: internalContext.flatObjectMetadataMaps, + }); if (!objectMetadata) { throw new TwentyORMException( diff --git a/packages/twenty-server/src/engine/workspace-event-emitter/workspace-event-emitter.service.ts b/packages/twenty-server/src/engine/workspace-event-emitter/workspace-event-emitter.service.ts index 751a366912f..e445b5e278f 100644 --- a/packages/twenty-server/src/engine/workspace-event-emitter/workspace-event-emitter.service.ts +++ b/packages/twenty-server/src/engine/workspace-event-emitter/workspace-event-emitter.service.ts @@ -13,6 +13,7 @@ import { type SerializableAuthContext } from 'src/engine/core-modules/auth/types import { type FlatWorkspaceMemberMaps } from 'src/engine/core-modules/user/types/flat-workspace-member-maps.type'; import { transformEventToWebhookEvent } from 'src/engine/metadata-modules/webhook/utils/transform-event-to-webhook-event'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { type FlatRowLevelPermissionPredicateGroupMaps } from 'src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate-group-maps.type'; @@ -265,7 +266,10 @@ export class WorkspaceEventEmitterService { Object.entries(restrictedFields) .filter(([, permissions]) => permissions.canRead === false) .map(([fieldMetadataId]) => { - const fieldMetadata = flatFieldMetadataMaps.byId[fieldMetadataId]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); return fieldMetadata?.name; }) diff --git a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/metadata/services/dev-seeder-metadata.service.ts b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/metadata/services/dev-seeder-metadata.service.ts index 0509c5e2b70..8003cec4c04 100644 --- a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/metadata/services/dev-seeder-metadata.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/metadata/services/dev-seeder-metadata.service.ts @@ -6,6 +6,10 @@ import { isDefined } from 'twenty-shared/utils'; import { type DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/services/field-metadata.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; +import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; +import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { buildObjectIdByNameMaps } from 'src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util'; import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; import { @@ -47,10 +51,9 @@ type JunctionConfigSeed = { label?: string; }; -// Helper type for flat entity maps type FlatMaps = { - fieldMaps: { byId: Record }; - objectMaps: { byId: Record }; + flatFieldMetadataMaps: FlatEntityMaps; + flatObjectMetadataMaps: FlatEntityMaps; objectIdByName: Record; }; @@ -324,8 +327,8 @@ export class DevSeederMetadataService { ); return { - fieldMaps: flatFieldMetadataMaps as FlatMaps['fieldMaps'], - objectMaps: flatObjectMetadataMaps as FlatMaps['objectMaps'], + flatFieldMetadataMaps, + flatObjectMetadataMaps, objectIdByName: idByNameSingular, }; } @@ -476,14 +479,22 @@ export class DevSeederMetadataService { throw new Error(`Object not found: ${objectName}`); } - const objectMetadata = flatMaps.objectMaps.byId[objectId]; + const objectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectId, + flatEntityMaps: flatMaps.flatObjectMetadataMaps, + }); if (!isDefined(objectMetadata)) { throw new Error(`Object metadata not found: ${objectName}`); } for (const fieldId of objectMetadata.fieldIds) { - if (flatMaps.fieldMaps.byId[fieldId]?.name === fieldName) { + const field = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldId, + flatEntityMaps: flatMaps.flatFieldMetadataMaps, + }); + + if (field?.name === fieldName) { return fieldId; } } diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/prefill-workflows.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/prefill-workflows.ts index 4645da933f5..5d16a3e0619 100644 --- a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/prefill-workflows.ts +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/prefill-workflows.ts @@ -3,6 +3,7 @@ import { isDefined } from 'twenty-shared/utils'; import { type EntityManager } from 'typeorm'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { buildObjectIdByNameMaps } from 'src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util'; @@ -31,11 +32,15 @@ export const prefillWorkflows = async ( throw new Error('Company or person object metadata not found'); } - const companyObjectMetadata = - flatObjectMetadataMaps.byId[companyObjectMetadataId]; + const companyObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: companyObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); - const personObjectMetadata = - flatObjectMetadataMaps.byId[personObjectMetadataId]; + const personObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: personObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(companyObjectMetadata) || !isDefined(personObjectMetadata)) { throw new Error('Company or person object metadata not found'); diff --git a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/services/twenty-standard-application.service.ts b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/services/twenty-standard-application.service.ts index 5d2d679e9e8..9b7badfcbc6 100644 --- a/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/services/twenty-standard-application.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/twenty-standard-application/services/twenty-standard-application.service.ts @@ -81,7 +81,7 @@ export class TwentyStandardApplicationService { ); const existingWorkspaceItems = Object.values( - existingFlatNavigationMenuItemMaps.byId, + existingFlatNavigationMenuItemMaps.byUniversalIdentifier, ).filter( (item) => isDefined(item) && diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-build-orchestrator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-build-orchestrator.service.ts index 058136ec6f8..b17deb2ed98 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-build-orchestrator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-build-orchestrator.service.ts @@ -177,16 +177,17 @@ export class WorkspaceMigrationBuildOrchestratorService { // Note: That's a hacky way to allow validating object against field metadatas, not optimal dependencyOptimisticFlatEntityMaps: { flatFieldMetadataMaps: { - byId: { - ...dependencyAllFlatEntityMaps?.flatFieldMetadataMaps?.byId, - ...flatFieldMetadataMaps?.from.byId, - ...flatFieldMetadataMaps?.to.byId, - }, - idByUniversalIdentifier: { + byUniversalIdentifier: { ...dependencyAllFlatEntityMaps?.flatFieldMetadataMaps - ?.idByUniversalIdentifier, - ...flatFieldMetadataMaps?.from.idByUniversalIdentifier, - ...flatFieldMetadataMaps?.to.idByUniversalIdentifier, + ?.byUniversalIdentifier, + ...flatFieldMetadataMaps?.from.byUniversalIdentifier, + ...flatFieldMetadataMaps?.to.byUniversalIdentifier, + }, + universalIdentifierById: { + ...dependencyAllFlatEntityMaps?.flatFieldMetadataMaps + ?.universalIdentifierById, + ...flatFieldMetadataMaps?.from.universalIdentifierById, + ...flatFieldMetadataMaps?.to.universalIdentifierById, }, universalIdentifiersByApplicationId: { ...dependencyAllFlatEntityMaps?.flatFieldMetadataMaps diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/__snapshots__/flat-entity-deleted-created-updated-matrix-dispatcher.util.spec.ts.snap b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/__snapshots__/flat-entity-deleted-created-updated-matrix-dispatcher.util.spec.ts.snap index 39ed5ed8b5e..50cb1ab1028 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/__snapshots__/flat-entity-deleted-created-updated-matrix-dispatcher.util.spec.ts.snap +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/__snapshots__/flat-entity-deleted-created-updated-matrix-dispatcher.util.spec.ts.snap @@ -3,8 +3,8 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a created entity 1`] = ` { "createdFlatEntityMaps": { - "byId": { - "field-id-1": { + "byUniversalIdentifier": { + "universal-identifier-1": { "applicationId": "application-id-1", "applicationUniversalIdentifier": "application-universal-identifier-1", "calendarViewIds": [], @@ -48,8 +48,8 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a crea "workspaceId": "workspace-id-1", }, }, - "idByUniversalIdentifier": { - "universal-identifier-1": "field-id-1", + "universalIdentifierById": { + "field-id-1": "universal-identifier-1", }, "universalIdentifiersByApplicationId": { "application-id-1": [ @@ -58,12 +58,12 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a crea }, }, "deletedFlatEntityMaps": { - "byId": {}, - "idByUniversalIdentifier": {}, + "byUniversalIdentifier": {}, + "universalIdentifierById": {}, "universalIdentifiersByApplicationId": {}, }, "updatedFlatEntityMaps": { - "byId": {}, + "byUniversalIdentifier": {}, }, } `; @@ -71,13 +71,13 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a crea exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a deleted entity 1`] = ` { "createdFlatEntityMaps": { - "byId": {}, - "idByUniversalIdentifier": {}, + "byUniversalIdentifier": {}, + "universalIdentifierById": {}, "universalIdentifiersByApplicationId": {}, }, "deletedFlatEntityMaps": { - "byId": { - "field-id-1": { + "byUniversalIdentifier": { + "universal-identifier-1": { "applicationId": "application-id-1", "applicationUniversalIdentifier": "application-universal-identifier-1", "calendarViewIds": [], @@ -121,8 +121,8 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a dele "workspaceId": "workspace-id-1", }, }, - "idByUniversalIdentifier": { - "universal-identifier-1": "field-id-1", + "universalIdentifierById": { + "field-id-1": "universal-identifier-1", }, "universalIdentifiersByApplicationId": { "application-id-1": [ @@ -131,7 +131,7 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a dele }, }, "updatedFlatEntityMaps": { - "byId": {}, + "byUniversalIdentifier": {}, }, } `; @@ -139,19 +139,19 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a dele exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect an updated entity 1`] = ` { "createdFlatEntityMaps": { - "byId": {}, - "idByUniversalIdentifier": {}, + "byUniversalIdentifier": {}, + "universalIdentifierById": {}, "universalIdentifiersByApplicationId": {}, }, "deletedFlatEntityMaps": { - "byId": {}, - "idByUniversalIdentifier": {}, + "byUniversalIdentifier": {}, + "universalIdentifierById": {}, "universalIdentifiersByApplicationId": {}, }, "updatedFlatEntityMaps": { - "byId": { - "field-id-1": { - "universalIdentifier": "universal-identifier-1", + "byUniversalIdentifier": { + "universal-identifier-1": { + "id": "field-id-1", "updates": [ { "from": false, @@ -168,8 +168,8 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect an upd exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect created, deleted and updated entities 1`] = ` { "createdFlatEntityMaps": { - "byId": { - "field-id-3": { + "byUniversalIdentifier": { + "universal-identifier-3": { "applicationId": "application-id-1", "applicationUniversalIdentifier": "application-universal-identifier-1", "calendarViewIds": [], @@ -213,8 +213,8 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create "workspaceId": "workspace-id-1", }, }, - "idByUniversalIdentifier": { - "universal-identifier-3": "field-id-3", + "universalIdentifierById": { + "field-id-3": "universal-identifier-3", }, "universalIdentifiersByApplicationId": { "application-id-1": [ @@ -223,8 +223,8 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create }, }, "deletedFlatEntityMaps": { - "byId": { - "field-id-2": { + "byUniversalIdentifier": { + "universal-identifier-2": { "applicationId": "application-id-1", "applicationUniversalIdentifier": "application-universal-identifier-1", "calendarViewIds": [], @@ -268,8 +268,8 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create "workspaceId": "workspace-id-1", }, }, - "idByUniversalIdentifier": { - "universal-identifier-2": "field-id-2", + "universalIdentifierById": { + "field-id-2": "universal-identifier-2", }, "universalIdentifiersByApplicationId": { "application-id-1": [ @@ -278,9 +278,9 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create }, }, "updatedFlatEntityMaps": { - "byId": { - "field-id-1": { - "universalIdentifier": "universal-identifier-1", + "byUniversalIdentifier": { + "universal-identifier-1": { + "id": "field-id-1", "updates": [ { "from": true, @@ -297,17 +297,17 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should not detect deleted entities when inferDeletionFromMissingEntities is false 1`] = ` { "createdFlatEntityMaps": { - "byId": {}, - "idByUniversalIdentifier": {}, + "byUniversalIdentifier": {}, + "universalIdentifierById": {}, "universalIdentifiersByApplicationId": {}, }, "deletedFlatEntityMaps": { - "byId": {}, - "idByUniversalIdentifier": {}, + "byUniversalIdentifier": {}, + "universalIdentifierById": {}, "universalIdentifiersByApplicationId": {}, }, "updatedFlatEntityMaps": { - "byId": {}, + "byUniversalIdentifier": {}, }, } `; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/validate-flat-entity-circular-dependency.util.spec.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/validate-flat-entity-circular-dependency.util.spec.ts index b73f86edfc0..bc74341a210 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/validate-flat-entity-circular-dependency.util.spec.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/__tests__/validate-flat-entity-circular-dependency.util.spec.ts @@ -14,9 +14,11 @@ type TestFlatEntity = SyncableFlatEntity & { const createFlatEntityMaps = ( entities: TestFlatEntity[], ): FlatEntityMaps => ({ - byId: Object.fromEntries(entities.map((entity) => [entity.id, entity])), - idByUniversalIdentifier: Object.fromEntries( - entities.map((entity) => [entity.universalIdentifier, entity.id]), + byUniversalIdentifier: Object.fromEntries( + entities.map((entity) => [entity.universalIdentifier, entity]), + ), + universalIdentifierById: Object.fromEntries( + entities.map((entity) => [entity.id, entity.universalIdentifier]), ), universalIdentifiersByApplicationId: {}, }); diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts index a00fcefd0af..3657a1c5a49 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util.ts @@ -20,18 +20,24 @@ export const addFlatEntityToFlatEntityMapsThroughMutationOrThrow = < flatEntity, flatEntityMapsToMutate, }: AddFlatEntityToFlatEntityMapsThroughMutationOrThrowArgs): void => { - if (isDefined(flatEntityMapsToMutate.byId[flatEntity.id])) { + if ( + isDefined( + flatEntityMapsToMutate.byUniversalIdentifier[ + flatEntity.universalIdentifier + ], + ) + ) { throw new FlatEntityMapsException( 'addFlatEntityToFlatEntityMapsThroughMutationOrThrow: flat entity to add already exists', FlatEntityMapsExceptionCode.ENTITY_ALREADY_EXISTS, ); } - flatEntityMapsToMutate.byId[flatEntity.id] = flatEntity; + flatEntityMapsToMutate.byUniversalIdentifier[flatEntity.universalIdentifier] = + flatEntity; - flatEntityMapsToMutate.idByUniversalIdentifier[ - flatEntity.universalIdentifier - ] = flatEntity.id; + flatEntityMapsToMutate.universalIdentifierById[flatEntity.id] = + flatEntity.universalIdentifier; if (isDefined(flatEntity.applicationId)) { const existingUniversalIdentifiers = diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts index 82e59a34aa6..87fdd9c96df 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util.ts @@ -20,31 +20,33 @@ export const deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow = < flatEntityMapsToMutate, entityToDeleteId, }: DeleteFlatEntityFromFlatEntityMapsThroughMutationOrThrowArgs): void => { - const entityToDelete = flatEntityMapsToMutate.byId[entityToDeleteId]; + const universalIdentifierToDelete = + flatEntityMapsToMutate.universalIdentifierById[entityToDeleteId]; - if (!isDefined(entityToDelete)) { + if (!isDefined(universalIdentifierToDelete)) { throw new FlatEntityMapsException( 'deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow: entity to delete not found', FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND, ); } - delete flatEntityMapsToMutate.byId[entityToDeleteId]; + const entityToDelete = + flatEntityMapsToMutate.byUniversalIdentifier[universalIdentifierToDelete]; - delete flatEntityMapsToMutate.idByUniversalIdentifier[ - entityToDelete.universalIdentifier + delete flatEntityMapsToMutate.byUniversalIdentifier[ + universalIdentifierToDelete ]; - if (isDefined(entityToDelete.applicationId)) { + delete flatEntityMapsToMutate.universalIdentifierById[entityToDeleteId]; + + if (isDefined(entityToDelete?.applicationId)) { const universalIdentifiers = flatEntityMapsToMutate.universalIdentifiersByApplicationId[ entityToDelete.applicationId ]; if (isDefined(universalIdentifiers)) { - const index = universalIdentifiers.indexOf( - entityToDelete.universalIdentifier, - ); + const index = universalIdentifiers.indexOf(universalIdentifierToDelete); if (index !== -1) { universalIdentifiers.splice(index, 1); diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util.ts index 89308ea43c1..fa388b8a787 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util.ts @@ -18,12 +18,12 @@ export type DeletedCreatedUpdatedMatrix = { createdFlatEntityMaps: MetadataFlatEntityMaps; deletedFlatEntityMaps: MetadataFlatEntityMaps; updatedFlatEntityMaps: { - byId: Record< + byUniversalIdentifier: Record< string, { updates: FlatEntityPropertiesUpdates; // TMP remove when maps is universal based - universalIdentifier: string; + id: string; } >; }; @@ -51,7 +51,7 @@ export const flatEntityDeletedCreatedUpdatedMatrixDispatcher = < const initialDispatcher: DeletedCreatedUpdatedMatrix = { createdFlatEntityMaps: createEmptyFlatEntityMaps(), deletedFlatEntityMaps: createEmptyFlatEntityMaps(), - updatedFlatEntityMaps: { byId: {} }, + updatedFlatEntityMaps: { byUniversalIdentifier: {} }, }; const fromMap = new Map(from.map((obj) => [obj.universalIdentifier, obj])); @@ -105,8 +105,10 @@ export const flatEntityDeletedCreatedUpdatedMatrixDispatcher = < continue; } - initialDispatcher.updatedFlatEntityMaps.byId[toFlatEntity.id] = { - universalIdentifier: fromFlatEntity.universalIdentifier, + initialDispatcher.updatedFlatEntityMaps.byUniversalIdentifier[ + fromFlatEntity.universalIdentifier + ] = { + id: toFlatEntity.id, updates, }; } diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util.ts index 200f8152d2a..55168f7a0f0 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util.ts @@ -1,5 +1,6 @@ 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 SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; @@ -76,7 +77,10 @@ export const validateFlatEntityCircularDependency = < visited.add(currentParentId); - const parentEntity: T | undefined = flatEntityMaps.byId[currentParentId]; + const parentEntity: T | undefined = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: currentParentId, + flatEntityMaps, + }); if (!isDefined(parentEntity)) { break; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service.ts index eca1bbe49fb..d1b3298715b 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service.ts @@ -15,6 +15,7 @@ import { MetadataValidationRelatedFlatEntityMaps } from 'src/engine/metadata-mod import { addFlatEntityToFlatEntityAndRelatedEntityMapsThroughMutationOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-and-related-entity-maps-through-mutation-or-throw.util'; import { deleteFlatEntityFromFlatEntityAndRelatedEntityMapsThroughMutationOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-and-related-entity-maps-through-mutation-or-throw.util'; import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; +import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util'; import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util'; import { WorkspaceMigrationBuilderAdditionalCacheDataMaps } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-builder-additional-cache-data-maps.type'; import { deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util'; @@ -66,12 +67,12 @@ export abstract class WorkspaceEntityMigrationBuilderService< 'matrix computation', ); - const fromFlatEntities = Object.values(fromFlatEntityMaps.byId).filter( - isDefined, - ); - const toFlatEntities = Object.values(toFlatEntityMaps.byId).filter( - isDefined, - ); + const fromFlatEntities = Object.values( + fromFlatEntityMaps.byUniversalIdentifier, + ).filter(isDefined); + const toFlatEntities = Object.values( + toFlatEntityMaps.byUniversalIdentifier, + ).filter(isDefined); const { createdFlatEntityMaps, @@ -109,16 +110,13 @@ export abstract class WorkspaceEntityMigrationBuilderService< `EntityBuilder ${this.metadataName}`, 'creation validation', ); - for (const flatEntityToCreateId in createdFlatEntityMaps.byId) { - const flatEntityToCreate = - createdFlatEntityMaps.byId[flatEntityToCreateId]; + for (const flatEntityToCreateUniversalIdentifier in createdFlatEntityMaps.byUniversalIdentifier) { + const flatEntityToCreate = findFlatEntityByUniversalIdentifierOrThrow({ + universalIdentifier: flatEntityToCreateUniversalIdentifier, + flatEntityMaps: createdFlatEntityMaps, + }); - if (!isDefined(flatEntityToCreate)) { - throw new FlatEntityMapsException( - 'Could not find flat entity to create in maps should never occur', - FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND, - ); - } + const flatEntityToCreateId = flatEntityToCreate.id; deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow({ entityToDeleteId: flatEntityToCreateId, @@ -170,12 +168,14 @@ export abstract class WorkspaceEntityMigrationBuilderService< buildOptions, metadataName: this.metadataName, }) - ? Object.keys(deletedFlatEntityMaps.byId) + ? Object.keys(deletedFlatEntityMaps.universalIdentifierById) : []; for (const flatEntityToDeleteId of flatEntityToDeleteIds) { - const flatEntityToDelete = - deletedFlatEntityMaps.byId[flatEntityToDeleteId]; + const flatEntityToDelete = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatEntityToDeleteId, + flatEntityMaps: deletedFlatEntityMaps, + }); if (!isDefined(flatEntityToDelete)) { throw new FlatEntityMapsException( @@ -223,9 +223,11 @@ export abstract class WorkspaceEntityMigrationBuilderService< ); this.logger.time(`EntityBuilder ${this.metadataName}`, 'update validation'); - for (const flatEntityToUpdateId in updatedFlatEntityMaps.byId) { + for (const flatEntityToUpdateUniversalIdentifier in updatedFlatEntityMaps.byUniversalIdentifier) { const flatEntityToUpdate = - updatedFlatEntityMaps.byId[flatEntityToUpdateId]; + updatedFlatEntityMaps.byUniversalIdentifier[ + flatEntityToUpdateUniversalIdentifier + ]; if (!isDefined(flatEntityToUpdate)) { throw new FlatEntityMapsException( @@ -236,12 +238,12 @@ export abstract class WorkspaceEntityMigrationBuilderService< const validationResult = await this.validateFlatEntityUpdate({ flatEntityUpdates: flatEntityToUpdate.updates, - flatEntityId: flatEntityToUpdateId, + flatEntityId: flatEntityToUpdate.id, optimisticFlatEntityMapsAndRelatedFlatEntityMaps, workspaceId, buildOptions, additionalCacheDataMaps, - universalIdentifier: flatEntityToUpdate.universalIdentifier, + universalIdentifier: flatEntityToUpdateUniversalIdentifier, }); if (validationResult.status === 'fail') { @@ -250,7 +252,7 @@ export abstract class WorkspaceEntityMigrationBuilderService< } const existingFlatEntity = findFlatEntityByIdInFlatEntityMaps({ - flatEntityId: flatEntityToUpdateId, + flatEntityId: flatEntityToUpdate.id, flatEntityMaps: optimisticFlatEntityMapsAndRelatedFlatEntityMaps[ flatEntityMapsKey ] as MetadataFlatEntityMaps, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-agent-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-agent-validator.service.ts index 373b62f8398..736bd8f7d2f 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-agent-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-agent-validator.service.ts @@ -37,9 +37,9 @@ export class FlatAgentValidatorService { type: 'create', }); - const existingAgents = Object.values(optimisticFlatAgentMaps.byId).filter( - isDefined, - ); + const existingAgents = Object.values( + optimisticFlatAgentMaps.byUniversalIdentifier, + ).filter(isDefined); validationResult.errors.push( ...validateAgentRequiredProperties({ @@ -180,7 +180,9 @@ export class FlatAgentValidatorService { ...partialFlatAgent, }; - const existingAgents = Object.values(optimisticFlatAgentMaps.byId) + const existingAgents = Object.values( + optimisticFlatAgentMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter((agent) => agent.id !== flatEntityId); diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-field-metadata-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-field-metadata-validator.service.ts index cab2f2bee73..c90ee819d32 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-field-metadata-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-field-metadata-validator.service.ts @@ -6,6 +6,7 @@ import { isDefined } from 'twenty-shared/utils'; import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception'; import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; 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'; @@ -41,7 +42,10 @@ export class FlatFieldMetadataValidatorService { typeof ALL_METADATA_NAME.fieldMetadata >): FailedFlatEntityValidation<'fieldMetadata', 'update'> { const existingFlatFieldMetadataToUpdate = - optimisticFlatFieldMetadataMaps.byId[flatEntityId]; + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatFieldMetadataMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { @@ -75,8 +79,10 @@ export class FlatFieldMetadataValidatorService { objectMetadataId: flatFieldMetadataToValidate.objectMetadataId, }; - const flatObjectMetadata = - flatObjectMetadataMaps.byId[flatFieldMetadataToValidate.objectMetadataId]; + const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatFieldMetadataToValidate.objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(flatObjectMetadata)) { validationResult.errors.push({ @@ -217,8 +223,10 @@ export class FlatFieldMetadataValidatorService { type: 'delete', }); - const flatFieldMetadataToDelete = - optimisticFlatFieldMetadataMaps.byId[flatFieldMetadataToDeleteId]; + const flatFieldMetadataToDelete = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatFieldMetadataToDeleteId, + flatEntityMaps: optimisticFlatFieldMetadataMaps, + }); if (!isDefined(flatFieldMetadataToDelete)) { validationResult.errors.push({ @@ -236,8 +244,10 @@ export class FlatFieldMetadataValidatorService { objectMetadataId: flatFieldMetadataToDelete.objectMetadataId, }; - const relatedFlatObjectMetadata = - flatObjectMetadataMaps.byId[flatFieldMetadataToDelete.objectMetadataId]; + const relatedFlatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatFieldMetadataToDelete.objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if ( isDefined(relatedFlatObjectMetadata) && @@ -255,12 +265,17 @@ export class FlatFieldMetadataValidatorService { const relationTargetObjectMetadataHasBeenDeleted = isMorphOrRelationFlatFieldMetadata(flatFieldMetadataToDelete) && !isDefined( - flatObjectMetadataMaps.byId[ - flatFieldMetadataToDelete.relationTargetObjectMetadataId - ], + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: + flatFieldMetadataToDelete.relationTargetObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }), ); const parentObjectMetadataHasBeenDeleted = !isDefined( - flatObjectMetadataMaps.byId[flatFieldMetadataToDelete.objectMetadataId], + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatFieldMetadataToDelete.objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }), ); if ( @@ -302,8 +317,10 @@ export class FlatFieldMetadataValidatorService { type: 'create', }); - const parentFlatObjectMetadata = - flatObjectMetadataMaps.byId[flatFieldMetadataToValidate.objectMetadataId]; + const parentFlatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatFieldMetadataToValidate.objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(parentFlatObjectMetadata)) { validationResult.errors.push({ @@ -314,7 +331,10 @@ export class FlatFieldMetadataValidatorService { } else { if ( isDefined( - optimisticFlatFieldMetadataMaps.byId[flatFieldMetadataToValidate.id], + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatFieldMetadataToValidate.id, + flatEntityMaps: optimisticFlatFieldMetadataMaps, + }), ) ) { validationResult.errors.push({ diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-index-metadata-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-index-metadata-validator.service.ts index fc79cae31df..3fe6ba53e4f 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-index-metadata-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-index-metadata-validator.service.ts @@ -97,7 +97,7 @@ export class FlatIndexValidatorService { } const allExistingFlatIndex = Object.values( - optimisticFlatIndexMaps.byId, + optimisticFlatIndexMaps.byUniversalIdentifier, ).filter(isDefined); const existingFlatIndexOnName = allExistingFlatIndex.find( diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-logic-function-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-logic-function-validator.service.ts index 35d29de00bd..0c7526efd25 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-logic-function-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-logic-function-validator.service.ts @@ -5,6 +5,7 @@ import { ALL_METADATA_NAME } from 'twenty-shared/metadata'; import { isDefined } from 'twenty-shared/utils'; import { LogicFunctionExceptionCode } from 'src/engine/metadata-modules/logic-function/logic-function.exception'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type'; import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util'; import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type'; @@ -22,8 +23,10 @@ export class FlatLogicFunctionValidatorService { }: FlatEntityUpdateValidationArgs< typeof ALL_METADATA_NAME.logicFunction >): FailedFlatEntityValidation<'logicFunction', 'update'> { - const existingFlatLogicFunction = - optimisticFlatLogicFunctionMaps.byId[flatEntityId]; + const existingFlatLogicFunction = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatLogicFunctionMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { @@ -62,8 +65,10 @@ export class FlatLogicFunctionValidatorService { type: 'delete', }); - const existingFlatLogicFunction = - optimisticFlatLogicFunctionMaps.byId[logicFunctionIdToDelete]; + const existingFlatLogicFunction = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: logicFunctionIdToDelete, + flatEntityMaps: optimisticFlatLogicFunctionMaps, + }); if (!isDefined(existingFlatLogicFunction)) { validationResult.errors.push({ @@ -95,7 +100,10 @@ export class FlatLogicFunctionValidatorService { if ( isDefined( - optimisticFlatLogicFunctionMaps.byId[flatLogicFunctionToValidate.id], + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatLogicFunctionToValidate.id, + flatEntityMaps: optimisticFlatLogicFunctionMaps, + }), ) ) { validationResult.errors.push({ diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-object-metadata-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-object-metadata-validator.service.ts index 79dd5937c60..09da9af7bba 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-object-metadata-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-object-metadata-validator.service.ts @@ -4,6 +4,7 @@ import { msg, t } from '@lingui/core/macro'; 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 { validateFlatObjectMetadataIdentifiers } from 'src/engine/metadata-modules/flat-object-metadata/validators/utils/validate-flat-object-metadata-identifiers.util'; import { validateFlatObjectMetadataNameAndLabels } from 'src/engine/metadata-modules/flat-object-metadata/validators/utils/validate-flat-object-metadata-name-and-labels.util'; import { ObjectMetadataExceptionCode } from 'src/engine/metadata-modules/object-metadata/object-metadata.exception'; @@ -27,8 +28,10 @@ export class FlatObjectMetadataValidatorService { }: FlatEntityUpdateValidationArgs< typeof ALL_METADATA_NAME.objectMetadata >): FailedFlatEntityValidation<'objectMetadata', 'update'> { - const existingFlatObjectMetadata = - optimisticFlatObjectMetadataMaps.byId[flatEntityId]; + const existingFlatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatObjectMetadataMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { @@ -114,8 +117,10 @@ export class FlatObjectMetadataValidatorService { type: 'delete', }); - const flatObjectMetadataToDelete = - optimisticFlatObjectMetadataMaps.byId[objectMetadataToDeleteId]; + const flatObjectMetadataToDelete = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectMetadataToDeleteId, + flatEntityMaps: optimisticFlatObjectMetadataMaps, + }); if (!isDefined(flatObjectMetadataToDelete)) { validationResult.errors.push({ @@ -176,7 +181,10 @@ export class FlatObjectMetadataValidatorService { if ( isDefined( - optimisticFlatObjectMetadataMaps.byId[flatObjectMetadataToValidate.id], + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatObjectMetadataToValidate.id, + flatEntityMaps: optimisticFlatObjectMetadataMaps, + }), ) ) { objectValidationResult.errors.push({ diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-widget-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-widget-validator.service.ts index 98cb55087db..3b3c919eb9c 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-widget-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-widget-validator.service.ts @@ -156,8 +156,10 @@ export class FlatPageLayoutWidgetValidatorService { type: 'delete', }); - const existingFlatPageLayoutWidget = - optimisticFlatPageLayoutWidgetMaps.byId[pageLayoutWidgetIdToDelete]; + const existingFlatPageLayoutWidget = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: pageLayoutWidgetIdToDelete, + flatEntityMaps: optimisticFlatPageLayoutWidgetMaps, + }); if (!isDefined(existingFlatPageLayoutWidget)) { validationResult.errors.push({ @@ -195,9 +197,11 @@ export class FlatPageLayoutWidgetValidatorService { type: 'create', }); - const existingFlatPageLayoutWidget = - optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatPageLayoutWidgetMaps - .byId[flatPageLayoutWidgetToValidate.id]; + const existingFlatPageLayoutWidget = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatPageLayoutWidgetToValidate.id, + flatEntityMaps: + optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatPageLayoutWidgetMaps, + }); if (isDefined(existingFlatPageLayoutWidget)) { const flatPageLayoutWidgetId = flatPageLayoutWidgetToValidate.id; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-target-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-target-validator.service.ts index 016678605bb..e461c00cad3 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-target-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-target-validator.service.ts @@ -121,7 +121,10 @@ export class FlatRoleTargetValidatorService { }: FlatEntityUpdateValidationArgs< typeof ALL_METADATA_NAME.roleTarget >): FailedFlatEntityValidation<'roleTarget', 'update'> { - const existingRoleTarget = optimisticFlatRoleTargetMaps.byId[flatEntityId]; + const existingRoleTarget = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatRoleTargetMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-validator.service.ts index af0722b8198..0d915118af4 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-validator.service.ts @@ -4,6 +4,7 @@ import { msg, t } from '@lingui/core/macro'; 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 { PermissionsExceptionCode } from 'src/engine/metadata-modules/permissions/permissions.exception'; import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/find-flat-entity-property-update.util'; import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type'; @@ -36,9 +37,9 @@ export class FlatRoleValidatorService { type: 'create', }); - const existingRoles = Object.values(optimisticFlatRoleMaps.byId).filter( - isDefined, - ); + const existingRoles = Object.values( + optimisticFlatRoleMaps.byUniversalIdentifier, + ).filter(isDefined); validationResult.errors.push( ...validateRoleRequiredPropertiesAreDefined({ @@ -81,7 +82,10 @@ export class FlatRoleValidatorService { type: 'delete', }); - const existingRole = optimisticFlatRoleMaps.byId[flatEntityToValidate.id]; + const existingRole = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatEntityToValidate.id, + flatEntityMaps: optimisticFlatRoleMaps, + }); if (!isDefined(existingRole)) { validationResult.errors.push({ @@ -113,7 +117,10 @@ export class FlatRoleValidatorService { }: FlatEntityUpdateValidationArgs< typeof ALL_METADATA_NAME.role >): FailedFlatEntityValidation<'role', 'update'> { - const fromFlatRole = optimisticFlatRoleMaps.byId[flatEntityId]; + const fromFlatRole = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatRoleMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { @@ -160,9 +167,9 @@ export class FlatRoleValidatorService { }); if (isDefined(flatRoleLabelUpdate)) { - const existingRoles = Object.values(optimisticFlatRoleMaps.byId).filter( - isDefined, - ); + const existingRoles = Object.values( + optimisticFlatRoleMaps.byUniversalIdentifier, + ).filter(isDefined); validationResult.errors.push( ...validateRoleLabelUniqueness({ diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-group-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-group-validator.service.ts index e13741781e2..ed34ab4cedd 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-group-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-group-validator.service.ts @@ -27,11 +27,7 @@ export class FlatRowLevelPermissionPredicateGroupValidatorService { optimisticFlatPredicateGroupMaps, flatRoleMaps, flatObjectMetadataMaps, - } = optimisticFlatEntityMapsAndRelatedFlatEntityMaps as Partial<{ - flatRowLevelPermissionPredicateGroupMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRowLevelPermissionPredicateGroupMaps; - flatRoleMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRoleMaps; - flatObjectMetadataMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatObjectMetadataMaps; - }>; + } = optimisticFlatEntityMapsAndRelatedFlatEntityMaps; const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { id: flatPredicateGroupToValidate.id, @@ -41,8 +37,10 @@ export class FlatRowLevelPermissionPredicateGroupValidatorService { type: 'create', }); - const existingPredicateGroup = - optimisticFlatPredicateGroupMaps?.byId[flatPredicateGroupToValidate.id]; + const existingPredicateGroup = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatPredicateGroupToValidate.id, + flatEntityMaps: optimisticFlatPredicateGroupMaps, + }); if (isDefined(existingPredicateGroup)) { validationResult.errors.push({ @@ -55,8 +53,7 @@ export class FlatRowLevelPermissionPredicateGroupValidatorService { if ( isDefined( flatPredicateGroupToValidate.parentRowLevelPermissionPredicateGroupId, - ) && - optimisticFlatPredicateGroupMaps + ) ) { const parentGroup = findFlatEntityByIdInFlatEntityMaps({ flatEntityId: @@ -115,9 +112,8 @@ export class FlatRowLevelPermissionPredicateGroupValidatorService { const { flatRowLevelPermissionPredicateGroupMaps: optimisticFlatPredicateGroupMaps, - } = optimisticFlatEntityMapsAndRelatedFlatEntityMaps as Partial<{ - flatRowLevelPermissionPredicateGroupMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRowLevelPermissionPredicateGroupMaps; - }>; + } = optimisticFlatEntityMapsAndRelatedFlatEntityMaps; + const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { id: flatPredicateGroupToDelete.id, @@ -127,8 +123,10 @@ export class FlatRowLevelPermissionPredicateGroupValidatorService { type: 'delete', }); - const existingPredicateGroup = - optimisticFlatPredicateGroupMaps?.byId[flatPredicateGroupToDelete.id]; + const existingPredicateGroup = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatPredicateGroupToDelete.id, + flatEntityMaps: optimisticFlatPredicateGroupMaps, + }); if (!isDefined(existingPredicateGroup)) { validationResult.errors.push({ @@ -153,14 +151,12 @@ export class FlatRowLevelPermissionPredicateGroupValidatorService { optimisticFlatPredicateGroupMaps, flatRoleMaps, flatObjectMetadataMaps, - } = optimisticFlatEntityMapsAndRelatedFlatEntityMaps as Partial<{ - flatRowLevelPermissionPredicateGroupMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRowLevelPermissionPredicateGroupMaps; - flatRoleMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRoleMaps; - flatObjectMetadataMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatObjectMetadataMaps; - }>; + } = optimisticFlatEntityMapsAndRelatedFlatEntityMaps; - const existingPredicateGroup = - optimisticFlatPredicateGroupMaps?.byId[flatEntityId]; + const existingPredicateGroup = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatPredicateGroupMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { @@ -214,10 +210,7 @@ export class FlatRowLevelPermissionPredicateGroupValidatorService { } if ( - isDefined( - updatedPredicateGroup.parentRowLevelPermissionPredicateGroupId, - ) && - optimisticFlatPredicateGroupMaps + isDefined(updatedPredicateGroup.parentRowLevelPermissionPredicateGroupId) ) { const parentGroup = findFlatEntityByIdInFlatEntityMaps({ flatEntityId: diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-validator.service.ts index 31cc661cabf..a9d055224e6 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-validator.service.ts @@ -28,13 +28,7 @@ export class FlatRowLevelPermissionPredicateValidatorService { flatObjectMetadataMaps, flatRowLevelPermissionPredicateGroupMaps, flatRoleMaps, - } = optimisticFlatEntityMapsAndRelatedFlatEntityMaps as Partial<{ - flatRowLevelPermissionPredicateMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRowLevelPermissionPredicateMaps; - flatFieldMetadataMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatFieldMetadataMaps; - flatObjectMetadataMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatObjectMetadataMaps; - flatRowLevelPermissionPredicateGroupMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRowLevelPermissionPredicateGroupMaps; - flatRoleMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRoleMaps; - }>; + } = optimisticFlatEntityMapsAndRelatedFlatEntityMaps; const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { @@ -45,8 +39,10 @@ export class FlatRowLevelPermissionPredicateValidatorService { type: 'create', }); - const existingPredicate = - optimisticFlatPredicateMaps?.byId[flatPredicateToValidate.id]; + const existingPredicate = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatPredicateToValidate.id, + flatEntityMaps: optimisticFlatPredicateMaps, + }); if (isDefined(existingPredicate)) { validationResult.errors.push({ @@ -130,9 +126,7 @@ export class FlatRowLevelPermissionPredicateValidatorService { typeof ALL_METADATA_NAME.rowLevelPermissionPredicate >): FailedFlatEntityValidation<'rowLevelPermissionPredicate', 'delete'> { const { flatRowLevelPermissionPredicateMaps: optimisticFlatPredicateMaps } = - optimisticFlatEntityMapsAndRelatedFlatEntityMaps as Partial<{ - flatRowLevelPermissionPredicateMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRowLevelPermissionPredicateMaps; - }>; + optimisticFlatEntityMapsAndRelatedFlatEntityMaps; const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { id: flatPredicateToDelete.id, @@ -142,8 +136,10 @@ export class FlatRowLevelPermissionPredicateValidatorService { type: 'delete', }); - const existingPredicate = - optimisticFlatPredicateMaps?.byId[flatPredicateToDelete.id]; + const existingPredicate = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatPredicateToDelete.id, + flatEntityMaps: optimisticFlatPredicateMaps, + }); if (!isDefined(existingPredicate)) { validationResult.errors.push({ @@ -169,15 +165,12 @@ export class FlatRowLevelPermissionPredicateValidatorService { flatObjectMetadataMaps, flatRowLevelPermissionPredicateGroupMaps, flatRoleMaps, - } = optimisticFlatEntityMapsAndRelatedFlatEntityMaps as Partial<{ - flatRowLevelPermissionPredicateMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRowLevelPermissionPredicateMaps; - flatFieldMetadataMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatFieldMetadataMaps; - flatObjectMetadataMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatObjectMetadataMaps; - flatRowLevelPermissionPredicateGroupMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRowLevelPermissionPredicateGroupMaps; - flatRoleMaps: typeof optimisticFlatEntityMapsAndRelatedFlatEntityMaps.flatRoleMaps; - }>; + } = optimisticFlatEntityMapsAndRelatedFlatEntityMaps; - const existingPredicate = optimisticFlatPredicateMaps?.byId[flatEntityId]; + const existingPredicate = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatPredicateMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-skill-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-skill-validator.service.ts index 52f6903ae68..86e7610727c 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-skill-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-skill-validator.service.ts @@ -41,9 +41,9 @@ export class FlatSkillValidatorService { type: 'create', }); - const existingSkills = Object.values(optimisticFlatSkillMaps.byId).filter( - isDefined, - ); + const existingSkills = Object.values( + optimisticFlatSkillMaps.byUniversalIdentifier, + ).filter(isDefined); validationResult.errors.push( ...validateSkillRequiredProperties({ flatSkill }), @@ -222,7 +222,9 @@ export class FlatSkillValidatorService { }); if (isDefined(nameUpdate)) { - const existingSkills = Object.values(optimisticFlatSkillMaps.byId) + const existingSkills = Object.values( + optimisticFlatSkillMaps.byUniversalIdentifier, + ) .filter(isDefined) .filter((skill) => skill.id !== flatEntityId); diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-field-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-field-validator.service.ts index df7c4bf6873..a0f96fa0e21 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-field-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-field-validator.service.ts @@ -30,8 +30,10 @@ export class FlatViewFieldValidatorService { }: FlatEntityUpdateValidationArgs< typeof ALL_METADATA_NAME.viewField >): FailedFlatEntityValidation<'viewField', 'update'> { - const existingFlatViewField = - optimisticFlatViewFieldMaps.byId[flatEntityId]; + const existingFlatViewField = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatViewFieldMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { @@ -139,8 +141,10 @@ export class FlatViewFieldValidatorService { type: 'delete', }); - const existingFlatViewField = - optimisticFlatViewFieldMaps.byId[viewFieldIdToDelete]; + const existingFlatViewField = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewFieldIdToDelete, + flatEntityMaps: optimisticFlatViewFieldMaps, + }); if (!isDefined(existingFlatViewField)) { validationResult.errors.push({ @@ -206,8 +210,10 @@ export class FlatViewFieldValidatorService { type: 'create', }); - const existingFlatViewField = - optimisticFlatViewFieldMaps.byId[flatViewFieldToValidate.id]; + const existingFlatViewField = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatViewFieldToValidate.id, + flatEntityMaps: optimisticFlatViewFieldMaps, + }); if (isDefined(existingFlatViewField)) { const flatViewFieldId = flatViewFieldToValidate.id; @@ -232,7 +238,10 @@ export class FlatViewFieldValidatorService { }); } - const flatView = flatViewMaps.byId[flatViewFieldToValidate.viewId]; + const flatView = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatViewFieldToValidate.viewId, + flatEntityMaps: flatViewMaps, + }); if (!isDefined(flatView)) { validationResult.errors.push({ diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-group-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-group-validator.service.ts index 7f972bed9d8..cd4022d16ec 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-group-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-group-validator.service.ts @@ -198,8 +198,10 @@ export class FlatViewFilterGroupValidatorService { }: FlatEntityUpdateValidationArgs< typeof ALL_METADATA_NAME.viewFilterGroup >): FailedFlatEntityValidation<'viewFilterGroup', 'update'> { - const existingViewFilterGroup = - optimisticFlatViewFilterGroupMaps.byId[flatEntityId]; + const existingViewFilterGroup = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatViewFilterGroupMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-validator.service.ts index 1befad89e7d..ff8137ffc46 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-validator.service.ts @@ -139,7 +139,10 @@ export class FlatViewFilterValidatorService { }: FlatEntityUpdateValidationArgs< typeof ALL_METADATA_NAME.viewFilter >): FailedFlatEntityValidation<'viewFilter', 'update'> { - const existingViewFilter = optimisticFlatViewFilterMaps.byId[flatEntityId]; + const existingViewFilter = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatViewFilterMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-group-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-group-validator.service.ts index 6250e47fade..81de0b57742 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-group-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-group-validator.service.ts @@ -24,8 +24,10 @@ export class FlatViewGroupValidatorService { }: FlatEntityUpdateValidationArgs< typeof ALL_METADATA_NAME.viewGroup >): FailedFlatEntityValidation<'viewGroup', 'update'> { - const existingFlatViewGroup = - optimisticFlatViewGroupMaps.byId[flatEntityId]; + const existingFlatViewGroup = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatViewGroupMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { @@ -100,8 +102,10 @@ export class FlatViewGroupValidatorService { type: 'delete', }); - const existingFlatViewGroup = - optimisticFlatViewGroupMaps.byId[viewGroupIdToDelete]; + const existingFlatViewGroup = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: viewGroupIdToDelete, + flatEntityMaps: optimisticFlatViewGroupMaps, + }); if (!isDefined(existingFlatViewGroup)) { validationResult.errors.push({ @@ -133,8 +137,10 @@ export class FlatViewGroupValidatorService { type: 'create', }); - const existingFlatViewGroup = - optimisticFlatViewGroupMaps.byId[flatViewGroupToValidate.id]; + const existingFlatViewGroup = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatViewGroupToValidate.id, + flatEntityMaps: optimisticFlatViewGroupMaps, + }); if (isDefined(existingFlatViewGroup)) { const flatViewGroupId = flatViewGroupToValidate.id; @@ -146,7 +152,10 @@ export class FlatViewGroupValidatorService { }); } - const flatView = flatViewMaps.byId[flatViewGroupToValidate.viewId]; + const flatView = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatViewGroupToValidate.viewId, + flatEntityMaps: flatViewMaps, + }); if (!isDefined(flatView)) { validationResult.errors.push({ diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-validator.service.ts index bee7f9c08d3..950a17d1407 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-validator.service.ts @@ -27,7 +27,10 @@ export class FlatViewValidatorService { }: FlatEntityUpdateValidationArgs< typeof ALL_METADATA_NAME.view >): FailedFlatEntityValidation<'view', 'update'> { - const existingFlatView = optimisticFlatViewMaps.byId[flatEntityId]; + const existingFlatView = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId, + flatEntityMaps: optimisticFlatViewMaps, + }); const validationResult = getEmptyFlatEntityValidationError({ flatEntityMinimalInformation: { @@ -164,8 +167,10 @@ export class FlatViewValidatorService { type: 'delete', }); - const existingFlatView = - optimisticFlatViewMaps.byId[flatEntityToValidate.id]; + const existingFlatView = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatEntityToValidate.id, + flatEntityMaps: optimisticFlatViewMaps, + }); if (!isDefined(existingFlatView)) { validationResult.errors.push({ @@ -197,8 +202,10 @@ export class FlatViewValidatorService { type: 'create', }); - const optimisticFlatObjectMetadata = - flatObjectMetadataMaps.byId[flatViewToValidate.objectMetadataId]; + const optimisticFlatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatViewToValidate.objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(optimisticFlatObjectMetadata)) { validationResult.errors.push({ @@ -208,7 +215,14 @@ export class FlatViewValidatorService { }); } - if (isDefined(optimisticFlatViewMaps.byId[flatViewToValidate.id])) { + if ( + isDefined( + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: flatViewToValidate.id, + flatEntityMaps: optimisticFlatViewMaps, + }), + ) + ) { validationResult.errors.push({ code: ViewExceptionCode.INVALID_VIEW_DATA, message: t`View with same id is already exists`, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/find-field-metadata-id-in-create-field-context.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/find-field-metadata-id-in-create-field-context.util.ts index fb2eeaa9a83..274d55643e3 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/find-field-metadata-id-in-create-field-context.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/find-field-metadata-id-in-create-field-context.util.ts @@ -20,8 +20,8 @@ export const findFieldMetadataIdInCreateFieldContext = ({ return generatedId; } - const existingFieldId = - flatFieldMetadataMaps.idByUniversalIdentifier[universalIdentifier]; + const existingField = + flatFieldMetadataMaps.byUniversalIdentifier[universalIdentifier]; - return existingFieldId ?? null; + return existingField?.id ?? null; }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/from-universal-flat-field-metadata-to-flat-field-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/from-universal-flat-field-metadata-to-flat-field-metadata.util.ts index cdd9e81b460..3dd8e55278e 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/from-universal-flat-field-metadata-to-flat-field-metadata.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/utils/from-universal-flat-field-metadata-to-flat-field-metadata.util.ts @@ -19,13 +19,6 @@ export type FromUniversalFlatFieldMetadataToFlatFieldMetadataArgs = { objectMetadataId?: string; }; -const getIdFromUniversalIdentifier = ( - universalIdentifier: string, - flatEntityMaps: { idByUniversalIdentifier: Partial> }, -): string | null => { - return flatEntityMaps.idByUniversalIdentifier[universalIdentifier] ?? null; -}; - export const fromUniversalFlatFieldMetadataToFlatFieldMetadata = ({ universalFlatFieldMetadata, allFieldIdToBeCreatedInActionByUniversalIdentifierMap, @@ -66,10 +59,10 @@ export const fromUniversalFlatFieldMetadataToFlatFieldMetadata = ({ const objectMetadataId = optionalObjectMetadataId ?? - getIdFromUniversalIdentifier( - objectMetadataUniversalIdentifier, - allFlatEntityMaps.flatObjectMetadataMaps, - ); + allFlatEntityMaps.flatObjectMetadataMaps.byUniversalIdentifier[ + objectMetadataUniversalIdentifier + ]?.id ?? + null; if (!isDefined(objectMetadataId)) { throw new Error( @@ -96,10 +89,10 @@ export const fromUniversalFlatFieldMetadataToFlatFieldMetadata = ({ let relationTargetObjectMetadataId: string | null = null; if (isDefined(relationTargetObjectMetadataUniversalIdentifier)) { - relationTargetObjectMetadataId = getIdFromUniversalIdentifier( - relationTargetObjectMetadataUniversalIdentifier, - allFlatEntityMaps.flatObjectMetadataMaps, - ); + relationTargetObjectMetadataId = + allFlatEntityMaps.flatObjectMetadataMaps.byUniversalIdentifier[ + relationTargetObjectMetadataUniversalIdentifier + ]?.id ?? null; if (!isDefined(relationTargetObjectMetadataId)) { throw new Error( diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/object/services/utils/from-universal-flat-object-metadata-to-flat-object-metadata.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/object/services/utils/from-universal-flat-object-metadata-to-flat-object-metadata.util.ts index 7bdc1289c5c..8b3145ef900 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/object/services/utils/from-universal-flat-object-metadata-to-flat-object-metadata.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/object/services/utils/from-universal-flat-object-metadata-to-flat-object-metadata.util.ts @@ -36,10 +36,10 @@ const findFieldMetadataIdInCreateObjectContext = ({ return generatedId; } - const existingFieldId = - flatFieldMetadataMaps.idByUniversalIdentifier[universalIdentifier]; + const existingField = + flatFieldMetadataMaps.byUniversalIdentifier[universalIdentifier]; - return existingFieldId ?? null; + return existingField?.id ?? null; }; export const fromUniversalFlatObjectMetadataToFlatObjectMetadata = ({ diff --git a/packages/twenty-server/src/modules/dashboard-sync/services/dashboard-sync.service.ts b/packages/twenty-server/src/modules/dashboard-sync/services/dashboard-sync.service.ts index 17dea0213a7..7566401f8b9 100644 --- a/packages/twenty-server/src/modules/dashboard-sync/services/dashboard-sync.service.ts +++ b/packages/twenty-server/src/modules/dashboard-sync/services/dashboard-sync.service.ts @@ -2,6 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; 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 { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { PageLayoutType } from 'src/engine/metadata-modules/page-layout/enums/page-layout-type.enum'; import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @@ -31,7 +32,10 @@ export class DashboardSyncService { }, ); - const pageLayout = flatPageLayoutMaps.byId[pageLayoutId]; + const pageLayout = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: pageLayoutId, + flatEntityMaps: flatPageLayoutMaps, + }); return ( isDefined(pageLayout) && pageLayout.type === PageLayoutType.DASHBOARD @@ -96,13 +100,19 @@ export class DashboardSyncService { }, ); - const tab = flatPageLayoutTabMaps.byId[tabId]; + const tab = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: tabId, + flatEntityMaps: flatPageLayoutTabMaps, + }); if (!isDefined(tab)) { return; } - const pageLayout = flatPageLayoutMaps.byId[tab.pageLayoutId]; + const pageLayout = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: tab.pageLayoutId, + flatEntityMaps: flatPageLayoutMaps, + }); if ( !isDefined(pageLayout) || @@ -143,19 +153,28 @@ export class DashboardSyncService { }, ); - const widget = flatPageLayoutWidgetMaps.byId[widgetId]; + const widget = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: widgetId, + flatEntityMaps: flatPageLayoutWidgetMaps, + }); if (!isDefined(widget)) { return; } - const tab = flatPageLayoutTabMaps.byId[widget.pageLayoutTabId]; + const tab = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: widget.pageLayoutTabId, + flatEntityMaps: flatPageLayoutTabMaps, + }); if (!isDefined(tab)) { return; } - const pageLayout = flatPageLayoutMaps.byId[tab.pageLayoutId]; + const pageLayout = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: tab.pageLayoutId, + flatEntityMaps: flatPageLayoutMaps, + }); if ( !isDefined(pageLayout) || diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/bar-chart-data.service.spec.ts b/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/bar-chart-data.service.spec.ts index da9680f0520..caeccfe3924 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/bar-chart-data.service.spec.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/bar-chart-data.service.spec.ts @@ -58,14 +58,38 @@ describe('BarChartDataService', () => { mockExecuteGroupByQuery = jest.fn(); mockGetOrRecomputeManyOrAllFlatEntityMaps = jest.fn().mockResolvedValue({ flatObjectMetadataMaps: { - byId: { [objectMetadataId]: mockObjectMetadata }, + byUniversalIdentifier: { + 'test-object-universal-id': { + ...mockObjectMetadata, + universalIdentifier: 'test-object-universal-id', + }, + }, + universalIdentifierById: { + [objectMetadataId]: 'test-object-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: { - [mockGroupByField.id]: mockGroupByField, - [mockAggregateField.id]: mockAggregateField, - [mockSelectField.id]: mockSelectField, + byUniversalIdentifier: { + 'group-by-field-universal-id': { + ...mockGroupByField, + universalIdentifier: 'group-by-field-universal-id', + }, + 'aggregate-field-universal-id': { + ...mockAggregateField, + universalIdentifier: 'aggregate-field-universal-id', + }, + 'select-field-universal-id': { + ...mockSelectField, + universalIdentifier: 'select-field-universal-id', + }, }, + universalIdentifierById: { + [mockGroupByField.id]: 'group-by-field-universal-id', + [mockAggregateField.id]: 'aggregate-field-universal-id', + [mockSelectField.id]: 'select-field-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, }); @@ -294,14 +318,38 @@ describe('BarChartDataService', () => { beforeEach(() => { mockGetOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue({ flatObjectMetadataMaps: { - byId: { [objectMetadataId]: mockObjectMetadata }, + byUniversalIdentifier: { + 'test-object-universal-id': { + ...mockObjectMetadata, + universalIdentifier: 'test-object-universal-id', + }, + }, + universalIdentifierById: { + [objectMetadataId]: 'test-object-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: { - [mockGroupByField.id]: mockGroupByField, - [mockAggregateField.id]: mockAggregateField, - [mockSelectField.id]: mockSelectField, + byUniversalIdentifier: { + 'group-by-field-universal-id': { + ...mockGroupByField, + universalIdentifier: 'group-by-field-universal-id', + }, + 'aggregate-field-universal-id': { + ...mockAggregateField, + universalIdentifier: 'aggregate-field-universal-id', + }, + 'select-field-universal-id': { + ...mockSelectField, + universalIdentifier: 'select-field-universal-id', + }, }, + universalIdentifierById: { + [mockGroupByField.id]: 'group-by-field-universal-id', + [mockAggregateField.id]: 'aggregate-field-universal-id', + [mockSelectField.id]: 'select-field-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, }); }); diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/line-chart-data.service.spec.ts b/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/line-chart-data.service.spec.ts index 840a67b64ad..75d7f9486c5 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/line-chart-data.service.spec.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/line-chart-data.service.spec.ts @@ -65,15 +65,44 @@ describe('LineChartDataService', () => { useValue: { getOrRecomputeManyOrAllFlatEntityMaps: jest.fn().mockResolvedValue({ flatObjectMetadataMaps: { - byId: { [objectMetadataId]: mockObjectMetadata }, + byUniversalIdentifier: { + 'test-object-universal-id': { + ...mockObjectMetadata, + universalIdentifier: 'test-object-universal-id', + }, + }, + universalIdentifierById: { + [objectMetadataId]: 'test-object-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: { - [mockGroupByFieldX.id]: mockGroupByFieldX, - [mockGroupByFieldXText.id]: mockGroupByFieldXText, - [mockGroupByFieldY.id]: mockGroupByFieldY, - [mockAggregateField.id]: mockAggregateField, + byUniversalIdentifier: { + 'group-by-field-x-universal-id': { + ...mockGroupByFieldX, + universalIdentifier: 'group-by-field-x-universal-id', + }, + 'group-by-field-x-text-universal-id': { + ...mockGroupByFieldXText, + universalIdentifier: 'group-by-field-x-text-universal-id', + }, + 'group-by-field-y-universal-id': { + ...mockGroupByFieldY, + universalIdentifier: 'group-by-field-y-universal-id', + }, + 'aggregate-field-universal-id': { + ...mockAggregateField, + universalIdentifier: 'aggregate-field-universal-id', + }, }, + universalIdentifierById: { + [mockGroupByFieldX.id]: 'group-by-field-x-universal-id', + [mockGroupByFieldXText.id]: + 'group-by-field-x-text-universal-id', + [mockGroupByFieldY.id]: 'group-by-field-y-universal-id', + [mockAggregateField.id]: 'aggregate-field-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, }), }, diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/pie-chart-data.service.spec.ts b/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/pie-chart-data.service.spec.ts index 2d114e6a4fc..f2367e6e8d0 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/pie-chart-data.service.spec.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/services/__tests__/pie-chart-data.service.spec.ts @@ -56,14 +56,38 @@ describe('PieChartDataService', () => { mockExecuteGroupByQuery = jest.fn(); mockGetOrRecomputeManyOrAllFlatEntityMaps = jest.fn().mockResolvedValue({ flatObjectMetadataMaps: { - byId: { [objectMetadataId]: mockObjectMetadata }, + byUniversalIdentifier: { + 'test-object-universal-id': { + ...mockObjectMetadata, + universalIdentifier: 'test-object-universal-id', + }, + }, + universalIdentifierById: { + [objectMetadataId]: 'test-object-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: { - [mockGroupByField.id]: mockGroupByField, - [mockSelectField.id]: mockSelectField, - [mockAggregateField.id]: mockAggregateField, + byUniversalIdentifier: { + 'group-by-field-universal-id': { + ...mockGroupByField, + universalIdentifier: 'group-by-field-universal-id', + }, + 'select-field-universal-id': { + ...mockSelectField, + universalIdentifier: 'select-field-universal-id', + }, + 'aggregate-field-universal-id': { + ...mockAggregateField, + universalIdentifier: 'aggregate-field-universal-id', + }, }, + universalIdentifierById: { + [mockGroupByField.id]: 'group-by-field-universal-id', + [mockSelectField.id]: 'select-field-universal-id', + [mockAggregateField.id]: 'aggregate-field-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, }); @@ -244,13 +268,33 @@ describe('PieChartDataService', () => { it('should format select field values using option labels', async () => { mockGetOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue({ flatObjectMetadataMaps: { - byId: { [objectMetadataId]: mockObjectMetadata }, + byUniversalIdentifier: { + 'test-object-universal-id': { + ...mockObjectMetadata, + universalIdentifier: 'test-object-universal-id', + }, + }, + universalIdentifierById: { + [objectMetadataId]: 'test-object-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: { - [mockSelectField.id]: mockSelectField, - [mockAggregateField.id]: mockAggregateField, + byUniversalIdentifier: { + 'select-field-universal-id': { + ...mockSelectField, + universalIdentifier: 'select-field-universal-id', + }, + 'aggregate-field-universal-id': { + ...mockAggregateField, + universalIdentifier: 'aggregate-field-universal-id', + }, }, + universalIdentifierById: { + [mockSelectField.id]: 'select-field-universal-id', + [mockAggregateField.id]: 'aggregate-field-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, }); @@ -293,8 +337,16 @@ describe('PieChartDataService', () => { it('should throw when object metadata is not found', async () => { mockGetOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue({ - flatObjectMetadataMaps: { byId: {} }, - flatFieldMetadataMaps: { byId: {} }, + flatObjectMetadataMaps: { + byUniversalIdentifier: {}, + universalIdentifierById: {}, + universalIdentifiersByApplicationId: {}, + }, + flatFieldMetadataMaps: { + byUniversalIdentifier: {}, + universalIdentifierById: {}, + universalIdentifiersByApplicationId: {}, + }, }); await expect( @@ -315,9 +367,22 @@ describe('PieChartDataService', () => { it('should throw when field metadata is not found', async () => { mockGetOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue({ flatObjectMetadataMaps: { - byId: { [objectMetadataId]: mockObjectMetadata }, + byUniversalIdentifier: { + 'test-object-universal-id': { + ...mockObjectMetadata, + universalIdentifier: 'test-object-universal-id', + }, + }, + universalIdentifierById: { + [objectMetadataId]: 'test-object-universal-id', + }, + universalIdentifiersByApplicationId: {}, + }, + flatFieldMetadataMaps: { + byUniversalIdentifier: {}, + universalIdentifierById: {}, + universalIdentifiersByApplicationId: {}, }, - flatFieldMetadataMaps: { byId: {} }, }); await expect( @@ -347,13 +412,33 @@ describe('PieChartDataService', () => { beforeEach(() => { mockGetOrRecomputeManyOrAllFlatEntityMaps.mockResolvedValue({ flatObjectMetadataMaps: { - byId: { [objectMetadataId]: mockObjectMetadata }, + byUniversalIdentifier: { + 'test-object-universal-id': { + ...mockObjectMetadata, + universalIdentifier: 'test-object-universal-id', + }, + }, + universalIdentifierById: { + [objectMetadataId]: 'test-object-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: { - [booleanField.id]: booleanField, - [mockAggregateField.id]: mockAggregateField, + byUniversalIdentifier: { + 'boolean-field-universal-id': { + ...booleanField, + universalIdentifier: 'boolean-field-universal-id', + }, + 'aggregate-field-universal-id': { + ...mockAggregateField, + universalIdentifier: 'aggregate-field-universal-id', + }, }, + universalIdentifierById: { + [booleanField.id]: 'boolean-field-universal-id', + [mockAggregateField.id]: 'aggregate-field-universal-id', + }, + universalIdentifiersByApplicationId: {}, }, }); }); diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/services/bar-chart-data.service.ts b/packages/twenty-server/src/modules/dashboard/chart-data/services/bar-chart-data.service.ts index 7e88ccf53ce..c65bfb58f7b 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/services/bar-chart-data.service.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/services/bar-chart-data.service.ts @@ -9,6 +9,7 @@ import { } from 'twenty-shared/utils'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { BarChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/bar-chart-configuration.dto'; @@ -78,7 +79,10 @@ export class BarChartDataService { ); } - const flatObjectMetadata = flatObjectMetadataMaps.byId[objectMetadataId]; + const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(flatObjectMetadata)) { throw new ChartDataException( @@ -92,12 +96,12 @@ export class BarChartDataService { const primaryAxisGroupByField = getFieldMetadata( configuration.primaryAxisGroupByFieldMetadataId, - flatFieldMetadataMaps.byId, + flatFieldMetadataMaps, ); const aggregateField = getFieldMetadata( configuration.aggregateFieldMetadataId, - flatFieldMetadataMaps.byId, + flatFieldMetadataMaps, ); const isTwoDimensional = isDefined( @@ -109,7 +113,7 @@ export class BarChartDataService { if (isTwoDimensional) { secondaryAxisGroupByField = getFieldMetadata( configuration.secondaryAxisGroupByFieldMetadataId!, - flatFieldMetadataMaps.byId, + flatFieldMetadataMaps, ); } @@ -131,11 +135,11 @@ export class BarChartDataService { const objectIdByNameSingular: Record = {}; - for (const objectId in flatObjectMetadataMaps.byId) { - const objMetadata = flatObjectMetadataMaps.byId[objectId]; - + for (const objMetadata of Object.values( + flatObjectMetadataMaps.byUniversalIdentifier, + )) { if (isDefined(objMetadata)) { - objectIdByNameSingular[objMetadata.nameSingular] = objectId; + objectIdByNameSingular[objMetadata.nameSingular] = objMetadata.id; } } diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/services/chart-data-query.service.ts b/packages/twenty-server/src/modules/dashboard/chart-data/services/chart-data-query.service.ts index d41b93af2ae..3787be49e24 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/services/chart-data-query.service.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/services/chart-data-query.service.ts @@ -89,12 +89,12 @@ export class ChartDataQueryService { const primaryGroupByField = getFieldMetadata( groupByFieldMetadataId, - flatFieldMetadataMaps.byId, + flatFieldMetadataMaps, ); const aggregateField = getFieldMetadata( aggregateFieldMetadataId, - flatFieldMetadataMaps.byId, + flatFieldMetadataMaps, ); const isPrimaryFieldDate = isFieldMetadataDateKind( @@ -146,7 +146,7 @@ export class ChartDataQueryService { if (isDefined(secondaryGroupByFieldMetadataId)) { const secondaryGroupByField = getFieldMetadata( secondaryGroupByFieldMetadataId, - flatFieldMetadataMaps.byId, + flatFieldMetadataMaps, ); const isSecondaryFieldDate = isFieldMetadataDateKind( diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/services/line-chart-data.service.ts b/packages/twenty-server/src/modules/dashboard/chart-data/services/line-chart-data.service.ts index f89c39d8005..29f0598a766 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/services/line-chart-data.service.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/services/line-chart-data.service.ts @@ -8,6 +8,7 @@ import { } from 'twenty-shared/utils'; import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { LineChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/line-chart-configuration.dto'; @@ -77,7 +78,10 @@ export class LineChartDataService { ); } - const flatObjectMetadata = flatObjectMetadataMaps.byId[objectMetadataId]; + const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(flatObjectMetadata)) { throw new ChartDataException( @@ -91,12 +95,12 @@ export class LineChartDataService { const primaryAxisGroupByField = getFieldMetadata( configuration.primaryAxisGroupByFieldMetadataId, - flatFieldMetadataMaps.byId, + flatFieldMetadataMaps, ); const aggregateField = getFieldMetadata( configuration.aggregateFieldMetadataId, - flatFieldMetadataMaps.byId, + flatFieldMetadataMaps, ); const isTwoDimensional = isDefined( @@ -108,7 +112,7 @@ export class LineChartDataService { if (isTwoDimensional) { secondaryAxisGroupByField = getFieldMetadata( configuration.secondaryAxisGroupByFieldMetadataId!, - flatFieldMetadataMaps.byId, + flatFieldMetadataMaps, ); } @@ -132,11 +136,11 @@ export class LineChartDataService { const objectIdByNameSingular: Record = {}; - for (const objectId in flatObjectMetadataMaps.byId) { - const objMetadata = flatObjectMetadataMaps.byId[objectId]; - + for (const objMetadata of Object.values( + flatObjectMetadataMaps.byUniversalIdentifier, + )) { if (isDefined(objMetadata)) { - objectIdByNameSingular[objMetadata.nameSingular] = objectId; + objectIdByNameSingular[objMetadata.nameSingular] = objMetadata.id; } } diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/services/pie-chart-data.service.ts b/packages/twenty-server/src/modules/dashboard/chart-data/services/pie-chart-data.service.ts index 119ac442522..7624de3d61c 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/services/pie-chart-data.service.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/services/pie-chart-data.service.ts @@ -8,6 +8,7 @@ import { } from 'twenty-shared/utils'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { PieChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/pie-chart-configuration.dto'; @@ -77,7 +78,10 @@ export class PieChartDataService { ); } - const flatObjectMetadata = flatObjectMetadataMaps.byId[objectMetadataId]; + const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(flatObjectMetadata)) { throw new ChartDataException( @@ -91,7 +95,7 @@ export class PieChartDataService { const groupByField = getFieldMetadata( configuration.groupByFieldMetadataId, - flatFieldMetadataMaps.byId, + flatFieldMetadataMaps, ); const limit = @@ -100,11 +104,11 @@ export class PieChartDataService { const objectIdByNameSingular: Record = {}; - for (const objectId in flatObjectMetadataMaps.byId) { - const objMetadata = flatObjectMetadataMaps.byId[objectId]; - + for (const objMetadata of Object.values( + flatObjectMetadataMaps.byUniversalIdentifier, + )) { if (isDefined(objMetadata)) { - objectIdByNameSingular[objMetadata.nameSingular] = objectId; + objectIdByNameSingular[objMetadata.nameSingular] = objMetadata.id; } } diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/utils/__tests__/is-relation-nested-field-date-kind.util.spec.ts b/packages/twenty-server/src/modules/dashboard/chart-data/utils/__tests__/is-relation-nested-field-date-kind.util.spec.ts index 19e7c037f10..9ecd1075207 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/utils/__tests__/is-relation-nested-field-date-kind.util.spec.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/utils/__tests__/is-relation-nested-field-date-kind.util.spec.ts @@ -63,19 +63,24 @@ describe('isRelationNestedFieldDateKind', () => { }); const flatObjectMetadataMaps: FlatEntityMaps = { - byId: { - [companyObjectId]: companyObject, + byUniversalIdentifier: { + [companyObject.universalIdentifier as string]: companyObject, + }, + universalIdentifierById: { + [companyObjectId]: companyObject.universalIdentifier as string, }, - idByUniversalIdentifier: {}, universalIdentifiersByApplicationId: {}, }; const flatFieldMetadataMaps: FlatEntityMaps = { - byId: { - [createdAtFieldId]: createdAtField, - [nameFieldId]: nameField, + byUniversalIdentifier: { + [createdAtField.universalIdentifier as string]: createdAtField, + [nameField.universalIdentifier as string]: nameField, + }, + universalIdentifierById: { + [createdAtFieldId]: createdAtField.universalIdentifier as string, + [nameFieldId]: nameField.universalIdentifier as string, }, - idByUniversalIdentifier: {}, universalIdentifiersByApplicationId: {}, }; @@ -193,13 +198,23 @@ describe('isRelationNestedFieldDateKind', () => { relationFieldMetadata: personRelationField, relationNestedFieldName: 'birthDate', flatObjectMetadataMaps: { - byId: { 'object-with-date-id': objectWithDateField }, - idByUniversalIdentifier: {}, + byUniversalIdentifier: { + [objectWithDateField.universalIdentifier as string]: + objectWithDateField, + }, + universalIdentifierById: { + 'object-with-date-id': + objectWithDateField.universalIdentifier as string, + }, universalIdentifiersByApplicationId: {}, }, flatFieldMetadataMaps: { - byId: { [dateFieldId]: dateField }, - idByUniversalIdentifier: {}, + byUniversalIdentifier: { + [dateField.universalIdentifier as string]: dateField, + }, + universalIdentifierById: { + [dateFieldId]: dateField.universalIdentifier as string, + }, universalIdentifiersByApplicationId: {}, }, }); diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/utils/convert-chart-filter-to-gql-operation-filter.util.ts b/packages/twenty-server/src/modules/dashboard/chart-data/utils/convert-chart-filter-to-gql-operation-filter.util.ts index 3861724a88b..1a976c93002 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/utils/convert-chart-filter-to-gql-operation-filter.util.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/utils/convert-chart-filter-to-gql-operation-filter.util.ts @@ -14,6 +14,7 @@ import { import { type ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -46,7 +47,10 @@ export const convertChartFilterToGqlOperationFilter = ({ const fieldIds = flatObjectMetadata.fieldIds ?? []; const fields: PartialFieldMetadataItem[] = fieldIds .map((fieldId: string) => { - const field = flatFieldMetadataMaps.byId[fieldId]; + const field = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!isDefined(field)) { return null; @@ -70,7 +74,10 @@ export const convertChartFilterToGqlOperationFilter = ({ const convertedRecordFilters: RecordFilter[] = recordFilters.map( (recordFilter) => { - const field = flatFieldMetadataMaps.byId[recordFilter.fieldMetadataId]; + const field = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: recordFilter.fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); return { id: recordFilter.id, diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/utils/get-field-metadata.util.ts b/packages/twenty-server/src/modules/dashboard/chart-data/utils/get-field-metadata.util.ts index f609e66746a..ac9cf7b0f44 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/utils/get-field-metadata.util.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/utils/get-field-metadata.util.ts @@ -1,5 +1,7 @@ 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 FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { ChartDataException, @@ -9,9 +11,12 @@ import { export const getFieldMetadata = ( fieldMetadataId: string, - fieldMetadataById: Partial>, + flatFieldMetadataMaps: FlatEntityMaps, ): FlatFieldMetadata => { - const fieldMetadata = fieldMetadataById[fieldMetadataId]; + const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldMetadataId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!isDefined(fieldMetadata)) { throw new ChartDataException( diff --git a/packages/twenty-server/src/modules/dashboard/chart-data/utils/is-relation-nested-field-date-kind.util.ts b/packages/twenty-server/src/modules/dashboard/chart-data/utils/is-relation-nested-field-date-kind.util.ts index c789aca272a..692b290acf2 100644 --- a/packages/twenty-server/src/modules/dashboard/chart-data/utils/is-relation-nested-field-date-kind.util.ts +++ b/packages/twenty-server/src/modules/dashboard/chart-data/utils/is-relation-nested-field-date-kind.util.ts @@ -1,5 +1,6 @@ import { isDefined, isFieldMetadataDateKind } 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 FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util'; @@ -30,7 +31,10 @@ export const isRelationNestedFieldDateKind = ({ return false; } - const targetObjectMetadata = flatObjectMetadataMaps.byId[targetObjectId]; + const targetObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: targetObjectId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(targetObjectMetadata)) { return false; @@ -41,7 +45,12 @@ export const isRelationNestedFieldDateKind = ({ const targetFieldIds = targetObjectMetadata.fieldIds; const nestedFieldMetadata = targetFieldIds - .map((fieldId: string) => flatFieldMetadataMaps.byId[fieldId]) + .map((fieldId: string) => + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldId, + flatEntityMaps: flatFieldMetadataMaps, + }), + ) .find( (fieldMetadata: FlatFieldMetadata | undefined) => isDefined(fieldMetadata) && fieldMetadata.name === nestedFieldName, diff --git a/packages/twenty-server/src/modules/workflow/common/workspace-services/workflow-common.workspace-service.ts b/packages/twenty-server/src/modules/workflow/common/workspace-services/workflow-common.workspace-service.ts index 35c9da06d2a..a945279f752 100644 --- a/packages/twenty-server/src/modules/workflow/common/workspace-services/workflow-common.workspace-service.ts +++ b/packages/twenty-server/src/modules/workflow/common/workspace-services/workflow-common.workspace-service.ts @@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common'; 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 { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; @@ -138,7 +139,10 @@ export class WorkflowCommonWorkspaceService { ); } - const flatObjectMetadata = flatObjectMetadataMaps.byId[objectId]; + const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(flatObjectMetadata)) { throw new WorkflowCommonException( diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-form-response.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-form-response.ts index b7c11d0063a..2d6eca2dd2c 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-form-response.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-form-response.ts @@ -1,5 +1,6 @@ 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 FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; @@ -39,7 +40,10 @@ export const generateFakeFormResponse = ({ ); } - const flatObjectMetadata = flatObjectMetadataMaps.byId[objectId]; + const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: objectId, + flatEntityMaps: flatObjectMetadataMaps, + }); if (!isDefined(flatObjectMetadata)) { throw new Error( diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/utils/resolve-rich-text-fields-in-record.util.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/utils/resolve-rich-text-fields-in-record.util.ts index de2b3478e8f..6444ed785bc 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/utils/resolve-rich-text-fields-in-record.util.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/utils/resolve-rich-text-fields-in-record.util.ts @@ -2,6 +2,7 @@ import { isString } from 'class-validator'; import { FieldMetadataType } from 'twenty-shared/types'; import { isDefined, resolveRichTextVariables } from 'twenty-shared/utils'; +import { findManyFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps.util'; import { type ObjectMetadataInfo } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service'; export const resolveRichTextFieldsInRecord = ( @@ -11,8 +12,10 @@ export const resolveRichTextFieldsInRecord = ( ): Record => { const { flatObjectMetadata, flatFieldMetadataMaps } = objectMetadataInfo; - const richTextFieldNames = flatObjectMetadata.fieldIds - .map((fieldId) => flatFieldMetadataMaps.byId[fieldId]) + const richTextFieldNames = findManyFlatEntityByIdInFlatEntityMaps({ + flatEntityIds: flatObjectMetadata.fieldIds, + flatEntityMaps: flatFieldMetadataMaps, + }) .filter((field) => field?.type === FieldMetadataType.RICH_TEXT_V2) .map((field) => field?.name) .filter(isDefined); diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/logic-function/logic-function.workflow-action.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/logic-function/logic-function.workflow-action.ts index 6e1de83ec75..aaa5ac3cf4b 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/logic-function/logic-function.workflow-action.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/logic-function/logic-function.workflow-action.ts @@ -5,6 +5,7 @@ import { resolveInput } from 'twenty-shared/utils'; import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface'; import { LogicFunctionExecutorService } from 'src/engine/core-modules/logic-function/logic-function-executor/services/logic-function-executor.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { WorkflowStepExecutorException, @@ -57,8 +58,10 @@ export class LogicFunctionWorkflowAction implements WorkflowAction { }, ); - const logicFunction = - flatLogicFunctionMaps.byId[workflowActionInput.logicFunctionId]; + const logicFunction = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: workflowActionInput.logicFunctionId, + flatEntityMaps: flatLogicFunctionMaps, + }); if (!logicFunction) { throw new WorkflowStepExecutorException( diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/record-crud/find-records.workflow-action.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/record-crud/find-records.workflow-action.ts index a1beb196a6c..4b2f0586f64 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/record-crud/find-records.workflow-action.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/record-crud/find-records.workflow-action.ts @@ -17,6 +17,7 @@ import { RecordCrudExceptionCode, } from 'src/engine/core-modules/record-crud/exceptions/record-crud.exception'; import { FindRecordsService } from 'src/engine/core-modules/record-crud/services/find-records.service'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service'; import { WorkflowStepExecutorException, @@ -73,7 +74,10 @@ export class FindRecordsWorkflowAction implements WorkflowAction { const fields = flatObjectMetadata.fieldIds .map((fieldId) => { - const field = flatFieldMetadataMaps.byId[fieldId]; + const field = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: fieldId, + flatEntityMaps: flatFieldMetadataMaps, + }); if (!field) { return null; diff --git a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/listeners/workflow-database-event-trigger.listener.ts b/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/listeners/workflow-database-event-trigger.listener.ts index db4cb59b880..9f6ec3127e7 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/listeners/workflow-database-event-trigger.listener.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/listeners/workflow-database-event-trigger.listener.ts @@ -18,6 +18,7 @@ import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decora import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants'; import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service'; import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util'; @@ -277,7 +278,10 @@ export class WorkflowDatabaseEventTriggerListener { } const relatedObjectMetadataNameSingular = - flatObjectMetadataMaps.byId[relatedObjectMetadataId]?.nameSingular; + findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: relatedObjectMetadataId, + flatEntityMaps: flatObjectMetadataMaps, + })?.nameSingular; if (!isDefined(relatedObjectMetadataNameSingular)) { continue;