Field deactivation side effect views calendar kanban viewFields (#15180)

# Introduction
Handling both:
- field deactivation side effect on view fields, view filters and views
- field deactivation side effect on view that targets it as
`kanbanAggregateFieldMetadataId`
- field deactivation side effect on view that targets it as
`calendarFieldMetadataId`

## Coverage
added coverage
```ts
 PASS  test/integration/metadata/suites/field-metadata/kanban-aggregate-field-deactivation-deletes-views.integration-spec.ts (13.132 s)
  kanban-aggregate-field-deactivation-nullifies-kanban-properties
    ✓ should nullify kanban properties when field used as kanbanAggregateOperationFieldMetadataId is deactivated (3923 ms)
    ✓ should not modify views when field not used as kanbanAggregateOperationFieldMetadataId is deactivated (2958 ms)
    ✓ should nullify kanban properties on multiple views when they all use the same field as kanbanAggregateOperationFieldMetadataId (2542 ms)
    ✓ should nullify kanban properties when views have different aggregate operations on same field (3380 ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        13.154 s
```

```ts
 PASS  test/integration/metadata/suites/field-metadata/view-group-field-deactivation-deletes-views.integration-spec.ts (12.639 s)
  view-group-field-deactivation-deletes-views
    ✓ should delete view when field used in view group is deactivated (3469 ms)
    ✓ should not delete view when field not used in view group is deactivated (3109 ms)
    ✓ should delete multiple views when they all use the same field in view groups (2741 ms)
    ✓ should handle deactivation when view has multiple view groups with different fields (3008 ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        12.664 s
```

```ts
 PASS  test/integration/metadata/suites/field-metadata/calendar-field-deactivation-deletes-views.integration-spec.ts (14.579 s)
  calendar-field-deactivation-deletes-views
    ✓ should delete view when field used as calendarFieldMetadataId is deactivated (3388 ms)
    ✓ should not delete view when field not used as calendarFieldMetadataId is deactivated (2438 ms)
    ✓ should delete multiple views when they all use the same field as calendarFieldMetadataId (2635 ms)
    ✓ should handle deactivation when views have different calendar layouts on same field (3195 ms)
    ✓ should delete calendar view but not other view types when calendar field is deactivated (2682 ms)

Test Suites: 1 passed, 1 total
Tests:       5 passed, 5 total
Snapshots:   0 total
Time:        14.601 s, estimated 15 s
```

## View soft deletion
We decided to remove the soft deletion grain on all the views, in this
PR context we've only removed soft deleted validation requirement on any
view entities

## Conclusion

close https://github.com/twentyhq/core-team-issues/issues/1754
This commit is contained in:
Paul Rastoin
2025-10-21 16:12:03 +02:00
committed by GitHub
parent 72fd8ae8d2
commit 45473218d3
45 changed files with 1674 additions and 194 deletions
@@ -221,6 +221,8 @@ export class WorkspaceMigrationBuildOrchestratorService {
dependencyOptimisticFlatEntityMaps: {
flatObjectMetadataMaps:
optimisticAllFlatEntityMaps.flatObjectMetadataMaps,
flatFieldMetadataMaps:
optimisticAllFlatEntityMaps.flatFieldMetadataMaps,
},
from: fromFlatViewMaps,
to: toFlatViewMaps,
@@ -0,0 +1,23 @@
import { type AllMetadataName } from 'src/engine/metadata-modules/flat-entity/types/all-metadata-name.type';
import { type FlatEntityPropertiesToCompare } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-compare.type';
import { type FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
import { type FlatEntityPropertyUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-property-update.type';
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
import { isPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/utils/is-property-update.util';
export const findFlatEntityPropertyUpdate = <
T extends AllMetadataName,
P extends Extract<
FlatEntityPropertiesToCompare<T>,
keyof MetadataFlatEntity<T>
>,
>({
property,
flatEntityUpdates,
}: {
flatEntityUpdates: FlatEntityPropertiesUpdates<T>;
property: P;
}) =>
flatEntityUpdates.find((update): update is FlatEntityPropertyUpdate<T, P> =>
isPropertyUpdate(update, property),
);
@@ -57,6 +57,53 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
});
const kanbanFieldMetadata = isDefined(
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
)
? findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId:
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
flatEntityMaps:
dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
})
: undefined;
const updatedFlatFieldMetadataMapsWithKanban = isDefined(
kanbanFieldMetadata,
)
? replaceFlatEntityInFlatEntityMapsOrThrow({
flatEntity: {
...kanbanFieldMetadata,
kanbanAggregateOperationViewIds: [
...kanbanFieldMetadata.kanbanAggregateOperationViewIds,
flatViewToValidate.id,
],
},
flatEntityMaps:
dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
})
: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps;
const calendarFieldMetadata = isDefined(
flatViewToValidate.calendarFieldMetadataId,
)
? findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: flatViewToValidate.calendarFieldMetadataId,
flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
})
: undefined;
const updatedFlatFieldMetadataMaps = isDefined(calendarFieldMetadata)
? replaceFlatEntityInFlatEntityMapsOrThrow({
flatEntity: {
...calendarFieldMetadata,
calendarViewIds: [
...calendarFieldMetadata.calendarViewIds,
flatViewToValidate.id,
],
},
flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
})
: updatedFlatFieldMetadataMapsWithKanban;
return {
status: 'success',
action: {
@@ -64,6 +111,7 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
view: flatViewToValidate,
},
dependencyOptimisticFlatEntityMaps: {
flatFieldMetadataMaps: updatedFlatFieldMetadataMaps,
flatObjectMetadataMaps: updatedFlatObjectMetadataMaps,
},
};
@@ -107,6 +155,54 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
})
: dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps;
const kanbanFieldMetadata = isDefined(
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
)
? findFlatEntityByIdInFlatEntityMaps({
flatEntityId:
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
flatEntityMaps:
dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
})
: undefined;
const updatedFlatFieldMetadataMapsWithKanban = isDefined(
kanbanFieldMetadata,
)
? replaceFlatEntityInFlatEntityMapsOrThrow({
flatEntity: {
...kanbanFieldMetadata,
kanbanAggregateOperationViewIds:
kanbanFieldMetadata.kanbanAggregateOperationViewIds.filter(
(id) => id !== flatViewToValidate.id,
),
},
flatEntityMaps:
dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
})
: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps;
const calendarFieldMetadata = isDefined(
flatViewToValidate.calendarFieldMetadataId,
)
? findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatViewToValidate.calendarFieldMetadataId,
flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
})
: undefined;
const updatedFlatFieldMetadataMaps = isDefined(calendarFieldMetadata)
? replaceFlatEntityInFlatEntityMapsOrThrow({
flatEntity: {
...calendarFieldMetadata,
calendarViewIds: calendarFieldMetadata.calendarViewIds.filter(
(id) => id !== flatViewToValidate.id,
),
},
flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
})
: updatedFlatFieldMetadataMapsWithKanban;
return {
status: 'success',
action: {
@@ -114,6 +210,7 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
viewId: flatViewToValidate.id,
},
dependencyOptimisticFlatEntityMaps: {
flatFieldMetadataMaps: updatedFlatFieldMetadataMaps,
flatObjectMetadataMaps: updatedFlatObjectMetadataMaps,
},
};
@@ -15,6 +15,7 @@ import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/
import { validateFlatFieldMetadataNameAvailability } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-flat-field-metadata-name-availability.util';
import { validateFlatFieldMetadataName } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-flat-field-metadata-name.util';
import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util';
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/utils/find-flat-entity-property-update.util';
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type';
@@ -89,6 +90,22 @@ export class FlatFieldMetadataValidatorService {
message: 'Label identifier field metadata id does not exist',
userFriendlyMessage: msg`Object related to updated field does not have a label identifier`,
});
} else if (
flatObjectMetadata.labelIdentifierFieldMetadataId ===
flatFieldMetadataToValidate.id &&
isDefined(
findFlatEntityPropertyUpdate({
flatEntityUpdates: updates,
property: 'isActive',
}),
) &&
flatFieldMetadataToValidate.isActive === false
) {
validationResult.errors.push({
code: FieldMetadataExceptionCode.LABEL_IDENTIFIER_FIELD_METADATA_ID_NOT_FOUND,
message: 'Label identifier field metadata cannot be deactivated',
userFriendlyMessage: msg`Label identifier field cannot be deactivated`,
});
}
if (isMorphOrRelationFlatFieldMetadata(flatFieldMetadataToValidate)) {
@@ -118,6 +118,10 @@ export class FlatViewFieldValidatorService {
public validateFlatViewFieldDeletion({
flatEntityToValidate: { id: viewFieldIdToDelete },
optimisticFlatEntityMaps: optimisticFlatViewFieldMaps,
dependencyOptimisticFlatEntityMaps: {
flatFieldMetadataMaps,
flatObjectMetadataMaps,
},
}: FlatEntityValidationArgs<
typeof ALL_METADATA_NAME.viewField
>): FailedFlatEntityValidation<FlatViewField> {
@@ -138,14 +142,37 @@ export class FlatViewFieldValidatorService {
message: t`View field to delete not found`,
userFriendlyMessage: msg`View field to delete not found`,
});
} else {
if (!isDefined(existingFlatViewField.deletedAt)) {
validationResult.errors.push({
code: ViewExceptionCode.INVALID_VIEW_DATA,
message: t`View field to delete has not been soft deleted`,
userFriendlyMessage: msg`View field to delete has not been soft deleted`,
});
}
return validationResult;
}
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: existingFlatViewField.fieldMetadataId,
flatEntityMaps: flatFieldMetadataMaps,
});
if (!isDefined(flatFieldMetadata)) {
return validationResult;
}
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: flatFieldMetadata.objectMetadataId,
flatEntityMaps: flatObjectMetadataMaps,
});
if (!isDefined(flatObjectMetadata)) {
return validationResult;
}
if (
flatObjectMetadata.labelIdentifierFieldMetadataId ===
existingFlatViewField.fieldMetadataId
) {
validationResult.errors.push({
code: ViewExceptionCode.INVALID_VIEW_DATA,
message: t`Label identifier view field cannot be deleted`,
userFriendlyMessage: msg`Label identifier view field cannot be deleted`,
});
}
return validationResult;
@@ -5,7 +5,6 @@ import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-name.constant';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { isEnumFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-enum-flat-field-metadata.util';
import { type FlatViewFilter } from 'src/engine/metadata-modules/flat-view-filter/types/flat-view-filter.type';
import { ViewFilterExceptionCode } from 'src/engine/metadata-modules/view-filter/exceptions/view-filter.exception';
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
@@ -77,7 +76,6 @@ export class FlatViewFilterValidatorService {
validateFlatViewFilterDeletion({
flatEntityToValidate: flatViewFilterToValidate,
optimisticFlatEntityMaps: optimisticFlatViewFilterMaps,
dependencyOptimisticFlatEntityMaps,
}: FlatEntityValidationArgs<
typeof ALL_METADATA_NAME.viewFilter
>): FailedFlatEntityValidation<FlatViewFilter> {
@@ -104,29 +102,6 @@ export class FlatViewFilterValidatorService {
return validationResult;
}
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: existingViewFilter.fieldMetadataId,
flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
});
if (!isDefined(flatFieldMetadata)) {
return validationResult;
}
const shouldValidateDeletion = isEnumFlatFieldMetadata(flatFieldMetadata)
? flatFieldMetadata.options.some(
(option) => option.value === existingViewFilter.value,
)
: true;
if (shouldValidateDeletion && !isDefined(existingViewFilter.deletedAt)) {
validationResult.errors.push({
code: ViewFilterExceptionCode.INVALID_VIEW_FILTER_DATA,
message: t`View filter has to be soft deleted first`,
userFriendlyMessage: msg`View filter has to be soft deleted first`,
});
}
return validationResult;
}
@@ -5,7 +5,6 @@ import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-name.constant';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { isEnumFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-enum-flat-field-metadata.util';
import { FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type';
import { ViewExceptionCode } from 'src/engine/metadata-modules/view/exceptions/view.exception';
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
@@ -89,7 +88,6 @@ export class FlatViewGroupValidatorService {
public validateFlatViewGroupDeletion({
flatEntityToValidate: { id: viewGroupIdToDelete },
optimisticFlatEntityMaps: optimisticFlatViewGroupMaps,
dependencyOptimisticFlatEntityMaps: { flatFieldMetadataMaps },
}: FlatEntityValidationArgs<
typeof ALL_METADATA_NAME.viewGroup
>): FailedFlatEntityValidation<FlatViewGroup> {
@@ -114,26 +112,6 @@ export class FlatViewGroupValidatorService {
return validationResult;
}
const relatedFlatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: existingFlatViewGroup.fieldMetadataId,
flatEntityMaps: flatFieldMetadataMaps,
});
if (
isDefined(relatedFlatFieldMetadata) &&
isEnumFlatFieldMetadata(relatedFlatFieldMetadata) &&
relatedFlatFieldMetadata.options.some(
(option) => option.value === existingFlatViewGroup.fieldValue,
) &&
!isDefined(existingFlatViewGroup.deletedAt)
) {
validationResult.errors.push({
code: ViewExceptionCode.INVALID_VIEW_DATA,
message: t`View group to delete has not been soft deleted`,
userFriendlyMessage: msg`View group to delete has not been soft deleted`,
});
}
return validationResult;
}
@@ -1,22 +1,23 @@
import { Injectable } from '@nestjs/common';
import { msg, t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
import { ALL_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-name.constant';
import { FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { type ALL_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-name.constant';
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 { ViewExceptionCode } from 'src/engine/metadata-modules/view/exceptions/view.exception';
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type';
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/utils/find-flat-entity-property-update.util';
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
import { type FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type';
@Injectable()
export class FlatViewValidatorService {
constructor() {}
public validateFlatViewUpdate({
flatEntityId,
flatEntityUpdates,
optimisticFlatEntityMaps: optimisticFlatViewMaps,
dependencyOptimisticFlatEntityMaps: { flatFieldMetadataMaps },
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.view
>): FailedFlatEntityValidation<FlatView> {
@@ -38,6 +39,29 @@ export class FlatViewValidatorService {
});
}
const kanbanAggregateOperationFieldMetadataIdUpdate =
findFlatEntityPropertyUpdate({
property: 'kanbanAggregateOperationFieldMetadataId',
flatEntityUpdates,
});
if (
isDefined(kanbanAggregateOperationFieldMetadataIdUpdate) &&
kanbanAggregateOperationFieldMetadataIdUpdate.to !== null &&
!isDefined(
findFlatEntityByIdInFlatEntityMaps({
flatEntityId: kanbanAggregateOperationFieldMetadataIdUpdate.to,
flatEntityMaps: flatFieldMetadataMaps,
}),
)
) {
validationResult.errors.push({
code: ViewExceptionCode.INVALID_VIEW_DATA,
message: t`View kanban aggregate field metadata not found`,
userFriendlyMessage: msg`View kanban aggregate field metadata not found`,
});
}
return validationResult;
}
@@ -63,14 +87,6 @@ export class FlatViewValidatorService {
message: t`View not found`,
userFriendlyMessage: msg`View not found`,
});
} else {
if (!isDefined(existingFlatView.deletedAt)) {
validationResult.errors.push({
code: ViewExceptionCode.INVALID_VIEW_DATA,
message: t`View to delete has not been soft deleted`,
userFriendlyMessage: msg`View to delete has not been soft deleted`,
});
}
}
return validationResult;
@@ -79,7 +95,10 @@ export class FlatViewValidatorService {
public async validateFlatViewCreation({
flatEntityToValidate: flatViewToValidate,
optimisticFlatEntityMaps: optimisticFlatViewMaps,
dependencyOptimisticFlatEntityMaps,
dependencyOptimisticFlatEntityMaps: {
flatFieldMetadataMaps,
flatObjectMetadataMaps,
},
}: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.view>): Promise<
FailedFlatEntityValidation<FlatView>
> {
@@ -92,9 +111,7 @@ export class FlatViewValidatorService {
};
const optimisticFlatObjectMetadata =
dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
flatViewToValidate.objectMetadataId
];
flatObjectMetadataMaps.byId[flatViewToValidate.objectMetadataId];
if (!isDefined(optimisticFlatObjectMetadata)) {
validationResult.errors.push({
@@ -112,6 +129,23 @@ export class FlatViewValidatorService {
});
}
if (
isDefined(flatViewToValidate.kanbanAggregateOperationFieldMetadataId) &&
!isDefined(
findFlatEntityByIdInFlatEntityMaps({
flatEntityId:
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
flatEntityMaps: flatFieldMetadataMaps,
}),
)
) {
validationResult.errors.push({
code: ViewExceptionCode.INVALID_VIEW_DATA,
message: t`View kanban aggregate field metadata not found`,
userFriendlyMessage: msg`View kanban aggregate field metadata not found`,
});
}
return validationResult;
}
}
@@ -26,8 +26,8 @@ import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-meta
import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util';
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
import { isMorphOrRelationFieldMetadataType } from 'src/engine/utils/is-morph-or-relation-field-metadata-type.util';
import { isPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/types/is-property-update.type';
import { PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/types/property-update.type';
import { isPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/utils/is-property-update.util';
import { type UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/types/workspace-migration-field-action-v2';
import { serializeDefaultValueV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/utils/serialize-default-value-v2.util';
import {
@@ -17,7 +17,7 @@ import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-meta
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
import { isPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/types/is-property-update.type';
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/utils/find-flat-entity-property-update.util';
import { type UpdateObjectAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/types/workspace-migration-object-action-v2';
import { type WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type';
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
@@ -105,9 +105,10 @@ export class UpdateObjectActionHandlerService extends WorkspaceMigrationRunnerAc
flatObjectMetadata: flatObjectMetadata,
});
const nameSingularUpdate = updates.find((update) =>
isPropertyUpdate(update, 'nameSingular'),
);
const nameSingularUpdate = findFlatEntityPropertyUpdate({
flatEntityUpdates: updates,
property: 'nameSingular',
});
if (isDefined(nameSingularUpdate)) {
const updatedObjectMetadata: FlatObjectMetadata = {