Workspace schema migration runner v2 - Fix Enums and Create TsVector (#13955)

## Context
- Adding ts-vector generatedType/asExpression as TS_VECTOR settings
- Using those settings to setup properly tsVector searchVector column
through the new migration runner
- Fix enum creation/suppression

Note: regarding the new tsVector, we should implement a command to
update existing fields

TODO: 
- TS_VECTOR search vector column update (note: should be properly
updated whenever the object labelIdentifier is updated or a new TEXT
field is added to the object to follow the current logic)
- relation type fields and columns are not implemented yet 
- index migrations
This commit is contained in:
Weiko
2025-08-18 16:33:51 +02:00
committed by GitHub
parent 3d3191425e
commit 43bb8d6043
16 changed files with 280 additions and 297 deletions
@@ -48,6 +48,11 @@ export type FieldMetadataAddressSettings = {
subFields?: AllowedAddressSubField[];
};
export type FieldMetadataTsVectorSettings = {
asExpression?: string;
generatedType?: 'STORED' | 'VIRTUAL';
};
type FieldMetadataSettingsMapping = {
[FieldMetadataType.NUMBER]: FieldMetadataNumberSettings | null;
[FieldMetadataType.DATE]: FieldMetadataDateSettings | null;
@@ -56,6 +61,7 @@ type FieldMetadataSettingsMapping = {
[FieldMetadataType.RELATION]: FieldMetadataRelationSettings;
[FieldMetadataType.ADDRESS]: FieldMetadataAddressSettings | null;
[FieldMetadataType.MORPH_RELATION]: FieldMetadataRelationSettings | null; // TODO Should not be null
[FieldMetadataType.TS_VECTOR]: FieldMetadataTsVectorSettings | null;
};
export type AllFieldMetadataSettings =
@@ -125,6 +125,15 @@ export const fromCreateFieldInputToFlatFieldMetadatasToCreate = async ({
],
};
}
case FieldMetadataType.TS_VECTOR: {
return {
status: 'fail',
error: new FieldMetadataException(
'TS Vector is not supported for field creation',
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
),
};
}
case FieldMetadataType.UUID:
case FieldMetadataType.TEXT:
case FieldMetadataType.PHONES:
@@ -143,8 +152,7 @@ export const fromCreateFieldInputToFlatFieldMetadatasToCreate = async ({
case FieldMetadataType.RICH_TEXT:
case FieldMetadataType.RICH_TEXT_V2:
case FieldMetadataType.ACTOR:
case FieldMetadataType.ARRAY:
case FieldMetadataType.TS_VECTOR: {
case FieldMetadataType.ARRAY: {
return {
status: 'success',
result: [
@@ -10,4 +10,5 @@ export const FLAT_OBJECT_METADATA_PROPERTIES_TO_COMPARE = [
'namePlural',
'nameSingular',
'standardOverrides', // Only if standard
'labelIdentifierFieldMetadataId',
] as const satisfies (keyof FlatObjectMetadata)[];
@@ -7,6 +7,7 @@ import {
BASE_OBJECT_STANDARD_FIELD_IDS,
CUSTOM_OBJECT_STANDARD_FIELD_IDS,
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
export const buildDefaultFieldsForCustomObject = (
workspaceId: string,
@@ -336,6 +337,39 @@ export const buildDefaultFlatFieldMetadataForCustomObject = ({
settings: null,
};
const searchVectorField: FlatFieldMetadata<FieldMetadataType.TS_VECTOR> = {
type: FieldMetadataType.TS_VECTOR,
id: v4(),
isLabelSyncedWithName: false,
isUnique: false,
objectMetadataId,
uniqueIdentifier: CUSTOM_OBJECT_STANDARD_FIELD_IDS.searchVector,
workspaceId,
standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.searchVector,
name: 'searchVector',
label: 'Search vector',
icon: 'IconSearch',
description: 'Search vector',
isNullable: true,
isActive: true,
isCustom: false,
isSystem: true,
defaultValue: null,
createdAt,
updatedAt: createdAt,
flatRelationTargetFieldMetadata: null,
flatRelationTargetObjectMetadata: null,
options: null,
standardOverrides: null,
relationTargetFieldMetadataId: null,
relationTargetObjectMetadataId: null,
settings: {
asExpression: getTsVectorColumnExpressionFromFields([nameField]),
generatedType: 'STORED',
},
};
return {
idField,
nameField,
@@ -344,5 +378,6 @@ export const buildDefaultFlatFieldMetadataForCustomObject = ({
deletedAtField,
createdByField,
positionField,
searchVectorField,
} as const;
};