Fix - Update searchVector when labelIdentifier is updated (#16940)
Fixes https://github.com/twentyhq/twenty/issues/16891 In next PR, validation rules will be added in migration logic
This commit is contained in:
+2
@@ -171,12 +171,14 @@ export const fromUpdateFieldInputToFlatFieldMetadata = ({
|
||||
flatViewsToDelete,
|
||||
flatViewFieldsToDelete,
|
||||
flatViewsToUpdate,
|
||||
flatFieldMetadatasToUpdate: flatFieldMetadatasToUpdateFromSideEffect,
|
||||
} = sideEffectResult.result;
|
||||
|
||||
return {
|
||||
flatFieldMetadatasToUpdate: [
|
||||
...accumulator.flatFieldMetadatasToUpdate,
|
||||
toFlatFieldMetadata,
|
||||
...flatFieldMetadatasToUpdateFromSideEffect,
|
||||
],
|
||||
flatIndexMetadatasToUpdate: [
|
||||
...accumulator.flatIndexMetadatasToUpdate,
|
||||
|
||||
+32
-1
@@ -1,6 +1,8 @@
|
||||
import { type FromTo } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { type FieldInputTranspilationResult } from 'src/engine/metadata-modules/flat-field-metadata/types/field-input-transpilation-result.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { handleEnumFlatFieldMetadataUpdateSideEffects } from 'src/engine/metadata-modules/flat-field-metadata/utils/handle-enum-flat-field-metadata-update-side-effects.util';
|
||||
@@ -12,6 +14,7 @@ import {
|
||||
type FieldMetadataUpdateIndexSideEffect,
|
||||
handleIndexChangesDuringFieldUpdate,
|
||||
} from 'src/engine/metadata-modules/flat-field-metadata/utils/handle-index-changes-during-field-update.util';
|
||||
import { handleLabelIdentifierChangesDuringFieldUpdate } from 'src/engine/metadata-modules/flat-field-metadata/utils/handle-label-identifier-changes-during-field-update.util';
|
||||
import { isEnumFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-enum-flat-field-metadata.util';
|
||||
import { type FlatViewFiltersToDeleteAndUpdate } from 'src/engine/metadata-modules/flat-field-metadata/utils/recompute-view-filters-on-flat-field-metadata-options-update.util';
|
||||
import { type FlatViewGroupsToDeleteUpdateAndCreate } from 'src/engine/metadata-modules/flat-field-metadata/utils/recompute-view-groups-on-flat-field-metadata-options-update.util';
|
||||
@@ -20,7 +23,9 @@ export type FlatFieldMetadataUpdateSideEffects =
|
||||
FlatViewFiltersToDeleteAndUpdate &
|
||||
FlatViewGroupsToDeleteUpdateAndCreate &
|
||||
FieldMetadataUpdateIndexSideEffect &
|
||||
FieldMetadataDeactivationSideEffect;
|
||||
FieldMetadataDeactivationSideEffect & {
|
||||
flatFieldMetadatasToUpdate: FlatFieldMetadata[];
|
||||
};
|
||||
|
||||
type HandleFlatFieldMetadataUpdateSideEffectArgs = FromTo<
|
||||
FlatFieldMetadata,
|
||||
@@ -52,6 +57,7 @@ export const FLAT_FIELD_METADATA_UPDATE_EMPTY_SIDE_EFFECTS: FlatFieldMetadataUpd
|
||||
flatViewsToDelete: [],
|
||||
flatViewFieldsToDelete: [],
|
||||
flatViewsToUpdate: [],
|
||||
flatFieldMetadatasToUpdate: [],
|
||||
};
|
||||
|
||||
export const handleFlatFieldMetadataUpdateSideEffect = ({
|
||||
@@ -131,6 +137,31 @@ export const handleFlatFieldMetadataUpdateSideEffect = ({
|
||||
return indexChangesSideEffectResult;
|
||||
}
|
||||
|
||||
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityMaps: flatObjectMetadataMaps,
|
||||
flatEntityId: fromFlatFieldMetadata.objectMetadataId,
|
||||
});
|
||||
|
||||
const isLabelIdentifierFieldMetadata =
|
||||
flatObjectMetadata.labelIdentifierFieldMetadataId ===
|
||||
toFlatFieldMetadata.id;
|
||||
|
||||
if (isLabelIdentifierFieldMetadata) {
|
||||
const flatSearchVectorFieldToUpdate =
|
||||
handleLabelIdentifierChangesDuringFieldUpdate({
|
||||
fromFlatFieldMetadata,
|
||||
toFlatFieldMetadata,
|
||||
flatObjectMetadata,
|
||||
flatFieldMetadataMaps,
|
||||
});
|
||||
|
||||
if (isDefined(flatSearchVectorFieldToUpdate)) {
|
||||
sideEffectResult.flatFieldMetadatasToUpdate.push(
|
||||
flatSearchVectorFieldToUpdate,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
flatIndexMetadatasToUpdate,
|
||||
flatIndexMetadatasToCreate,
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
import { type FieldMetadataType, type FromTo } from 'twenty-shared/types';
|
||||
import { findOrThrow } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
FieldMetadataException,
|
||||
FieldMetadataExceptionCode,
|
||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
|
||||
import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/search-field-metadata/constants/search-vector-field.constants';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
import { type SearchableFieldType } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/is-searchable-field.util';
|
||||
|
||||
type HandleLabelIdentifierChangesDuringFieldUpdateArgs = {
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
} & FromTo<FlatFieldMetadata, 'flatFieldMetadata'> &
|
||||
Pick<AllFlatEntityMaps, 'flatFieldMetadataMaps'>;
|
||||
|
||||
export const handleLabelIdentifierChangesDuringFieldUpdate = ({
|
||||
fromFlatFieldMetadata,
|
||||
toFlatFieldMetadata,
|
||||
flatObjectMetadata,
|
||||
flatFieldMetadataMaps,
|
||||
}: HandleLabelIdentifierChangesDuringFieldUpdateArgs):
|
||||
| FlatFieldMetadata<FieldMetadataType.TS_VECTOR>
|
||||
| undefined => {
|
||||
const hasNameChanged =
|
||||
fromFlatFieldMetadata.name !== toFlatFieldMetadata.name;
|
||||
|
||||
if (!hasNameChanged) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const objectFlatFieldMetadatas =
|
||||
findManyFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityMaps: flatFieldMetadataMaps,
|
||||
flatEntityIds: flatObjectMetadata.fieldMetadataIds,
|
||||
});
|
||||
|
||||
const searchVectorField = findOrThrow(
|
||||
objectFlatFieldMetadatas,
|
||||
(field) => field.name === SEARCH_VECTOR_FIELD.name,
|
||||
new FieldMetadataException(
|
||||
`Search vector field not found for object metadata ${flatObjectMetadata.id}`,
|
||||
FieldMetadataExceptionCode.FIELD_METADATA_NOT_FOUND,
|
||||
),
|
||||
) as FlatFieldMetadata<FieldMetadataType.TS_VECTOR>;
|
||||
|
||||
try {
|
||||
const newAsExpression = getTsVectorColumnExpressionFromFields([
|
||||
{
|
||||
name: toFlatFieldMetadata.name,
|
||||
type: toFlatFieldMetadata.type as SearchableFieldType,
|
||||
},
|
||||
]);
|
||||
|
||||
return {
|
||||
...searchVectorField,
|
||||
settings: {
|
||||
...searchVectorField.settings,
|
||||
asExpression: newAsExpression,
|
||||
},
|
||||
};
|
||||
} catch {
|
||||
throw new FieldMetadataException(
|
||||
`Failed to compute search vector column expression for field ${toFlatFieldMetadata.name}`,
|
||||
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
|
||||
);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user