Label identifier validation v2 (#14867)

# Introduction
Adding a hacky way to validate object against fields before fields
validation ( bi-directional validation process )
If you encounter an identical setup we will add a specific devXp as
cleanup validation but for the moment this seems enough

close https://github.com/twentyhq/core-team-issues/issues/1639
This commit is contained in:
Paul Rastoin
2025-10-07 13:27:21 +02:00
committed by GitHub
parent 0670bb2043
commit 23e21cbeea
22 changed files with 417 additions and 233 deletions
@@ -7,7 +7,7 @@ import {
} from 'src/engine/core-modules/common/exceptions/flat-entity-maps.exception';
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { findObjectFieldsInFlatFieldMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
import { findObjectFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
@@ -30,11 +30,10 @@ export const findAllOthersMorphRelationFlatFieldMetadatasOrThrow = ({
);
}
const { objectFlatFieldMetadatas } =
findObjectFieldsInFlatFieldMetadataMapsOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata,
});
const { objectFlatFieldMetadatas } = findObjectFlatFieldMetadatasOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata,
});
return objectFlatFieldMetadatas.filter(
(
@@ -9,24 +9,22 @@ type FindObjectFieldsInFlatFieldMetadataMapsArgs = {
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
flatObjectMetadata: FlatObjectMetadata;
};
export const findObjectFieldsInFlatFieldMetadataMapsOrThrow = ({
export const findObjectFlatFieldMetadatasOrThrow = ({
flatFieldMetadataMaps,
flatObjectMetadata,
}: FindObjectFieldsInFlatFieldMetadataMapsArgs): {
objectFlatFieldMetadataById: FlatEntityMaps<FlatFieldMetadata>;
objectFlatFieldMetadatas: FlatFieldMetadata[];
} => {
const objectFlatFieldMetadataById = getSubFlatEntityMapsOrThrow({
const objectFlatFieldMetadataMaps = getSubFlatEntityMapsOrThrow({
flatEntityIds: flatObjectMetadata.fieldMetadataIds,
flatEntityMaps: flatFieldMetadataMaps,
});
const objectFlatFieldMetadatas = Object.values(
objectFlatFieldMetadataById.byId,
objectFlatFieldMetadataMaps.byId,
).filter(isDefined);
return {
objectFlatFieldMetadataById,
objectFlatFieldMetadatas,
};
};
@@ -13,7 +13,7 @@ import {
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { computeFlatFieldMetadataRelatedFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/compute-flat-field-metadata-related-flat-field-metadata.util';
import { findObjectFieldsInFlatFieldMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
import { findObjectFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
@@ -140,11 +140,10 @@ export const fromDeleteFieldInputToFlatFieldMetadatasToDelete = ({
flatEntityMaps: existingFlatObjectMetadataMaps,
flatEntityId: flatIndex.objectMetadataId,
});
const { objectFlatFieldMetadatas } =
findObjectFieldsInFlatFieldMetadataMapsOrThrow({
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
flatObjectMetadata,
});
const { objectFlatFieldMetadatas } = findObjectFlatFieldMetadatasOrThrow({
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
flatObjectMetadata,
});
const newIndex = generateFlatIndexMetadataWithNameOrThrow({
flatObjectMetadata,
@@ -2,7 +2,7 @@ import { isDefined } from 'twenty-shared/utils';
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { findObjectFieldsInFlatFieldMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
import { findObjectFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.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 { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
@@ -35,11 +35,10 @@ export const recomputeIndexOnFlatFieldMetadataNameUpdate = ({
return [];
}
const { objectFlatFieldMetadatas } =
findObjectFieldsInFlatFieldMetadataMapsOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata,
});
const { objectFlatFieldMetadatas } = findObjectFlatFieldMetadatasOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata,
});
const optimisticObjectFlatFieldMetadatas = objectFlatFieldMetadatas.map(
(flatFieldMetadata) => {
if (flatFieldMetadata.id === fromFlatFieldMetadata.id) {
@@ -10,7 +10,7 @@ import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-me
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
import { type FlatFieldMetadataValidationError } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-validation-error.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { findObjectFieldsInFlatFieldMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
import { findObjectFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.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 { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
@@ -50,11 +50,10 @@ export const validateFlatFieldMetadataNameAvailability = ({
remainingFlatEntityMapsToValidate?: FlatEntityMaps<FlatFieldMetadata>;
}): FlatFieldMetadataValidationError[] => {
const errors: FlatFieldMetadataValidationError[] = [];
const { objectFlatFieldMetadatas } =
findObjectFieldsInFlatFieldMetadataMapsOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata,
});
const { objectFlatFieldMetadatas } = findObjectFlatFieldMetadatasOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata,
});
const reservedCompositeFieldsNames = getReservedCompositeFieldNames(
objectFlatFieldMetadatas,
);
@@ -9,7 +9,7 @@ import { type FlatObjectMetadataEntityJsonbProperties } from 'src/engine/metadat
import { type FlatObjectMetadataPropertiesToCompare } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata-properties-to-compare.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util';
import { type UpdateObjectAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-object-action-v2';
import { type FlatObjectPropertiesUpdates } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-object-action-v2';
import { transformMetadataForComparison } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/utils/transform-metadata-for-comparison.util';
export const compareTwoFlatObjectMetadata = ({
@@ -50,42 +50,42 @@ export const compareTwoFlatObjectMetadata = ({
);
const objectMetadataDifference = diff(fromCompare, omit(toCompare, 'fields'));
return objectMetadataDifference.flatMap<
UpdateObjectAction['updates'][number]
>((difference) => {
switch (difference.type) {
case 'CHANGE': {
const { oldValue, path, value } = difference;
const property = path[0] as FlatObjectMetadataPropertiesToCompare;
const isJsonb = FLAT_OBJECT_METADATA_JSONB_PROPERTIES.includes(
property as FlatObjectMetadataEntityJsonbProperties,
);
return objectMetadataDifference.flatMap<FlatObjectPropertiesUpdates[number]>(
(difference) => {
switch (difference.type) {
case 'CHANGE': {
const { oldValue, path, value } = difference;
const property = path[0] as FlatObjectMetadataPropertiesToCompare;
const isJsonb = FLAT_OBJECT_METADATA_JSONB_PROPERTIES.includes(
property as FlatObjectMetadataEntityJsonbProperties,
);
if (isJsonb) {
return {
from: parseJson(oldValue),
to: parseJson(value),
property,
};
}
if (isJsonb) {
return {
from: parseJson(oldValue),
to: parseJson(value),
from: oldValue,
to: value,
property,
};
}
return {
from: oldValue,
to: value,
property,
};
case 'CREATE':
case 'REMOVE': {
// Should never occurs ? should throw ?
return [];
}
default: {
assertUnreachable(
difference,
`Unexpected difference type: ${difference['type']}`,
);
}
}
case 'CREATE':
case 'REMOVE': {
// Should never occurs ? should throw ?
return [];
}
default: {
assertUnreachable(
difference,
`Unexpected difference type: ${difference['type']}`,
);
}
}
});
},
);
};
@@ -6,7 +6,7 @@ import {
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/find-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 { findObjectFieldsInFlatFieldMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
import { findObjectFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
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';
@@ -52,11 +52,10 @@ export const fromDeleteObjectInputToFlatFieldMetadatasToDelete = ({
);
}
const { objectFlatFieldMetadatas } =
findObjectFieldsInFlatFieldMetadataMapsOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata: flatObjectMetadataToDelete,
});
const { objectFlatFieldMetadatas } = findObjectFlatFieldMetadatasOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata: flatObjectMetadataToDelete,
});
const flatFieldMetadatasToDelete = objectFlatFieldMetadatas.flatMap(
(flatFieldMetadata) => {
if (isMorphOrRelationFlatFieldMetadata(flatFieldMetadata)) {
@@ -1,7 +1,7 @@
import { isDefined } from 'twenty-shared/utils';
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
import { findObjectFieldsInFlatFieldMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
import { findObjectFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.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 { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
@@ -31,11 +31,10 @@ export const recomputeIndexAfterFlatObjectMetadataSingularNameUpdate = ({
nameSingular: updatedSingularName,
};
const { objectFlatFieldMetadatas } =
findObjectFieldsInFlatFieldMetadataMapsOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata: optimisticFlatObjectMetadata,
});
const { objectFlatFieldMetadatas } = findObjectFlatFieldMetadatasOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata: optimisticFlatObjectMetadata,
});
return allRelatedFlatIndexMetadata.map<FlatIndexMetadata>((flatIndex) => {
const newIndex = generateFlatIndexMetadataWithNameOrThrow({
@@ -8,7 +8,7 @@ import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all
import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util';
import { computeMorphRelationFieldName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-relation-field-name.util';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { findObjectFieldsInFlatFieldMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
import { findObjectFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
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';
@@ -43,11 +43,10 @@ export const renameRelatedMorphFieldOnObjectNamesUpdate = ({
toFlatObjectMetadata,
flatFieldMetadataMaps,
}: RenameRelatedMorphFieldOnObjectNamesUpdateArgs): FlatFieldMetadata<FieldMetadataType.MORPH_RELATION>[] => {
const { objectFlatFieldMetadatas } =
findObjectFieldsInFlatFieldMetadataMapsOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata: fromFlatObjectMetadata,
});
const { objectFlatFieldMetadatas } = findObjectFlatFieldMetadatasOrThrow({
flatFieldMetadataMaps,
flatObjectMetadata: fromFlatObjectMetadata,
});
const manyToOneMorphRelationFlatFieldMetadatas =
getFlatObjectMetadataTargetMorphRelationFlatFieldMetadatasOrThrow({
flatFieldMetadataMaps,
@@ -4,6 +4,8 @@ import {
isLabelIdentifierFieldMetadataTypes,
} from 'twenty-shared/utils';
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type FlatObjectMetadataValidationError } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata-validation-error.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
@@ -11,24 +13,25 @@ import { ObjectMetadataExceptionCode } from 'src/engine/metadata-modules/object-
export const validateFlatObjectMetadataIdentifiers = ({
flatObjectMetadata,
objectFlatFieldMetadatas,
flatFieldMetadataMaps,
}: {
flatObjectMetadata: Pick<
FlatObjectMetadata,
'labelIdentifierFieldMetadataId' | 'imageIdentifierFieldMetadataId'
>;
objectFlatFieldMetadatas: FlatFieldMetadata[];
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
}) => {
const errors: FlatObjectMetadataValidationError[] = [];
const { labelIdentifierFieldMetadataId, imageIdentifierFieldMetadataId } =
flatObjectMetadata;
// TODO should not be nullable
if (isDefined(labelIdentifierFieldMetadataId)) {
const flatFieldMetadata = objectFlatFieldMetadatas.find(
(flatFieldMetadata) =>
flatFieldMetadata.id === labelIdentifierFieldMetadataId,
);
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: labelIdentifierFieldMetadataId,
flatEntityMaps: flatFieldMetadataMaps,
});
if (!isDefined(flatFieldMetadata)) {
errors.push({
@@ -48,10 +51,10 @@ export const validateFlatObjectMetadataIdentifiers = ({
}
if (isDefined(imageIdentifierFieldMetadataId)) {
const relatedFlatFieldMetadata = objectFlatFieldMetadatas.find(
(flatFieldMetadata) =>
flatFieldMetadata.id === imageIdentifierFieldMetadataId,
);
const relatedFlatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: imageIdentifierFieldMetadataId,
flatEntityMaps: flatFieldMetadataMaps,
});
if (!isDefined(relatedFlatFieldMetadata)) {
errors.push({
@@ -0,0 +1,62 @@
import { t } from '@lingui/core/macro';
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
import { type FlatObjectMetadataValidationError } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata-validation-error.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { areFlatObjectMetadataNamesSyncedWithLabels } from 'src/engine/metadata-modules/flat-object-metadata/utils/are-flat-object-metadata-names-synced-with-labels.util';
import { validateFlatObjectMetadataLabel } from 'src/engine/metadata-modules/flat-object-metadata/validators/utils/validate-flat-object-metadata-label.util';
import { validateFlatObjectMetadataNames } from 'src/engine/metadata-modules/flat-object-metadata/validators/utils/validate-flat-object-metadata-name.util';
import { ObjectMetadataExceptionCode } from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
import { doesOtherObjectWithSameNameExists } from 'src/engine/metadata-modules/utils/validate-no-other-object-with-same-name-exists-or-throw.util';
export const validateFlatObjectMetadataNameAndLabels = ({
optimisticFlatObjectMetadataMaps,
flatObjectMetadataToValidate,
}: {
flatObjectMetadataToValidate: FlatObjectMetadata;
optimisticFlatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata>;
}): FlatObjectMetadataValidationError[] => {
const errors: FlatObjectMetadataValidationError[] = [];
errors.push(
...validateFlatObjectMetadataNames({
namePlural: flatObjectMetadataToValidate.namePlural,
nameSingular: flatObjectMetadataToValidate.nameSingular,
}),
);
errors.push(
...validateFlatObjectMetadataLabel({
labelPlural: flatObjectMetadataToValidate.labelPlural,
labelSingular: flatObjectMetadataToValidate.labelSingular,
}),
);
if (
flatObjectMetadataToValidate.isLabelSyncedWithName &&
!areFlatObjectMetadataNamesSyncedWithLabels(flatObjectMetadataToValidate)
) {
errors.push({
code: ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
message: t`Names are not synced with labels`,
userFriendlyMessage: t`Names are not synced with labels`,
});
}
if (
doesOtherObjectWithSameNameExists({
objectMetadataNamePlural: flatObjectMetadataToValidate.namePlural,
objectMetadataNameSingular: flatObjectMetadataToValidate.nameSingular,
objectMetadataMaps: optimisticFlatObjectMetadataMaps,
existingObjectMetadataId: flatObjectMetadataToValidate.id,
})
) {
errors.push({
code: ObjectMetadataExceptionCode.OBJECT_ALREADY_EXISTS,
message: 'Object already exists',
userFriendlyMessage: t`Object already exists`,
});
}
return errors;
};
@@ -14,7 +14,7 @@ import { FlatView } from 'src/engine/core-modules/view/flat-view/types/flat-view
import { fromCreateViewFieldInputToFlatViewFieldToCreate } from 'src/engine/core-modules/view/flat-view/utils/from-create-view-field-input-to-flat-view-field-to-create.util';
import { fromCreateViewInputToFlatViewToCreate } from 'src/engine/core-modules/view/flat-view/utils/from-create-view-input-to-flat-view-to-create.util';
import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { findObjectFieldsInFlatFieldMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
import { findObjectFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCreate } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-create-object-input-to-flat-object-metadata-and-flat-field-metadatas-to-create.util';
import { fromDeleteObjectInputToFlatFieldMetadatasToDelete } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-delete-object-input-to-flat-field-metadatas-to-delete.util';
@@ -353,11 +353,10 @@ export class ObjectMetadataServiceV2 {
flatEntityMaps: existingFlatViewMaps,
});
const { objectFlatFieldMetadatas } =
findObjectFieldsInFlatFieldMetadataMapsOrThrow({
flatFieldMetadataMaps: toFlatFieldMetadataMaps,
flatObjectMetadata: flatObjectMetadataToCreate,
});
const { objectFlatFieldMetadatas } = findObjectFlatFieldMetadatasOrThrow({
flatFieldMetadataMaps: toFlatFieldMetadataMaps,
flatObjectMetadata: flatObjectMetadataToCreate,
});
const flatDefaultViewFieldsToCreate =
await this.createDefaultFlatViewFields({
objectFlatFieldMetadatas,
@@ -12,13 +12,13 @@ import {
} from 'typeorm';
import { type WorkspaceEntityDuplicateCriteria } from 'src/engine/api/graphql/workspace-query-builder/types/workspace-entity-duplicate-criteria.type';
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import { type ObjectStandardOverridesDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-standard-overrides.dto';
import { FieldPermissionEntity } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.entity';
import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
@Entity('objectMetadata')
@Unique('IDX_OBJECT_METADATA_NAME_SINGULAR_WORKSPACE_ID_UNIQUE', [
@@ -96,6 +96,7 @@ export class ObjectMetadataEntity implements Required<ObjectMetadataEntity> {
@Column({ nullable: true, type: 'varchar' })
shortcut: string | null;
// TODO: This should not be nullable - legacy field introduced when label identifier was nullable
@Column({ nullable: true, type: 'uuid' })
labelIdentifierFieldMetadataId: string | null;