ObjectMetadataServiceV2.updateOne (#13891)

# Introduction
Last service to get migrated, `updateOne` object metadata service v2
This commit is contained in:
Paul Rastoin
2025-08-14 11:37:52 +02:00
committed by GitHub
parent 3c034c4ab4
commit ad77d2f462
42 changed files with 798 additions and 282 deletions
@@ -2,36 +2,17 @@ import diff from 'microdiff';
import { FieldMetadataType, type FromTo } from 'twenty-shared/types';
import { isDefined } 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';
import { FLAT_FIELD_METADATA_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-properties-to-compare.constant';
import { FLAT_FIELD_METADATA_RELATION_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-relation-properties-to-compare.constant';
import { type FlatFieldMetadataEntityJsonbProperties } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-jsonb-properties.type';
import { type FlatFieldMetadataPropertiesToCompare } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-properties-to-compare.type';
import { type FlatFieldMetadataRelationPropertiesToCompare } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-relation-properties-to-compare.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.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';
export const flatFieldMetadataPropertiesToCompare = [
'defaultValue',
'description',
'icon',
'isActive',
'isLabelSyncedWithName',
'isUnique',
'label',
'name',
'options',
'standardOverrides',
'settings',
] as const satisfies (keyof FlatFieldMetadata)[];
export type FlatFieldMetadataPropertiesToCompare =
(typeof flatFieldMetadataPropertiesToCompare)[number];
export const flatFieldMetadataEntityJsonbProperties = [
'defaultValue',
'options',
'settings',
'standardOverrides',
] as const satisfies (keyof FlatFieldMetadata)[];
export type FlatFieldMetadataEntityJsonbProperties =
(typeof flatFieldMetadataEntityJsonbProperties)[number];
const shouldNotOverrideDefaultValue = (type: FieldMetadataType) => {
return [
FieldMetadataType.BOOLEAN,
@@ -51,13 +32,13 @@ export const compareTwoFlatFieldMetadata = ({
from,
to,
}: GetWorkspaceMigrationUpdateFieldActionArgs) => {
const compareFieldMetadataOptions = {
const transformMetadataForComparisonParameters = {
shouldIgnoreProperty: (
property: string,
fieldMetadata: FlatFieldMetadata,
) => {
if (
!flatFieldMetadataPropertiesToCompare.includes(
!FLAT_FIELD_METADATA_PROPERTIES_TO_COMPARE.includes(
property as FlatFieldMetadataPropertiesToCompare,
)
) {
@@ -73,26 +54,38 @@ export const compareTwoFlatFieldMetadata = ({
}
// Remove below assertion when we authorize relation edition, see https://github.com/twentyhq/twenty/commit/39f6f3c4bb101272a9014e142a842d0801a3c33b
if (
const isRelationFieldType =
isDefined(fieldMetadata.type) &&
(fieldMetadata.type === FieldMetadataType.RELATION ||
fieldMetadata.type === FieldMetadataType.MORPH_RELATION) &&
!['label', 'description', 'isActive'].includes(property)
fieldMetadata.type === FieldMetadataType.MORPH_RELATION);
if (
isRelationFieldType &&
!FLAT_FIELD_METADATA_RELATION_PROPERTIES_TO_COMPARE.includes(
property as FlatFieldMetadataRelationPropertiesToCompare,
)
) {
return true;
}
if (
isStandardMetadata(fieldMetadata) &&
property !== 'standardOverrides'
) {
return true;
}
return false;
},
propertiesToStringify: flatFieldMetadataEntityJsonbProperties,
propertiesToStringify: FLAT_FIELD_METADATA_JSONB_PROPERTIES,
};
const fromCompare = transformMetadataForComparison(
from,
compareFieldMetadataOptions,
transformMetadataForComparisonParameters,
);
const toCompare = transformMetadataForComparison(
to,
compareFieldMetadataOptions,
transformMetadataForComparisonParameters,
);
const flatFieldMetadataDifferences = diff(fromCompare, toCompare);
@@ -104,7 +97,7 @@ export const compareTwoFlatFieldMetadata = ({
case 'CHANGE': {
const { oldValue, path, value } = difference;
const property = path[0] as FlatFieldMetadataPropertiesToCompare;
const isJsonb = flatFieldMetadataEntityJsonbProperties.includes(
const isJsonb = FLAT_FIELD_METADATA_JSONB_PROPERTIES.includes(
property as FlatFieldMetadataEntityJsonbProperties,
);
@@ -4,30 +4,28 @@ import {
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties,
} from 'twenty-shared/utils';
import {
fieldMetadataStandardOverridesProperties,
type FieldMetadataStandardOverridesProperties,
} from 'src/engine/metadata-modules/field-metadata/dtos/field-standard-overrides.dto';
import { FIELD_METADATA_STANDARD_OVERRIDES_PROPERTIES } from 'src/engine/metadata-modules/field-metadata/constants/field-metadata-standard-overrides-properties.constant';
import { type UpdateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/update-field.input';
import {
FieldMetadataException,
FieldMetadataExceptionCode,
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
import { type FieldMetadataStandardOverridesProperties } from 'src/engine/metadata-modules/field-metadata/types/field-metadata-standard-overrides-properties.type';
import { FLAT_FIELD_METADATA_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-properties-to-compare.constant';
import { type FieldInputTranspilationResult } from 'src/engine/metadata-modules/flat-field-metadata/types/field-input-transpilation-result.type';
import { type FlatFieldMetadataPropertiesToCompare } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-properties-to-compare.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import {
flatFieldMetadataPropertiesToCompare,
type FlatFieldMetadataPropertiesToCompare,
} from 'src/engine/metadata-modules/flat-field-metadata/utils/compare-two-flat-field-metadata.util';
import {} from 'src/engine/metadata-modules/flat-field-metadata/utils/compare-two-flat-field-metadata.util';
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
import { findFlatFieldMetadataInFlatObjectMetadataMapsWithOnlyFieldId } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-field-metadata-in-flat-object-metadata-maps-with-field-id-only.util';
import {
ObjectMetadataException,
ObjectMetadataExceptionCode,
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util';
const fieldMetadataEditableProperties =
flatFieldMetadataPropertiesToCompare.filter(
FLAT_FIELD_METADATA_PROPERTIES_TO_COMPARE.filter(
(
property,
): property is Exclude<
@@ -36,20 +34,20 @@ const fieldMetadataEditableProperties =
> => property !== 'standardOverrides',
);
type FromUpdateFieldInputToFlatFieldMetadataToUpdateArgs = {
type FromUpdateFieldInputToFlatFieldMetadataArgs = {
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
updateFieldInput: UpdateFieldInput;
};
export const fromUpdateFieldInputToFlatFieldMetadataToUpdate = ({
export const fromUpdateFieldInputToFlatFieldMetadata = ({
existingFlatObjectMetadataMaps,
updateFieldInput: rawUpdateFieldInput,
}: FromUpdateFieldInputToFlatFieldMetadataToUpdateArgs): FieldInputTranspilationResult<FlatFieldMetadata> => {
}: FromUpdateFieldInputToFlatFieldMetadataArgs): FieldInputTranspilationResult<FlatFieldMetadata> => {
const updateFieldInputInformalProperties =
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
rawUpdateFieldInput,
['objectMetadataId', 'id'],
);
const updatedEditableFields = extractAndSanitizeObjectStringFields(
const updatedEditableFieldProperties = extractAndSanitizeObjectStringFields(
rawUpdateFieldInput,
fieldMetadataEditableProperties,
);
@@ -94,16 +92,14 @@ export const fromUpdateFieldInputToFlatFieldMetadataToUpdate = ({
),
};
}
const isStandardField =
relatedFlatFieldMetadata.standardId !== null &&
!relatedFlatFieldMetadata.isCustom;
if (isStandardField) {
const invalidUpdatedProperties = Object.keys(updatedEditableFields).filter(
(property) =>
fieldMetadataStandardOverridesProperties.includes(
property as FieldMetadataStandardOverridesProperties,
),
if (isStandardMetadata(relatedFlatFieldMetadata)) {
const invalidUpdatedProperties = Object.keys(
updatedEditableFieldProperties,
).filter((property) =>
FIELD_METADATA_STANDARD_OVERRIDES_PROPERTIES.includes(
property as FieldMetadataStandardOverridesProperties,
),
);
if (invalidUpdatedProperties.length > 0) {
@@ -117,15 +113,16 @@ export const fromUpdateFieldInputToFlatFieldMetadataToUpdate = ({
}
const updatedStandardFlatFieldMetadata =
fieldMetadataStandardOverridesProperties.reduce((acc, property) => {
const isPropertyUpdated = updatedEditableFields[property] !== undefined;
FIELD_METADATA_STANDARD_OVERRIDES_PROPERTIES.reduce((acc, property) => {
const isPropertyUpdated =
updatedEditableFieldProperties[property] !== undefined;
return {
...acc,
standardOverrides: {
...acc.standardOverrides,
...(isPropertyUpdated
? { [property]: updatedEditableFields[property] }
? { [property]: updatedEditableFieldProperties[property] }
: {}),
},
};
@@ -139,12 +136,13 @@ export const fromUpdateFieldInputToFlatFieldMetadataToUpdate = ({
const updatedFlatFieldMetadata = fieldMetadataEditableProperties.reduce(
(acc, property) => {
const isPropertyUpdated = updatedEditableFields[property] !== undefined;
const isPropertyUpdated =
updatedEditableFieldProperties[property] !== undefined;
return {
...acc,
...(isPropertyUpdated
? { [property]: updatedEditableFields[property] }
? { [property]: updatedEditableFieldProperties[property] }
: {}),
};
},
@@ -0,0 +1,13 @@
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { computeMetadataNameFromLabel } from 'src/engine/metadata-modules/utils/validate-name-and-label-are-sync-or-throw.util';
export const isFlatFieldMetadataNameSyncedWithLabel = (
flatFieldMetadata: Pick<
FlatFieldMetadata,
'name' | 'isLabelSyncedWithName' | 'label'
>,
) => {
const computedName = computeMetadataNameFromLabel(flatFieldMetadata.label);
return flatFieldMetadata.name === computedName;
};