Morph relation : migration builder (#13173)

This PR will create the migration to be run for the morph relations

- We created a dedicated util to generate the column name and refactored
a little the code in order to have less dependencies and a clearer devX
(updated the snapshot that changed because of this)
- Moved the `createMigrationActions` to its own util as well
- Created the `MorphRelationColumnActionFactory` based on the relation
one

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Guillim
2025-07-17 11:39:45 +02:00
committed by GitHub
parent 0a8a6b652a
commit 530a7dea86
10 changed files with 210 additions and 83 deletions
@@ -3,30 +3,93 @@ 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 MorphRelationColumnActionFactory extends ColumnActionAbstractFactory<FieldMetadataType.MORPH_RELATION> {
protected readonly logger = new Logger(MorphRelationColumnActionFactory.name);
protected handleCreateAction(
_fieldMetadata: FieldMetadataInterface<FieldMetadataType.MORPH_RELATION>,
fieldMetadata: FieldMetadataInterface<FieldMetadataType.MORPH_RELATION>,
_options?: WorkspaceColumnActionOptions,
): WorkspaceMigrationColumnCreate[] {
return [];
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: false,
defaultValue: null,
},
];
}
protected handleAlterAction(
_currentFieldMetadata: FieldMetadataInterface<FieldMetadataType.MORPH_RELATION>,
_alteredFieldMetadata: FieldMetadataInterface<FieldMetadataType.MORPH_RELATION>,
currentFieldMetadata: FieldMetadataInterface<FieldMetadataType.MORPH_RELATION>,
alteredFieldMetadata: FieldMetadataInterface<FieldMetadataType.MORPH_RELATION>,
_options?: WorkspaceColumnActionOptions,
): WorkspaceMigrationColumnAlter[] {
return [];
if (!currentFieldMetadata.settings || !alteredFieldMetadata.settings) {
return [];
}
if (
currentFieldMetadata.settings.relationType === RelationType.ONE_TO_MANY
) {
return [];
}
const currentJoinColumnName = currentFieldMetadata.settings.joinColumnName;
const alteredJoinColumnName = alteredFieldMetadata.settings.joinColumnName;
if (!currentJoinColumnName || !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: false,
defaultValue: null,
},
alteredColumnDefinition: {
columnName: alteredJoinColumnName,
columnType: fieldMetadataTypeToColumnType(FieldMetadataType.UUID),
isArray: false,
isNullable: alteredFieldMetadata.isNullable ?? true,
isUnique: false,
defaultValue: null,
},
},
];
}
}