Migrate Views-xxx Index Field Object Skill to be fully universal ( all actions and metadata runner and builder ) + all metadata update actions runner (#17687)

# What this PR does
Overall naming `universal` versus `flat` is not always the most updated
and so on
Will make a big cleaning tour after I've finished the whole migration
Migrating all `view` and ( filter fields etc ) `field` `object` `index`
to the universal pattern on all `services`, `builder` and `runner`
levels

## Universal and flat optimistic tooling

`addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow`
and its delete counterpart maintain the consistency of
`UniversalFlatEntityMaps` when an entity is created or removed. Beyond
inserting/removing the entity from its own maps, they walk through
`ALL_UNIVERSAL_METADATA_RELATIONS` to update the **aggregator arrays**
on related parent entities — the add appends the new entity's
`universalIdentifier` to the parent's aggregator (e.g. a new viewField's
identifier gets appended to its parent view's
`viewFieldUniversalIdentifiers`), and the delete filters it out. This
keeps the maps in sync so that diff computations and relation lookups
remain accurate throughout the migration building process.

## ALL_UNIVERSAL_METADATA_RELATIONS
`ALL_UNIVERSAL_METADATA_RELATIONS` is the universal counterpart of
`ALL_METADATA_RELATIONS`. It maps each metadata entity to its
many-to-one and one-to-many relations using universal foreign keys
(`*UniversalIdentifier`) instead of database IDs (`*Id`). This allows
migration actions to reference related entities in a workspace-agnostic
way. Relations that are workspace-specific (e.g. `workspace`,
`dataSource`, `userWorkspace`) are set to `null` and skipped during
resolution.

## `workspaceMigrationCreateIdEnrichment`
Reserved to API metadata ( will be able to validate at app installation
lvl )
- Workspace migration `create` actions now carry an optional `id` (and
`fieldIdByUniversalIdentifier` for object/field actions) so that
caller-provided IDs flow through the entire build-validate-run pipeline.
- New `enrichCreateWorkspaceMigrationActionsWithIds` utility resolves
`universalIdentifier → id` mappings after the builder runs and injects
them into the migration actions before the runner persists entities.
- Runner action handlers use the provided IDs instead of generating new
UUIDs, enabling deterministic entity creation for synchronization
workflows.


## `resolveUniversalUpdateRelationIdentifiersToIds`
`resolveUniversalUpdateRelationIdentifiersToIds` converts universal
identifiers (workspace-agnostic, stable keys) in a migration update
payload into concrete database UUIDs, so the update can be applied to a
specific workspace.

It iterates over the many-to-one relations defined in
`ALL_UNIVERSAL_METADATA_RELATIONS` for the given entity type, replaces
each `*UniversalIdentifier` property with its corresponding `*Id` by
looking up the target entity in `allFlatEntityMaps`, and throws if a
non-null identifier can't be resolved.

Used by all `update` action handlers in
`transpileUniversalActionToFlatAction`, avoiding duplicated resolution
logic across handlers.

