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:
+3
-3
@@ -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 =
|
||||
|
||||
+2
-2
@@ -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'
|
||||
>;
|
||||
}) => {
|
||||
|
||||
+16
-30
@@ -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,
|
||||
),
|
||||
|
||||
+4
-4
@@ -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 } =
|
||||
|
||||
+16
-2
@@ -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,
|
||||
|
||||
+4
-4
@@ -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({
|
||||
|
||||
+15
-12
@@ -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)) {
|
||||
|
||||
+19
-15
@@ -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;
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
+7
-7
@@ -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',
|
||||
},
|
||||
|
||||
+10
-10
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user