From 6397a4d90650625ad65ff0799b17a6ccf8d12632 Mon Sep 17 00:00:00 2001 From: Paul Rastoin <45004772+prastoin@users.noreply.github.com> Date: Fri, 29 Aug 2025 16:46:15 +0200 Subject: [PATCH] Update object handle morph join col rename (#14153) # Introduction When udpating a flat object metadata name we need to search for RELATION field that has a MORPH RELATION target flat field metadata with MANY_TO_ONE relationType as its settings are binded to the updated flat object metadata name In the best of the world we would remove this complexity to be computed at runtime only and deprecate implemented logic here close https://github.com/twentyhq/core-team-issues/issues/1412 --- .../field-metadata-settings.interface.ts | 2 +- .../types/field-metadata-entity-test.type.ts | 2 +- .../compare-two-flat-field-metadata.util.ts | 6 +- ...related-to-morph-relation-or-throw.util.ts | 3 +- ...arget-flat-field-metadata-or-throw.util.ts | 24 +++++-- ...tadatas-target-flat-field-metadata.util.ts | 7 ++- ...ject-input-to-flat-object-metadata.util.ts | 62 +++++++++++++++---- ...tion-flat-field-metadatas-or-throw.util.ts | 50 +++++++++++++++ ...etadatas-settings-join-column-name.util.ts | 46 ++++++++++++++ .../object-metadata-v2.service.ts | 34 +++++++--- 10 files changed, 201 insertions(+), 35 deletions(-) create mode 100644 packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/get-flat-object-metadata-many-to-one-target-morph-relation-flat-field-metadatas-or-throw.util.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/rename-flat-object-metadata-morph-relation-flat-field-metadatas-settings-join-column-name.util.ts diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface.ts index 1d713fcab9..e842664dc7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface.ts @@ -60,7 +60,7 @@ type FieldMetadataSettingsMapping = { [FieldMetadataType.TEXT]: FieldMetadataTextSettings | null; [FieldMetadataType.RELATION]: FieldMetadataRelationSettings; [FieldMetadataType.ADDRESS]: FieldMetadataAddressSettings | null; - [FieldMetadataType.MORPH_RELATION]: FieldMetadataRelationSettings | null; // TODO Should not be null + [FieldMetadataType.MORPH_RELATION]: FieldMetadataRelationSettings; [FieldMetadataType.TS_VECTOR]: FieldMetadataTsVectorSettings | null; }; diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/types/field-metadata-entity-test.type.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/types/field-metadata-entity-test.type.ts index 2d751a5e15..9901fa85fa 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/types/field-metadata-entity-test.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/types/field-metadata-entity-test.type.ts @@ -174,7 +174,7 @@ type SettingsAssertions = [ Expect< HasAllProperties< MorphRelationFieldMetadata, - { settings: FieldMetadataRelationSettings | null } + { settings: FieldMetadataRelationSettings } > >, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/compare-two-flat-field-metadata.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/compare-two-flat-field-metadata.util.ts index d55aef4138..4967616909 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/compare-two-flat-field-metadata.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/compare-two-flat-field-metadata.util.ts @@ -1,5 +1,5 @@ import diff from 'microdiff'; -import { FieldMetadataType, type FromTo } from 'twenty-shared/types'; +import { type FromTo } from 'twenty-shared/types'; import { isDefined, parseJson } from 'twenty-shared/utils'; import { FLAT_FIELD_METADATA_JSONB_PROPERTIES } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-jsonb-properties.constant'; @@ -10,6 +10,7 @@ import { type FlatFieldMetadataRelationPropertiesToCompare } from 'src/engine/me import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { isFlatFieldMetadataJsonbProperty } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-jsonb-property.util'; import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; import { type UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-field-action-v2'; import { transformMetadataForComparison } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/utils/transform-metadata-for-comparison.util'; @@ -40,8 +41,7 @@ export const compareTwoFlatFieldMetadata = ({ // Remove below assertion when we authorize relation edition, see https://github.com/twentyhq/twenty/commit/39f6f3c4bb101272a9014e142a842d0801a3c33b const isRelationFieldType = isDefined(fieldMetadata.type) && - (fieldMetadata.type === FieldMetadataType.RELATION || - fieldMetadata.type === FieldMetadataType.MORPH_RELATION); + isRelationFieldMetadataType(fieldMetadata.type); if ( isRelationFieldType && diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-flat-field-metadatas-related-to-morph-relation-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-flat-field-metadatas-related-to-morph-relation-or-throw.util.ts index 34b998df6b..33af20a0b7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-flat-field-metadatas-related-to-morph-relation-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-flat-field-metadatas-related-to-morph-relation-or-throw.util.ts @@ -1,6 +1,7 @@ import { FieldMetadataType } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; +import { type RelationFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/relation-field-metadata-type.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util'; import { isFlatFieldMetadataEntityOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util'; @@ -17,7 +18,7 @@ export type FindFlatFieldMetadatasRelatedToMorphRelationOrThrowArgs = { export const findFlatFieldMetadatasRelatedToMorphRelationOrThrow = ({ flatObjectMetadataMaps, flatFieldMetadata: morphRelationFlatFieldMetadata, -}: FindFlatFieldMetadatasRelatedToMorphRelationOrThrowArgs): FlatFieldMetadata[] => { +}: FindFlatFieldMetadatasRelatedToMorphRelationOrThrowArgs): FlatFieldMetadata[] => { const flatObjectMetadataWithFlatFieldMaps = flatObjectMetadataMaps.byId[ morphRelationFlatFieldMetadata.objectMetadataId 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 911c71f7e9..8ab74af378 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 @@ -1,24 +1,24 @@ -import { type FieldMetadataType } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; +import { FieldMetadataType } from 'twenty-shared/types'; import { FieldMetadataException, FieldMetadataExceptionCode, } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception'; +import { type RelationFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/relation-field-metadata-type.type'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; +import { isFlatFieldMetadataEntityOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util'; import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type'; export type GetRelationFlatFieldMetadatasUtilArgs = { flatObjectMetadataMaps: FlatObjectMetadataMaps; - flatFieldMetadata: FlatFieldMetadata< - FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION - >; + flatFieldMetadata: FlatFieldMetadata; }; -// TODO prastoin handle morph relation + export const findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow = ({ flatObjectMetadataMaps, flatFieldMetadata, -}: GetRelationFlatFieldMetadatasUtilArgs): FlatFieldMetadata => { +}: GetRelationFlatFieldMetadatasUtilArgs): FlatFieldMetadata => { const { relationTargetFieldMetadataId, relationTargetObjectMetadataId } = flatFieldMetadata; @@ -41,5 +41,17 @@ export const findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow = ({ ); } + if ( + !isFlatFieldMetadataEntityOfType( + relatedFlatFieldMetadata, + FieldMetadataType.RELATION, + ) + ) { + throw new FieldMetadataException( + `Relation target field metadata is not a relation field metadata`, + FieldMetadataExceptionCode.FIELD_METADATA_RELATION_MALFORMED, + ); + } + return relatedFlatFieldMetadata; }; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata.util.ts index 6d60f203d1..9f71f18f84 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata.util.ts @@ -1,4 +1,3 @@ -import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow, type GetRelationFlatFieldMetadatasUtilArgs, @@ -6,7 +5,11 @@ import { export const findRelationFlatFieldMetadataTargetFlatFieldMetadata = ( args: GetRelationFlatFieldMetadatasUtilArgs, -): FlatFieldMetadata | undefined => { +): + | ReturnType< + typeof findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow + > + | undefined => { try { return findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow(args); } catch { diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-update-object-input-to-flat-object-metadata.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-update-object-input-to-flat-object-metadata.util.ts index 72a0f350de..cc81c7e3fb 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-update-object-input-to-flat-object-metadata.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/from-update-object-input-to-flat-object-metadata.util.ts @@ -4,11 +4,13 @@ import { trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties, } from 'twenty-shared/utils'; +import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type'; import { findFlatObjectMetadataInFlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-in-flat-object-metadata-maps.util'; import { FLAT_OBJECT_METADATA_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/flat-object-metadata/constants/flat-object-metadata-properties-to-compare.constant'; import { type FlatObjectMetadataPropertiesToCompare } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata-properties-to-compare.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; +import { renameFlatObjectMetadataManyToOneMorphRelationTargetFlatFieldMetadatasSettingsJoinColumnName } from 'src/engine/metadata-modules/flat-object-metadata/utils/rename-flat-object-metadata-morph-relation-flat-field-metadatas-settings-join-column-name.util'; import { OBJECT_METADATA_STANDARD_OVERRIDES_PROPERTIES } from 'src/engine/metadata-modules/object-metadata/constants/object-metadata-standard-overrides-properties.constant'; import { type UpdateOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input'; import { @@ -33,10 +35,15 @@ const objectMetadataEditableProperties = > => property !== 'standardOverrides', ); +type UpdatedFlatObjectAndOtherObjectFieldMetadatas = { + flatObjectMetadata: FlatObjectMetadata; + otherObjectFlatFieldMetadatas: FlatFieldMetadata[]; +}; + export const fromUpdateObjectInputToFlatObjectMetadata = ({ existingFlatObjectMetadataMaps, updateObjectInput: rawUpdateObjectInput, -}: FromUpdateObjectInputToFlatObjectMetadataArgs): FlatObjectMetadata => { +}: FromUpdateObjectInputToFlatObjectMetadataArgs): UpdatedFlatObjectAndOtherObjectFieldMetadatas => { const { id: objectMetadataIdToUpdate } = trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties( rawUpdateObjectInput, @@ -93,23 +100,54 @@ export const fromUpdateObjectInputToFlatObjectMetadata = ({ }; }, flatObjectMetadataToUpdate); - return updatedStandardFlatObjectdMetadata; + return { + flatObjectMetadata: updatedStandardFlatObjectdMetadata, + otherObjectFlatFieldMetadatas: [], + }; } - const updatedFlatObjectMetadata = objectMetadataEditableProperties.reduce( - (acc, property) => { + const initialAccumulator: UpdatedFlatObjectAndOtherObjectFieldMetadatas = { + flatObjectMetadata: flatObjectMetadataToUpdate, + otherObjectFlatFieldMetadatas: [], + }; + + return objectMetadataEditableProperties.reduce( + ({ flatObjectMetadata, otherObjectFlatFieldMetadatas }, property) => { + const updatedPropertyValue = updatedEditableObjectProperties[property]; const isPropertyUpdated = - updatedEditableObjectProperties[property] !== undefined; + updatedPropertyValue !== undefined && + flatObjectMetadata[property] !== updatedPropertyValue; + + if (!isPropertyUpdated) { + return { + flatObjectMetadata, + otherObjectFlatFieldMetadatas, + }; + } + + const updatedFlatObjectMetadata = { + ...flatObjectMetadata, + [property]: updatedPropertyValue, + }; + const newUpdatedOtherObjectFlatFieldMetadatas = + property === 'nameSingular' + ? renameFlatObjectMetadataManyToOneMorphRelationTargetFlatFieldMetadatasSettingsJoinColumnName( + { + existingFlatObjectMetadataMaps, + fromFlatObjectMetadata: updatedFlatObjectMetadata, + toFlatObjectMetadata: updatedFlatObjectMetadata, + }, + ) + : []; return { - ...acc, - ...(isPropertyUpdated - ? { [property]: updatedEditableObjectProperties[property] } - : {}), + flatObjectMetadata: updatedFlatObjectMetadata, + otherObjectFlatFieldMetadatas: [ + ...otherObjectFlatFieldMetadatas, + ...newUpdatedOtherObjectFlatFieldMetadatas, + ], }; }, - flatObjectMetadataToUpdate, + initialAccumulator, ); - - return updatedFlatObjectMetadata; }; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/get-flat-object-metadata-many-to-one-target-morph-relation-flat-field-metadatas-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/get-flat-object-metadata-many-to-one-target-morph-relation-flat-field-metadatas-or-throw.util.ts new file mode 100644 index 0000000000..de725e99e8 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/get-flat-object-metadata-many-to-one-target-morph-relation-flat-field-metadatas-or-throw.util.ts @@ -0,0 +1,50 @@ +import { FieldMetadataType } from 'twenty-shared/types'; + +import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface'; + +import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; +import { isFlatFieldMetadataEntityOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util'; +import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type'; +import { findFlatFieldMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-field-metadata-in-flat-object-metadata-maps-or-throw.util'; +import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; + +type GetFlatObjectMetadataMorphRelationFlatFieldMetadatasArgs = { + flatObjectMetadata: FlatObjectMetadata; + existingFlatObjectMetadataMaps: FlatObjectMetadataMaps; +}; +export const getFlatObjectMetadataManyToOneTargetMorphRelationFlatFieldMetadatasOrThrow = + ({ + flatObjectMetadata, + existingFlatObjectMetadataMaps, + }: GetFlatObjectMetadataMorphRelationFlatFieldMetadatasArgs) => { + const manyToOneMorphRelationTargetFlatFieldMetadataIds = + flatObjectMetadata.flatFieldMetadatas + .filter( + ( + flatFieldMetadata, + ): flatFieldMetadata is FlatFieldMetadata => + isFlatFieldMetadataEntityOfType( + flatFieldMetadata, + FieldMetadataType.RELATION, + ) && + flatFieldMetadata.settings.relationType === + RelationType.MANY_TO_ONE && + isFlatFieldMetadataEntityOfType( + flatFieldMetadata.flatRelationTargetFieldMetadata, + FieldMetadataType.MORPH_RELATION, + ), + ) + .map(({ id: fieldMetadataId, objectMetadataId }) => ({ + fieldMetadataId, + objectMetadataId, + })); + + return manyToOneMorphRelationTargetFlatFieldMetadataIds.map( + ({ fieldMetadataId, objectMetadataId }) => + findFlatFieldMetadataInFlatObjectMetadataMapsOrThrow({ + fieldMetadataId, + flatObjectMetadataMaps: existingFlatObjectMetadataMaps, + objectMetadataId, + }), + ) as FlatFieldMetadata[]; + }; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/rename-flat-object-metadata-morph-relation-flat-field-metadatas-settings-join-column-name.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/rename-flat-object-metadata-morph-relation-flat-field-metadatas-settings-join-column-name.util.ts new file mode 100644 index 0000000000..fef6765d05 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/rename-flat-object-metadata-morph-relation-flat-field-metadatas-settings-join-column-name.util.ts @@ -0,0 +1,46 @@ +import { type FieldMetadataType, type FromTo } from 'twenty-shared/types'; +import { computeMorphRelationFieldJoinColumnName } from 'twenty-shared/utils'; + +import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; +import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type'; +import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; +import { getFlatObjectMetadataManyToOneTargetMorphRelationFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-object-metadata/utils/get-flat-object-metadata-many-to-one-target-morph-relation-flat-field-metadatas-or-throw.util'; + +type RenameFlatObjectMetadataManyToOneMorphRelationTargetFlatFieldMetadatasSettingsJoinColumnNameArgs = + FromTo & { + existingFlatObjectMetadataMaps: FlatObjectMetadataMaps; + }; +export const renameFlatObjectMetadataManyToOneMorphRelationTargetFlatFieldMetadatasSettingsJoinColumnName = + ({ + fromFlatObjectMetadata, + toFlatObjectMetadata, + existingFlatObjectMetadataMaps, + }: RenameFlatObjectMetadataManyToOneMorphRelationTargetFlatFieldMetadatasSettingsJoinColumnNameArgs): FlatFieldMetadata[] => { + const manyToOneMorphRelationFlatFieldMetadatas = + getFlatObjectMetadataManyToOneTargetMorphRelationFlatFieldMetadatasOrThrow( + { + flatObjectMetadata: fromFlatObjectMetadata, + existingFlatObjectMetadataMaps, + }, + ); + + const updatedFlatFieldMetadatas = + manyToOneMorphRelationFlatFieldMetadatas.map( + (morphRelationFlatFieldMetadata) => { + const newJoinColumnName = computeMorphRelationFieldJoinColumnName({ + name: morphRelationFlatFieldMetadata.name, + targetObjectMetadataNameSingular: toFlatObjectMetadata.nameSingular, + }); + + return { + ...morphRelationFlatFieldMetadata, + settings: { + ...morphRelationFlatFieldMetadata.settings, + joinColumnName: newJoinColumnName, + }, + }; + }, + ); + + return updatedFlatFieldMetadatas; + }; diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata-v2.service.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata-v2.service.ts index 3b2f729e09..bdaed1d567 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata-v2.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata-v2.service.ts @@ -12,6 +12,7 @@ import { deleteFieldFromFlatObjectMetadataMapsOrThrow } from 'src/engine/metadat import { deleteObjectFromFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/delete-object-from-flat-object-metadata-maps-or-throw.util'; import { getSubFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/get-sub-flat-object-metadata-maps-or-throw.util'; import { getSubFlatObjectMetadataMapsOutOfFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/get-sub-flat-object-metadata-maps-out-of-flat-field-metadatas-or-throw.util'; +import { replaceFlatFieldMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/replace-flat-field-metadata-in-flat-object-metadata-maps-or-throw.util'; import { replaceFlatObjectMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/replace-flat-object-metadata-in-flat-object-metadata-maps-or-throw.util'; import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCreate } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-create-object-input-to-flat-object-metadata-and-flat-field-metadatas-to-create.util'; @@ -55,22 +56,37 @@ export class ObjectMetadataServiceV2 { }, ); - const optimisticallyUpdatedFlatObjectMetadata = - fromUpdateObjectInputToFlatObjectMetadata({ - existingFlatObjectMetadataMaps, - updateObjectInput, - }); + const { + flatObjectMetadata: optimisticallyUpdatedFlatObjectMetadata, + otherObjectFlatFieldMetadatas, + } = fromUpdateObjectInputToFlatObjectMetadata({ + existingFlatObjectMetadataMaps, + updateObjectInput, + }); + const impactedObjectMetadataIds = [ + ...new Set([ + optimisticallyUpdatedFlatObjectMetadata.id, + ...otherObjectFlatFieldMetadatas.map( + (flatFieldMetadata) => flatFieldMetadata.objectMetadataId, + ), + ]), + ]; const fromFlatObjectMetadataMaps = getSubFlatObjectMetadataMapsOrThrow({ flatObjectMetadataMaps: existingFlatObjectMetadataMaps, - objectMetadataIds: [optimisticallyUpdatedFlatObjectMetadata.id], + objectMetadataIds: impactedObjectMetadataIds, }); - const toFlatObjectMetadataMaps = + const toFlatObjectMetadataMaps = otherObjectFlatFieldMetadatas.reduce( + (flatObjectMetadataMaps, flatFieldMetadata) => + replaceFlatFieldMetadataInFlatObjectMetadataMapsOrThrow({ + flatFieldMetadata, + flatObjectMetadataMaps, + }), replaceFlatObjectMetadataInFlatObjectMetadataMapsOrThrow({ flatObjectMetadata: optimisticallyUpdatedFlatObjectMetadata, flatObjectMetadataMaps: fromFlatObjectMetadataMaps, - }); - + }), + ); const validateAndBuildResult = await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( {