Refactor workspace migration update action (#17701)
# Introduction
Removing:
- `from` property from actions definition, as it's a legitimate source
of truth. The stored comparison might have been compromised since action
generation. If from is needed it should be computed from the optimistic
cache at runner lvl
- Removed the `FlatEntityPropertyUpdates` Array complexity in favor of
From
```ts
export type PropertyUpdate<T, P extends keyof T> = {
property: P;
} & FromTo<T[P]>;
```
To
```ts
export type FlatEntityUpdate<T extends AllMetadataName> = Partial<
Pick<
MetadataFlatEntity<T>,
Extract<FlatEntityPropertiesToCompare<T>, keyof MetadataFlatEntity<T>>
>
>;
```
## New interactions
From
```ts
const positionUpdate = findFlatEntityPropertyUpdate({
flatEntityUpdates,
property: 'position',
});
if (
isDefined(positionUpdate) &&
(!Number.isInteger(positionUpdate.to) || positionUpdate.to < 0)
) {
const toFlatNavigationMenuItem = {
...fromFlatNavigationMenuItem,
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
updates: flatEntityUpdates,
}),
};
```
To
```ts
const positionUpdate = flatEntityUpdate.position;
if (
isDefined(positionUpdate) &&
(!Number.isInteger(positionUpdate) || positionUpdate < 0)
) {
const toFlatNavigationMenuItem = {
...fromFlatNavigationMenuItem,
...flatEntityUpdate,
};
```
## `SanitizeFlatEntityUpdate`
Enforcing the `flatEntityUpdate` to only contains comparable properties
per flat entity by striping out all unexpected keys
In the future we will also move the whole validation at runner lvl at
some point
```ts
export const sanitizeFlatEntityUpdate = <T extends AllMetadataName>({
flatEntityUpdate,
metadataName,
}: {
flatEntityUpdate: FlatEntityUpdate<T>;
metadataName: T;
}): FlatEntityUpdate<T> => {
const { propertiesToCompare } =
ALL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY[metadataName];
const initialAccumulator: FlatEntityUpdate<T> = {};
return propertiesToCompare.reduce((accumulator, property) => {
const updatedValue =
flatEntityUpdate[property as MetadataFlatEntityComparableProperties<T>];
if (updatedValue === undefined) {
return accumulator;
}
return {
...accumulator,
[property]: updatedValue,
};
}, initialAccumulator);
};
```
This commit is contained in:
@@ -913,7 +913,7 @@ export class WorkspaceMigrationMyEntityActionsBuilderService extends WorkspaceEn
|
||||
type: 'update',
|
||||
metadataName: 'myEntity',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdates,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+6
-5
@@ -1,10 +1,11 @@
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
import { type FlatEntityPropertiesToCompare } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-compare.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';
|
||||
|
||||
export type FlatEntityPropertiesUpdates<
|
||||
T extends AllMetadataName,
|
||||
K extends FlatEntityPropertiesToCompare<T> = FlatEntityPropertiesToCompare<T>,
|
||||
> = Array<FlatEntityPropertyUpdate<T, Extract<K, keyof MetadataFlatEntity<T>>>>;
|
||||
export type MetadataFlatEntityComparableProperties<T extends AllMetadataName> =
|
||||
Extract<FlatEntityPropertiesToCompare<T>, keyof MetadataFlatEntity<T>>;
|
||||
|
||||
export type FlatEntityUpdate<T extends AllMetadataName> = Partial<
|
||||
Pick<MetadataFlatEntity<T>, MetadataFlatEntityComparableProperties<T>>
|
||||
>;
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
import { type FlatEntityPropertiesToCompare } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-compare.type';
|
||||
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
|
||||
import { type PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/types/property-update.type';
|
||||
|
||||
export type FlatEntityPropertyUpdate<
|
||||
T extends AllMetadataName,
|
||||
K extends FlatEntityPropertiesToCompare<T> = FlatEntityPropertiesToCompare<T>,
|
||||
> = PropertyUpdate<
|
||||
MetadataFlatEntity<T>,
|
||||
Extract<K, keyof MetadataFlatEntity<T>>
|
||||
>;
|
||||
+4
-12
@@ -1,21 +1,13 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`compareTwoFlatEntity It should detect flat field metadata isActive diff from true to false 1`] = `
|
||||
[
|
||||
{
|
||||
"from": true,
|
||||
"property": "isActive",
|
||||
"to": false,
|
||||
},
|
||||
]
|
||||
"isActive": false,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`compareTwoFlatEntity It should detect flat field metadata isActive diff from true to false 2`] = `
|
||||
[
|
||||
{
|
||||
"from": false,
|
||||
"property": "isActive",
|
||||
"to": true,
|
||||
},
|
||||
]
|
||||
"isActive": true,
|
||||
}
|
||||
`;
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ describe('compareTwoFlatEntity', () => {
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot(
|
||||
extractRecordIdsAndDatesAsExpectAny(result),
|
||||
extractRecordIdsAndDatesAsExpectAny({ ...result }),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
+17
-15
@@ -1,10 +1,10 @@
|
||||
import diff from 'microdiff';
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
import { type FromTo } from 'twenty-shared/types';
|
||||
import { parseJson } from 'twenty-shared/utils';
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
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 FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
|
||||
import { transformFlatEntityForComparison } from 'src/engine/metadata-modules/flat-entity/utils/transform-flat-entity-for-comparison.util';
|
||||
|
||||
@@ -23,7 +23,7 @@ export const compareTwoFlatEntity = <
|
||||
}: FromTo<MetadataFlatEntity<T>, 'flatEntity'> & {
|
||||
propertiesToCompare: readonly PToCompare[];
|
||||
propertiesToStringify: readonly PJsonB[];
|
||||
}): FlatEntityPropertiesUpdates<T> => {
|
||||
}): FlatEntityUpdate<T> | undefined => {
|
||||
const [transformedFromFlatEntity, transformedToFlatEntity] = [
|
||||
fromFlatEntity,
|
||||
toFlatEntity,
|
||||
@@ -40,11 +40,16 @@ export const compareTwoFlatEntity = <
|
||||
transformedToFlatEntity,
|
||||
);
|
||||
|
||||
return flatEntityDifferences.flatMap<FlatEntityPropertiesUpdates<T>[number]>(
|
||||
(difference) => {
|
||||
if (flatEntityDifferences.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const initialAccumulator: FlatEntityUpdate<T> = {};
|
||||
|
||||
return flatEntityDifferences.reduce((accumulator, difference) => {
|
||||
switch (difference.type) {
|
||||
case 'CHANGE': {
|
||||
const { oldValue, path, value } = difference;
|
||||
const { path, value } = difference;
|
||||
const property = path[0] as PToCompare;
|
||||
const isJsonb = propertiesToStringify.includes(
|
||||
property as unknown as PJsonB,
|
||||
@@ -52,25 +57,22 @@ export const compareTwoFlatEntity = <
|
||||
|
||||
if (isJsonb) {
|
||||
return {
|
||||
from: parseJson(oldValue),
|
||||
to: parseJson(value),
|
||||
property,
|
||||
...accumulator,
|
||||
[property]: parseJson(value),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
from: oldValue,
|
||||
to: value,
|
||||
property,
|
||||
...accumulator,
|
||||
[property]: value,
|
||||
};
|
||||
}
|
||||
case 'CREATE':
|
||||
case 'REMOVE':
|
||||
default: {
|
||||
// Should never occur, we should only provide null never undefined and so on
|
||||
return [];
|
||||
return accumulator;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}, initialAccumulator);
|
||||
};
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@ import { isDefined } from 'class-validator';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type FlatFieldMetadataTypeValidator } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-type-validator.type';
|
||||
import { FlatFieldMetadataValidationError } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-validation-error.type';
|
||||
import { validateEnumSelectFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-enum-flat-field-metadata.util';
|
||||
@@ -18,7 +18,7 @@ const DEFAULT_NO_VALIDATION = (): FlatFieldMetadataValidationError[] => [];
|
||||
|
||||
export type GenericValidateFlatFieldMetadataTypeSpecificitiesArgs =
|
||||
FlatEntityValidationArgs<'fieldMetadata'> & {
|
||||
updates?: FlatEntityPropertiesUpdates<'fieldMetadata'>;
|
||||
update?: FlatEntityUpdate<'fieldMetadata'>;
|
||||
};
|
||||
|
||||
const rejectUserCreation = (
|
||||
@@ -29,7 +29,7 @@ const rejectUserCreation = (
|
||||
return (
|
||||
args: GenericValidateFlatFieldMetadataTypeSpecificitiesArgs,
|
||||
): FlatFieldMetadataValidationError[] => {
|
||||
const isCreation = !isDefined(args.updates);
|
||||
const isCreation = !isDefined(args.update);
|
||||
const isCustomField = args.flatEntityToValidate.isCustom;
|
||||
|
||||
if (isCreation && isCustomField) {
|
||||
|
||||
+4
-11
@@ -11,7 +11,6 @@ import {
|
||||
type FlatViewGroupsToDeleteUpdateAndCreate,
|
||||
recomputeViewGroupsOnFlatFieldMetadataOptionsUpdate,
|
||||
} from 'src/engine/metadata-modules/flat-field-metadata/utils/recompute-view-groups-on-flat-field-metadata-options-update.util';
|
||||
import { type PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/types/property-update.type';
|
||||
|
||||
type HandleEnumFlatFieldMetadataOptionsUpdateSideEffectsArgs = FromTo<
|
||||
FlatFieldMetadata<EnumFieldMetadataType>,
|
||||
@@ -49,20 +48,14 @@ export const handleEnumFlatFieldMetadataUpdateSideEffects = ({
|
||||
JSON.stringify(fromFlatFieldMetadata.options) !==
|
||||
JSON.stringify(toFlatFieldMetadata.options)
|
||||
) {
|
||||
const optionsPropertyUpdate: PropertyUpdate<
|
||||
FlatFieldMetadata<EnumFieldMetadataType>,
|
||||
'options'
|
||||
> = {
|
||||
from: fromFlatFieldMetadata.options,
|
||||
property: 'options',
|
||||
to: toFlatFieldMetadata.options,
|
||||
};
|
||||
const optionsPropertyUpdate =
|
||||
toFlatFieldMetadata.options as FlatFieldMetadata<EnumFieldMetadataType>['options'];
|
||||
|
||||
const { flatViewFiltersToDelete, flatViewFiltersToUpdate } =
|
||||
recomputeViewFiltersOnFlatFieldMetadataOptionsUpdate({
|
||||
flatViewFilterMaps,
|
||||
fromFlatFieldMetadata,
|
||||
update: optionsPropertyUpdate,
|
||||
toOptions: optionsPropertyUpdate,
|
||||
});
|
||||
|
||||
sideEffectResult.flatViewFiltersToDelete.push(...flatViewFiltersToDelete);
|
||||
@@ -76,7 +69,7 @@ export const handleEnumFlatFieldMetadataUpdateSideEffects = ({
|
||||
flatViewMaps,
|
||||
flatViewGroupMaps,
|
||||
fromFlatFieldMetadata,
|
||||
update: optionsPropertyUpdate,
|
||||
toOptions: optionsPropertyUpdate,
|
||||
});
|
||||
|
||||
sideEffectResult.flatViewGroupsToCreate.push(...flatViewGroupsToCreate);
|
||||
|
||||
+3
-4
@@ -11,11 +11,10 @@ import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metada
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { compareTwoFlatFieldMetadataEnumOptions } from 'src/engine/metadata-modules/flat-field-metadata/utils/compare-two-flat-field-metadata-enum-options.util';
|
||||
import { type FlatViewFilter } from 'src/engine/metadata-modules/flat-view-filter/types/flat-view-filter.type';
|
||||
import { type PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/types/property-update.type';
|
||||
|
||||
type RecomputeViewFiltersOnFlatFieldMetadataOptionsUpdateArgs = {
|
||||
fromFlatFieldMetadata: FlatFieldMetadata<EnumFieldMetadataType>;
|
||||
update: PropertyUpdate<FlatFieldMetadata<EnumFieldMetadataType>, 'options'>;
|
||||
toOptions: FlatFieldMetadata<EnumFieldMetadataType>['options'];
|
||||
} & Pick<AllFlatEntityMaps, 'flatViewFilterMaps'>;
|
||||
|
||||
export type FlatViewFiltersToDeleteAndUpdate = {
|
||||
@@ -25,7 +24,7 @@ export type FlatViewFiltersToDeleteAndUpdate = {
|
||||
export const recomputeViewFiltersOnFlatFieldMetadataOptionsUpdate = ({
|
||||
flatViewFilterMaps,
|
||||
fromFlatFieldMetadata,
|
||||
update,
|
||||
toOptions,
|
||||
}: RecomputeViewFiltersOnFlatFieldMetadataOptionsUpdateArgs): FlatViewFiltersToDeleteAndUpdate => {
|
||||
const flatViewFiltersToCreateAndUpdate: FlatViewFiltersToDeleteAndUpdate = {
|
||||
flatViewFiltersToDelete: [],
|
||||
@@ -38,7 +37,7 @@ export const recomputeViewFiltersOnFlatFieldMetadataOptionsUpdate = ({
|
||||
} = compareTwoFlatFieldMetadataEnumOptions({
|
||||
compareLabel: false,
|
||||
fromOptions: fromFlatFieldMetadata.options,
|
||||
toOptions: update.to,
|
||||
toOptions,
|
||||
});
|
||||
|
||||
if (
|
||||
|
||||
+3
-4
@@ -13,11 +13,10 @@ import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-m
|
||||
import { compareTwoFlatFieldMetadataEnumOptions } from 'src/engine/metadata-modules/flat-field-metadata/utils/compare-two-flat-field-metadata-enum-options.util';
|
||||
import { type FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type';
|
||||
import { reduceFlatViewGroupsByViewId } from 'src/engine/metadata-modules/flat-view-group/utils/reduce-flat-view-groups-by-view-id.util';
|
||||
import { type PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/types/property-update.type';
|
||||
|
||||
type RecomputeViewGroupsOnFlatFieldMetadataOptionsUpdateArgs = {
|
||||
fromFlatFieldMetadata: FlatFieldMetadata<EnumFieldMetadataType>;
|
||||
update: PropertyUpdate<FlatFieldMetadata<EnumFieldMetadataType>, 'options'>;
|
||||
toOptions: FlatFieldMetadata<EnumFieldMetadataType>['options'];
|
||||
} & Pick<AllFlatEntityMaps, 'flatViewMaps' | 'flatViewGroupMaps'>;
|
||||
|
||||
export type FlatViewGroupsToDeleteUpdateAndCreate = {
|
||||
@@ -29,7 +28,7 @@ export const recomputeViewGroupsOnFlatFieldMetadataOptionsUpdate = ({
|
||||
flatViewMaps,
|
||||
flatViewGroupMaps,
|
||||
fromFlatFieldMetadata,
|
||||
update,
|
||||
toOptions,
|
||||
}: RecomputeViewGroupsOnFlatFieldMetadataOptionsUpdateArgs): FlatViewGroupsToDeleteUpdateAndCreate => {
|
||||
const {
|
||||
deleted: deletedFieldMetadataOptions,
|
||||
@@ -38,7 +37,7 @@ export const recomputeViewGroupsOnFlatFieldMetadataOptionsUpdate = ({
|
||||
} = compareTwoFlatFieldMetadataEnumOptions({
|
||||
compareLabel: false,
|
||||
fromOptions: fromFlatFieldMetadata.options,
|
||||
toOptions: update.to,
|
||||
toOptions,
|
||||
});
|
||||
|
||||
const flatViewsAffected = findManyFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
|
||||
+35
-21
@@ -3,7 +3,7 @@ import { isDefined, isValidUuid } from 'twenty-shared/utils';
|
||||
|
||||
import { FieldMetadataExceptionCode } 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 FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { type FlatFieldMetadataTypeValidationArgs } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-type-validator.type';
|
||||
import { type FlatFieldMetadataValidationError } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-validation-error.type';
|
||||
@@ -12,14 +12,12 @@ import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/
|
||||
import { validateJunctionTargetSettings } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-junction-target-settings.util';
|
||||
import { validateMorphOrRelationFlatFieldJoinColumName } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-or-relation-flat-field-join-column-name.util';
|
||||
import { validateMorphOrRelationFlatFieldOnDelete } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-or-relation-flat-field-on-delete.util';
|
||||
import { type PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/types/property-update.type';
|
||||
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/find-flat-entity-property-update.util';
|
||||
|
||||
type ValidateMorphOrRelationFlatFieldMetadataUpdatesArgs = Omit<
|
||||
FlatFieldMetadataTypeValidationArgs<MorphOrRelationFieldMetadataType>,
|
||||
'updates'
|
||||
> & {
|
||||
updates: FlatEntityPropertiesUpdates<'fieldMetadata'>;
|
||||
update: FlatEntityUpdate<'fieldMetadata'>;
|
||||
};
|
||||
|
||||
export const validateMorphOrRelationFlatFieldMetadataUpdates = ({
|
||||
@@ -28,28 +26,44 @@ export const validateMorphOrRelationFlatFieldMetadataUpdates = ({
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadataMaps,
|
||||
},
|
||||
updates,
|
||||
update,
|
||||
buildOptions,
|
||||
}: ValidateMorphOrRelationFlatFieldMetadataUpdatesArgs): FlatFieldMetadataValidationError[] => {
|
||||
const errors: FlatFieldMetadataValidationError[] = [];
|
||||
|
||||
const settingsUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates: updates,
|
||||
property: 'settings',
|
||||
}) as
|
||||
| PropertyUpdate<
|
||||
FlatFieldMetadata<MorphOrRelationFieldMetadataType>,
|
||||
'settings'
|
||||
>
|
||||
| undefined;
|
||||
const fromFlatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: flatFieldMetadataToValidate.id,
|
||||
flatEntityMaps: flatFieldMetadataMaps,
|
||||
});
|
||||
|
||||
const toSettings = settingsUpdate?.to;
|
||||
const fromSettings = settingsUpdate?.from;
|
||||
if (!isDefined(fromFlatFieldMetadata)) {
|
||||
return [
|
||||
{
|
||||
code: FieldMetadataExceptionCode.FIELD_METADATA_NOT_FOUND,
|
||||
message: 'Could not found updated field metadata',
|
||||
userFriendlyMessage: msg`Could not found updated field metadata`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
if (!isMorphOrRelationFlatFieldMetadata(fromFlatFieldMetadata)) {
|
||||
return [
|
||||
{
|
||||
code: FieldMetadataExceptionCode.FIELD_METADATA_NOT_FOUND,
|
||||
message: 'Udpated field is not a morph relation or a relation',
|
||||
userFriendlyMessage: msg`Udpated field is not a morph relation or a relation`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const toSettings = update.settings as
|
||||
| FlatFieldMetadata<MorphOrRelationFieldMetadataType>['settings']
|
||||
| undefined;
|
||||
const fromSettings = fromFlatFieldMetadata.settings;
|
||||
|
||||
const isJoinColumnNameUpdated =
|
||||
isDefined(settingsUpdate) &&
|
||||
isDefined(toSettings?.joinColumnName) &&
|
||||
isDefined(fromSettings?.joinColumnName) &&
|
||||
isDefined(fromSettings.joinColumnName) &&
|
||||
toSettings.joinColumnName !== fromSettings.joinColumnName;
|
||||
|
||||
if (isJoinColumnNameUpdated) {
|
||||
@@ -80,7 +94,7 @@ export const validateMorphOrRelationFlatFieldMetadata = ({
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadataMaps,
|
||||
},
|
||||
updates,
|
||||
update,
|
||||
remainingFlatEntityMapsToValidate,
|
||||
buildOptions,
|
||||
workspaceId,
|
||||
@@ -192,7 +206,7 @@ export const validateMorphOrRelationFlatFieldMetadata = ({
|
||||
}
|
||||
|
||||
// TODO prastoin refactor FlatFieldMetadataTypeValidator to implement two code flow: create and update https://github.com/twentyhq/core-team-issues/issues/2044
|
||||
if (isDefined(updates)) {
|
||||
if (isDefined(update)) {
|
||||
errors.push(
|
||||
...validateMorphOrRelationFlatFieldMetadataUpdates({
|
||||
flatEntityToValidate: flatFieldMetadataToValidate,
|
||||
@@ -202,7 +216,7 @@ export const validateMorphOrRelationFlatFieldMetadata = ({
|
||||
},
|
||||
remainingFlatEntityMapsToValidate,
|
||||
workspaceId,
|
||||
updates,
|
||||
update,
|
||||
buildOptions,
|
||||
additionalCacheDataMaps,
|
||||
}),
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import {
|
||||
type FlatPageLayoutWidgetTypeValidatorForCreation,
|
||||
type FlatPageLayoutWidgetTypeValidatorForUpdate,
|
||||
@@ -24,7 +24,7 @@ import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace
|
||||
|
||||
export type GenericValidateFlatPageLayoutWidgetTypeSpecificitiesArgs =
|
||||
FlatEntityValidationArgs<'pageLayoutWidget'> & {
|
||||
updates?: FlatEntityPropertiesUpdates<'pageLayoutWidget'>;
|
||||
update?: FlatEntityUpdate<'pageLayoutWidget'>;
|
||||
};
|
||||
|
||||
export type ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs =
|
||||
@@ -32,7 +32,7 @@ export type ValidateFlatPageLayoutWidgetTypeSpecificitiesForCreationArgs =
|
||||
|
||||
export type ValidateFlatPageLayoutWidgetTypeSpecificitiesForUpdateArgs =
|
||||
FlatEntityValidationArgs<'pageLayoutWidget'> & {
|
||||
updates: FlatEntityPropertiesUpdates<'pageLayoutWidget'>;
|
||||
update: FlatEntityUpdate<'pageLayoutWidget'>;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import { type FromTo } from 'twenty-shared/types';
|
||||
|
||||
export type PropertyUpdate<T, P extends keyof T> = {
|
||||
property: P;
|
||||
} & FromTo<T[P]>;
|
||||
+5
-13
@@ -1,4 +1,4 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a created entity 1`] = `
|
||||
{
|
||||
@@ -152,13 +152,9 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect an upd
|
||||
"byUniversalIdentifier": {
|
||||
"universal-identifier-1": {
|
||||
"id": "field-id-1",
|
||||
"updates": [
|
||||
{
|
||||
"from": false,
|
||||
"property": "isActive",
|
||||
"to": true,
|
||||
"update": {
|
||||
"isActive": true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -281,13 +277,9 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create
|
||||
"byUniversalIdentifier": {
|
||||
"universal-identifier-1": {
|
||||
"id": "field-id-1",
|
||||
"updates": [
|
||||
{
|
||||
"from": true,
|
||||
"property": "isActive",
|
||||
"to": false,
|
||||
"update": {
|
||||
"isActive": false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
+6
-18
@@ -21,37 +21,25 @@ describe('aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldA
|
||||
type: 'update',
|
||||
metadataName: 'fieldMetadata',
|
||||
universalIdentifier: 'search-vector-field-1',
|
||||
updates: [
|
||||
{
|
||||
property: 'label',
|
||||
from: 'Search Vector',
|
||||
to: 'Updated Search Vector',
|
||||
update: {
|
||||
label: 'Updated Search Vector',
|
||||
},
|
||||
],
|
||||
} satisfies UniversalUpdateFieldAction,
|
||||
{
|
||||
type: 'update',
|
||||
metadataName: 'fieldMetadata',
|
||||
universalIdentifier: 'regular-field-1',
|
||||
updates: [
|
||||
{
|
||||
property: 'label',
|
||||
from: 'First Name',
|
||||
to: 'Updated First Name',
|
||||
update: {
|
||||
label: 'Updated First Name',
|
||||
},
|
||||
],
|
||||
} satisfies UniversalUpdateFieldAction,
|
||||
{
|
||||
type: 'update',
|
||||
metadataName: 'fieldMetadata',
|
||||
universalIdentifier: 'regular-field-2',
|
||||
updates: [
|
||||
{
|
||||
property: 'label',
|
||||
from: 'Last Name',
|
||||
to: 'Updated Last Name',
|
||||
update: {
|
||||
label: 'Updated Last Name',
|
||||
},
|
||||
],
|
||||
} satisfies UniversalUpdateFieldAction,
|
||||
],
|
||||
delete: [],
|
||||
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
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/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),
|
||||
);
|
||||
+5
-5
@@ -6,7 +6,7 @@ import { ALL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY } from 'src/engine/
|
||||
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
|
||||
import { type FlatEntityPropertiesToCompare } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-compare.type';
|
||||
import { type FlatEntityPropertiesToStringify } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-stringify.type';
|
||||
import { type FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
|
||||
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
|
||||
import { compareTwoFlatEntity } from 'src/engine/metadata-modules/flat-entity/utils/compare-two-flat-entity.util';
|
||||
@@ -21,7 +21,7 @@ export type DeletedCreatedUpdatedMatrix<T extends AllMetadataName> = {
|
||||
byUniversalIdentifier: Record<
|
||||
string,
|
||||
{
|
||||
updates: FlatEntityPropertiesUpdates<T>;
|
||||
update: FlatEntityUpdate<T>;
|
||||
// TMP remove when maps is universal based
|
||||
id: string;
|
||||
}
|
||||
@@ -88,7 +88,7 @@ export const flatEntityDeletedCreatedUpdatedMatrixDispatcher = <
|
||||
if (!isDefined(toFlatEntity)) {
|
||||
continue;
|
||||
}
|
||||
const updates = compareTwoFlatEntity({
|
||||
const update = compareTwoFlatEntity({
|
||||
fromFlatEntity,
|
||||
toFlatEntity,
|
||||
propertiesToCompare: propertiesToCompare as unknown as Extract<
|
||||
@@ -101,7 +101,7 @@ export const flatEntityDeletedCreatedUpdatedMatrixDispatcher = <
|
||||
>[],
|
||||
});
|
||||
|
||||
if (updates.length === 0) {
|
||||
if (!isDefined(update)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ export const flatEntityDeletedCreatedUpdatedMatrixDispatcher = <
|
||||
fromFlatEntity.universalIdentifier
|
||||
] = {
|
||||
id: toFlatEntity.id,
|
||||
updates,
|
||||
update,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
import { type PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/types/property-update.type';
|
||||
|
||||
export const isPropertyUpdate = <T, P extends keyof T>(
|
||||
update: PropertyUpdate<T, keyof T>,
|
||||
property: P,
|
||||
): update is PropertyUpdate<T, P> => {
|
||||
return update.property === property;
|
||||
};
|
||||
+2
-2
@@ -82,13 +82,13 @@ export class WorkspaceMigrationAgentActionsBuilderService extends WorkspaceEntit
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateAgentAction: FlatUpdateAgentAction = {
|
||||
type: 'update',
|
||||
metadataName: 'agent',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -99,13 +99,13 @@ export class WorkspaceMigrationCommandMenuItemActionsBuilderService extends Work
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateCommandMenuItemAction: FlatUpdateCommandMenuItemAction = {
|
||||
type: 'update',
|
||||
metadataName: 'commandMenuItem',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -101,13 +101,13 @@ export class WorkspaceMigrationFieldActionsBuilderService extends WorkspaceEntit
|
||||
};
|
||||
}
|
||||
|
||||
const { universalIdentifier, flatEntityUpdates } = args;
|
||||
const { universalIdentifier, flatEntityUpdate } = args;
|
||||
|
||||
const updateFieldAction: UniversalUpdateFieldAction = {
|
||||
type: 'update',
|
||||
metadataName: 'fieldMetadata',
|
||||
universalIdentifier,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -99,13 +99,13 @@ export class WorkspaceMigrationFrontComponentActionsBuilderService extends Works
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateFrontComponentAction: FlatUpdateFrontComponentAction = {
|
||||
type: 'update',
|
||||
metadataName: 'frontComponent',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+4
-4
@@ -1,6 +1,7 @@
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
|
||||
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
|
||||
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
|
||||
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
|
||||
|
||||
export type FlatCreateIndexAction =
|
||||
@@ -12,9 +13,8 @@ export type UniversalDeleteIndexAction =
|
||||
export type FlatDeleteIndexAction =
|
||||
BaseFlatDeleteWorkspaceMigrationAction<'index'>;
|
||||
|
||||
export type FlatUpdateIndexAction = {
|
||||
type: 'update';
|
||||
metadataName: 'index';
|
||||
entityId: string;
|
||||
export type FlatUpdateIndexAction =
|
||||
BaseFlatUpdateWorkspaceMigrationAction<'index'> & {
|
||||
// TODO document
|
||||
updatedFlatEntity: FlatIndexMetadata;
|
||||
};
|
||||
|
||||
+7
-6
@@ -7,13 +7,13 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
|
||||
import { FlatEntityMapsExceptionCode } from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util';
|
||||
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
|
||||
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
|
||||
import { FlatIndexValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-index-metadata-validator.service';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationIndexActionsBuilderService extends WorkspaceEntityMigrationBuilderService<
|
||||
@@ -78,7 +78,7 @@ export class WorkspaceMigrationIndexActionsBuilderService extends WorkspaceEntit
|
||||
protected validateFlatEntityUpdate({
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
buildOptions,
|
||||
workspaceId,
|
||||
additionalCacheDataMaps,
|
||||
@@ -128,11 +128,9 @@ export class WorkspaceMigrationIndexActionsBuilderService extends WorkspaceEntit
|
||||
};
|
||||
}
|
||||
|
||||
const updatedFlatIndex = {
|
||||
const updatedFlatIndex: FlatIndexMetadata = {
|
||||
...flatEntity,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
const tempOptimisticFlatIndexMaps = structuredClone(
|
||||
@@ -174,7 +172,10 @@ export class WorkspaceMigrationIndexActionsBuilderService extends WorkspaceEntit
|
||||
type: 'update',
|
||||
metadataName: 'index',
|
||||
entityId: flatEntity.id,
|
||||
// Note: Index update action ignores the native update field
|
||||
// As under the hood it result as a drop and create
|
||||
updatedFlatEntity: updatedFlatIndex,
|
||||
update: {},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
+2
-2
@@ -139,13 +139,13 @@ export class WorkspaceMigrationLogicFunctionActionsBuilderService extends Worksp
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateLogicFunctionAction: FlatUpdateLogicFunctionAction = {
|
||||
type: 'update',
|
||||
metadataName: 'logicFunction',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -100,13 +100,13 @@ export class WorkspaceMigrationNavigationMenuItemActionsBuilderService extends W
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateNavigationMenuItemAction: FlatUpdateNavigationMenuItemAction = {
|
||||
type: 'update',
|
||||
metadataName: 'navigationMenuItem',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -95,13 +95,13 @@ export class WorkspaceMigrationObjectActionsBuilderService extends WorkspaceEnti
|
||||
};
|
||||
}
|
||||
|
||||
const { universalIdentifier, flatEntityUpdates } = args;
|
||||
const { universalIdentifier, flatEntityUpdate } = args;
|
||||
|
||||
const updateObjectAction: UniversalUpdateObjectAction = {
|
||||
type: 'update',
|
||||
metadataName: 'objectMetadata',
|
||||
universalIdentifier,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -99,13 +99,13 @@ export class WorkspaceMigrationPageLayoutTabActionsBuilderService extends Worksp
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updatePageLayoutTabAction: FlatUpdatePageLayoutTabAction = {
|
||||
type: 'update',
|
||||
metadataName: 'pageLayoutTab',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -101,13 +101,13 @@ export class WorkspaceMigrationPageLayoutWidgetActionsBuilderService extends Wor
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updatePageLayoutWidgetAction: FlatUpdatePageLayoutWidgetAction = {
|
||||
type: 'update',
|
||||
metadataName: 'pageLayoutWidget',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -95,13 +95,13 @@ export class WorkspaceMigrationPageLayoutActionsBuilderService extends Workspace
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updatePageLayoutAction: FlatUpdatePageLayoutAction = {
|
||||
type: 'update',
|
||||
metadataName: 'pageLayout',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -91,13 +91,13 @@ export class WorkspaceMigrationRoleTargetActionsBuilderService extends Workspace
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateRoleTargetAction: FlatUpdateRoleTargetAction = {
|
||||
type: 'update',
|
||||
metadataName: 'roleTarget',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -82,13 +82,13 @@ export class WorkspaceMigrationRoleActionsBuilderService extends WorkspaceEntity
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateRoleAction: FlatUpdateRoleAction = {
|
||||
type: 'update',
|
||||
metadataName: 'role',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -109,13 +109,13 @@ export class WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderSer
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateAction: FlatUpdateRowLevelPermissionPredicateGroupAction = {
|
||||
type: 'update',
|
||||
metadataName: 'rowLevelPermissionPredicateGroup',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -109,13 +109,13 @@ export class WorkspaceMigrationRowLevelPermissionPredicateActionsBuilderService
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateAction: FlatUpdateRowLevelPermissionPredicateAction = {
|
||||
type: 'update',
|
||||
metadataName: 'rowLevelPermissionPredicate',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -82,13 +82,13 @@ export class WorkspaceMigrationSkillActionsBuilderService extends WorkspaceEntit
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateSkillAction: FlatUpdateSkillAction = {
|
||||
type: 'update',
|
||||
metadataName: 'skill',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -89,13 +89,13 @@ export class WorkspaceMigrationViewFieldActionsBuilderService extends WorkspaceE
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateViewFieldAction: FlatUpdateViewFieldAction = {
|
||||
type: 'update',
|
||||
metadataName: 'viewField',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -99,13 +99,13 @@ export class WorkspaceMigrationViewFilterGroupActionsBuilderService extends Work
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateViewFilterGroupAction: FlatUpdateViewFilterGroupAction = {
|
||||
type: 'update',
|
||||
metadataName: 'viewFilterGroup',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -91,13 +91,13 @@ export class WorkspaceMigrationViewFilterActionsBuilderService extends Workspace
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateViewFilterAction: FlatUpdateViewFilterAction = {
|
||||
type: 'update',
|
||||
metadataName: 'viewFilter',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -91,13 +91,13 @@ export class WorkspaceMigrationViewGroupActionsBuilderService extends WorkspaceE
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateViewGroupAction: FlatUpdateViewGroupAction = {
|
||||
type: 'update',
|
||||
metadataName: 'viewGroup',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -82,13 +82,13 @@ export class WorkspaceMigrationViewActionsBuilderService extends WorkspaceEntity
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateViewAction: FlatUpdateViewAction = {
|
||||
type: 'update',
|
||||
metadataName: 'view',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+2
-2
@@ -91,13 +91,13 @@ export class WorkspaceMigrationWebhookActionsBuilderService extends WorkspaceEnt
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityId, flatEntityUpdates } = args;
|
||||
const { flatEntityId, flatEntityUpdate } = args;
|
||||
|
||||
const updateWebhookAction: FlatUpdateWebhookAction = {
|
||||
type: 'update',
|
||||
metadataName: 'webhook',
|
||||
entityId: flatEntityId,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+4
-6
@@ -11,6 +11,7 @@ import {
|
||||
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
|
||||
import { MetadataFlatEntityAndRelatedFlatEntityMapsForValidation } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-and-related-flat-entity-maps-for-validation.type';
|
||||
import { MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity-maps.type';
|
||||
import { MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
|
||||
import { MetadataValidationRelatedFlatEntityMaps } 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 { deleteFlatEntityFromFlatEntityAndRelatedEntityMapsThroughMutationOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-and-related-entity-maps-through-mutation-or-throw.util';
|
||||
@@ -29,7 +30,6 @@ import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace
|
||||
import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type';
|
||||
import { SuccessfulFlatEntityValidateAndBuild } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/successful-flat-entity-validate-and-build.type';
|
||||
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
export type ValidateAndBuildArgs<T extends AllMetadataName> = {
|
||||
buildOptions: WorkspaceMigrationBuilderOptions;
|
||||
@@ -237,7 +237,7 @@ export abstract class WorkspaceEntityMigrationBuilderService<
|
||||
}
|
||||
|
||||
const validationResult = await this.validateFlatEntityUpdate({
|
||||
flatEntityUpdates: flatEntityToUpdate.updates,
|
||||
flatEntityUpdate: flatEntityToUpdate.update,
|
||||
flatEntityId: flatEntityToUpdate.id,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
|
||||
workspaceId,
|
||||
@@ -265,11 +265,9 @@ export abstract class WorkspaceEntityMigrationBuilderService<
|
||||
);
|
||||
}
|
||||
|
||||
const updatedFlatEntity = {
|
||||
const updatedFlatEntity: MetadataFlatEntity<T> = {
|
||||
...existingFlatEntity,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityToUpdate.updates,
|
||||
}),
|
||||
...flatEntityToUpdate.update,
|
||||
};
|
||||
|
||||
replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
import { type FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/constants/workspace-migration-action-type.constant';
|
||||
|
||||
export type BaseFlatUpdateWorkspaceMigrationAction<T extends AllMetadataName> =
|
||||
@@ -8,5 +8,5 @@ export type BaseFlatUpdateWorkspaceMigrationAction<T extends AllMetadataName> =
|
||||
type: typeof WORKSPACE_MIGRATION_ACTION_TYPE.update;
|
||||
metadataName: T;
|
||||
entityId: string;
|
||||
updates: FlatEntityPropertiesUpdates<T>;
|
||||
update: FlatEntityUpdate<T>;
|
||||
};
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
import { type FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/constants/workspace-migration-action-type.constant';
|
||||
|
||||
export type BaseUniversalUpdateWorkspaceMigrationAction<
|
||||
@@ -9,5 +9,5 @@ export type BaseUniversalUpdateWorkspaceMigrationAction<
|
||||
type: typeof WORKSPACE_MIGRATION_ACTION_TYPE.update;
|
||||
metadataName: T;
|
||||
universalIdentifier: string;
|
||||
updates: FlatEntityPropertiesUpdates<T>;
|
||||
update: FlatEntityUpdate<T>;
|
||||
};
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
import { type FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
|
||||
export type FlatEntityUpdateValidationArgs<T extends AllMetadataName> = Omit<
|
||||
@@ -8,6 +8,6 @@ export type FlatEntityUpdateValidationArgs<T extends AllMetadataName> = Omit<
|
||||
'flatEntityToValidate' | 'remainingFlatEntityMapsToValidate'
|
||||
> & {
|
||||
flatEntityId: string;
|
||||
flatEntityUpdates: FlatEntityPropertiesUpdates<T>;
|
||||
flatEntityUpdate: FlatEntityUpdate<T>;
|
||||
universalIdentifier: string;
|
||||
};
|
||||
|
||||
+7
-13
@@ -15,7 +15,6 @@ import { type FlatEntityValidationArgs } from 'src/engine/workspace-manager/work
|
||||
import { validateAgentNameUniqueness } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-agent-name-uniqueness.util';
|
||||
import { validateAgentRequiredProperties } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-agent-required-properties.util';
|
||||
import { validateAgentResponseFormat } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-agent-response-format.util';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatAgentValidatorService {
|
||||
@@ -121,7 +120,7 @@ export class FlatAgentValidatorService {
|
||||
|
||||
public validateFlatAgentUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatAgentMaps: optimisticFlatAgentMaps,
|
||||
},
|
||||
@@ -170,14 +169,9 @@ export class FlatAgentValidatorService {
|
||||
});
|
||||
}
|
||||
|
||||
const partialFlatAgent: Partial<FlatAgent> =
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
});
|
||||
|
||||
const optimisticFlatAgent: FlatAgent = {
|
||||
...fromFlatAgent,
|
||||
...partialFlatAgent,
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
const existingAgents = Object.values(
|
||||
@@ -189,23 +183,23 @@ export class FlatAgentValidatorService {
|
||||
validationResult.errors.push(
|
||||
...validateAgentRequiredProperties({
|
||||
flatAgent: optimisticFlatAgent,
|
||||
updatedProperties: partialFlatAgent,
|
||||
updatedProperties: flatEntityUpdate,
|
||||
}),
|
||||
);
|
||||
|
||||
if (isDefined(partialFlatAgent.name)) {
|
||||
if (isDefined(flatEntityUpdate.name)) {
|
||||
validationResult.errors.push(
|
||||
...validateAgentNameUniqueness({
|
||||
name: partialFlatAgent.name,
|
||||
name: flatEntityUpdate.name,
|
||||
existingFlatAgents: existingAgents,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (isDefined(partialFlatAgent.responseFormat)) {
|
||||
if (isDefined(flatEntityUpdate.responseFormat)) {
|
||||
validationResult.errors.push(
|
||||
...validateAgentResponseFormat({
|
||||
responseFormat: partialFlatAgent.responseFormat,
|
||||
responseFormat: flatEntityUpdate.responseFormat,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
+3
-7
@@ -7,7 +7,6 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { CommandMenuItemExceptionCode } from 'src/engine/metadata-modules/command-menu-item/command-menu-item.exception';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
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';
|
||||
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
|
||||
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
|
||||
@@ -88,7 +87,7 @@ export class FlatCommandMenuItemValidatorService {
|
||||
|
||||
public validateFlatCommandMenuItemUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatCommandMenuItemMaps: optimisticFlatCommandMenuItemMaps,
|
||||
},
|
||||
@@ -119,12 +118,9 @@ export class FlatCommandMenuItemValidatorService {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const labelUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates,
|
||||
property: 'label',
|
||||
});
|
||||
const labelUpdate = flatEntityUpdate.label;
|
||||
|
||||
if (isDefined(labelUpdate) && !isNonEmptyString(labelUpdate.to)) {
|
||||
if (isDefined(labelUpdate) && !isNonEmptyString(labelUpdate)) {
|
||||
validationResult.errors.push({
|
||||
code: CommandMenuItemExceptionCode.INVALID_COMMAND_MENU_ITEM_INPUT,
|
||||
message: t`Label is required`,
|
||||
|
||||
+9
-17
@@ -15,12 +15,10 @@ 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 { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util';
|
||||
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/find-flat-entity-property-update.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';
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatFieldMetadataValidatorService {
|
||||
@@ -30,7 +28,7 @@ export class FlatFieldMetadataValidatorService {
|
||||
|
||||
validateFlatFieldMetadataUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates: updates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatFieldMetadataMaps: optimisticFlatFieldMetadataMaps,
|
||||
flatObjectMetadataMaps,
|
||||
@@ -69,7 +67,7 @@ export class FlatFieldMetadataValidatorService {
|
||||
|
||||
const flatFieldMetadataToValidate = {
|
||||
...existingFlatFieldMetadataToUpdate,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({ updates }),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
validationResult.flatEntityMinimalInformation = {
|
||||
@@ -103,12 +101,7 @@ export class FlatFieldMetadataValidatorService {
|
||||
} else if (
|
||||
flatObjectMetadata.labelIdentifierFieldMetadataId ===
|
||||
flatFieldMetadataToValidate.id &&
|
||||
isDefined(
|
||||
findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates: updates,
|
||||
property: 'isActive',
|
||||
}),
|
||||
) &&
|
||||
isDefined(flatEntityUpdate.isActive) &&
|
||||
flatFieldMetadataToValidate.isActive === false
|
||||
) {
|
||||
validationResult.errors.push({
|
||||
@@ -120,13 +113,12 @@ export class FlatFieldMetadataValidatorService {
|
||||
|
||||
// Should be moved in relation field validator
|
||||
if (isMorphOrRelationFlatFieldMetadata(flatFieldMetadataToValidate)) {
|
||||
const relationNonEditableUpdatedProperties = updates.flatMap(
|
||||
({ property }) =>
|
||||
const updatedProperties = Object.keys(flatEntityUpdate);
|
||||
const relationNonEditableUpdatedProperties = updatedProperties.filter(
|
||||
(property) =>
|
||||
!FLAT_FIELD_METADATA_RELATION_PROPERTIES_TO_COMPARE.includes(
|
||||
property as FlatFieldMetadataRelationPropertiesToCompare,
|
||||
)
|
||||
? property
|
||||
: [],
|
||||
),
|
||||
);
|
||||
|
||||
if (relationNonEditableUpdatedProperties.length > 0) {
|
||||
@@ -139,7 +131,7 @@ export class FlatFieldMetadataValidatorService {
|
||||
}
|
||||
///
|
||||
|
||||
if (updates.some((update) => update.property === 'name')) {
|
||||
if (isDefined(flatEntityUpdate.name)) {
|
||||
validationResult.errors.push(
|
||||
...validateFlatFieldMetadataName({
|
||||
name: flatFieldMetadataToValidate.name,
|
||||
@@ -182,7 +174,7 @@ export class FlatFieldMetadataValidatorService {
|
||||
const fieldMetadataTypeValidationErrors =
|
||||
this.flatFieldMetadataTypeValidatorService.validateFlatFieldMetadataTypeSpecificities(
|
||||
{
|
||||
updates,
|
||||
update: flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatFieldMetadataMaps: optimisticFlatFieldMetadataMaps,
|
||||
flatObjectMetadataMaps,
|
||||
|
||||
+8
-27
@@ -7,7 +7,6 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { MetadataFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-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 { NavigationMenuItemExceptionCode } from 'src/engine/metadata-modules/navigation-menu-item/navigation-menu-item.exception';
|
||||
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/find-flat-entity-property-update.util';
|
||||
import { validateFlatEntityCircularDependency } from 'src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util';
|
||||
import {
|
||||
type FailedFlatEntityValidation,
|
||||
@@ -16,7 +15,6 @@ import {
|
||||
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
|
||||
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
|
||||
import { type FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
const NAVIGATION_MENU_ITEM_MAX_DEPTH = 2;
|
||||
|
||||
@@ -263,7 +261,7 @@ export class FlatNavigationMenuItemValidatorService {
|
||||
|
||||
public validateFlatNavigationMenuItemUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatNavigationMenuItemMaps: optimisticFlatNavigationMenuItemMaps,
|
||||
},
|
||||
@@ -294,14 +292,11 @@ export class FlatNavigationMenuItemValidatorService {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const positionUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates,
|
||||
property: 'position',
|
||||
});
|
||||
const positionUpdate = flatEntityUpdate.position;
|
||||
|
||||
if (
|
||||
isDefined(positionUpdate) &&
|
||||
(!Number.isInteger(positionUpdate.to) || positionUpdate.to < 0)
|
||||
(!Number.isInteger(positionUpdate) || positionUpdate < 0)
|
||||
) {
|
||||
validationResult.errors.push({
|
||||
code: NavigationMenuItemExceptionCode.INVALID_NAVIGATION_MENU_ITEM_INPUT,
|
||||
@@ -312,15 +307,10 @@ export class FlatNavigationMenuItemValidatorService {
|
||||
|
||||
const toFlatNavigationMenuItem = {
|
||||
...fromFlatNavigationMenuItem,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
const nameUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates,
|
||||
property: 'name',
|
||||
});
|
||||
const nameUpdate = flatEntityUpdate.name;
|
||||
|
||||
const typeValidationErrors = this.validateNavigationMenuItemType({
|
||||
hasTargetRecordId: isDefined(toFlatNavigationMenuItem.targetRecordId),
|
||||
@@ -328,28 +318,19 @@ export class FlatNavigationMenuItemValidatorService {
|
||||
toFlatNavigationMenuItem.targetObjectMetadataId,
|
||||
),
|
||||
hasViewId: isDefined(toFlatNavigationMenuItem.viewId),
|
||||
name: isDefined(nameUpdate)
|
||||
? nameUpdate.to
|
||||
: toFlatNavigationMenuItem.name,
|
||||
name: isDefined(nameUpdate) ? nameUpdate : toFlatNavigationMenuItem.name,
|
||||
isUpdate: true,
|
||||
});
|
||||
|
||||
validationResult.errors.push(...typeValidationErrors);
|
||||
|
||||
const folderIdUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates,
|
||||
property: 'folderId',
|
||||
});
|
||||
const folderIdUpdate = flatEntityUpdate.folderId;
|
||||
|
||||
if (!isDefined(folderIdUpdate)) {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const newFolderId = folderIdUpdate.to;
|
||||
|
||||
if (!isDefined(newFolderId)) {
|
||||
return validationResult;
|
||||
}
|
||||
const newFolderId = folderIdUpdate;
|
||||
|
||||
const circularDependencyErrors = this.getCircularDependencyValidationErrors(
|
||||
{
|
||||
|
||||
+4
-12
@@ -13,13 +13,12 @@ import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspa
|
||||
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';
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatObjectMetadataValidatorService {
|
||||
public validateFlatObjectMetadataUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
buildOptions,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatObjectMetadataMaps: optimisticFlatObjectMetadataMaps,
|
||||
@@ -54,9 +53,7 @@ export class FlatObjectMetadataValidatorService {
|
||||
|
||||
const updatedFlatObjectMetadata = {
|
||||
...existingFlatObjectMetadata,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
validationResult.flatEntityMinimalInformation = {
|
||||
@@ -73,14 +70,9 @@ export class FlatObjectMetadataValidatorService {
|
||||
buildOptions,
|
||||
}),
|
||||
);
|
||||
|
||||
const labelIdentifierFieldMetadataIdUpdate = flatEntityUpdates.find(
|
||||
(update) => update.property === 'labelIdentifierFieldMetadataId',
|
||||
);
|
||||
|
||||
// TODO remove this once we migrated labelIdentifierFieldMetadataId as non nullable
|
||||
if (isDefined(labelIdentifierFieldMetadataIdUpdate)) {
|
||||
if (!isDefined(labelIdentifierFieldMetadataIdUpdate.to)) {
|
||||
if (flatEntityUpdate.labelIdentifierFieldMetadataId !== undefined) {
|
||||
if (flatEntityUpdate.labelIdentifierFieldMetadataId === null) {
|
||||
validationResult.errors.push({
|
||||
code: ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
|
||||
message: 'labelIdentifierFieldMetadataId cannot be null',
|
||||
|
||||
+3
-6
@@ -28,7 +28,6 @@ import {
|
||||
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';
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatPageLayoutWidgetValidatorService {
|
||||
@@ -38,7 +37,7 @@ export class FlatPageLayoutWidgetValidatorService {
|
||||
|
||||
public async validateFlatPageLayoutWidgetUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
|
||||
additionalCacheDataMaps: { featureFlagsMap },
|
||||
workspaceId,
|
||||
@@ -76,9 +75,7 @@ export class FlatPageLayoutWidgetValidatorService {
|
||||
|
||||
const updatedFlatPageLayoutWidget = {
|
||||
...existingFlatPageLayoutWidget,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
validationResult.flatEntityMinimalInformation = {
|
||||
@@ -122,7 +119,7 @@ export class FlatPageLayoutWidgetValidatorService {
|
||||
{
|
||||
flatEntityToValidate: updatedFlatPageLayoutWidget,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
|
||||
updates: flatEntityUpdates,
|
||||
update: flatEntityUpdate,
|
||||
additionalCacheDataMaps: { featureFlagsMap },
|
||||
workspaceId,
|
||||
buildOptions,
|
||||
|
||||
+2
-5
@@ -12,7 +12,6 @@ import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/wor
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { validateFlatRoleTargetAssignationAvailability } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-flat-role-target-assignation-availability.util';
|
||||
import { validateFlatRoleTargetTargetsOnlyOneEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-flat-role-target-targets-only-one-entity.util';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatRoleTargetValidatorService {
|
||||
@@ -113,7 +112,7 @@ export class FlatRoleTargetValidatorService {
|
||||
|
||||
validateFlatRoleTargetUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatRoleTargetMaps: optimisticFlatRoleTargetMaps,
|
||||
flatRoleMaps,
|
||||
@@ -147,9 +146,7 @@ export class FlatRoleTargetValidatorService {
|
||||
|
||||
const updatedFlatRoleTarget = {
|
||||
...existingRoleTarget,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
validationResult.errors.push(
|
||||
|
||||
+4
-11
@@ -6,7 +6,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 { 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';
|
||||
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
|
||||
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
|
||||
@@ -15,7 +14,6 @@ import { validateRoleIsEditable } from 'src/engine/workspace-manager/workspace-m
|
||||
import { validateRoleLabelUniqueness } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-role-label-uniqueness.util';
|
||||
import { validateRoleReadWritePermissionsConsistency } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-role-read-write-permissions-consistency.util';
|
||||
import { validateRoleRequiredPropertiesAreDefined } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-role-required-properties-are-defined.util';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatRoleValidatorService {
|
||||
@@ -109,7 +107,7 @@ export class FlatRoleValidatorService {
|
||||
|
||||
public validateFlatRoleUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatRoleMaps: optimisticFlatRoleMaps,
|
||||
},
|
||||
@@ -150,9 +148,7 @@ export class FlatRoleValidatorService {
|
||||
|
||||
const toFlatRole = {
|
||||
...fromFlatRole,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
validationResult.errors.push(
|
||||
@@ -161,10 +157,7 @@ export class FlatRoleValidatorService {
|
||||
}),
|
||||
);
|
||||
|
||||
const flatRoleLabelUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates,
|
||||
property: 'label',
|
||||
});
|
||||
const flatRoleLabelUpdate = flatEntityUpdate.label;
|
||||
|
||||
if (isDefined(flatRoleLabelUpdate)) {
|
||||
const existingRoles = Object.values(
|
||||
@@ -173,7 +166,7 @@ export class FlatRoleValidatorService {
|
||||
|
||||
validationResult.errors.push(
|
||||
...validateRoleLabelUniqueness({
|
||||
label: flatRoleLabelUpdate.to,
|
||||
label: flatRoleLabelUpdate,
|
||||
existingFlatRoles: existingRoles,
|
||||
}),
|
||||
);
|
||||
|
||||
+2
-5
@@ -12,7 +12,6 @@ import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspa
|
||||
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';
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatRowLevelPermissionPredicateGroupValidatorService {
|
||||
@@ -141,7 +140,7 @@ export class FlatRowLevelPermissionPredicateGroupValidatorService {
|
||||
|
||||
validateFlatRowLevelPermissionPredicateGroupUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
|
||||
}: FlatEntityUpdateValidationArgs<
|
||||
typeof ALL_METADATA_NAME.rowLevelPermissionPredicateGroup
|
||||
@@ -179,9 +178,7 @@ export class FlatRowLevelPermissionPredicateGroupValidatorService {
|
||||
|
||||
const updatedPredicateGroup = {
|
||||
...existingPredicateGroup,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
if (updatedPredicateGroup.roleId !== existingPredicateGroup.roleId) {
|
||||
|
||||
+2
-5
@@ -12,7 +12,6 @@ import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspa
|
||||
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';
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatRowLevelPermissionPredicateValidatorService {
|
||||
@@ -154,7 +153,7 @@ export class FlatRowLevelPermissionPredicateValidatorService {
|
||||
|
||||
validateFlatRowLevelPermissionPredicateUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps,
|
||||
}: FlatEntityUpdateValidationArgs<
|
||||
typeof ALL_METADATA_NAME.rowLevelPermissionPredicate
|
||||
@@ -193,9 +192,7 @@ export class FlatRowLevelPermissionPredicateValidatorService {
|
||||
|
||||
const updatedPredicate = {
|
||||
...existingPredicate,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
if (updatedPredicate.roleId !== existingPredicate.roleId) {
|
||||
|
||||
+9
-26
@@ -8,7 +8,6 @@ import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/
|
||||
import { type FlatSkill } from 'src/engine/metadata-modules/flat-skill/types/flat-skill.type';
|
||||
import { SkillExceptionCode } from 'src/engine/metadata-modules/skill/skill.exception';
|
||||
import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util';
|
||||
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';
|
||||
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
|
||||
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
|
||||
@@ -19,7 +18,6 @@ import {
|
||||
validateSkillLabelIsDefined,
|
||||
validateSkillRequiredProperties,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-skill-required-properties.util';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatSkillValidatorService {
|
||||
@@ -115,7 +113,7 @@ export class FlatSkillValidatorService {
|
||||
|
||||
public validateFlatSkillUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatSkillMaps: optimisticFlatSkillMaps,
|
||||
},
|
||||
@@ -147,14 +145,10 @@ export class FlatSkillValidatorService {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
// Standard skills can only have isActive toggled, not other properties
|
||||
const isActiveUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates,
|
||||
property: 'isActive',
|
||||
});
|
||||
const isActiveUpdate = flatEntityUpdate.isActive;
|
||||
|
||||
const hasNonIsActiveUpdates = flatEntityUpdates.some(
|
||||
(update) => update.property !== 'isActive',
|
||||
const hasNonIsActiveUpdates = Object.keys(flatEntityUpdate).some(
|
||||
(key) => key !== 'isActive',
|
||||
);
|
||||
|
||||
// TODO refactor once skill has been migrated to universal pattern
|
||||
@@ -189,15 +183,10 @@ export class FlatSkillValidatorService {
|
||||
|
||||
const optimisticFlatSkill: FlatSkill = {
|
||||
...fromFlatSkill,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
const labelUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates,
|
||||
property: 'label',
|
||||
});
|
||||
const labelUpdate = flatEntityUpdate.label;
|
||||
|
||||
if (isDefined(labelUpdate)) {
|
||||
validationResult.errors.push(
|
||||
@@ -205,10 +194,7 @@ export class FlatSkillValidatorService {
|
||||
);
|
||||
}
|
||||
|
||||
const contentUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates,
|
||||
property: 'content',
|
||||
});
|
||||
const contentUpdate = flatEntityUpdate.content;
|
||||
|
||||
if (isDefined(contentUpdate)) {
|
||||
validationResult.errors.push(
|
||||
@@ -216,10 +202,7 @@ export class FlatSkillValidatorService {
|
||||
);
|
||||
}
|
||||
|
||||
const nameUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates,
|
||||
property: 'name',
|
||||
});
|
||||
const nameUpdate = flatEntityUpdate.name;
|
||||
|
||||
if (isDefined(nameUpdate)) {
|
||||
const existingSkills = Object.values(
|
||||
@@ -230,7 +213,7 @@ export class FlatSkillValidatorService {
|
||||
|
||||
validationResult.errors.push(
|
||||
...validateSkillNameUniqueness({
|
||||
name: nameUpdate.to,
|
||||
name: nameUpdate,
|
||||
existingFlatSkills: existingSkills,
|
||||
}),
|
||||
);
|
||||
|
||||
+2
-5
@@ -13,7 +13,6 @@ import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/
|
||||
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { validateLabelIdentifierFieldMetadataIdFlatViewField } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-label-identifier-field-metadata-id-flat-view-field.util';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatViewFieldValidatorService {
|
||||
@@ -21,7 +20,7 @@ export class FlatViewFieldValidatorService {
|
||||
|
||||
public validateFlatViewFieldUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatViewFieldMaps: optimisticFlatViewFieldMaps,
|
||||
flatViewMaps,
|
||||
@@ -56,9 +55,7 @@ export class FlatViewFieldValidatorService {
|
||||
|
||||
const updatedFlatViewField = {
|
||||
...existingFlatViewField,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
validationResult.flatEntityMinimalInformation = {
|
||||
|
||||
+4
-11
@@ -7,7 +7,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 FlatViewFilterGroupMaps } from 'src/engine/metadata-modules/flat-view-filter-group/types/flat-view-filter-group-maps.type';
|
||||
import { ViewFilterGroupExceptionCode } from 'src/engine/metadata-modules/view-filter-group/exceptions/view-filter-group.exception';
|
||||
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/find-flat-entity-property-update.util';
|
||||
import { validateFlatEntityCircularDependency } from 'src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util';
|
||||
import {
|
||||
type FailedFlatEntityValidation,
|
||||
@@ -191,7 +190,7 @@ export class FlatViewFilterGroupValidatorService {
|
||||
|
||||
validateFlatViewFilterGroupUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatViewFilterGroupMaps: optimisticFlatViewFilterGroupMaps,
|
||||
},
|
||||
@@ -220,20 +219,14 @@ export class FlatViewFilterGroupValidatorService {
|
||||
});
|
||||
}
|
||||
|
||||
const parentViewFilterGroupIdUpdate = findFlatEntityPropertyUpdate({
|
||||
property: 'parentViewFilterGroupId',
|
||||
flatEntityUpdates,
|
||||
});
|
||||
const parentViewFilterGroupIdUpdate =
|
||||
flatEntityUpdate.parentViewFilterGroupId;
|
||||
|
||||
if (!isDefined(parentViewFilterGroupIdUpdate)) {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const newParentViewFilterGroupId = parentViewFilterGroupIdUpdate.to;
|
||||
|
||||
if (!isDefined(newParentViewFilterGroupId)) {
|
||||
return validationResult;
|
||||
}
|
||||
const newParentViewFilterGroupId = parentViewFilterGroupIdUpdate;
|
||||
|
||||
const circularDependencyErrors = this.getCircularDependencyValidationErrors(
|
||||
{
|
||||
|
||||
+2
-5
@@ -10,7 +10,6 @@ import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/wo
|
||||
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
|
||||
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
|
||||
import { type FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatViewFilterValidatorService {
|
||||
@@ -130,7 +129,7 @@ export class FlatViewFilterValidatorService {
|
||||
|
||||
validateFlatViewFilterUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatViewFilterMaps: optimisticFlatViewFilterMaps,
|
||||
flatFieldMetadataMaps,
|
||||
@@ -165,9 +164,7 @@ export class FlatViewFilterValidatorService {
|
||||
|
||||
const updatedFlatViewFilter = {
|
||||
...existingViewFilter,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
const referencedFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
|
||||
|
||||
+2
-5
@@ -10,13 +10,12 @@ import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspa
|
||||
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';
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class FlatViewGroupValidatorService {
|
||||
public validateFlatViewGroupUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatViewGroupMaps: optimisticFlatViewGroupMaps,
|
||||
flatViewMaps,
|
||||
@@ -50,9 +49,7 @@ export class FlatViewGroupValidatorService {
|
||||
|
||||
const updatedFlatViewGroup = {
|
||||
...existingFlatViewGroup,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
}),
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
if (!isDefined(updatedFlatViewGroup.fieldValue)) {
|
||||
|
||||
+5
-14
@@ -7,19 +7,17 @@ import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/
|
||||
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
|
||||
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
|
||||
import { ViewExceptionCode } from 'src/engine/metadata-modules/view/exceptions/view.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';
|
||||
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
|
||||
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
|
||||
import { type FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
export class FlatViewValidatorService {
|
||||
constructor() {}
|
||||
|
||||
public validateFlatViewUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatViewMaps: optimisticFlatViewMaps,
|
||||
flatFieldMetadataMaps,
|
||||
@@ -51,27 +49,20 @@ export class FlatViewValidatorService {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const partialUpdates = fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates: flatEntityUpdates,
|
||||
});
|
||||
|
||||
const updatedFlatView: FlatView = {
|
||||
...existingFlatView,
|
||||
...partialUpdates,
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
const kanbanAggregateOperationFieldMetadataIdUpdate =
|
||||
findFlatEntityPropertyUpdate({
|
||||
property: 'kanbanAggregateOperationFieldMetadataId',
|
||||
flatEntityUpdates,
|
||||
});
|
||||
flatEntityUpdate.kanbanAggregateOperationFieldMetadataId;
|
||||
|
||||
if (
|
||||
isDefined(kanbanAggregateOperationFieldMetadataIdUpdate) &&
|
||||
kanbanAggregateOperationFieldMetadataIdUpdate.to !== null &&
|
||||
kanbanAggregateOperationFieldMetadataIdUpdate !== null &&
|
||||
!isDefined(
|
||||
findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: kanbanAggregateOperationFieldMetadataIdUpdate.to,
|
||||
flatEntityId: kanbanAggregateOperationFieldMetadataIdUpdate,
|
||||
flatEntityMaps: flatFieldMetadataMaps,
|
||||
}),
|
||||
)
|
||||
|
||||
+3
-7
@@ -7,7 +7,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 { WebhookExceptionCode } from 'src/engine/metadata-modules/webhook/webhook.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';
|
||||
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
|
||||
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type';
|
||||
@@ -95,7 +94,7 @@ export class FlatWebhookValidatorService {
|
||||
|
||||
public validateFlatWebhookUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatWebhookMaps: optimisticFlatWebhookMaps,
|
||||
},
|
||||
@@ -126,14 +125,11 @@ export class FlatWebhookValidatorService {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const targetUrlUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates,
|
||||
property: 'targetUrl',
|
||||
});
|
||||
const targetUrlUpdate = flatEntityUpdate.targetUrl;
|
||||
|
||||
if (
|
||||
isDefined(targetUrlUpdate) &&
|
||||
!this.validateTargetUrl(targetUrlUpdate.to)
|
||||
!this.validateTargetUrl(targetUrlUpdate)
|
||||
) {
|
||||
validationResult.errors.push({
|
||||
code: WebhookExceptionCode.INVALID_TARGET_URL,
|
||||
|
||||
+6
-5
@@ -1,5 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { type QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
||||
|
||||
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
|
||||
|
||||
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
|
||||
@@ -8,7 +10,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateAgentActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -25,16 +26,16 @@ export class UpdateAgentActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateAgentAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, updates } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const agentRepository =
|
||||
queryRunner.manager.getRepository<AgentEntity>(AgentEntity);
|
||||
|
||||
// Cast needed because TypeORM's QueryDeepPartialEntity doesn't handle
|
||||
// JsonbProperty branded types with nested Record<string, unknown> well
|
||||
await agentRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates,
|
||||
}),
|
||||
update as QueryDeepPartialEntity<AgentEntity>,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+2
-5
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateCommandMenuItemActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -25,7 +24,7 @@ export class UpdateCommandMenuItemActionHandlerService extends WorkspaceMigratio
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateCommandMenuItemAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, updates } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const commandMenuItemRepository =
|
||||
queryRunner.manager.getRepository<CommandMenuItemEntity>(
|
||||
@@ -34,9 +33,7 @@ export class UpdateCommandMenuItemActionHandlerService extends WorkspaceMigratio
|
||||
|
||||
await commandMenuItemRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates,
|
||||
}),
|
||||
update,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+125
-93
@@ -1,6 +1,9 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import {
|
||||
FieldMetadataSettingsMapping,
|
||||
FieldMetadataType,
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ColumnType, type QueryRunner } from 'typeorm';
|
||||
|
||||
@@ -9,21 +12,19 @@ import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-mana
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
||||
import { getCompositeTypeOrThrow } from 'src/engine/metadata-modules/field-metadata/utils/get-composite-type-or-throw.util';
|
||||
import { FlatEntityPropertiesToCompare } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-compare.type';
|
||||
import { FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
|
||||
import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { isCompositeFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-composite-flat-field-metadata.util';
|
||||
import { isEnumFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-enum-flat-field-metadata.util';
|
||||
import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util';
|
||||
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';
|
||||
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 { isMorphOrRelationFieldMetadataType } from 'src/engine/utils/is-morph-or-relation-field-metadata-type.util';
|
||||
import { PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/types/property-update.type';
|
||||
import { convertOnDeleteActionToOnDelete } from 'src/engine/workspace-manager/workspace-migration/utils/convert-on-delete-action-to-on-delete.util';
|
||||
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/find-flat-entity-property-update.util';
|
||||
import { isPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/is-property-update.util';
|
||||
import {
|
||||
FlatUpdateFieldAction,
|
||||
UniversalUpdateFieldAction,
|
||||
@@ -38,7 +39,6 @@ import {
|
||||
type WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fieldMetadataTypeToColumnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/field-metadata-type-to-column-type.util';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
import { generateColumnDefinitions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/generate-column-definitions.util';
|
||||
import { getWorkspaceSchemaContextForMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/get-workspace-schema-context-for-migration.util';
|
||||
import {
|
||||
@@ -47,15 +47,32 @@ import {
|
||||
executeBatchEnumOperations,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/workspace-schema-enum-operations.util';
|
||||
|
||||
type UpdateFieldPropertyUpdateHandlerArgs<
|
||||
P extends FlatEntityPropertiesToCompare<'fieldMetadata'>,
|
||||
type UpdateFieldPropertyHandlerArgs<
|
||||
T extends FieldMetadataType = FieldMetadataType,
|
||||
> = {
|
||||
queryRunner: QueryRunner;
|
||||
schemaName: string;
|
||||
tableName: string;
|
||||
flatFieldMetadata: FlatFieldMetadata<T>;
|
||||
update: PropertyUpdate<FlatFieldMetadata, P>;
|
||||
update: FlatEntityUpdate<'fieldMetadata'>;
|
||||
};
|
||||
|
||||
type NameUpdateHandlerArgs<T extends FieldMetadataType = FieldMetadataType> =
|
||||
UpdateFieldPropertyHandlerArgs<T> & {
|
||||
toName: string;
|
||||
};
|
||||
|
||||
type DefaultValueUpdateHandlerArgs<
|
||||
T extends FieldMetadataType = FieldMetadataType,
|
||||
> = UpdateFieldPropertyHandlerArgs<T> & {
|
||||
toDefaultValue: FlatFieldMetadata['defaultValue'];
|
||||
};
|
||||
|
||||
type OptionsUpdateHandlerArgs<T extends FieldMetadataType = FieldMetadataType> =
|
||||
UpdateFieldPropertyHandlerArgs<T> & {
|
||||
toOptions: FlatFieldMetadata['options'];
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
workspaceId: string;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
@@ -86,25 +103,22 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
type: 'update',
|
||||
metadataName: 'fieldMetadata',
|
||||
entityId: flatFieldMetadata.id,
|
||||
updates: action.updates,
|
||||
update: action.update,
|
||||
};
|
||||
}
|
||||
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateFieldAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const fieldMetadataRepository =
|
||||
queryRunner.manager.getRepository<FieldMetadataEntity>(
|
||||
FieldMetadataEntity,
|
||||
);
|
||||
|
||||
const { entityId } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
await fieldMetadataRepository.update(
|
||||
entityId,
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction),
|
||||
);
|
||||
await fieldMetadataRepository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
@@ -116,7 +130,7 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
allFlatEntityMaps: { flatObjectMetadataMaps, flatFieldMetadataMaps },
|
||||
workspaceId,
|
||||
} = context;
|
||||
const { entityId, updates } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const currentFlatFieldMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: entityId,
|
||||
@@ -135,54 +149,28 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
|
||||
let optimisticFlatFieldMetadata = structuredClone(currentFlatFieldMetadata);
|
||||
|
||||
const defaultValueUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates: updates,
|
||||
property: 'defaultValue',
|
||||
});
|
||||
const hasDefaultValueUpdate = isDefined(defaultValueUpdate);
|
||||
|
||||
let wasDefaultValueHandledByEnumUpdate = false;
|
||||
|
||||
const sortedUpdatesWithDefaultValuesUpdateLast = hasDefaultValueUpdate
|
||||
? [
|
||||
...updates.filter((update) => update.property !== 'defaultValue'),
|
||||
defaultValueUpdate,
|
||||
]
|
||||
: updates;
|
||||
|
||||
for (const update of sortedUpdatesWithDefaultValuesUpdateLast) {
|
||||
if (isPropertyUpdate(update, 'name')) {
|
||||
if (isDefined(update.name)) {
|
||||
await this.handleFieldNameUpdate({
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
flatFieldMetadata: optimisticFlatFieldMetadata,
|
||||
update,
|
||||
toName: update.name,
|
||||
});
|
||||
optimisticFlatFieldMetadata.name = update.to;
|
||||
}
|
||||
if (isPropertyUpdate(update, 'defaultValue')) {
|
||||
if (wasDefaultValueHandledByEnumUpdate) {
|
||||
optimisticFlatFieldMetadata.defaultValue = update.to;
|
||||
} else {
|
||||
await this.handleFieldDefaultValueUpdate({
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
flatFieldMetadata: optimisticFlatFieldMetadata,
|
||||
update,
|
||||
});
|
||||
optimisticFlatFieldMetadata.defaultValue = update.to;
|
||||
}
|
||||
optimisticFlatFieldMetadata.name = update.name;
|
||||
}
|
||||
|
||||
if (
|
||||
isPropertyUpdate(update, 'options') &&
|
||||
update.options !== undefined &&
|
||||
isEnumFlatFieldMetadata(optimisticFlatFieldMetadata)
|
||||
) {
|
||||
if (hasDefaultValueUpdate) {
|
||||
if (update.defaultValue !== undefined) {
|
||||
optimisticFlatFieldMetadata = {
|
||||
...optimisticFlatFieldMetadata,
|
||||
defaultValue: defaultValueUpdate.to,
|
||||
defaultValue: update.defaultValue,
|
||||
};
|
||||
wasDefaultValueHandledByEnumUpdate = true;
|
||||
}
|
||||
@@ -193,39 +181,76 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
tableName,
|
||||
flatFieldMetadata: optimisticFlatFieldMetadata,
|
||||
flatObjectMetadata,
|
||||
update,
|
||||
toOptions: update.options,
|
||||
workspaceId,
|
||||
update,
|
||||
});
|
||||
optimisticFlatFieldMetadata.options = update.to ?? [];
|
||||
optimisticFlatFieldMetadata.options = update.options ?? [];
|
||||
}
|
||||
|
||||
if (update.defaultValue !== undefined) {
|
||||
if (wasDefaultValueHandledByEnumUpdate) {
|
||||
optimisticFlatFieldMetadata.defaultValue = update.defaultValue;
|
||||
} else {
|
||||
await this.handleFieldDefaultValueUpdate({
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
flatFieldMetadata: optimisticFlatFieldMetadata,
|
||||
toDefaultValue: update.defaultValue,
|
||||
update,
|
||||
});
|
||||
optimisticFlatFieldMetadata.defaultValue = update.defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefined(update.settings)) {
|
||||
// Handle joinColumnName rename
|
||||
if (isMorphOrRelationFlatFieldMetadata(optimisticFlatFieldMetadata)) {
|
||||
const fromSettings = optimisticFlatFieldMetadata.settings;
|
||||
const toSettings = update.settings as
|
||||
| FieldMetadataSettingsMapping['MORPH_RELATION']
|
||||
| FieldMetadataSettingsMapping['RELATION'];
|
||||
|
||||
if (
|
||||
isPropertyUpdate(update, 'settings') &&
|
||||
isDefined(update.from?.joinColumnName) &&
|
||||
isDefined(update.to?.joinColumnName) &&
|
||||
update.from.joinColumnName !== update.to.joinColumnName &&
|
||||
isMorphOrRelationFlatFieldMetadata(optimisticFlatFieldMetadata)
|
||||
isDefined(fromSettings?.joinColumnName) &&
|
||||
isDefined(toSettings?.joinColumnName) &&
|
||||
fromSettings.joinColumnName !== toSettings.joinColumnName
|
||||
) {
|
||||
await this.workspaceSchemaManagerService.columnManager.renameColumn({
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
oldColumnName: update.from.joinColumnName,
|
||||
newColumnName: update.to.joinColumnName,
|
||||
oldColumnName: fromSettings.joinColumnName,
|
||||
newColumnName: toSettings.joinColumnName,
|
||||
});
|
||||
optimisticFlatFieldMetadata = {
|
||||
...optimisticFlatFieldMetadata,
|
||||
settings: {
|
||||
...optimisticFlatFieldMetadata.settings,
|
||||
joinColumnName: update.to.joinColumnName,
|
||||
joinColumnName: toSettings.joinColumnName,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Handle asExpression/generatedType change (for TS_VECTOR fields)
|
||||
if (
|
||||
isPropertyUpdate(update, 'settings') &&
|
||||
isDefined(update.to?.asExpression) &&
|
||||
isDefined(update.from?.asExpression) &&
|
||||
(update.to.asExpression !== update.from.asExpression ||
|
||||
update.to.generatedType !== update.from.generatedType)
|
||||
isFlatFieldMetadataOfType(
|
||||
optimisticFlatFieldMetadata,
|
||||
FieldMetadataType.TS_VECTOR,
|
||||
)
|
||||
) {
|
||||
const fromSettings =
|
||||
optimisticFlatFieldMetadata.settings as FieldMetadataSettingsMapping['TS_VECTOR'];
|
||||
const toSettings =
|
||||
update.settings as FieldMetadataSettingsMapping['TS_VECTOR'];
|
||||
|
||||
if (
|
||||
isDefined(toSettings?.asExpression) &&
|
||||
isDefined(fromSettings?.asExpression) &&
|
||||
(toSettings.asExpression !== fromSettings.asExpression ||
|
||||
toSettings.generatedType !== fromSettings.generatedType)
|
||||
) {
|
||||
await this.workspaceSchemaManagerService.columnManager.dropColumns({
|
||||
queryRunner,
|
||||
@@ -241,24 +266,30 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
{
|
||||
name: optimisticFlatFieldMetadata.name,
|
||||
type: 'tsvector',
|
||||
...update.to,
|
||||
...toSettings,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
optimisticFlatFieldMetadata = {
|
||||
...optimisticFlatFieldMetadata,
|
||||
settings: update.to,
|
||||
settings: toSettings,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Handle onDelete change (for morph/relation fields) order matters
|
||||
if (isMorphOrRelationFlatFieldMetadata(optimisticFlatFieldMetadata)) {
|
||||
const fromSettings = optimisticFlatFieldMetadata.settings;
|
||||
const toSettings = update.settings as
|
||||
| FieldMetadataSettingsMapping['MORPH_RELATION']
|
||||
| FieldMetadataSettingsMapping['RELATION'];
|
||||
|
||||
if (
|
||||
isMorphOrRelationFlatFieldMetadata(optimisticFlatFieldMetadata) &&
|
||||
isDefined(optimisticFlatFieldMetadata.settings.joinColumnName) &&
|
||||
isPropertyUpdate(update, 'settings') &&
|
||||
isDefined(update.from?.onDelete) &&
|
||||
isDefined(update.to?.onDelete) &&
|
||||
update.to.onDelete !== update.from.onDelete
|
||||
isDefined(fromSettings?.onDelete) &&
|
||||
isDefined(toSettings?.onDelete) &&
|
||||
toSettings.onDelete !== fromSettings.onDelete
|
||||
) {
|
||||
const foreignKeyName =
|
||||
await this.workspaceSchemaManagerService.foreignKeyManager.getForeignKeyName(
|
||||
@@ -303,11 +334,11 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
schemaName,
|
||||
foreignKey: {
|
||||
tableName,
|
||||
columnName: update.to.joinColumnName,
|
||||
columnName: optimisticFlatFieldMetadata.settings.joinColumnName,
|
||||
referencedTableName,
|
||||
referencedColumnName: 'id',
|
||||
onDelete:
|
||||
convertOnDeleteActionToOnDelete(update.to.onDelete) ??
|
||||
convertOnDeleteActionToOnDelete(toSettings.onDelete) ??
|
||||
'CASCADE',
|
||||
},
|
||||
},
|
||||
@@ -315,14 +346,17 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async handleFieldNameUpdate({
|
||||
flatFieldMetadata,
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
update,
|
||||
}: UpdateFieldPropertyUpdateHandlerArgs<'name'>) {
|
||||
toName,
|
||||
}: NameUpdateHandlerArgs) {
|
||||
const fromName = flatFieldMetadata.name;
|
||||
|
||||
if (isCompositeFlatFieldMetadata(flatFieldMetadata)) {
|
||||
const compositeType = getCompositeTypeOrThrow(flatFieldMetadata.type);
|
||||
|
||||
@@ -336,11 +370,11 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
}
|
||||
|
||||
const fromCompositeColumnName = computeCompositeColumnName(
|
||||
update.from,
|
||||
fromName,
|
||||
property,
|
||||
);
|
||||
const toCompositeColumnName = computeCompositeColumnName(
|
||||
update.to,
|
||||
toName,
|
||||
property,
|
||||
);
|
||||
|
||||
@@ -357,8 +391,8 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
oldColumnName: update.from,
|
||||
newColumnName: update.to,
|
||||
oldColumnName: fromName,
|
||||
newColumnName: toName,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -367,7 +401,7 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
tableName,
|
||||
operation: EnumOperation.RENAME,
|
||||
options: {
|
||||
newFieldName: update.to,
|
||||
newFieldName: toName,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -384,8 +418,8 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
update,
|
||||
}: UpdateFieldPropertyUpdateHandlerArgs<'defaultValue'>) {
|
||||
toDefaultValue,
|
||||
}: DefaultValueUpdateHandlerArgs) {
|
||||
if (isCompositeFlatFieldMetadata(flatFieldMetadata)) {
|
||||
const compositeType = getCompositeTypeOrThrow(flatFieldMetadata.type);
|
||||
|
||||
@@ -407,7 +441,7 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
property,
|
||||
);
|
||||
// @ts-expect-error - TODO: fix this
|
||||
let compositeDefaultValue = update.to?.[property.name]; // not valid should be serialized
|
||||
const compositeDefaultValue = toDefaultValue?.[property.name];
|
||||
|
||||
const serializedNewDefaultValue = serializeDefaultValue({
|
||||
columnName: compositeColumnName,
|
||||
@@ -440,7 +474,7 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
schemaName,
|
||||
tableName,
|
||||
columnType,
|
||||
defaultValue: update.to,
|
||||
defaultValue: toDefaultValue,
|
||||
});
|
||||
|
||||
return await this.workspaceSchemaManagerService.columnManager.alterColumnDefault(
|
||||
@@ -459,21 +493,19 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
update,
|
||||
toOptions,
|
||||
flatObjectMetadata,
|
||||
workspaceId,
|
||||
}: UpdateFieldPropertyUpdateHandlerArgs<'options'> & {
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
workspaceId: string;
|
||||
}) {
|
||||
}: OptionsUpdateHandlerArgs) {
|
||||
const fromOptions = flatFieldMetadata.options;
|
||||
const fromOptionsById = new Map(
|
||||
(update.from ?? [])
|
||||
(fromOptions ?? [])
|
||||
.filter((opt) => isDefined(opt.id))
|
||||
.map((opt) => [opt.id, opt]),
|
||||
);
|
||||
|
||||
const toOptionsById = new Map(
|
||||
(update.to ?? [])
|
||||
(toOptions ?? [])
|
||||
.filter((opt) => isDefined(opt.id))
|
||||
.map((opt) => [opt.id, opt]),
|
||||
);
|
||||
@@ -500,7 +532,7 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
schemaName,
|
||||
tableName,
|
||||
columnDefinition: enumColumnDefinition,
|
||||
enumValues: update.to?.map((opt) => opt.value) ?? [],
|
||||
enumValues: toOptions?.map((opt) => opt.value) ?? [],
|
||||
oldToNewEnumOptionMap: valueMapping,
|
||||
});
|
||||
}
|
||||
|
||||
+2
-5
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateFrontComponentActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -25,7 +24,7 @@ export class UpdateFrontComponentActionHandlerService extends WorkspaceMigration
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateFrontComponentAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, updates } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const frontComponentRepository =
|
||||
queryRunner.manager.getRepository<FrontComponentEntity>(
|
||||
@@ -34,9 +33,7 @@ export class UpdateFrontComponentActionHandlerService extends WorkspaceMigration
|
||||
|
||||
await frontComponentRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates,
|
||||
}),
|
||||
update,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+18
-24
@@ -4,32 +4,31 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { promises as fs } from 'fs';
|
||||
import { dirname, join } from 'path';
|
||||
|
||||
import { isObject } from '@sniptt/guards';
|
||||
import { FileFolder, Sources } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Repository } from 'typeorm';
|
||||
import { FileFolder, Sources } from 'twenty-shared/types';
|
||||
import { isObject } from '@sniptt/guards';
|
||||
|
||||
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
|
||||
|
||||
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
|
||||
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
|
||||
import { LogicFunctionBuildService } from 'src/engine/core-modules/logic-function/logic-function-build/services/logic-function-build.service';
|
||||
import { getLogicFunctionBaseFolderPath } from 'src/engine/core-modules/logic-function/logic-function-build/utils/get-logic-function-base-folder-path.util';
|
||||
import { LambdaBuildDirectoryManager } from 'src/engine/core-modules/logic-function/logic-function-drivers/utils/lambda-build-directory-manager';
|
||||
import { LogicFunctionExecutorService } from 'src/engine/core-modules/logic-function/logic-function-executor/services/logic-function-executor.service';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { LogicFunctionEntity } from 'src/engine/metadata-modules/logic-function/logic-function.entity';
|
||||
import { FlatLogicFunction } from 'src/engine/metadata-modules/logic-function/types/flat-logic-function.type';
|
||||
import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { FlatUpdateLogicFunctionAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/logic-function/types/workspace-migration-logic-function-action.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
|
||||
import { LogicFunctionBuildService } from 'src/engine/core-modules/logic-function/logic-function-build/services/logic-function-build.service';
|
||||
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
|
||||
import { getLogicFunctionBaseFolderPath } from 'src/engine/core-modules/logic-function/logic-function-build/utils/get-logic-function-base-folder-path.util';
|
||||
import { LambdaBuildDirectoryManager } from 'src/engine/core-modules/logic-function/logic-function-drivers/utils/lambda-build-directory-manager';
|
||||
import {
|
||||
LogicFunctionException,
|
||||
LogicFunctionExceptionCode,
|
||||
} from 'src/engine/metadata-modules/logic-function/logic-function.exception';
|
||||
import { FlatLogicFunction } from 'src/engine/metadata-modules/logic-function/types/flat-logic-function.type';
|
||||
import { FlatUpdateLogicFunctionAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/logic-function/types/workspace-migration-logic-function-action.type';
|
||||
import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateLogicFunctionActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -55,38 +54,33 @@ export class UpdateLogicFunctionActionHandlerService extends WorkspaceMigrationR
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateLogicFunctionAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { entityId, code } = flatAction;
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, code, update } = flatAction;
|
||||
|
||||
const logicFunctionRepository =
|
||||
queryRunner.manager.getRepository<LogicFunctionEntity>(
|
||||
LogicFunctionEntity,
|
||||
);
|
||||
|
||||
await logicFunctionRepository.update(
|
||||
entityId,
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction),
|
||||
);
|
||||
await logicFunctionRepository.update({ id: entityId, workspaceId }, update);
|
||||
|
||||
const flatLogicFunction = findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: entityId,
|
||||
flatEntityMaps: context.allFlatEntityMaps.flatLogicFunctionMaps,
|
||||
});
|
||||
|
||||
for (const update of flatAction.updates) {
|
||||
if (update.property === 'checksum' && isDefined(code)) {
|
||||
if (isDefined(update.checksum) && isDefined(code)) {
|
||||
await this.handleChecksumUpdate({
|
||||
flatLogicFunction,
|
||||
code,
|
||||
});
|
||||
}
|
||||
if (update.property === 'deletedAt' && isDefined(update.to)) {
|
||||
if (update.deletedAt !== undefined) {
|
||||
await this.handleDeletedAtUpdate({
|
||||
flatLogicFunction,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async handleDeletedAtUpdate({
|
||||
flatLogicFunction,
|
||||
|
||||
+2
-5
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateNavigationMenuItemActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -25,7 +24,7 @@ export class UpdateNavigationMenuItemActionHandlerService extends WorkspaceMigra
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateNavigationMenuItemAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, updates } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const navigationMenuItemRepository =
|
||||
queryRunner.manager.getRepository<NavigationMenuItemEntity>(
|
||||
@@ -34,9 +33,7 @@ export class UpdateNavigationMenuItemActionHandlerService extends WorkspaceMigra
|
||||
|
||||
await navigationMenuItemRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates,
|
||||
}),
|
||||
update,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+5
-12
@@ -13,7 +13,6 @@ 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 { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration/utils/find-flat-entity-property-update.util';
|
||||
import {
|
||||
type FlatUpdateObjectAction,
|
||||
type UniversalUpdateObjectAction,
|
||||
@@ -22,7 +21,6 @@ import {
|
||||
type WorkspaceMigrationActionRunnerArgs,
|
||||
type WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
import { getWorkspaceSchemaContextForMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/get-workspace-schema-context-for-migration.util';
|
||||
import {
|
||||
collectEnumOperationsForObject,
|
||||
@@ -58,7 +56,7 @@ export class UpdateObjectActionHandlerService extends WorkspaceMigrationRunnerAc
|
||||
type: 'update',
|
||||
metadataName: 'objectMetadata',
|
||||
entityId: flatObjectMetadata.id,
|
||||
updates: action.updates,
|
||||
update: action.update,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,7 +72,7 @@ export class UpdateObjectActionHandlerService extends WorkspaceMigrationRunnerAc
|
||||
|
||||
await objectMetadataRepository.update(
|
||||
flatAction.entityId,
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction),
|
||||
flatAction.update,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -87,7 +85,7 @@ export class UpdateObjectActionHandlerService extends WorkspaceMigrationRunnerAc
|
||||
allFlatEntityMaps: { flatObjectMetadataMaps, flatFieldMetadataMaps },
|
||||
workspaceId,
|
||||
} = context;
|
||||
const { entityId, updates } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityMaps: flatObjectMetadataMaps,
|
||||
@@ -100,15 +98,10 @@ export class UpdateObjectActionHandlerService extends WorkspaceMigrationRunnerAc
|
||||
objectMetadata: flatObjectMetadata,
|
||||
});
|
||||
|
||||
const nameSingularUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates: updates,
|
||||
property: 'nameSingular',
|
||||
});
|
||||
|
||||
if (isDefined(nameSingularUpdate)) {
|
||||
if (isDefined(update.nameSingular)) {
|
||||
const updatedFlatObjectMetadata: FlatObjectMetadata = {
|
||||
...flatObjectMetadata,
|
||||
nameSingular: nameSingularUpdate.to,
|
||||
nameSingular: update.nameSingular,
|
||||
};
|
||||
|
||||
const newTableName = computeObjectTargetTable(updatedFlatObjectMetadata);
|
||||
|
||||
+2
-8
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdatePageLayoutTabActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -25,19 +24,14 @@ export class UpdatePageLayoutTabActionHandlerService extends WorkspaceMigrationR
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdatePageLayoutTabAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, updates } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const pageLayoutTabRepository =
|
||||
queryRunner.manager.getRepository<PageLayoutTabEntity>(
|
||||
PageLayoutTabEntity,
|
||||
);
|
||||
|
||||
await pageLayoutTabRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates,
|
||||
}),
|
||||
);
|
||||
await pageLayoutTabRepository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+4
-10
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdatePageLayoutWidgetActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -28,22 +27,17 @@ export class UpdatePageLayoutWidgetActionHandlerService extends WorkspaceMigrati
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdatePageLayoutWidgetAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { entityId, updates } = flatAction;
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const pageLayoutWidgetRepository =
|
||||
queryRunner.manager.getRepository<PageLayoutWidgetEntity>(
|
||||
PageLayoutWidgetEntity,
|
||||
);
|
||||
|
||||
const partialPageLayoutWidget =
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates,
|
||||
});
|
||||
|
||||
await pageLayoutWidgetRepository.update(
|
||||
{ id: entityId },
|
||||
partialPageLayoutWidget,
|
||||
{ id: entityId, workspaceId },
|
||||
update,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+2
-8
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdatePageLayoutActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -25,17 +24,12 @@ export class UpdatePageLayoutActionHandlerService extends WorkspaceMigrationRunn
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdatePageLayoutAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, updates } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const pageLayoutRepository =
|
||||
queryRunner.manager.getRepository<PageLayoutEntity>(PageLayoutEntity);
|
||||
|
||||
await pageLayoutRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates,
|
||||
}),
|
||||
);
|
||||
await pageLayoutRepository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+3
-7
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateRoleTargetActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -28,16 +27,13 @@ export class UpdateRoleTargetActionHandlerService extends WorkspaceMigrationRunn
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateRoleTargetAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { entityId } = flatAction;
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const roleTargetRepository =
|
||||
queryRunner.manager.getRepository<RoleTargetEntity>(RoleTargetEntity);
|
||||
|
||||
const update =
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction);
|
||||
|
||||
await roleTargetRepository.update(entityId, update);
|
||||
await roleTargetRepository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+2
-6
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateRoleActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -25,15 +24,12 @@ export class UpdateRoleActionHandlerService extends WorkspaceMigrationRunnerActi
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateRoleAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const roleRepository =
|
||||
queryRunner.manager.getRepository<RoleEntity>(RoleEntity);
|
||||
|
||||
await roleRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction),
|
||||
);
|
||||
await roleRepository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+3
-7
@@ -10,7 +10,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateRowLevelPermissionPredicateGroupActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -26,18 +25,15 @@ export class UpdateRowLevelPermissionPredicateGroupActionHandlerService extends
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateRowLevelPermissionPredicateGroupAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { entityId } = flatAction;
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const repository =
|
||||
queryRunner.manager.getRepository<RowLevelPermissionPredicateGroupEntity>(
|
||||
RowLevelPermissionPredicateGroupEntity,
|
||||
);
|
||||
|
||||
const update =
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction);
|
||||
|
||||
await repository.update(entityId, update);
|
||||
await repository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+3
-7
@@ -10,7 +10,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateRowLevelPermissionPredicateActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -26,18 +25,15 @@ export class UpdateRowLevelPermissionPredicateActionHandlerService extends Works
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateRowLevelPermissionPredicateAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { entityId } = flatAction;
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const repository =
|
||||
queryRunner.manager.getRepository<RowLevelPermissionPredicateEntity>(
|
||||
RowLevelPermissionPredicateEntity,
|
||||
);
|
||||
|
||||
const update =
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction);
|
||||
|
||||
await repository.update(entityId, update);
|
||||
await repository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+2
-8
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateSkillActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -25,17 +24,12 @@ export class UpdateSkillActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateSkillAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, updates } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const skillRepository =
|
||||
queryRunner.manager.getRepository<SkillEntity>(SkillEntity);
|
||||
|
||||
await skillRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates,
|
||||
}),
|
||||
);
|
||||
await skillRepository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+3
-7
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateViewFieldActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -28,16 +27,13 @@ export class UpdateViewFieldActionHandlerService extends WorkspaceMigrationRunne
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateViewFieldAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { entityId } = flatAction;
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const viewFieldRepository =
|
||||
queryRunner.manager.getRepository<ViewFieldEntity>(ViewFieldEntity);
|
||||
|
||||
const update =
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction);
|
||||
|
||||
await viewFieldRepository.update(entityId, update);
|
||||
await viewFieldRepository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+6
-7
@@ -8,7 +8,6 @@ import {
|
||||
type WorkspaceMigrationActionRunnerArgs,
|
||||
type WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateViewFilterGroupActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -28,18 +27,18 @@ export class UpdateViewFilterGroupActionHandlerService extends WorkspaceMigratio
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateViewFilterGroupAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { entityId } = flatAction;
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const viewFilterGroupRepository =
|
||||
queryRunner.manager.getRepository<ViewFilterGroupEntity>(
|
||||
ViewFilterGroupEntity,
|
||||
);
|
||||
|
||||
const update =
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction);
|
||||
|
||||
await viewFilterGroupRepository.update(entityId, update);
|
||||
await viewFilterGroupRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
update,
|
||||
);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+3
-7
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateViewFilterActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -28,16 +27,13 @@ export class UpdateViewFilterActionHandlerService extends WorkspaceMigrationRunn
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateViewFilterAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { entityId } = flatAction;
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const viewFilterRepository =
|
||||
queryRunner.manager.getRepository<ViewFilterEntity>(ViewFilterEntity);
|
||||
|
||||
const update =
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction);
|
||||
|
||||
await viewFilterRepository.update(entityId, update);
|
||||
await viewFilterRepository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+3
-7
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateViewGroupActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -24,16 +23,13 @@ export class UpdateViewGroupActionHandlerService extends WorkspaceMigrationRunne
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateViewGroupAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { entityId } = flatAction;
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const viewGroupRepository =
|
||||
queryRunner.manager.getRepository<ViewGroupEntity>(ViewGroupEntity);
|
||||
|
||||
const update =
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction);
|
||||
|
||||
await viewGroupRepository.update(entityId, update);
|
||||
await viewGroupRepository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+3
-7
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateViewActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -28,16 +27,13 @@ export class UpdateViewActionHandlerService extends WorkspaceMigrationRunnerActi
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateViewAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { entityId } = flatAction;
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const viewRepository =
|
||||
queryRunner.manager.getRepository<ViewEntity>(ViewEntity);
|
||||
|
||||
await viewRepository.update(
|
||||
entityId,
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction),
|
||||
);
|
||||
await viewRepository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+2
-8
@@ -8,7 +8,6 @@ import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateWebhookActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
@@ -25,17 +24,12 @@ export class UpdateWebhookActionHandlerService extends WorkspaceMigrationRunnerA
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdateWebhookAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, updates } = flatAction;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const webhookRepository =
|
||||
queryRunner.manager.getRepository<WebhookEntity>(WebhookEntity);
|
||||
|
||||
await webhookRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
fromFlatEntityPropertiesUpdatesToPartialFlatEntity({
|
||||
updates,
|
||||
}),
|
||||
);
|
||||
await webhookRepository.update({ id: entityId, workspaceId }, update);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
|
||||
+30
-1
@@ -6,6 +6,7 @@ import { LoggerService } from 'src/engine/core-modules/logger/logger.service';
|
||||
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
|
||||
import { AllFlatEntityTypesByMetadataName } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-types-by-metadata-name';
|
||||
import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
|
||||
import { MetadataRelatedFlatEntityMapsKeys } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-flat-entity-maps-keys.type';
|
||||
import { MetadataToFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/types/metadata-to-flat-entity-maps-key';
|
||||
@@ -30,6 +31,7 @@ import {
|
||||
import { optimisticallyApplyCreateActionOnAllFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-create-action-on-all-flat-entity-maps.util';
|
||||
import { optimisticallyApplyDeleteActionOnAllFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-delete-action-on-all-flat-entity-maps.util';
|
||||
import { optimisticallyApplyUpdateActionOnAllFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-update-action-on-all-flat-entity-maps.util';
|
||||
import { sanitizeFlatEntityUpdate } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/sanitize-flat-entity-update.util';
|
||||
|
||||
type OptimisticallyApplyActionOnAllFlatEntityMapsArgs<
|
||||
TFlatAction extends AllFlatWorkspaceMigrationAction,
|
||||
@@ -131,11 +133,38 @@ export abstract class BaseWorkspaceMigrationRunnerActionHandlerService<
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
private sanitizeUniversalAction(
|
||||
universalAction: TUniversalAction,
|
||||
): TUniversalAction {
|
||||
if (universalAction.type === 'update') {
|
||||
const sanitizedFlatEntityUpdate = sanitizeFlatEntityUpdate({
|
||||
metadataName: universalAction.metadataName,
|
||||
flatEntityUpdate: universalAction.update as FlatEntityUpdate<
|
||||
typeof universalAction.metadataName
|
||||
>,
|
||||
});
|
||||
|
||||
return {
|
||||
...universalAction,
|
||||
update: sanitizedFlatEntityUpdate,
|
||||
};
|
||||
}
|
||||
|
||||
return universalAction;
|
||||
}
|
||||
|
||||
private async transpileUniversalActionToFlatActionOrThrow(
|
||||
context: WorkspaceMigrationActionRunnerArgs<TUniversalAction>,
|
||||
): Promise<TFlatAction> {
|
||||
try {
|
||||
return await this.transpileUniversalActionToFlatAction(context);
|
||||
const sanitizedUniversalAction = this.sanitizeUniversalAction(
|
||||
context.action,
|
||||
);
|
||||
|
||||
return await this.transpileUniversalActionToFlatAction({
|
||||
...context,
|
||||
action: sanitizedUniversalAction,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new WorkspaceMigrationRunnerException({
|
||||
action: context.action,
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`sanitizeFlatEntityUpdate should handle agent metadata updates 1`] = `
|
||||
{
|
||||
"description": "Agent description",
|
||||
"name": "My Agent",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`sanitizeFlatEntityUpdate should handle role metadata updates 1`] = `
|
||||
{
|
||||
"description": "Administrator role",
|
||||
"label": "Admin Role",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`sanitizeFlatEntityUpdate should handle viewField metadata updates 1`] = `
|
||||
{
|
||||
"isVisible": true,
|
||||
"position": 1,
|
||||
"size": 100,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`sanitizeFlatEntityUpdate should handle webhook metadata updates 1`] = `
|
||||
{
|
||||
"description": "My webhook",
|
||||
"targetUrl": "https://example.com/webhook",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`sanitizeFlatEntityUpdate should preserve null values as they are valid updates for fieldMetadata 1`] = `
|
||||
{
|
||||
"description": "Updated description",
|
||||
"isActive": false,
|
||||
"label": null,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`sanitizeFlatEntityUpdate should return empty object when all properties are undefined for fieldMetadata 1`] = `{}`;
|
||||
|
||||
exports[`sanitizeFlatEntityUpdate should return empty object when update is empty for fieldMetadata 1`] = `{}`;
|
||||
|
||||
exports[`sanitizeFlatEntityUpdate should return only valid properties for fieldMetadata when update contains valid and invalid properties 1`] = `
|
||||
{
|
||||
"isActive": true,
|
||||
"label": "New Label",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`sanitizeFlatEntityUpdate should return only valid properties for objectMetadata 1`] = `
|
||||
{
|
||||
"isActive": true,
|
||||
"labelPlural": "People",
|
||||
"labelSingular": "Person",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`sanitizeFlatEntityUpdate should return only valid properties for view metadata 1`] = `
|
||||
{
|
||||
"icon": "IconUser",
|
||||
"name": "My View",
|
||||
}
|
||||
`;
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
import { sanitizeFlatEntityUpdate } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/sanitize-flat-entity-update.util';
|
||||
|
||||
describe('sanitizeFlatEntityUpdate', () => {
|
||||
it('should return only valid properties for fieldMetadata when update contains valid and invalid properties', () => {
|
||||
const result = sanitizeFlatEntityUpdate({
|
||||
flatEntityUpdate: {
|
||||
isActive: true,
|
||||
label: 'New Label',
|
||||
invalidProperty: 'should be removed',
|
||||
} as any,
|
||||
metadataName: 'fieldMetadata' as AllMetadataName,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should return empty object when all properties are undefined for fieldMetadata', () => {
|
||||
const result = sanitizeFlatEntityUpdate({
|
||||
flatEntityUpdate: {
|
||||
isActive: undefined,
|
||||
label: undefined,
|
||||
} as any,
|
||||
metadataName: 'fieldMetadata' as AllMetadataName,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should return empty object when update is empty for fieldMetadata', () => {
|
||||
const result = sanitizeFlatEntityUpdate({
|
||||
flatEntityUpdate: {} as any,
|
||||
metadataName: 'fieldMetadata' as AllMetadataName,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should preserve null values as they are valid updates for fieldMetadata', () => {
|
||||
const result = sanitizeFlatEntityUpdate({
|
||||
flatEntityUpdate: {
|
||||
isActive: false,
|
||||
label: null,
|
||||
description: 'Updated description',
|
||||
} as any,
|
||||
metadataName: 'fieldMetadata' as AllMetadataName,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should return only valid properties for view metadata', () => {
|
||||
const result = sanitizeFlatEntityUpdate({
|
||||
flatEntityUpdate: {
|
||||
name: 'My View',
|
||||
icon: 'IconUser',
|
||||
invalidProperty: 'should be removed',
|
||||
} as any,
|
||||
metadataName: 'view' as AllMetadataName,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should return only valid properties for objectMetadata', () => {
|
||||
const result = sanitizeFlatEntityUpdate({
|
||||
flatEntityUpdate: {
|
||||
isActive: true,
|
||||
labelSingular: 'Person',
|
||||
labelPlural: 'People',
|
||||
invalidProperty: 'should be removed',
|
||||
} as any,
|
||||
metadataName: 'objectMetadata' as AllMetadataName,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should handle viewField metadata updates', () => {
|
||||
const result = sanitizeFlatEntityUpdate({
|
||||
flatEntityUpdate: {
|
||||
position: 1,
|
||||
size: 100,
|
||||
isVisible: true,
|
||||
invalidProperty: 'should be removed',
|
||||
} as any,
|
||||
metadataName: 'viewField' as AllMetadataName,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should handle role metadata updates', () => {
|
||||
const result = sanitizeFlatEntityUpdate({
|
||||
flatEntityUpdate: {
|
||||
label: 'Admin Role',
|
||||
description: 'Administrator role',
|
||||
invalidProperty: 'should be removed',
|
||||
} as any,
|
||||
metadataName: 'role' as AllMetadataName,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should handle agent metadata updates', () => {
|
||||
const result = sanitizeFlatEntityUpdate({
|
||||
flatEntityUpdate: {
|
||||
name: 'My Agent',
|
||||
description: 'Agent description',
|
||||
invalidProperty: 'should be removed',
|
||||
} as any,
|
||||
metadataName: 'agent' as AllMetadataName,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should handle webhook metadata updates', () => {
|
||||
const result = sanitizeFlatEntityUpdate({
|
||||
flatEntityUpdate: {
|
||||
targetUrl: 'https://example.com/webhook',
|
||||
description: 'My webhook',
|
||||
invalidProperty: 'should be removed',
|
||||
} as any,
|
||||
metadataName: 'webhook' as AllMetadataName,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
export const fromFlatEntityPropertiesUpdatesToPartialFlatEntity = <
|
||||
T extends { updates: Array<{ property: string; to: unknown }> },
|
||||
>(
|
||||
action: T,
|
||||
) => {
|
||||
return action.updates.reduce((acc, { to, property }) => {
|
||||
return {
|
||||
...acc,
|
||||
[property]: to,
|
||||
};
|
||||
}, {});
|
||||
};
|
||||
+1
-2
@@ -9,7 +9,6 @@ import { deleteFlatEntityFromFlatEntityAndRelatedEntityMapsThroughMutationOrThro
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
|
||||
import { replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
|
||||
type FlatUpdateAction<TMetadataName extends AllMetadataName> =
|
||||
AllFlatEntityTypesByMetadataName[TMetadataName]['flatActions']['update'];
|
||||
@@ -81,7 +80,7 @@ export const optimisticallyApplyUpdateActionOnAllFlatEntityMaps = <
|
||||
|
||||
const toFlatEntity = {
|
||||
...fromFlatEntity,
|
||||
...fromFlatEntityPropertiesUpdatesToPartialFlatEntity(flatAction),
|
||||
...flatAction.update,
|
||||
};
|
||||
|
||||
replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
import { ALL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY } from 'src/engine/metadata-modules/flat-entity/constant/all-flat-entity-properties-to-compare-and-stringify.constant';
|
||||
import {
|
||||
type FlatEntityUpdate,
|
||||
type MetadataFlatEntityComparableProperties,
|
||||
} from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
|
||||
export const sanitizeFlatEntityUpdate = <T extends AllMetadataName>({
|
||||
flatEntityUpdate,
|
||||
metadataName,
|
||||
}: {
|
||||
flatEntityUpdate: FlatEntityUpdate<T>;
|
||||
metadataName: T;
|
||||
}): FlatEntityUpdate<T> => {
|
||||
const { propertiesToCompare } =
|
||||
ALL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY[metadataName];
|
||||
|
||||
const initialAccumulator: FlatEntityUpdate<T> = {};
|
||||
|
||||
return propertiesToCompare.reduce((accumulator, property) => {
|
||||
const updatedValue =
|
||||
flatEntityUpdate[property as MetadataFlatEntityComparableProperties<T>];
|
||||
|
||||
if (updatedValue === undefined) {
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
return {
|
||||
...accumulator,
|
||||
[property]: updatedValue,
|
||||
};
|
||||
}, initialAccumulator);
|
||||
};
|
||||
Reference in New Issue
Block a user