From 67e27a69ffbf0f9ebca295af585089f625ccdd6f Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Fri, 23 Feb 2024 09:51:42 +0100 Subject: [PATCH] Handle relations between same objects (#4137) * Handle relations between same objects * Simplify conditions --------- Co-authored-by: Thomas Trompette --- .../deduce-relation-direction.spec.ts | 61 +++++++++++++++---- .../utils/deduce-relation-direction.util.ts | 15 +++-- .../relation-metadata.health.service.ts | 2 +- .../factories/relation-field-alias.factory.ts | 2 +- .../extend-object-type-definition.factory.ts | 2 +- 5 files changed, 62 insertions(+), 20 deletions(-) diff --git a/packages/twenty-server/src/workspace/utils/__tests__/deduce-relation-direction.spec.ts b/packages/twenty-server/src/workspace/utils/__tests__/deduce-relation-direction.spec.ts index e050e15ee..048e372f0 100644 --- a/packages/twenty-server/src/workspace/utils/__tests__/deduce-relation-direction.spec.ts +++ b/packages/twenty-server/src/workspace/utils/__tests__/deduce-relation-direction.spec.ts @@ -1,5 +1,7 @@ +import { FieldMetadataInterface } from 'src/metadata/field-metadata/interfaces/field-metadata.interface'; import { RelationMetadataInterface } from 'src/metadata/field-metadata/interfaces/relation-metadata.interface'; +import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity'; import { RelationMetadataType } from 'src/metadata/relation-metadata/relation-metadata.entity'; import { deduceRelationDirection, @@ -7,39 +9,61 @@ import { } from 'src/workspace/utils/deduce-relation-direction.util'; describe('deduceRelationDirection', () => { - it('should return FROM when the current object Metadata ID matches fromObjectMetadataId', () => { - const currentObjectId = 'from_object_id'; + it('should return FROM when the current object Metadata ID matches fromObjectMetadataId and id matches fromFieldMetadataId', () => { + const fieldMetadata: FieldMetadataInterface = { + id: 'field_id', + objectMetadataId: 'from_object_id', + type: FieldMetadataType.RELATION, + name: 'field_name', + label: 'Field Name', + description: 'Field Description', + targetColumnMap: { + default: 'default_column', + }, + }; + const relationMetadata = { id: 'relation_id', - fromObjectMetadataId: currentObjectId, + fromObjectMetadataId: fieldMetadata.objectMetadataId, toObjectMetadataId: 'to_object_id', - fromFieldMetadataId: 'from_field_id', + fromFieldMetadataId: fieldMetadata.id, toFieldMetadataId: 'to_field_id', relationType: RelationMetadataType.ONE_TO_ONE, }; const result = deduceRelationDirection( - currentObjectId, + fieldMetadata, relationMetadata as RelationMetadataInterface, ); expect(result).toBe(RelationDirection.FROM); }); - it('should return TO when the current object Metadata ID matches toObjectMetadataId', () => { + it('should return TO when the current object Metadata ID matches toObjectMetadataId and id matches toFieldMetadataId', () => { // Arrange - const currentObjectId = 'to_object_id'; + const fieldMetadata: FieldMetadataInterface = { + id: 'field_id', + objectMetadataId: 'to_object_id', + type: FieldMetadataType.RELATION, + name: 'field_name', + label: 'Field Name', + description: 'Field Description', + targetColumnMap: { + default: 'default_column', + }, + }; + const relationMetadata = { id: 'relation_id', fromObjectMetadataId: 'from_object_id', - toObjectMetadataId: currentObjectId, + toObjectMetadataId: fieldMetadata.objectMetadataId, fromFieldMetadataId: 'from_field_id', - toFieldMetadataId: 'to_field_id', + toFieldMetadataId: fieldMetadata.id, relationType: RelationMetadataType.ONE_TO_ONE, }; const result = deduceRelationDirection( - currentObjectId, + fieldMetadata, relationMetadata as RelationMetadataInterface, ); @@ -47,7 +71,18 @@ describe('deduceRelationDirection', () => { }); it('should throw an error when the current object Metadata ID does not match any object metadata ID', () => { - const currentObjectId = 'unrelated_object_id'; + const fieldMetadata: FieldMetadataInterface = { + id: 'field_id', + objectMetadataId: 'unrelated_object_id', + type: FieldMetadataType.RELATION, + name: 'field_name', + label: 'Field Name', + description: 'Field Description', + targetColumnMap: { + default: 'default_column', + }, + }; + const relationMetadata = { id: 'relation_id', fromObjectMetadataId: 'from_object_id', @@ -59,11 +94,11 @@ describe('deduceRelationDirection', () => { expect(() => deduceRelationDirection( - currentObjectId, + fieldMetadata, relationMetadata as RelationMetadataInterface, ), ).toThrow( - `Relation metadata ${relationMetadata.id} is not related to object ${currentObjectId}`, + `Relation metadata ${relationMetadata.id} is not related to object ${fieldMetadata.objectMetadataId}`, ); }); }); diff --git a/packages/twenty-server/src/workspace/utils/deduce-relation-direction.util.ts b/packages/twenty-server/src/workspace/utils/deduce-relation-direction.util.ts index 5d91f90a7..479932933 100644 --- a/packages/twenty-server/src/workspace/utils/deduce-relation-direction.util.ts +++ b/packages/twenty-server/src/workspace/utils/deduce-relation-direction.util.ts @@ -1,3 +1,4 @@ +import { FieldMetadataInterface } from 'src/metadata/field-metadata/interfaces/field-metadata.interface'; import { RelationMetadataInterface } from 'src/metadata/field-metadata/interfaces/relation-metadata.interface'; export enum RelationDirection { @@ -6,18 +7,24 @@ export enum RelationDirection { } export const deduceRelationDirection = ( - currentObjectId: string, + fieldMetadata: FieldMetadataInterface, relationMetadata: RelationMetadataInterface, ): RelationDirection => { - if (relationMetadata.fromObjectMetadataId === currentObjectId) { + if ( + relationMetadata.fromObjectMetadataId === fieldMetadata.objectMetadataId && + relationMetadata.fromFieldMetadataId === fieldMetadata.id + ) { return RelationDirection.FROM; } - if (relationMetadata.toObjectMetadataId === currentObjectId) { + if ( + relationMetadata.toObjectMetadataId === fieldMetadata.objectMetadataId && + relationMetadata.toFieldMetadataId === fieldMetadata.id + ) { return RelationDirection.TO; } throw new Error( - `Relation metadata ${relationMetadata.id} is not related to object ${currentObjectId}`, + `Relation metadata ${relationMetadata.id} is not related to object ${fieldMetadata.objectMetadataId}`, ); }; diff --git a/packages/twenty-server/src/workspace/workspace-health/services/relation-metadata.health.service.ts b/packages/twenty-server/src/workspace/workspace-health/services/relation-metadata.health.service.ts index 8a045e504..93f060a74 100644 --- a/packages/twenty-server/src/workspace/workspace-health/services/relation-metadata.health.service.ts +++ b/packages/twenty-server/src/workspace/workspace-health/services/relation-metadata.health.service.ts @@ -55,7 +55,7 @@ export class RelationMetadataHealthService { } const relationDirection = deduceRelationDirection( - objectMetadata.id, + fieldMetadata, relationMetadata, ); diff --git a/packages/twenty-server/src/workspace/workspace-query-builder/factories/relation-field-alias.factory.ts b/packages/twenty-server/src/workspace/workspace-query-builder/factories/relation-field-alias.factory.ts index bceedf54d..383db4e53 100644 --- a/packages/twenty-server/src/workspace/workspace-query-builder/factories/relation-field-alias.factory.ts +++ b/packages/twenty-server/src/workspace/workspace-query-builder/factories/relation-field-alias.factory.ts @@ -72,7 +72,7 @@ export class RelationFieldAliasFactory { } const relationDirection = deduceRelationDirection( - fieldMetadata.objectMetadataId, + fieldMetadata, relationMetadata, ); // Retrieve the referenced object metadata based on the relation direction diff --git a/packages/twenty-server/src/workspace/workspace-schema-builder/factories/extend-object-type-definition.factory.ts b/packages/twenty-server/src/workspace/workspace-schema-builder/factories/extend-object-type-definition.factory.ts index 0c1891ef2..f288a74b3 100644 --- a/packages/twenty-server/src/workspace/workspace-schema-builder/factories/extend-object-type-definition.factory.ts +++ b/packages/twenty-server/src/workspace/workspace-schema-builder/factories/extend-object-type-definition.factory.ts @@ -128,7 +128,7 @@ export class ExtendObjectTypeDefinitionFactory { } const relationDirection = deduceRelationDirection( - fieldMetadata.objectMetadataId, + fieldMetadata, relationMetadata, ); const relationType = this.relationTypeFactory.create(