mirror of
				https://github.com/lingble/twenty.git
				synced 2025-10-31 04:37:56 +00:00 
			
		
		
		
	[Emails migration] Fix email field migration (#7065)
Fix email field migration - Remove deprecated field of type Email - Add standard emails field on person to person views in position 4
This commit is contained in:
		| @@ -0,0 +1,161 @@ | ||||
| import { InjectRepository } from '@nestjs/typeorm'; | ||||
|  | ||||
| import chalk from 'chalk'; | ||||
| import { isDefined } from 'class-validator'; | ||||
| import { Command } from 'nest-commander'; | ||||
| import { Repository } from 'typeorm'; | ||||
|  | ||||
| import { | ||||
|   ActiveWorkspacesCommandOptions, | ||||
|   ActiveWorkspacesCommandRunner, | ||||
| } from 'src/database/commands/active-workspaces.command'; | ||||
| import { TypeORMService } from 'src/database/typeorm/typeorm.service'; | ||||
| import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; | ||||
| import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; | ||||
| import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; | ||||
| import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service'; | ||||
| import { PERSON_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||||
| import { ViewService } from 'src/modules/view/services/view.service'; | ||||
| @Command({ | ||||
|   name: 'upgrade-0.30:fix-email-field-migration', | ||||
|   description: | ||||
|     'Fix migration - delete deprecated email fields and add emails to person views', | ||||
| }) | ||||
| export class FixEmailFieldsToEmailsCommand extends ActiveWorkspacesCommandRunner { | ||||
|   constructor( | ||||
|     @InjectRepository(Workspace, 'core') | ||||
|     protected readonly workspaceRepository: Repository<Workspace>, | ||||
|     @InjectRepository(FieldMetadataEntity, 'metadata') | ||||
|     private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>, | ||||
|     private readonly fieldMetadataService: FieldMetadataService, | ||||
|     private readonly typeORMService: TypeORMService, | ||||
|     private readonly dataSourceService: DataSourceService, | ||||
|     private readonly viewService: ViewService, | ||||
|   ) { | ||||
|     super(workspaceRepository); | ||||
|   } | ||||
|  | ||||
|   async executeActiveWorkspacesCommand( | ||||
|     _passedParam: string[], | ||||
|     _options: ActiveWorkspacesCommandOptions, | ||||
|     workspaceIds: string[], | ||||
|   ): Promise<void> { | ||||
|     this.logger.log('Running command to fix migration'); | ||||
|  | ||||
|     for (const workspaceId of workspaceIds) { | ||||
|       let dataSourceMetadata; | ||||
|  | ||||
|       this.logger.log(`Running command for workspace ${workspaceId}`); | ||||
|       try { | ||||
|         dataSourceMetadata = | ||||
|           await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceId( | ||||
|             workspaceId, | ||||
|           ); | ||||
|  | ||||
|         if (!dataSourceMetadata) { | ||||
|           throw new Error( | ||||
|             `Could not find dataSourceMetadata for workspace ${workspaceId}`, | ||||
|           ); | ||||
|         } | ||||
|  | ||||
|         const workspaceDataSource = | ||||
|           await this.typeORMService.connectToDataSource(dataSourceMetadata); | ||||
|  | ||||
|         if (!workspaceDataSource) { | ||||
|           throw new Error( | ||||
|             `Could not connect to dataSource for workspace ${workspaceId}`, | ||||
|           ); | ||||
|         } | ||||
|       } catch (error) { | ||||
|         this.logger.log( | ||||
|           chalk.red( | ||||
|             `Could not connect to workspace data source for workspace ${workspaceId}`, | ||||
|           ), | ||||
|         ); | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       try { | ||||
|         const deprecatedPersonEmailFieldsMetadata = | ||||
|           await this.fieldMetadataRepository.findBy({ | ||||
|             standardId: PERSON_STANDARD_FIELD_IDS.email, | ||||
|             workspaceId: workspaceId, | ||||
|           }); | ||||
|  | ||||
|         const migratedEmailFieldMetadata = await this.fieldMetadataRepository | ||||
|           .findBy({ | ||||
|             standardId: PERSON_STANDARD_FIELD_IDS.emails, | ||||
|             workspaceId: workspaceId, | ||||
|           }) | ||||
|           .then((fields) => fields[0]); | ||||
|  | ||||
|         const personEmailFieldWasMigratedButHasDuplicate = | ||||
|           deprecatedPersonEmailFieldsMetadata.length > 0 && | ||||
|           isDefined(migratedEmailFieldMetadata); | ||||
|  | ||||
|         if (!personEmailFieldWasMigratedButHasDuplicate) { | ||||
|           this.logger.log( | ||||
|             chalk.yellow('No fields to migrate for workspace ' + workspaceId), | ||||
|           ); | ||||
|           continue; | ||||
|         } | ||||
|  | ||||
|         for (const deprecatedEmailFieldMetadata of deprecatedPersonEmailFieldsMetadata) { | ||||
|           await this.fieldMetadataService.deleteOneField( | ||||
|             { id: deprecatedEmailFieldMetadata.id }, | ||||
|             workspaceId, | ||||
|           ); | ||||
|           this.logger.log( | ||||
|             chalk.green(`Deleted email field for workspace ${workspaceId}.`), | ||||
|           ); | ||||
|         } | ||||
|  | ||||
|         const personObjectMetadaIdForWorkspace = | ||||
|           migratedEmailFieldMetadata.objectMetadataId; | ||||
|  | ||||
|         if (!isDefined(personObjectMetadaIdForWorkspace)) { | ||||
|           this.logger.log( | ||||
|             chalk.red( | ||||
|               `Could not find person object for workspace ${workspaceId}. Could not add emails to person view`, | ||||
|             ), | ||||
|           ); | ||||
|           continue; | ||||
|         } | ||||
|  | ||||
|         const personViewsIds = | ||||
|           await this.viewService.getViewsIdsForObjectMetadataId({ | ||||
|             workspaceId, | ||||
|             objectMetadataId: personObjectMetadaIdForWorkspace as string, | ||||
|           }); | ||||
|  | ||||
|         await this.viewService.addFieldToViews({ | ||||
|           workspaceId: workspaceId, | ||||
|           fieldId: migratedEmailFieldMetadata.id, | ||||
|           viewsIds: personViewsIds, | ||||
|           positions: personViewsIds.reduce((acc, personView) => { | ||||
|             if (!personView.id) { | ||||
|               return acc; | ||||
|             } | ||||
|             acc[personView.id] = 4; | ||||
|  | ||||
|             return acc; | ||||
|           }, []), | ||||
|         }); | ||||
|         this.logger.log(chalk.green(`Added emails to view ${workspaceId}.`)); | ||||
|       } catch (error) { | ||||
|         this.logger.log( | ||||
|           chalk.red( | ||||
|             `Running command on workspace ${workspaceId} failed with error: ${error}`, | ||||
|           ), | ||||
|         ); | ||||
|         continue; | ||||
|       } finally { | ||||
|         this.logger.log( | ||||
|           chalk.green(`Finished running command for workspace ${workspaceId}.`), | ||||
|         ); | ||||
|       } | ||||
|  | ||||
|       this.logger.log(chalk.green(`Command completed!`)); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -4,6 +4,7 @@ import { Command } from 'nest-commander'; | ||||
| import { Repository } from 'typeorm'; | ||||
|  | ||||
| import { ActiveWorkspacesCommandRunner } from 'src/database/commands/active-workspaces.command'; | ||||
| import { FixEmailFieldsToEmailsCommand } from 'src/database/commands/upgrade-version/0-30/0-30-fix-email-field-migration.command'; | ||||
| import { MigrateEmailFieldsToEmailsCommand } from 'src/database/commands/upgrade-version/0-30/0-30-migrate-email-fields-to-emails.command'; | ||||
| import { SetStaleMessageSyncBackToPendingCommand } from 'src/database/commands/upgrade-version/0-30/0-30-set-stale-message-sync-back-to-pending'; | ||||
| import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; | ||||
| @@ -24,6 +25,7 @@ export class UpgradeTo0_30Command extends ActiveWorkspacesCommandRunner { | ||||
|     private readonly syncWorkspaceMetadataCommand: SyncWorkspaceMetadataCommand, | ||||
|     private readonly migrateEmailFieldsToEmails: MigrateEmailFieldsToEmailsCommand, | ||||
|     private readonly setStaleMessageSyncBackToPendingCommand: SetStaleMessageSyncBackToPendingCommand, | ||||
|     private readonly fixEmailFieldsToEmailsCommand: FixEmailFieldsToEmailsCommand, | ||||
|   ) { | ||||
|     super(workspaceRepository); | ||||
|   } | ||||
| @@ -51,5 +53,10 @@ export class UpgradeTo0_30Command extends ActiveWorkspacesCommandRunner { | ||||
|       options, | ||||
|       workspaceIds, | ||||
|     ); | ||||
|     await this.fixEmailFieldsToEmailsCommand.executeActiveWorkspacesCommand( | ||||
|       passedParam, | ||||
|       options, | ||||
|       workspaceIds, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { Module } from '@nestjs/common'; | ||||
| import { TypeOrmModule } from '@nestjs/typeorm'; | ||||
|  | ||||
| import { FixEmailFieldsToEmailsCommand } from 'src/database/commands/upgrade-version/0-30/0-30-fix-email-field-migration.command'; | ||||
| import { MigrateEmailFieldsToEmailsCommand } from 'src/database/commands/upgrade-version/0-30/0-30-migrate-email-fields-to-emails.command'; | ||||
| import { SetStaleMessageSyncBackToPendingCommand } from 'src/database/commands/upgrade-version/0-30/0-30-set-stale-message-sync-back-to-pending'; | ||||
| import { UpgradeTo0_30Command } from 'src/database/commands/upgrade-version/0-30/0-30-upgrade-version.command'; | ||||
| @@ -32,6 +33,7 @@ import { ViewModule } from 'src/modules/view/view.module'; | ||||
|     UpgradeTo0_30Command, | ||||
|     MigrateEmailFieldsToEmailsCommand, | ||||
|     SetStaleMessageSyncBackToPendingCommand, | ||||
|     FixEmailFieldsToEmailsCommand, | ||||
|   ], | ||||
| }) | ||||
| export class UpgradeTo0_30CommandModule {} | ||||
|   | ||||
| @@ -98,4 +98,26 @@ export class ViewService { | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async getViewsIdsForObjectMetadataId({ | ||||
|     workspaceId, | ||||
|     objectMetadataId, | ||||
|   }: { | ||||
|     workspaceId: string; | ||||
|     objectMetadataId: string; | ||||
|   }) { | ||||
|     const viewRepository = | ||||
|       await this.twentyORMGlobalManager.getRepositoryForWorkspace( | ||||
|         workspaceId, | ||||
|         'view', | ||||
|       ); | ||||
|  | ||||
|     return viewRepository | ||||
|       .find({ | ||||
|         where: { | ||||
|           objectMetadataId: objectMetadataId, | ||||
|         }, | ||||
|       }) | ||||
|       .then((views) => views.map((view) => view.id)); | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Marie
					Marie