diff --git a/packages/twenty-server/src/database/commands/database-command.module.ts b/packages/twenty-server/src/database/commands/database-command.module.ts index f673ca3937ae..a3f7ad0dcbe7 100644 --- a/packages/twenty-server/src/database/commands/database-command.module.ts +++ b/packages/twenty-server/src/database/commands/database-command.module.ts @@ -1,27 +1,27 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { ConfirmationQuestion } from 'src/database/commands/questions/confirmation.question'; -import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module'; -import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; -import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module'; -import { DataSeedWorkspaceCommand } from 'src/database/commands/data-seed-dev-workspace.command'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module'; -import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; +import { UpdateMessageChannelSyncStatusEnumCommand } from 'src/database/commands/0-20-update-message-channel-sync-status-enum.command'; import { StartDataSeedDemoWorkspaceCronCommand } from 'src/database/commands/data-seed-demo-workspace/crons/start-data-seed-demo-workspace.cron.command'; import { StopDataSeedDemoWorkspaceCronCommand } from 'src/database/commands/data-seed-demo-workspace/crons/stop-data-seed-demo-workspace.cron.command'; -import { WorkspaceAddTotalCountCommand } from 'src/database/commands/workspace-add-total-count.command'; import { DataSeedDemoWorkspaceCommand } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace-command'; import { DataSeedDemoWorkspaceModule } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module'; -import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { DataSeedWorkspaceCommand } from 'src/database/commands/data-seed-dev-workspace.command'; +import { ConfirmationQuestion } from 'src/database/commands/questions/confirmation.question'; import { UpdateMessageChannelVisibilityEnumCommand } from 'src/database/commands/update-message-channel-visibility-enum.command'; +import { UpgradeTo0_22CommandModule } from 'src/database/commands/upgrade-version/0-22/0-22-upgrade-version.module'; +import { WorkspaceAddTotalCountCommand } from 'src/database/commands/workspace-add-total-count.command'; +import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; -import { UpdateMessageChannelSyncStatusEnumCommand } from 'src/database/commands/0-20-update-message-channel-sync-status-enum.command'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { UpdateBooleanFieldsNullDefaultValuesAndNullValuesCommand } from 'src/database/commands/0-22-update-boolean-fields-null-default-values-and-null-values.command'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; +import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module'; +import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module'; @Module({ imports: [ @@ -39,6 +39,9 @@ import { UpdateBooleanFieldsNullDefaultValuesAndNullValuesCommand } from 'src/da ObjectMetadataModule, DataSeedDemoWorkspaceModule, WorkspaceCacheVersionModule, + + // Upgrades + UpgradeTo0_22CommandModule, ], providers: [ DataSeedWorkspaceCommand, @@ -49,7 +52,6 @@ import { UpdateBooleanFieldsNullDefaultValuesAndNullValuesCommand } from 'src/da StopDataSeedDemoWorkspaceCronCommand, UpdateMessageChannelVisibilityEnumCommand, UpdateMessageChannelSyncStatusEnumCommand, - UpdateBooleanFieldsNullDefaultValuesAndNullValuesCommand, ], }) export class DatabaseCommandModule {} diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-fix-object-metadata-id-standard-id.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-fix-object-metadata-id-standard-id.command.ts new file mode 100644 index 000000000000..213892637d95 --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-fix-object-metadata-id-standard-id.command.ts @@ -0,0 +1,101 @@ +import { Logger } from '@nestjs/common'; +import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; + +import chalk from 'chalk'; +import { Command, CommandRunner, Option } from 'nest-commander'; +import { DataSource, Repository } from 'typeorm'; + +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; +import { AUDIT_LOGS_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; + +interface FixObjectMetadataIdStandardIdCommandOptions { + workspaceId?: string; +} + +@Command({ + name: 'upgrade-0.22:fix-object-metadata-id-standard-id', + description: 'Fix object metadata id standard id', +}) +export class FixObjectMetadataIdStandardIdCommand extends CommandRunner { + private readonly logger = new Logger( + FixObjectMetadataIdStandardIdCommand.name, + ); + constructor( + @InjectRepository(Workspace, 'core') + private readonly workspaceRepository: Repository, + private readonly workspaceCacheVersionService: WorkspaceCacheVersionService, + @InjectDataSource('metadata') + private readonly metadataDataSource: DataSource, + ) { + super(); + } + + @Option({ + flags: '-w, --workspace-id [workspace_id]', + description: 'workspace id. Command runs on all workspaces if not provided', + required: false, + }) + parseWorkspaceId(value: string): string { + return value; + } + + async run( + _passedParam: string[], + options: FixObjectMetadataIdStandardIdCommandOptions, + ): Promise { + const workspaceIds = options.workspaceId + ? [options.workspaceId] + : (await this.workspaceRepository.find()).map( + (workspace) => workspace.id, + ); + + if (!workspaceIds.length) { + this.logger.log(chalk.yellow('No workspace found')); + + return; + } + + this.logger.log( + chalk.green(`Running command on ${workspaceIds.length} workspaces`), + ); + + const metadataQueryRunner = this.metadataDataSource.createQueryRunner(); + + await metadataQueryRunner.connect(); + + const fieldMetadataRepository = + metadataQueryRunner.manager.getRepository(FieldMetadataEntity); + + for (const workspaceId of workspaceIds) { + try { + await metadataQueryRunner.startTransaction(); + + await fieldMetadataRepository.delete({ + workspaceId, + standardId: AUDIT_LOGS_STANDARD_FIELD_IDS.objectName, + name: 'objectMetadataId', + }); + + await metadataQueryRunner.commitTransaction(); + } catch (error) { + await metadataQueryRunner.rollbackTransaction(); + this.logger.log( + chalk.red(`Running command on workspace ${workspaceId} failed`), + ); + throw error; + } + + await this.workspaceCacheVersionService.incrementVersion(workspaceId); + + this.logger.log( + chalk.green(`Running command on workspace ${workspaceId} done`), + ); + } + + await metadataQueryRunner.release(); + + this.logger.log(chalk.green(`Command completed!`)); + } +} diff --git a/packages/twenty-server/src/database/commands/0-22-update-boolean-fields-null-default-values-and-null-values.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-update-boolean-fields-null-default-values-and-null-values.command.ts similarity index 97% rename from packages/twenty-server/src/database/commands/0-22-update-boolean-fields-null-default-values-and-null-values.command.ts rename to packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-update-boolean-fields-null-default-values-and-null-values.command.ts index 89b18dde9744..1bbcef9caa40 100644 --- a/packages/twenty-server/src/database/commands/0-22-update-boolean-fields-null-default-values-and-null-values.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-update-boolean-fields-null-default-values-and-null-values.command.ts @@ -1,13 +1,13 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; import { Logger } from '@nestjs/common'; +import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; -import { Command, CommandRunner, Option } from 'nest-commander'; -import { Repository, IsNull, DataSource } from 'typeorm'; import chalk from 'chalk'; +import { Command, CommandRunner, Option } from 'nest-commander'; +import { DataSource, IsNull, Repository } from 'typeorm'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; 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, FieldMetadataType, @@ -20,7 +20,7 @@ interface UpdateBooleanFieldsNullDefaultValuesAndNullValuesCommandOptions { } @Command({ - name: 'migrate-0.22:update-boolean-field-null-default-values-and-null-values', + name: 'upgrade-0.22:update-boolean-field-null-default-values-and-null-values', description: 'Update boolean fields null default values and null values to false', }) diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-upgrade-version.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-upgrade-version.command.ts new file mode 100644 index 000000000000..ff6e3a68b773 --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-upgrade-version.command.ts @@ -0,0 +1,41 @@ +import { Command, CommandRunner, Option } from 'nest-commander'; + +import { FixObjectMetadataIdStandardIdCommand } from 'src/database/commands/upgrade-version/0-22/0-22-fix-object-metadata-id-standard-id.command'; +import { UpdateBooleanFieldsNullDefaultValuesAndNullValuesCommand } from 'src/database/commands/upgrade-version/0-22/0-22-update-boolean-fields-null-default-values-and-null-values.command'; + +interface UpdateBooleanFieldsNullDefaultValuesAndNullValuesCommandOptions { + workspaceId?: string; +} + +@Command({ + name: 'upgrade-0.22', + description: 'Upgrade to 0.22', +}) +export class UpgradeTo0_22Command extends CommandRunner { + constructor( + private readonly fixObjectMetadataIdStandardIdCommand: FixObjectMetadataIdStandardIdCommand, + private readonly updateBooleanFieldsNullDefaultValuesAndNullValuesCommand: UpdateBooleanFieldsNullDefaultValuesAndNullValuesCommand, + ) { + super(); + } + + @Option({ + flags: '-w, --workspace-id [workspace_id]', + description: 'workspace id. Command runs on all workspaces if not provided', + required: false, + }) + parseWorkspaceId(value: string): string { + return value; + } + + async run( + _passedParam: string[], + options: UpdateBooleanFieldsNullDefaultValuesAndNullValuesCommandOptions, + ): Promise { + await this.fixObjectMetadataIdStandardIdCommand.run(_passedParam, options); + await this.updateBooleanFieldsNullDefaultValuesAndNullValuesCommand.run( + _passedParam, + options, + ); + } +} diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-upgrade-version.module.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-upgrade-version.module.ts new file mode 100644 index 000000000000..0bd19bff7c1b --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-22/0-22-upgrade-version.module.ts @@ -0,0 +1,25 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { FixObjectMetadataIdStandardIdCommand } from 'src/database/commands/upgrade-version/0-22/0-22-fix-object-metadata-id-standard-id.command'; +import { UpdateBooleanFieldsNullDefaultValuesAndNullValuesCommand } from 'src/database/commands/upgrade-version/0-22/0-22-update-boolean-fields-null-default-values-and-null-values.command'; +import { UpgradeTo0_22Command } from 'src/database/commands/upgrade-version/0-22/0-22-upgrade-version.command'; +import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; +import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([Workspace], 'core'), + WorkspaceCacheVersionModule, + TypeORMModule, + DataSourceModule, + ], + providers: [ + FixObjectMetadataIdStandardIdCommand, + UpdateBooleanFieldsNullDefaultValuesAndNullValuesCommand, + UpgradeTo0_22Command, + ], +}) +export class UpgradeTo0_22CommandModule {}