Refactor new relation sync (#11711)

In this PR:
- this should fix the sync metadata for new relation system

This goes with the recent PR:
https://github.com/twentyhq/twenty/pull/11725

What we want:
- ONE_TO_MANY relations should have no joinColumn and no onDelete
- MANY_TO_ONE should have both
This commit is contained in:
Charles Bochet
2025-04-25 01:02:49 +02:00
committed by GitHub
parent 9fb7ef5d47
commit 0c8eb149e6
7 changed files with 285 additions and 156 deletions

View File

@ -129,8 +129,14 @@ export class MigrateRelationsToFieldMetadataCommand extends ActiveOrSuspendedWor
...fieldMetadata, ...fieldMetadata,
settings: { settings: {
relationType, relationType,
onDelete: relationMetadata.onDeleteAction, onDelete:
joinColumnName: joinColumnFieldMetadata?.name, relationType === RelationType.MANY_TO_ONE
? relationMetadata.onDeleteAction
: undefined,
joinColumnName:
relationType === RelationType.MANY_TO_ONE
? joinColumnFieldMetadata?.name
: undefined,
}, },
relationTargetFieldMetadataId, relationTargetFieldMetadataId,
relationTargetObjectMetadataId, relationTargetObjectMetadataId,

View File

@ -72,6 +72,9 @@ export class AccessTokenService {
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkspaceMemberWorkspaceEntity>( await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkspaceMemberWorkspaceEntity>(
workspaceId, workspaceId,
'workspaceMember', 'workspaceMember',
{
shouldFailIfMetadataNotFound: false,
},
); );
const workspaceMember = await workspaceMemberRepository.findOne({ const workspaceMember = await workspaceMemberRepository.findOne({

View File

@ -355,7 +355,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
}); });
if (fieldMetadata.type === FieldMetadataType.RELATION) { if (fieldMetadata.type === FieldMetadataType.RELATION) {
const isManyToManyRelation = const isManyToOneRelation =
(fieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>) (fieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>)
.settings?.relationType === RelationType.MANY_TO_ONE; .settings?.relationType === RelationType.MANY_TO_ONE;
@ -385,7 +385,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
columns: [ columns: [
{ {
action: WorkspaceMigrationColumnActionType.DROP, action: WorkspaceMigrationColumnActionType.DROP,
columnName: isManyToManyRelation columnName: isManyToOneRelation
? `${(fieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>).settings?.joinColumnName}` ? `${(fieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>).settings?.joinColumnName}`
: `${(targetFieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>).settings?.joinColumnName}`, : `${(targetFieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>).settings?.joinColumnName}`,
} satisfies WorkspaceMigrationColumnDrop, } satisfies WorkspaceMigrationColumnDrop,

View File

@ -100,7 +100,6 @@ export class ObjectMetadataFieldRelationService {
...sourceFieldMetadata, ...sourceFieldMetadata,
settings: { settings: {
relationType: RelationType.ONE_TO_MANY, relationType: RelationType.ONE_TO_MANY,
onDelete: RelationOnDeleteAction.CASCADE,
}, },
relationTargetObjectMetadataId: targetObjectMetadata.id, relationTargetObjectMetadataId: targetObjectMetadata.id,
relationTargetFieldMetadataId: targetFieldMetadata.id, relationTargetFieldMetadataId: targetFieldMetadata.id,

View File

@ -55,6 +55,12 @@ export class RelationColumnActionFactory extends ColumnActionAbstractFactory<Fie
return []; return [];
} }
if (
currentFieldMetadata.settings.relationType === RelationType.ONE_TO_MANY
) {
return [];
}
const currentJoinColumnName = currentFieldMetadata.settings.joinColumnName; const currentJoinColumnName = currentFieldMetadata.settings.joinColumnName;
const alteredJoinColumnName = alteredFieldMetadata.settings.joinColumnName; const alteredJoinColumnName = alteredFieldMetadata.settings.joinColumnName;

View File

@ -1,110 +1,232 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { isDefined } from 'class-validator';
import { FieldMetadataType } from 'twenty-shared/types'; import { FieldMetadataType } from 'twenty-shared/types';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
import { WorkspaceRelationMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-relation-metadata-args.interface';
import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface'; import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-entity';
import { metadataArgsStorage } from 'src/engine/twenty-orm/storage/metadata-args.storage'; import { metadataArgsStorage } from 'src/engine/twenty-orm/storage/metadata-args.storage';
import { getJoinColumn } from 'src/engine/twenty-orm/utils/get-join-column.util'; import { getJoinColumn } from 'src/engine/twenty-orm/utils/get-join-column.util';
import { convertClassNameToObjectMetadataName } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/convert-class-to-object-metadata-name.util'; import { convertClassNameToObjectMetadataName } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/convert-class-to-object-metadata-name.util';
import { isGatedAndNotEnabled } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/is-gate-and-not-enabled.util'; import { isGatedAndNotEnabled } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/is-gate-and-not-enabled.util';
import { assert } from 'src/utils/assert';
interface CustomRelationFactory {
object: ObjectMetadataEntity;
metadata: typeof BaseWorkspaceEntity;
}
@Injectable() @Injectable()
export class StandardFieldRelationFactory { export class StandardFieldRelationFactory {
createFieldRelationForCustomObject( computeRelationFieldsForCustomObject(
customObjectFactories: CustomRelationFactory[], customObjectMetadata: ObjectMetadataEntity,
context: WorkspaceSyncContext,
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>, originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
): FieldMetadataEntity<FieldMetadataType.RELATION>[] { ): FieldMetadataEntity<FieldMetadataType.RELATION>[] {
return customObjectFactories.flatMap((customObjectFactory) =>
this.updateFieldRelationMetadata(
customObjectFactory,
context,
originalObjectMetadataMap,
),
);
}
createFieldRelationForStandardObject(
standardObjectMetadataDefinitions: (typeof BaseWorkspaceEntity)[],
context: WorkspaceSyncContext,
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
): Map<string, FieldMetadataEntity<FieldMetadataType.RELATION>[]> {
return standardObjectMetadataDefinitions.reduce(
(acc, standardObjectMetadata) => {
const workspaceEntityMetadataArgs = metadataArgsStorage.filterEntities(
standardObjectMetadata,
);
if (!workspaceEntityMetadataArgs) {
return acc;
}
if (
isGatedAndNotEnabled(
workspaceEntityMetadataArgs.gate,
context.featureFlags,
)
) {
return acc;
}
acc.set(
workspaceEntityMetadataArgs.standardId,
this.updateFieldRelationMetadata(
standardObjectMetadata,
context,
originalObjectMetadataMap,
),
);
return acc;
},
new Map<string, FieldMetadataEntity<FieldMetadataType.RELATION>[]>(),
);
}
private updateFieldRelationMetadata(
workspaceEntityOrCustomRelationFactory:
| typeof BaseWorkspaceEntity
| CustomRelationFactory,
context: WorkspaceSyncContext,
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
): FieldMetadataEntity<FieldMetadataType.RELATION>[] {
const target =
'metadata' in workspaceEntityOrCustomRelationFactory
? workspaceEntityOrCustomRelationFactory.metadata
: workspaceEntityOrCustomRelationFactory;
const workspaceEntity =
'metadata' in workspaceEntityOrCustomRelationFactory
? metadataArgsStorage.filterExtendedEntities(target)
: metadataArgsStorage.filterEntities(target);
const workspaceRelationMetadataArgsCollection = const workspaceRelationMetadataArgsCollection =
metadataArgsStorage.filterRelations(target); metadataArgsStorage.filterRelations(CustomWorkspaceEntity);
if (!workspaceEntity) { const joinColumnsMetadataArgsCollection =
metadataArgsStorage.filterJoinColumns(CustomWorkspaceEntity);
const objectNameSingular = customObjectMetadata.nameSingular;
const sourceObjectMetadata = originalObjectMetadataMap[objectNameSingular];
if (!isDefined(sourceObjectMetadata)) {
throw new Error( throw new Error(
`Object metadata decorator not found, can't parse ${target.name}`, `Source object ${objectNameSingular} not found in database while parsing ${objectNameSingular} relations`,
); );
} }
return workspaceRelationMetadataArgsCollection.map(
(workspaceRelationMetadataArgs) => {
const inverseSideTarget =
workspaceRelationMetadataArgs.inverseSideTarget();
const targetObjectNameSingular = convertClassNameToObjectMetadataName(
inverseSideTarget.name,
);
const targetObjectMetadata =
originalObjectMetadataMap[targetObjectNameSingular];
if (!isDefined(targetObjectMetadata)) {
throw new Error(
`Target object ${targetObjectNameSingular} not found in database while parsing ${objectNameSingular} relations`,
);
}
const sourceFieldMetadataName = workspaceRelationMetadataArgs.name;
const targetFieldMetadataName =
workspaceRelationMetadataArgs.inverseSideFieldKey ??
objectNameSingular;
const targetFieldMetadata = targetObjectMetadata.fields.find(
(field) => field.name === targetFieldMetadataName,
) as FieldMetadataEntity<FieldMetadataType.RELATION>;
if (!isDefined(targetFieldMetadata)) {
throw new Error(
`Target field ${targetFieldMetadataName} not found in object ${targetObjectNameSingular} for relation ${workspaceRelationMetadataArgs.name} of type ${workspaceRelationMetadataArgs.type}`,
);
}
const joinColumnName =
workspaceRelationMetadataArgs.type === RelationType.MANY_TO_ONE
? getJoinColumn(
joinColumnsMetadataArgsCollection,
workspaceRelationMetadataArgs as WorkspaceRelationMetadataArgs,
)
: undefined;
const sourceFieldMetadata = sourceObjectMetadata.fields.find(
(field) => field.name === sourceFieldMetadataName,
) as FieldMetadataEntity<FieldMetadataType.RELATION>;
if (!isDefined(sourceFieldMetadata)) {
throw new Error(
`Source field ${sourceFieldMetadataName} not found in object ${sourceFieldMetadata.name} for relation ${workspaceRelationMetadataArgs.name} of type ${workspaceRelationMetadataArgs.type}`,
);
}
return {
...sourceFieldMetadata,
type: FieldMetadataType.RELATION,
settings: {
relationType: workspaceRelationMetadataArgs.type,
onDelete:
workspaceRelationMetadataArgs.type === RelationType.MANY_TO_ONE
? workspaceRelationMetadataArgs.onDelete
: undefined,
joinColumnName,
},
relationTargetObjectMetadataId: targetObjectMetadata.id,
relationTargetFieldMetadataId: targetFieldMetadata.id,
isNullable: workspaceRelationMetadataArgs.isNullable,
} satisfies FieldMetadataEntity<FieldMetadataType.RELATION>;
},
);
}
computeRelationFieldsForStandardObject(
standardObjectMetadataWorkspaceEntity: typeof BaseWorkspaceEntity,
context: WorkspaceSyncContext,
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
): FieldMetadataEntity<FieldMetadataType.RELATION>[] {
const workspaceEntityMetadataArgs = metadataArgsStorage.filterEntities(
standardObjectMetadataWorkspaceEntity,
);
if (!workspaceEntityMetadataArgs) {
return [];
}
if ( if (
!workspaceRelationMetadataArgsCollection || isGatedAndNotEnabled(
isGatedAndNotEnabled(workspaceEntity?.gate, context.featureFlags) workspaceEntityMetadataArgs.gate,
context.featureFlags,
)
) { ) {
return []; return [];
} }
return workspaceRelationMetadataArgsCollection const sourceObjectNameSingular = workspaceEntityMetadataArgs.nameSingular;
const workspaceStaticRelationMetadataArgsCollection =
metadataArgsStorage.filterRelations(
standardObjectMetadataWorkspaceEntity,
);
const workspaceDynamicRelationMetadataArgsCollection =
metadataArgsStorage.filterDynamicRelations(
standardObjectMetadataWorkspaceEntity,
);
const joinColumnsMetadataArgsCollection =
metadataArgsStorage.filterJoinColumns(
standardObjectMetadataWorkspaceEntity,
);
if (
!isDefined(workspaceStaticRelationMetadataArgsCollection) &&
!isDefined(workspaceDynamicRelationMetadataArgsCollection)
) {
throw new Error(
`No relations found for object ${sourceObjectNameSingular}`,
);
}
const sourceObjectMetadata =
originalObjectMetadataMap[sourceObjectNameSingular];
if (!isDefined(sourceObjectMetadata)) {
throw new Error(
`Source object ${sourceObjectNameSingular} not found in database while parsing relations`,
);
}
const relationsFromDynamicRelations =
workspaceDynamicRelationMetadataArgsCollection
.filter(
(workspaceDynamicRelationMetadataArgs) =>
!isGatedAndNotEnabled(
workspaceDynamicRelationMetadataArgs.gate,
context.featureFlags,
),
)
.flatMap((workspaceDynamicRelationMetadataArgs) => {
const customObjectMetadataItems = Object.values(
originalObjectMetadataMap,
).filter((objectMetadata) => objectMetadata.isCustom);
// TODO: this is hacky and needs to be simplified
return customObjectMetadataItems.flatMap((targetObjectMetadata) => {
const relationMetadataArgs =
workspaceDynamicRelationMetadataArgs.argsFactory(
targetObjectMetadata,
);
const sourceFieldMetadata = sourceObjectMetadata?.fields.find(
(field) => field.name === relationMetadataArgs.name,
) as FieldMetadataEntity<FieldMetadataType.RELATION>;
const targetFieldMetadata = targetObjectMetadata?.fields.find(
(field) =>
field.name ===
workspaceDynamicRelationMetadataArgs.inverseSideFieldKey,
) as FieldMetadataEntity<FieldMetadataType.RELATION>;
if (!isDefined(sourceFieldMetadata)) {
throw new Error(
`Source field ${relationMetadataArgs.name} not found in object ${sourceObjectNameSingular} for relation ${relationMetadataArgs.name} of type ${relationMetadataArgs}`,
);
}
if (!isDefined(targetFieldMetadata)) {
throw new Error(
`Target field ${workspaceDynamicRelationMetadataArgs.inverseSideFieldKey} not found in object ${targetObjectMetadata.nameSingular} for relation ${relationMetadataArgs.name} of type ${workspaceDynamicRelationMetadataArgs.type}`,
);
}
return {
...sourceFieldMetadata,
type: FieldMetadataType.RELATION,
settings: {
relationType: workspaceDynamicRelationMetadataArgs.type,
onDelete:
workspaceDynamicRelationMetadataArgs.type ===
RelationType.MANY_TO_ONE
? workspaceDynamicRelationMetadataArgs.onDelete
: undefined,
joinColumnName: relationMetadataArgs.joinColumn,
},
relationTargetObjectMetadataId: targetObjectMetadata.id,
relationTargetFieldMetadataId: targetFieldMetadata.id,
isNullable: workspaceDynamicRelationMetadataArgs.isNullable,
} satisfies FieldMetadataEntity<FieldMetadataType.RELATION>;
});
});
const staticRelations = workspaceStaticRelationMetadataArgsCollection
.filter( .filter(
(workspaceRelationMetadataArgs) => (workspaceRelationMetadataArgs) =>
!isGatedAndNotEnabled( !isGatedAndNotEnabled(
@ -113,13 +235,6 @@ export class StandardFieldRelationFactory {
), ),
) )
.map((workspaceRelationMetadataArgs) => { .map((workspaceRelationMetadataArgs) => {
// Compute reflect relation metadata
const sourceObjectNameSingular =
'object' in workspaceEntityOrCustomRelationFactory
? workspaceEntityOrCustomRelationFactory.object.nameSingular
: convertClassNameToObjectMetadataName(
workspaceRelationMetadataArgs.target.name,
);
const inverseSideTarget = const inverseSideTarget =
workspaceRelationMetadataArgs.inverseSideTarget(); workspaceRelationMetadataArgs.inverseSideTarget();
const targetObjectNameSingular = convertClassNameToObjectMetadataName( const targetObjectNameSingular = convertClassNameToObjectMetadataName(
@ -127,60 +242,62 @@ export class StandardFieldRelationFactory {
); );
const sourceFieldMetadataName = workspaceRelationMetadataArgs.name; const sourceFieldMetadataName = workspaceRelationMetadataArgs.name;
const targetFieldMetadataName = const targetFieldMetadataName =
(workspaceRelationMetadataArgs.inverseSideFieldKey as workspaceRelationMetadataArgs.inverseSideFieldKey ??
| string sourceObjectNameSingular;
| undefined) ?? sourceObjectNameSingular;
const sourceObjectMetadata =
originalObjectMetadataMap[sourceObjectNameSingular];
const joinColumnsMetadataArgsCollection =
metadataArgsStorage.filterJoinColumns(target);
const joinColumnName = getJoinColumn(
joinColumnsMetadataArgsCollection,
workspaceRelationMetadataArgs,
);
assert( const joinColumnName =
sourceObjectMetadata, workspaceRelationMetadataArgs.type === RelationType.MANY_TO_ONE
`Source object ${sourceObjectNameSingular} not found in databse for relation ${workspaceRelationMetadataArgs.name} of type ${workspaceRelationMetadataArgs.type}`, ? getJoinColumn(
); joinColumnsMetadataArgsCollection,
workspaceRelationMetadataArgs as WorkspaceRelationMetadataArgs,
const targetObjectMetadata = )
originalObjectMetadataMap[targetObjectNameSingular]; : undefined;
assert(
targetObjectMetadata,
`Target object ${targetObjectNameSingular} not found in databse for relation ${workspaceRelationMetadataArgs.name} of type ${workspaceRelationMetadataArgs.type}`,
);
const sourceFieldMetadata = sourceObjectMetadata?.fields.find( const sourceFieldMetadata = sourceObjectMetadata?.fields.find(
(field) => field.name === sourceFieldMetadataName, (field) => field.name === sourceFieldMetadataName,
) as FieldMetadataEntity<FieldMetadataType.RELATION>; ) as FieldMetadataEntity<FieldMetadataType.RELATION>;
assert( if (!isDefined(sourceFieldMetadata)) {
sourceFieldMetadata, throw new Error(
`Source field ${sourceFieldMetadataName} not found in object ${sourceObjectNameSingular} for relation ${workspaceRelationMetadataArgs.name} of type ${workspaceRelationMetadataArgs.type}`, `Source field ${sourceFieldMetadataName} not found in object ${sourceObjectNameSingular} for relation ${workspaceRelationMetadataArgs.name} of type ${workspaceRelationMetadataArgs.type}`,
); );
}
const targetFieldMetadata = targetObjectMetadata?.fields.find( const targetObjectMetadata =
originalObjectMetadataMap[targetObjectNameSingular];
if (!isDefined(targetObjectMetadata)) {
throw new Error(
`Target object ${targetObjectNameSingular} not found in database for relation ${workspaceRelationMetadataArgs.name} of type ${workspaceRelationMetadataArgs.type}`,
);
}
const targetFieldMetadata = targetObjectMetadata.fields.find(
(field) => field.name === targetFieldMetadataName, (field) => field.name === targetFieldMetadataName,
) as FieldMetadataEntity<FieldMetadataType.RELATION>; ) as FieldMetadataEntity<FieldMetadataType.RELATION>;
assert( if (!isDefined(targetFieldMetadata)) {
targetFieldMetadata, throw new Error(
`Target field ${targetFieldMetadataName} not found in object ${targetObjectNameSingular} for relation ${workspaceRelationMetadataArgs.name} of type ${workspaceRelationMetadataArgs.type}`, `Target field ${targetFieldMetadataName} not found in object ${targetObjectNameSingular} for relation ${workspaceRelationMetadataArgs.name} of type ${workspaceRelationMetadataArgs.type}`,
); );
}
return { return {
...sourceFieldMetadata, ...sourceFieldMetadata,
type: FieldMetadataType.RELATION, type: FieldMetadataType.RELATION,
settings: { settings: {
relationType: workspaceRelationMetadataArgs.type, relationType: workspaceRelationMetadataArgs.type,
onDelete: workspaceRelationMetadataArgs.onDelete, onDelete:
workspaceRelationMetadataArgs.type === RelationType.MANY_TO_ONE
? workspaceRelationMetadataArgs.onDelete
: undefined,
joinColumnName, joinColumnName,
}, },
relationTargetObjectMetadataId: targetObjectMetadata.id, relationTargetObjectMetadataId: targetObjectMetadata.id,
relationTargetFieldMetadataId: targetFieldMetadata.id, relationTargetFieldMetadataId: targetFieldMetadata.id,
} satisfies FieldMetadataEntity<FieldMetadataType.RELATION>; } satisfies FieldMetadataEntity<FieldMetadataType.RELATION>;
}); });
return [...staticRelations, ...relationsFromDynamicRelations];
} }
} }

View File

@ -13,7 +13,7 @@ import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-syn
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-entity'; import { metadataArgsStorage } from 'src/engine/twenty-orm/storage/metadata-args.storage';
import { WorkspaceMigrationFieldRelationFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field-relation.factory'; import { WorkspaceMigrationFieldRelationFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field-relation.factory';
import { import {
FieldMetadataUpdate, FieldMetadataUpdate,
@ -150,26 +150,30 @@ export class WorkspaceSyncFieldMetadataRelationService {
originalObjectMetadataMapByName: Record<string, ObjectMetadataEntity>, originalObjectMetadataMapByName: Record<string, ObjectMetadataEntity>,
storage: WorkspaceSyncStorage, storage: WorkspaceSyncStorage,
): Promise<void> { ): Promise<void> {
// Create standard field metadata map
const standardFieldMetadataRelationCollection =
this.standardFieldRelationFactory.createFieldRelationForStandardObject(
standardObjectMetadataDefinitions,
context,
originalObjectMetadataMapByName,
);
// Create map of original and standard object metadata by standard ids // Create map of original and standard object metadata by standard ids
const originalObjectMetadataMap = mapObjectMetadataByUniqueIdentifier( const originalObjectMetadataMap = mapObjectMetadataByUniqueIdentifier(
originalObjectMetadataCollection, originalObjectMetadataCollection,
); );
// Loop over all standard objects and compare them with the objects in DB // Loop over all standard objects and compare them with the objects in DB
for (const [ for (const standardObjectMetadataDefinition of standardObjectMetadataDefinitions) {
standardObjectId, const workspaceEntityMetadataArgs = metadataArgsStorage.filterEntities(
standardFieldMetadataCollection, standardObjectMetadataDefinition,
] of standardFieldMetadataRelationCollection) { );
if (!workspaceEntityMetadataArgs) {
continue;
}
const standardFieldMetadataRelationCollection =
this.standardFieldRelationFactory.computeRelationFieldsForStandardObject(
standardObjectMetadataDefinition,
context,
originalObjectMetadataMapByName,
);
const originalObjectMetadata = const originalObjectMetadata =
originalObjectMetadataMap[standardObjectId]; originalObjectMetadataMap[workspaceEntityMetadataArgs.standardId];
const originalFieldRelationMetadataCollection = const originalFieldRelationMetadataCollection =
(originalObjectMetadata?.fields.filter( (originalObjectMetadata?.fields.filter(
@ -183,7 +187,7 @@ export class WorkspaceSyncFieldMetadataRelationService {
const fieldComparatorResults = const fieldComparatorResults =
this.workspaceFieldRelationComparator.compare( this.workspaceFieldRelationComparator.compare(
originalFieldRelationMetadataCollection, originalFieldRelationMetadataCollection,
standardFieldMetadataCollection, standardFieldMetadataRelationCollection,
); );
this.storeComparatorResults(fieldComparatorResults, storage); this.storeComparatorResults(fieldComparatorResults, storage);
@ -196,25 +200,22 @@ export class WorkspaceSyncFieldMetadataRelationService {
originalObjectMetadataMapByName: Record<string, ObjectMetadataEntity>, originalObjectMetadataMapByName: Record<string, ObjectMetadataEntity>,
storage: WorkspaceSyncStorage, storage: WorkspaceSyncStorage,
): Promise<void> { ): Promise<void> {
// Create standard field metadata collection
const customFieldMetadataRelationCollection =
this.standardFieldRelationFactory.createFieldRelationForCustomObject(
customObjectMetadataCollection.map((objectMetadata) => ({
object: objectMetadata,
metadata: CustomWorkspaceEntity,
})),
context,
originalObjectMetadataMapByName,
);
// Loop over all custom objects from the DB and compare their fields with standard fields // Loop over all custom objects from the DB and compare their fields with standard fields
for (const customObjectMetadata of customObjectMetadataCollection) { for (const customObjectMetadata of customObjectMetadataCollection) {
/** const originalFieldRelationMetadataCollection =
* COMPARE FIELD METADATA (customObjectMetadata.fields.filter(
*/ (field) => field.type === FieldMetadataType.RELATION,
) ?? []) as FieldMetadataEntity<FieldMetadataType.RELATION>[];
const customFieldMetadataRelationCollection =
this.standardFieldRelationFactory.computeRelationFieldsForCustomObject(
customObjectMetadata,
originalObjectMetadataMapByName,
);
const fieldComparatorResults = const fieldComparatorResults =
this.workspaceFieldRelationComparator.compare( this.workspaceFieldRelationComparator.compare(
customObjectMetadata.fields as FieldMetadataEntity<FieldMetadataType.RELATION>[], originalFieldRelationMetadataCollection,
customFieldMetadataRelationCollection, customFieldMetadataRelationCollection,
); );
@ -233,9 +234,6 @@ export class WorkspaceSyncFieldMetadataRelationService {
await objectMetadataRepository.find({ await objectMetadataRepository.find({
where: { where: {
workspaceId: context.workspaceId, workspaceId: context.workspaceId,
fields: {
type: FieldMetadataType.RELATION,
},
}, },
relations: ['dataSource', 'fields'], relations: ['dataSource', 'fields'],
}); });