diff --git a/packages/twenty-server/src/workspace/workspace-health/interfaces/workspace-health-issue.interface.ts b/packages/twenty-server/src/workspace/workspace-health/interfaces/workspace-health-issue.interface.ts index 44294a01a..216b32908 100644 --- a/packages/twenty-server/src/workspace/workspace-health/interfaces/workspace-health-issue.interface.ts +++ b/packages/twenty-server/src/workspace/workspace-health/interfaces/workspace-health-issue.interface.ts @@ -25,6 +25,7 @@ export enum WorkspaceHealthIssueType { COLUMN_DEFAULT_VALUE_CONFLICT = 'COLUMN_DEFAULT_VALUE_CONFLICT', COLUMN_DEFAULT_VALUE_NOT_VALID = 'COLUMN_DEFAULT_VALUE_NOT_VALID', COLUMN_OPTIONS_NOT_VALID = 'COLUMN_OPTIONS_NOT_VALID', + RELATION_METADATA_NOT_VALID = 'RELATION_METADATA_NOT_VALID', RELATION_FROM_OR_TO_FIELD_METADATA_NOT_VALID = 'RELATION_FROM_OR_TO_FIELD_METADATA_NOT_VALID', RELATION_FOREIGN_KEY_NOT_VALID = 'RELATION_FOREIGN_KEY_NOT_VALID', RELATION_FOREIGN_KEY_CONFLICT = 'RELATION_FOREIGN_KEY_CONFLICT', @@ -80,6 +81,7 @@ export interface WorkspaceHealthColumnIssue< * Relation issues */ export type WorkspaceRelationIssueTypes = + | WorkspaceHealthIssueType.RELATION_METADATA_NOT_VALID | WorkspaceHealthIssueType.RELATION_FROM_OR_TO_FIELD_METADATA_NOT_VALID | WorkspaceHealthIssueType.RELATION_FOREIGN_KEY_NOT_VALID | WorkspaceHealthIssueType.RELATION_FOREIGN_KEY_CONFLICT @@ -89,9 +91,9 @@ export interface WorkspaceHealthRelationIssue< T extends WorkspaceRelationIssueTypes, > { type: T; - fromFieldMetadata: FieldMetadataEntity | undefined; - toFieldMetadata: FieldMetadataEntity | undefined; - relationMetadata: RelationMetadataEntity; + fromFieldMetadata?: FieldMetadataEntity | undefined; + toFieldMetadata?: FieldMetadataEntity | undefined; + relationMetadata?: RelationMetadataEntity; columnStructure?: WorkspaceTableStructure; message: string; } diff --git a/packages/twenty-server/src/workspace/workspace-health/services/field-metadata-health.service.ts b/packages/twenty-server/src/workspace/workspace-health/services/field-metadata-health.service.ts index 40a82a839..cf4c7c4d1 100644 --- a/packages/twenty-server/src/workspace/workspace-health/services/field-metadata-health.service.ts +++ b/packages/twenty-server/src/workspace/workspace-health/services/field-metadata-health.service.ts @@ -28,6 +28,7 @@ import { serializeDefaultValue } from 'src/metadata/field-metadata/utils/seriali import { computeCompositeFieldMetadata } from 'src/workspace/workspace-health/utils/compute-composite-field-metadata.util'; import { generateTargetColumnMap } from 'src/metadata/field-metadata/utils/generate-target-column-map.util'; import { customNamePrefix } from 'src/workspace/utils/compute-custom-name.util'; +import { isRelationFieldMetadataType } from 'src/workspace/utils/is-relation-field-metadata-type.util'; @Injectable() export class FieldMetadataHealthService { @@ -45,10 +46,7 @@ export class FieldMetadataHealthService { for (const fieldMetadata of fieldMetadataCollection) { // Relation metadata are checked in another service - if ( - fieldMetadata.fromRelationMetadata || - fieldMetadata.toRelationMetadata - ) { + if (isRelationFieldMetadataType(fieldMetadata.type)) { continue; } 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 573f8376c..9de85fd9f 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 @@ -10,10 +10,7 @@ import { WorkspaceHealthOptions, } from 'src/workspace/workspace-health/interfaces/workspace-health-options.interface'; -import { - FieldMetadataEntity, - FieldMetadataType, -} from 'src/metadata/field-metadata/field-metadata.entity'; +import { FieldMetadataEntity } from 'src/metadata/field-metadata/field-metadata.entity'; import { RelationMetadataEntity, RelationMetadataType, @@ -25,6 +22,7 @@ import { import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity'; import { createRelationForeignKeyColumnName } from 'src/metadata/relation-metadata/utils/create-relation-foreign-key-column-name.util'; import { createRelationForeignKeyFieldMetadataName } from 'src/metadata/relation-metadata/utils/create-relation-foreign-key-field-metadata-name.util'; +import { isRelationFieldMetadataType } from 'src/workspace/utils/is-relation-field-metadata-type.util'; @Injectable() export class RelationMetadataHealthService { @@ -40,12 +38,22 @@ export class RelationMetadataHealthService { for (const fieldMetadata of objectMetadata.fields) { // We're only interested in relation fields - if (fieldMetadata.type !== FieldMetadataType.RELATION) { + if (!isRelationFieldMetadataType(fieldMetadata.type)) { continue; } const relationMetadata = fieldMetadata.fromRelationMetadata ?? fieldMetadata.toRelationMetadata; + + if (!relationMetadata) { + issues.push({ + type: WorkspaceHealthIssueType.RELATION_METADATA_NOT_VALID, + message: `Field ${fieldMetadata.id} has invalid relation metadata`, + }); + + continue; + } + const relationDirection = deduceRelationDirection( objectMetadata.id, relationMetadata,