diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-17/2-17-upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-17/2-17-upgrade-version-command.module.ts index 2110c604c5..a79131e2ef 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/2-17/2-17-upgrade-version-command.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-17/2-17-upgrade-version-command.module.ts @@ -5,14 +5,12 @@ import { AddReplyToMessageParticipantRoleOptionCommand } from 'src/database/comm import { AddWorkspaceMemberJobTitleFieldCommand } from 'src/database/commands/upgrade-version-command/2-17/2-17-workspace-command-1801000010000-add-workspace-member-job-title-field.command'; import { SyncCallRecordingNavigationCommandMenuItemAvailabilityExpressionCommand } from 'src/database/commands/upgrade-version-command/2-17/2-17-workspace-command-1801000000000-sync-call-recording-navigation-command-menu-item-availability-expression.command'; import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; -import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module'; import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module'; import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module'; @Module({ imports: [ ApplicationModule, - FieldMetadataModule, WorkspaceCacheModule, WorkspaceIteratorModule, WorkspaceMigrationModule, diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-17/2-17-workspace-command-1801000010000-add-workspace-member-job-title-field.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-17/2-17-workspace-command-1801000010000-add-workspace-member-job-title-field.command.ts index 03d4aaace0..8679ce14c8 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/2-17/2-17-workspace-command-1801000010000-add-workspace-member-job-title-field.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-17/2-17-workspace-command-1801000010000-add-workspace-member-job-title-field.command.ts @@ -1,6 +1,5 @@ import { Command } from 'nest-commander'; import { STANDARD_OBJECTS } from 'twenty-shared/metadata'; -import { FieldMetadataType } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; @@ -8,12 +7,12 @@ import { WorkspaceIteratorService } from 'src/database/commands/command-runners/ import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { RegisteredWorkspaceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-workspace-command.decorator'; -import { type CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input'; -import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/services/field-metadata.service'; import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util'; import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; +import { computeTwentyStandardApplicationAllFlatEntityMaps } from 'src/engine/workspace-manager/twenty-standard-application/utils/twenty-standard-application-all-flat-entity-maps.constant'; +import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service'; const WORKSPACE_MEMBER_UNIVERSAL_IDENTIFIER = STANDARD_OBJECTS.workspaceMember.universalIdentifier; @@ -32,7 +31,7 @@ export class AddWorkspaceMemberJobTitleFieldCommand extends ActiveOrSuspendedWor protected readonly workspaceIteratorService: WorkspaceIteratorService, private readonly applicationService: ApplicationService, private readonly workspaceCacheService: WorkspaceCacheService, - private readonly fieldMetadataService: FieldMetadataService, + private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, ) { super(workspaceIteratorService); } @@ -77,20 +76,6 @@ export class AddWorkspaceMemberJobTitleFieldCommand extends ActiveOrSuspendedWor return; } - const createFieldInput: Omit = { - objectMetadataId: workspaceMemberObject.id, - name: 'jobTitle', - type: FieldMetadataType.TEXT, - label: 'Job Title', - description: 'Workspace member job title', - icon: 'IconBriefcase', - isNullable: true, - isUIReadOnly: true, - isSystem: true, - isActive: true, - universalIdentifier: JOB_TITLE_FIELD_UNIVERSAL_IDENTIFIER, - }; - if (isDryRun) { this.logger.log( `[DRY RUN] Would create jobTitle field on workspaceMember for workspace ${workspaceId}`, @@ -104,20 +89,61 @@ export class AddWorkspaceMemberJobTitleFieldCommand extends ActiveOrSuspendedWor { workspaceId }, ); - try { - await this.fieldMetadataService.createManyFields({ - createFieldInputs: [createFieldInput], + const { allFlatEntityMaps: standardAllFlatEntityMaps } = + computeTwentyStandardApplicationAllFlatEntityMaps({ + now: new Date().toISOString(), workspaceId, - ownerFlatApplication: twentyStandardFlatApplication, - isSystemBuild: true, + twentyStandardApplicationId: twentyStandardFlatApplication.id, }); - } catch (error) { - this.logger.error( - `Failed to add jobTitle field on workspaceMember for workspace ${workspaceId}:\n${ - error instanceof Error ? error.stack : JSON.stringify(error, null, 2) - }`, + + const standardJobTitleFlatFieldMetadata = + standardAllFlatEntityMaps.flatFieldMetadataMaps.byUniversalIdentifier[ + JOB_TITLE_FIELD_UNIVERSAL_IDENTIFIER + ]; + + if (!isDefined(standardJobTitleFlatFieldMetadata)) { + this.logger.log( + `jobTitle standard field definition not found, skipping workspace ${workspaceId}`, + ); + + return; + } + + const flatFieldMetadataToCreate: FlatFieldMetadata = { + ...standardJobTitleFlatFieldMetadata, + viewFieldIds: [], + viewFieldUniversalIdentifiers: [], + }; + + const validateAndBuildResult = + await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( + { + allFlatEntityOperationByMetadataName: { + fieldMetadata: { + flatEntityToCreate: [flatFieldMetadataToCreate], + flatEntityToDelete: [], + flatEntityToUpdate: [], + }, + }, + workspaceId, + isSystemBuild: true, + applicationUniversalIdentifier: + twentyStandardFlatApplication.universalIdentifier, + }, + ); + + if (validateAndBuildResult.status === 'fail') { + this.logger.error( + `Failed to add jobTitle field on workspaceMember for workspace ${workspaceId}:\n${JSON.stringify( + validateAndBuildResult, + null, + 2, + )}`, + ); + + throw new Error( + `Failed to add jobTitle field on workspaceMember for workspace ${workspaceId}`, ); - throw error; } this.logger.log(