Morph relation validation v2 (#14141)

## Introduction
Binding morph relation validation to relation validation code flow
Please note that ALL create field will go through basic atomic
validation, which involve name availability and so on

close https://github.com/twentyhq/core-team-issues/issues/1407
This commit is contained in:
Paul Rastoin
2025-08-28 18:05:58 +02:00
committed by GitHub
parent af6fc1e9ef
commit b364acf5bb
6 changed files with 91 additions and 70 deletions
@@ -1,12 +1,12 @@
import { type RelationCreationPayload } from 'twenty-shared/types';
import { t } from '@lingui/core/macro';
import { isDefined } from 'class-validator';
import { type RelationCreationPayload } from 'twenty-shared/types';
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
import {
type FailedFieldInputTranspilation,
type SuccessfulFieldInputTranspilation,
type FieldInputTranspilationResult,
type SuccessfulFieldInputTranspilation,
} from 'src/engine/metadata-modules/flat-field-metadata/types/field-input-transpilation-result.type';
import { validateRelationCreationPayload } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-relation-creation-payload.util';
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
@@ -27,6 +27,17 @@ export const validateMorphRelationCreationPayload = async ({
}: ValidateMorphRelationCreationPayloadUtilArgs): Promise<
FieldInputTranspilationResult<RelationCreationPayloadAndObjectMetadata[]>
> => {
if (morphRelationCreationPayload.length === 0) {
return {
status: 'fail',
error: {
code: FieldMetadataExceptionCode.FIELD_METADATA_RELATION_MALFORMED,
message: 'Morph relation creation payloads are empty',
userFriendlyMessage: t`At least one relation is require`,
},
};
}
const allRelationType = [
...new Set(
morphRelationCreationPayload.map(
@@ -40,8 +51,9 @@ export const validateMorphRelationCreationPayload = async ({
status: 'fail',
error: {
code: FieldMetadataExceptionCode.FIELD_METADATA_RELATION_MALFORMED,
message: 'Morph relation relations must have the same relation type',
userFriendlyMessage: t`Morph relation relations must have the same relation type`,
message:
'Morph relation creation payloads must have the same relation type',
userFriendlyMessage: t`Morph relation creation payloads must have the same relation type`,
},
};
}
@@ -61,8 +73,8 @@ export const validateMorphRelationCreationPayload = async ({
error: {
code: FieldMetadataExceptionCode.FIELD_METADATA_RELATION_MALFORMED,
message:
'Morph relation relations must have only relation to the same object metadata',
userFriendlyMessage: t`Morph relation relations must have only relation to the same object metadata`,
'Morph relation creation payloads must have only relation to the same object metadata',
userFriendlyMessage: t`Morph relation creation payloads must only contain relation to the same object metadata`,
},
};
}
@@ -1,16 +1,16 @@
import { t } from '@lingui/core/macro';
import { type FieldMetadataType } from 'twenty-shared/types';
import { isDefined, isValidUuid } from 'twenty-shared/utils';
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
import { type RelationFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/relation-field-metadata-type.type';
import { type ValidateOneFieldMetadataArgs } from 'src/engine/metadata-modules/flat-field-metadata/services/flat-field-metadata-validator.service';
import { type FlatFieldMetadataValidationError } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-validation-error.type';
export const validateRelationFlatFieldMetadata = async ({
export const validateRelationOrMorphRelationFlatFieldMetadata = async ({
existingFlatObjectMetadataMaps,
flatFieldMetadataToValidate,
otherFlatObjectMetadataMapsToValidate,
}: ValidateOneFieldMetadataArgs<FieldMetadataType.RELATION>): Promise<
}: ValidateOneFieldMetadataArgs<RelationFieldMetadataType>): Promise<
FlatFieldMetadataValidationError[]
> => {
const { relationTargetFieldMetadataId, relationTargetObjectMetadataId } =