feat: new relation sync-metadata, twenty-orm, create/update (#10217)
Fix https://github.com/twentyhq/core-team-issues/issues/330#issue-2827026606 and https://github.com/twentyhq/core-team-issues/issues/327#issue-2827001814 What this PR does when `isNewRelationEnabled` is set to `true`: - [x] Drop the creation of the foreign key as a `FieldMetadata` - [x] Stop creating `RelationMetadata` - [x] Properly fill `FieldMetadata` of type `RELATION` during the sync command - [x] Use new relation settings in TwentyORM - [x] Properly create `FieldMetadata` relations when we create a new object - [x] Handle `database:reset` with new relations --------- Co-authored-by: Charles Bochet <charles@twenty.com> Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
import { BasicColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory';
|
||||
import { CompositeColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory';
|
||||
import { EnumColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/enum-column-action.factory';
|
||||
import { RelationColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/relation-column-action.factory';
|
||||
import { TsVectorColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/ts-vector-column-action.factory';
|
||||
|
||||
export const workspaceColumnActionFactories = [
|
||||
@ -8,4 +9,5 @@ export const workspaceColumnActionFactories = [
|
||||
BasicColumnActionFactory,
|
||||
EnumColumnActionFactory,
|
||||
CompositeColumnActionFactory,
|
||||
RelationColumnActionFactory,
|
||||
];
|
||||
|
||||
@ -0,0 +1,97 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
|
||||
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface';
|
||||
|
||||
import { ColumnActionAbstractFactory } from 'src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory';
|
||||
import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util';
|
||||
import {
|
||||
WorkspaceMigrationColumnActionType,
|
||||
WorkspaceMigrationColumnAlter,
|
||||
WorkspaceMigrationColumnCreate,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import {
|
||||
WorkspaceMigrationException,
|
||||
WorkspaceMigrationExceptionCode,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.exception';
|
||||
|
||||
@Injectable()
|
||||
export class RelationColumnActionFactory extends ColumnActionAbstractFactory<FieldMetadataType.RELATION> {
|
||||
protected readonly logger = new Logger(RelationColumnActionFactory.name);
|
||||
|
||||
protected handleCreateAction(
|
||||
fieldMetadata: FieldMetadataInterface<FieldMetadataType.RELATION>,
|
||||
_options?: WorkspaceColumnActionOptions,
|
||||
): WorkspaceMigrationColumnCreate[] {
|
||||
if (!fieldMetadata.settings || !fieldMetadata.settings.joinColumnName) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const joinColumnName = fieldMetadata.settings.joinColumnName;
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: joinColumnName,
|
||||
columnType: fieldMetadataTypeToColumnType(FieldMetadataType.UUID),
|
||||
isArray: false,
|
||||
isNullable: fieldMetadata.isNullable ?? true,
|
||||
isUnique:
|
||||
fieldMetadata.settings.relationType === RelationType.ONE_TO_ONE,
|
||||
defaultValue: null,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
protected handleAlterAction(
|
||||
currentFieldMetadata: FieldMetadataInterface<FieldMetadataType.RELATION>,
|
||||
alteredFieldMetadata: FieldMetadataInterface<FieldMetadataType.RELATION>,
|
||||
_options?: WorkspaceColumnActionOptions,
|
||||
): WorkspaceMigrationColumnAlter[] {
|
||||
if (!currentFieldMetadata.settings || !alteredFieldMetadata.settings) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const currentJoinColumnName = currentFieldMetadata.settings.joinColumnName;
|
||||
const alteredJoinColumnName = alteredFieldMetadata.settings.joinColumnName;
|
||||
|
||||
if (!currentJoinColumnName || !alteredJoinColumnName) {
|
||||
this.logger.error(
|
||||
`Column name not found for current or altered field metadata, can be due to a missing or an invalid target column map. Current column name: ${currentJoinColumnName}, Altered column name: ${alteredJoinColumnName}.`,
|
||||
);
|
||||
throw new WorkspaceMigrationException(
|
||||
`Column name not found for current or altered field metadata`,
|
||||
WorkspaceMigrationExceptionCode.INVALID_FIELD_METADATA,
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.ALTER,
|
||||
currentColumnDefinition: {
|
||||
columnName: currentJoinColumnName,
|
||||
columnType: fieldMetadataTypeToColumnType(FieldMetadataType.UUID),
|
||||
isArray: false,
|
||||
isNullable: currentFieldMetadata.isNullable ?? true,
|
||||
isUnique:
|
||||
currentFieldMetadata.settings.relationType ===
|
||||
RelationType.ONE_TO_ONE,
|
||||
defaultValue: null,
|
||||
},
|
||||
alteredColumnDefinition: {
|
||||
columnName: alteredJoinColumnName,
|
||||
columnType: fieldMetadataTypeToColumnType(FieldMetadataType.UUID),
|
||||
isArray: false,
|
||||
isNullable: alteredFieldMetadata.isNullable ?? true,
|
||||
isUnique:
|
||||
alteredFieldMetadata.settings.relationType ===
|
||||
RelationType.ONE_TO_ONE,
|
||||
defaultValue: null,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/worksp
|
||||
import { BasicColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory';
|
||||
import { CompositeColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory';
|
||||
import { EnumColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/enum-column-action.factory';
|
||||
import { RelationColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/relation-column-action.factory';
|
||||
import { TsVectorColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/ts-vector-column-action.factory';
|
||||
import {
|
||||
WorkspaceMigrationColumnAction,
|
||||
@ -35,6 +36,7 @@ export class WorkspaceMigrationFactory {
|
||||
private readonly tsVectorColumnActionFactory: TsVectorColumnActionFactory,
|
||||
private readonly enumColumnActionFactory: EnumColumnActionFactory,
|
||||
private readonly compositeColumnActionFactory: CompositeColumnActionFactory,
|
||||
private readonly relationColumnActionFactory: RelationColumnActionFactory,
|
||||
) {
|
||||
this.factoriesMap = new Map<
|
||||
FieldMetadataType,
|
||||
@ -98,6 +100,10 @@ export class WorkspaceMigrationFactory {
|
||||
FieldMetadataType.RICH_TEXT_V2,
|
||||
{ factory: this.compositeColumnActionFactory },
|
||||
],
|
||||
[
|
||||
FieldMetadataType.RELATION,
|
||||
{ factory: this.relationColumnActionFactory },
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user