## What this PR does not
- Migrating twenty-standard declaration to universal
- Migrating all the inputs transpilers to universal
- Migrating all metadata to be fully universal ( we still need to
de-scope the type of all of them and refactor their validator very close
)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Paul Rastoin
2026-02-09 19:02:38 +01:00
committed by GitHub
parent 2a76e1791e
commit 8c951d3623
366 changed files with 10036 additions and 6606 deletions
@@ -1,7 +1,7 @@
import { FieldMetadataType, RelationType } from 'twenty-shared/types';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { getMorphNameFromMorphFieldMetadataName } from 'src/engine/metadata-modules/flat-object-metadata/utils/get-morph-name-from-morph-field-metadata-name.util';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
describe('getMorphNameFromMorphFieldMetadataName', () => {
const createMorphRelationFlatFieldMetadataMock = (
@@ -12,8 +12,8 @@ describe('getMorphNameFromMorphFieldMetadataName', () => {
name,
type: FieldMetadataType.MORPH_RELATION,
label: name,
settings: { relationType },
}) as unknown as FlatFieldMetadata<FieldMetadataType.MORPH_RELATION>;
universalSettings: { relationType },
}) as unknown as UniversalFlatFieldMetadata<FieldMetadataType.MORPH_RELATION>;
it('should extract base morph field name for MANY_TO_ONE (removes singular suffix)', () => {
const morphRelationFlatFieldMetadata =
@@ -1,6 +1,6 @@
import { computeMetadataNameFromLabel } from 'twenty-shared/metadata';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { type UniversalFlatObjectMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-object-metadata.type';
export const areFlatObjectMetadataNamesSyncedWithLabels = ({
flatObjectdMetadata,
@@ -8,7 +8,7 @@ export const areFlatObjectMetadataNamesSyncedWithLabels = ({
}: {
isSystemBuild: boolean;
flatObjectdMetadata: Pick<
FlatObjectMetadata,
UniversalFlatObjectMetadata,
'namePlural' | 'nameSingular' | 'labelPlural' | 'labelSingular'
>;
}) => {
@@ -8,33 +8,31 @@ import { type FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interf
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { type CreateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input';
import { buildDefaultFlatFieldMetadatasForCustomObject } from 'src/engine/metadata-modules/object-metadata/utils/build-default-flat-field-metadatas-for-custom-object.util';
import { buildDefaultIndexesForCustomObject } from 'src/engine/metadata-modules/object-metadata/utils/build-default-index-for-custom-object.util';
import { buildDefaultRelationFlatFieldMetadatasForCustomObject } from 'src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
import { type UniversalFlatIndexMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-index-metadata.type';
import { type UniversalFlatObjectMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-object-metadata.type';
type FromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCreateArgs =
{
createObjectInput: CreateObjectInput;
workspaceId: string;
flatApplication: FlatApplication;
existingFeatureFlagsMap: FeatureFlagMap;
} & Pick<AllFlatEntityMaps, 'flatObjectMetadataMaps'>;
export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCreate =
({
createObjectInput: rawCreateObjectInput,
workspaceId,
flatApplication,
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
existingFeatureFlagsMap,
}: FromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCreateArgs): {
flatObjectMetadataToCreate: FlatObjectMetadata;
relationTargetFlatFieldMetadataToCreate: FlatFieldMetadata[];
flatFieldMetadataToCreateOnObject: FlatFieldMetadata[];
flatIndexMetadataToCreate: FlatIndexMetadata[];
flatObjectMetadataToCreate: UniversalFlatObjectMetadata & { id: string };
relationTargetFlatFieldMetadataToCreate: UniversalFlatFieldMetadata[];
flatFieldMetadataToCreateOnObject: UniversalFlatFieldMetadata[];
flatIndexMetadataToCreate: UniversalFlatIndexMetadata[];
} => {
const createObjectInput =
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
@@ -55,35 +53,29 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
const defaultFlatFieldForCustomObjectMaps =
buildDefaultFlatFieldMetadatasForCustomObject({
flatObjectMetadata: {
id: objectMetadataId,
applicationId: flatApplication.id,
applicationUniversalIdentifier: flatApplication.universalIdentifier,
universalIdentifier,
},
workspaceId,
skipNameField: createObjectInput.skipNameField,
});
const createdAt = new Date().toISOString();
// Use nameField.id if it exists, otherwise use idField.id (for junction tables without name)
const nameField = defaultFlatFieldForCustomObjectMaps.fields.nameField;
const labelIdentifierFieldMetadataId =
nameField?.id ?? defaultFlatFieldForCustomObjectMaps.fields.idField.id;
const labelIdentifierFieldMetadataUniversalIdentifier =
nameField?.universalIdentifier ??
defaultFlatFieldForCustomObjectMaps.fields.idField.universalIdentifier;
const flatObjectMetadataToCreate: FlatObjectMetadata = {
fieldIds: [],
viewIds: [],
indexMetadataIds: [],
const universalFlatObjectMetadataToCreate: UniversalFlatObjectMetadata & {
id: string;
} = {
id: objectMetadataId,
universalIdentifier,
createdAt,
updatedAt: createdAt,
duplicateCriteria: null,
description: createObjectInput.description ?? null,
icon: createObjectInput.icon ?? null,
id: objectMetadataId,
imageIdentifierFieldMetadataId: null,
isActive: true,
isAuditLogged: true,
isCustom: true,
@@ -92,17 +84,13 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
isSearchable: true,
isUIReadOnly: false,
isSystem: false,
labelIdentifierFieldMetadataId,
labelPlural: capitalize(createObjectInput.labelPlural),
labelSingular: capitalize(createObjectInput.labelSingular),
namePlural: createObjectInput.namePlural,
nameSingular: createObjectInput.nameSingular,
shortcut: createObjectInput.shortcut ?? null,
standardOverrides: null,
applicationId: flatApplication.id,
universalIdentifier,
targetTableName: 'DEPRECATED',
workspaceId,
applicationUniversalIdentifier: flatApplication.universalIdentifier,
fieldUniversalIdentifiers: [],
viewUniversalIdentifiers: [],
@@ -116,13 +104,12 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
standardTargetFlatFieldMetadatas,
} = buildDefaultRelationFlatFieldMetadatasForCustomObject({
existingFlatObjectMetadataMaps,
sourceFlatObjectMetadata: flatObjectMetadataToCreate,
workspaceId,
sourceFlatObjectMetadata: universalFlatObjectMetadataToCreate,
flatApplication,
existingFeatureFlagsMap,
});
const objectFlatFieldMetadatas: FlatFieldMetadata[] = [
const objectFlatFieldMetadatas: UniversalFlatFieldMetadata[] = [
...Object.values(defaultFlatFieldForCustomObjectMaps.fields),
...standardSourceFlatFieldMetadatas,
];
@@ -130,12 +117,11 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
const defaultIndexesForCustomObject = buildDefaultIndexesForCustomObject({
objectFlatFieldMetadatas,
defaultFlatFieldForCustomObjectMaps,
flatObjectMetadata: flatObjectMetadataToCreate,
workspaceId,
flatObjectMetadata: universalFlatObjectMetadataToCreate,
});
return {
flatObjectMetadataToCreate,
flatObjectMetadataToCreate: universalFlatObjectMetadataToCreate,
flatIndexMetadataToCreate: Object.values(
defaultIndexesForCustomObject.indexes,
),
@@ -6,16 +6,16 @@ import {
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 { 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 { findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util';
import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { type DeleteOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/delete-object.input';
import {
ObjectMetadataException,
ObjectMetadataExceptionCode,
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
import { type UniversalFlatObjectMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-object-metadata.type';
type FromDeleteObjectInputToFlatFieldMetadatasToDeleteArgs = {
deleteObjectInput: DeleteOneObjectInput;
@@ -30,8 +30,8 @@ export const fromDeleteObjectInputToFlatFieldMetadatasToDelete = ({
flatIndexMaps,
// This should return an AllFlatEntityMaps
}: FromDeleteObjectInputToFlatFieldMetadatasToDeleteArgs): {
flatFieldMetadatasToDelete: FlatFieldMetadata[];
flatObjectMetadataToDelete: FlatObjectMetadata;
flatFieldMetadatasToDelete: UniversalFlatFieldMetadata[];
flatObjectMetadataToDelete: UniversalFlatObjectMetadata;
flatIndexToDelete: FlatIndexMetadata[];
} => {
const { id: objectMetadataToDeleteId } =
@@ -4,9 +4,9 @@ import {
} 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 { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { FLAT_OBJECT_METADATA_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-object-metadata/constants/flat-object-metadata-editable-properties.constant';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import {
type FlatObjectMetadataUpdateSideEffects,
handleFlatObjectMetadataUpdateSideEffect,
@@ -18,6 +18,7 @@ import {
ObjectMetadataExceptionCode,
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
import { belongsToTwentyStandardApp } from 'src/engine/metadata-modules/utils/belongs-to-twenty-standard-app.util';
import { type UniversalFlatObjectMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-object-metadata.type';
import { mergeUpdateInExistingRecord } from 'src/utils/merge-update-in-existing-record.util';
type FromUpdateObjectInputToFlatObjectMetadataArgs = {
@@ -40,7 +41,7 @@ export const fromUpdateObjectInputToFlatObjectMetadataAndRelatedFlatEntities =
flatViewFieldMaps,
flatViewMaps,
}: FromUpdateObjectInputToFlatObjectMetadataArgs): FlatObjectMetadataUpdateSideEffects & {
flatObjectMetadataToUpdate: FlatObjectMetadata;
flatObjectMetadataToUpdate: UniversalFlatObjectMetadata;
} => {
const { id: objectMetadataIdToUpdate } =
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
@@ -81,6 +82,19 @@ export const fromUpdateObjectInputToFlatObjectMetadataAndRelatedFlatEntities =
standardOverrides,
};
if (
isDefined(updatedEditableObjectProperties.labelIdentifierFieldMetadataId)
) {
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityMaps: flatFieldMetadataMaps,
flatEntityId:
updatedEditableObjectProperties.labelIdentifierFieldMetadataId,
});
toFlatObjectMetadata.labelIdentifierFieldMetadataUniversalIdentifier =
flatFieldMetadata?.universalIdentifier;
}
const {
flatIndexMetadatasToUpdate,
flatViewFieldsToCreate,
@@ -1,8 +1,8 @@
import { type FieldMetadataType, RelationType } from 'twenty-shared/types';
import { capitalize } from 'twenty-shared/utils';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { searchAndReplaceLast } from 'src/engine/metadata-modules/flat-object-metadata/utils/search-and-replace-last.util';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
export const getMorphNameFromMorphFieldMetadataName = ({
morphRelationFlatFieldMetadata,
@@ -10,14 +10,14 @@ export const getMorphNameFromMorphFieldMetadataName = ({
namePlural,
}: {
morphRelationFlatFieldMetadata: Pick<
FlatFieldMetadata<FieldMetadataType.MORPH_RELATION>,
'name' | 'settings'
UniversalFlatFieldMetadata<FieldMetadataType.MORPH_RELATION>,
'name' | 'universalSettings'
>;
nameSingular: string;
namePlural: string;
}): string => {
const isManyToOneRelationType =
morphRelationFlatFieldMetadata.settings.relationType ===
morphRelationFlatFieldMetadata.universalSettings.relationType ===
RelationType.MANY_TO_ONE;
return searchAndReplaceLast({
@@ -3,20 +3,21 @@ import { isDefined } from 'twenty-shared/utils';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { recomputeIndexAfterFlatObjectMetadataSingularNameUpdate } from 'src/engine/metadata-modules/flat-object-metadata/utils/recompute-index-after-flat-object-metadata-singular-name-update.util';
import { recomputeSearchVectorFieldAfterLabelIdentifierUpdate } from 'src/engine/metadata-modules/flat-object-metadata/utils/recompute-search-vector-field-after-label-identifier-update.util';
import { recomputeViewFieldIdentifierAfterFlatObjectIdentifierUpdate } from 'src/engine/metadata-modules/flat-object-metadata/utils/recompute-view-field-identifier-after-flat-object-identifier-update.util';
import { renameRelatedMorphFieldOnObjectNamesUpdate } from 'src/engine/metadata-modules/flat-object-metadata/utils/rename-related-morph-field-on-object-names-update.util';
import { type FlatViewField } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field.type';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
import { type UniversalFlatIndexMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-index-metadata.type';
import { type UniversalFlatViewField } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-field.type';
export type FlatObjectMetadataUpdateSideEffects = {
otherObjectFlatFieldMetadatasToUpdate: FlatFieldMetadata[];
sameObjectFlatFieldMetadatasToUpdate: FlatFieldMetadata[];
flatViewFieldsToUpdate: FlatViewField[];
flatViewFieldsToCreate: FlatViewField[];
flatIndexMetadatasToUpdate: FlatIndexMetadata[];
otherObjectFlatFieldMetadatasToUpdate: UniversalFlatFieldMetadata[];
sameObjectFlatFieldMetadatasToUpdate: UniversalFlatFieldMetadata[];
flatViewFieldsToUpdate: UniversalFlatViewField[];
flatViewFieldsToCreate: UniversalFlatViewField[];
flatIndexMetadatasToUpdate: UniversalFlatIndexMetadata[];
};
type HandleFlatObjectMetadataUpdateSideEffectArgs = FromTo<
@@ -88,16 +89,18 @@ export const handleFlatObjectMetadataUpdateSideEffect = ({
if (
toFlatObjectMetadata.isSearchable &&
isDefined(toFlatObjectMetadata.labelIdentifierFieldMetadataId) &&
fromFlatObjectMetadata.labelIdentifierFieldMetadataId !==
toFlatObjectMetadata.labelIdentifierFieldMetadataId
isDefined(
toFlatObjectMetadata.labelIdentifierFieldMetadataUniversalIdentifier,
) &&
fromFlatObjectMetadata.labelIdentifierFieldMetadataUniversalIdentifier !==
toFlatObjectMetadata.labelIdentifierFieldMetadataUniversalIdentifier
) {
const updatedSearchVectorField =
recomputeSearchVectorFieldAfterLabelIdentifierUpdate({
existingFlatObjectMetadata: fromFlatObjectMetadata,
flatFieldMetadataMaps,
updatedLabelIdentifierFieldMetadataId:
toFlatObjectMetadata.labelIdentifierFieldMetadataId,
labelIdentifierFieldMetadataUniversalIdentifier:
toFlatObjectMetadata.labelIdentifierFieldMetadataUniversalIdentifier,
});
if (isDefined(updatedSearchVectorField)) {
@@ -1,8 +1,8 @@
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 FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { findManyFlatEntityByUniversalIdentifierInUniversalFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-universal-identifier-in-universal-flat-entity-maps-or-throw.util';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
import { type UniversalFlatIndexMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-index-metadata.type';
type RecomputeIndexAfterFlatObjectMetadataSingularNameUpdateArgs = {
existingFlatObjectMetadata: FlatObjectMetadata;
@@ -13,10 +13,11 @@ export const recomputeIndexAfterFlatObjectMetadataSingularNameUpdate = ({
flatIndexMaps,
updatedSingularName,
flatFieldMetadataMaps,
}: RecomputeIndexAfterFlatObjectMetadataSingularNameUpdateArgs): FlatIndexMetadata[] => {
}: RecomputeIndexAfterFlatObjectMetadataSingularNameUpdateArgs): UniversalFlatIndexMetadata[] => {
const allRelatedFlatIndexMetadata =
findManyFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityIds: existingFlatObjectMetadata.indexMetadataIds,
findManyFlatEntityByUniversalIdentifierInUniversalFlatEntityMapsOrThrow({
universalIdentifiers:
existingFlatObjectMetadata.indexMetadataUniversalIdentifiers,
flatEntityMaps: flatIndexMaps,
});
@@ -30,18 +31,21 @@ export const recomputeIndexAfterFlatObjectMetadataSingularNameUpdate = ({
};
const objectFlatFieldMetadatas =
findManyFlatEntityByIdInFlatEntityMapsOrThrow({
findManyFlatEntityByUniversalIdentifierInUniversalFlatEntityMapsOrThrow({
flatEntityMaps: flatFieldMetadataMaps,
flatEntityIds: optimisticFlatObjectMetadata.fieldIds,
universalIdentifiers:
optimisticFlatObjectMetadata.fieldUniversalIdentifiers,
});
return allRelatedFlatIndexMetadata.map<FlatIndexMetadata>((flatIndex) => {
const newIndex = generateFlatIndexMetadataWithNameOrThrow({
flatIndex,
flatObjectMetadata: optimisticFlatObjectMetadata,
objectFlatFieldMetadatas,
});
return allRelatedFlatIndexMetadata.map<UniversalFlatIndexMetadata>(
(flatIndex) => {
const newIndex = generateFlatIndexMetadataWithNameOrThrow({
flatIndex,
flatObjectMetadata: optimisticFlatObjectMetadata,
objectFlatFieldMetadatas,
});
return newIndex;
});
return newIndex;
},
);
};
@@ -2,7 +2,7 @@ import { type FieldMetadataType } from 'twenty-shared/types';
import { findOrThrow, isDefined } from 'twenty-shared/utils';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-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 { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
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';
@@ -16,13 +16,13 @@ import { type SearchableFieldType } from 'src/engine/workspace-manager/utils/is-
type RecomputeSearchVectorFieldAfterLabelIdentifierUpdateArgs = {
existingFlatObjectMetadata: FlatObjectMetadata;
updatedLabelIdentifierFieldMetadataId: string;
labelIdentifierFieldMetadataUniversalIdentifier: string;
} & Pick<AllFlatEntityMaps, 'flatFieldMetadataMaps'>;
export const recomputeSearchVectorFieldAfterLabelIdentifierUpdate = ({
existingFlatObjectMetadata,
flatFieldMetadataMaps,
updatedLabelIdentifierFieldMetadataId,
labelIdentifierFieldMetadataUniversalIdentifier,
}: RecomputeSearchVectorFieldAfterLabelIdentifierUpdateArgs):
| FlatFieldMetadata<FieldMetadataType.TS_VECTOR>
| undefined => {
@@ -37,9 +37,9 @@ export const recomputeSearchVectorFieldAfterLabelIdentifierUpdate = ({
(field) => field.name === SEARCH_VECTOR_FIELD.name,
) as FlatFieldMetadata<FieldMetadataType.TS_VECTOR>;
const newLabelIdentifierField = findFlatEntityByIdInFlatEntityMaps({
const newLabelIdentifierField = findFlatEntityByUniversalIdentifier({
flatEntityMaps: flatFieldMetadataMaps,
flatEntityId: updatedLabelIdentifierFieldMetadataId,
universalIdentifier: labelIdentifierFieldMetadataUniversalIdentifier,
});
if (!isDefined(newLabelIdentifierField)) {
@@ -59,8 +59,8 @@ export const recomputeSearchVectorFieldAfterLabelIdentifierUpdate = ({
return {
...searchVectorField,
settings: {
...searchVectorField.settings,
universalSettings: {
...searchVectorField.universalSettings,
asExpression: newAsExpression,
generatedType: 'STORED',
},
@@ -9,27 +9,27 @@ import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-m
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 { 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 { findFieldRelatedIndexes } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-field-related-index.util';
import { recomputeIndexOnFlatFieldMetadataNameUpdate } from 'src/engine/metadata-modules/flat-field-metadata/utils/recompute-index-on-flat-field-metadata-name-update.util';
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { getFlatObjectMetadataTargetMorphRelationFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-object-metadata/utils/get-flat-object-metadata-many-to-one-target-morph-relation-flat-field-metadatas-or-throw.util';
import { getMorphNameFromMorphFieldMetadataName } from 'src/engine/metadata-modules/flat-object-metadata/utils/get-morph-name-from-morph-field-metadata-name.util';
import { type UniversalFlatFieldMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-metadata.type';
import { type UniversalFlatIndexMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-index-metadata.type';
type UpdateMorphFlatFieldNameArgs = FromTo<
FlatObjectMetadata,
'relationTargetFlatObjectMetadata'
> & {
fromMorphFlatFieldMetadata: FlatFieldMetadata<FieldMetadataType.MORPH_RELATION>;
fromMorphFlatFieldMetadata: UniversalFlatFieldMetadata<FieldMetadataType.MORPH_RELATION>;
};
const updateMorphFlatFieldName = ({
fromMorphFlatFieldMetadata,
fromRelationTargetFlatObjectMetadata,
toRelationTargetFlatObjectMetadata,
}: UpdateMorphFlatFieldNameArgs): FlatFieldMetadata<FieldMetadataType.MORPH_RELATION> => {
}: UpdateMorphFlatFieldNameArgs): UniversalFlatFieldMetadata<FieldMetadataType.MORPH_RELATION> => {
const isManyToOneRelationType =
fromMorphFlatFieldMetadata.settings.relationType ===
fromMorphFlatFieldMetadata.universalSettings.relationType ===
RelationType.MANY_TO_ONE;
const initialMorphRelationFieldName = getMorphNameFromMorphFieldMetadataName({
morphRelationFlatFieldMetadata: fromMorphFlatFieldMetadata,
@@ -39,7 +39,7 @@ const updateMorphFlatFieldName = ({
const newMorphFieldName = computeMorphRelationFieldName({
fieldName: initialMorphRelationFieldName,
relationType: fromMorphFlatFieldMetadata.settings.relationType,
relationType: fromMorphFlatFieldMetadata.universalSettings.relationType,
targetObjectMetadataNameSingular:
toRelationTargetFlatObjectMetadata.nameSingular,
targetObjectMetadataNamePlural:
@@ -55,8 +55,8 @@ const updateMorphFlatFieldName = ({
return {
...fromMorphFlatFieldMetadata,
name: newMorphFieldName,
settings: {
...fromMorphFlatFieldMetadata.settings,
universalSettings: {
...fromMorphFlatFieldMetadata.universalSettings,
joinColumnName: newJoinColumnName,
},
};
@@ -72,8 +72,8 @@ type RenameRelatedMorphFieldOnObjectNamesUpdateArgs = FromTo<
>;
type RenameRelatedMorphFieldOnObjectNamesUpdateReturnType = {
morphFlatFieldMetadatasToUpdate: FlatFieldMetadata<FieldMetadataType.MORPH_RELATION>[];
morphRelatedFlatIndexesToUpdate: FlatIndexMetadata[];
morphFlatFieldMetadatasToUpdate: UniversalFlatFieldMetadata<FieldMetadataType.MORPH_RELATION>[];
morphRelatedFlatIndexesToUpdate: UniversalFlatIndexMetadata[];
};
export const renameRelatedMorphFieldOnObjectNamesUpdate = ({
fromFlatObjectMetadata,