diff --git a/packages/twenty-server/src/database/commands/command-runners/__tests__/upgrade.command-runner.spec.ts b/packages/twenty-server/src/database/commands/command-runners/__tests__/upgrade.command-runner.spec.ts index 04fe6f4e05..62942bfafa 100644 --- a/packages/twenty-server/src/database/commands/command-runners/__tests__/upgrade.command-runner.spec.ts +++ b/packages/twenty-server/src/database/commands/command-runners/__tests__/upgrade.command-runner.spec.ts @@ -11,14 +11,13 @@ import { UpgradeCommandRunner, type AllCommands, } from 'src/database/commands/command-runners/upgrade.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { CoreMigrationRunnerService } from 'src/database/commands/core-migration-runner/services/core-migration-runner.service'; import { UPGRADE_COMMAND_SUPPORTED_VERSIONS } from 'src/engine/constants/upgrade-command-supported-versions.constant'; import { CoreEngineVersionService } from 'src/engine/core-engine-version/services/core-engine-version.service'; import { type ConfigVariables } from 'src/engine/core-modules/twenty-config/config-variables'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; import { WorkspaceVersionService } from 'src/engine/workspace-manager/workspace-version/services/workspace-version.service'; const CURRENT_VERSION = @@ -66,41 +65,31 @@ const buildUpgradeCommandModule = async ({ appVersion, commandRunner, }: BuildUpgradeCommandModuleArgs) => { - const mockDataSourceService = { - getLastDataSourceMetadataFromWorkspaceId: jest.fn(), - }; - const module: TestingModule = await Test.createTestingModule({ providers: [ { provide: commandRunner, useFactory: ( workspaceRepository: Repository, - twentyConfigService: TwentyConfigService, - globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, - dataSourceService: DataSourceService, coreEngineVersionService: CoreEngineVersionService, workspaceVersionService: WorkspaceVersionService, coreMigrationRunnerService: CoreMigrationRunnerService, + workspaceIteratorService: WorkspaceIteratorService, ) => { return new commandRunner( workspaceRepository, - twentyConfigService, - globalWorkspaceOrmManager, - dataSourceService, coreEngineVersionService, workspaceVersionService, coreMigrationRunnerService, + workspaceIteratorService, ); }, inject: [ getRepositoryToken(WorkspaceEntity), - TwentyConfigService, - GlobalWorkspaceOrmManager, - DataSourceService, CoreEngineVersionService, WorkspaceVersionService, CoreMigrationRunnerService, + WorkspaceIteratorService, ], }, { @@ -131,27 +120,43 @@ const buildUpgradeCommandModule = async ({ }), }, }, - { - provide: GlobalWorkspaceOrmManager, - useValue: { - connect: jest.fn(), - destroyDataSourceForWorkspace: jest.fn(), - getDataSourceForWorkspace: jest.fn(), - executeInWorkspaceContext: jest - .fn() - .mockImplementation((fn: () => any, _authContext?: any) => fn()), - }, - }, - { - provide: DataSourceService, - useValue: mockDataSourceService, - }, CoreEngineVersionService, WorkspaceVersionService, { provide: CoreMigrationRunnerService, useValue: { run: jest.fn().mockResolvedValue(undefined) }, }, + { + provide: WorkspaceIteratorService, + useValue: { + iterate: jest.fn().mockImplementation(async (args: any) => { + const { callback, ...options } = args; + const workspaceIds = + options.workspaceIds ?? + workspaces.map((workspace) => workspace.id); + + const report = { + fail: [] as any[], + success: [] as any[], + }; + + for (const [index, workspaceId] of workspaceIds.entries()) { + try { + await callback({ + workspaceId, + index, + total: workspaceIds.length, + }); + report.success.push({ workspaceId }); + } catch (error) { + report.fail.push({ error, workspaceId }); + } + } + + return report; + }), + }, + }, ], }).compile(); @@ -161,7 +166,6 @@ const buildUpgradeCommandModule = async ({ describe('UpgradeCommandRunner', () => { let upgradeCommandRunner: BasicUpgradeCommandRunner; let workspaceRepository: Repository; - let coreMigrationRunnerService: CoreMigrationRunnerService; type BuildModuleAndSetupSpiesArgs = { numberOfWorkspace?: number; @@ -197,10 +201,6 @@ describe('UpgradeCommandRunner', () => { jest.spyOn(upgradeCommandRunner['logger'], 'error').mockImplementation(); jest.spyOn(upgradeCommandRunner['logger'], 'warn').mockImplementation(); - jest.spyOn(upgradeCommandRunner, 'runOnWorkspace'); - - coreMigrationRunnerService = module.get(CoreMigrationRunnerService); - workspaceRepository = module.get>( getRepositoryToken(WorkspaceEntity), ); @@ -223,16 +223,6 @@ describe('UpgradeCommandRunner', () => { // @ts-expect-error legacy noImplicitAny await upgradeCommandRunner.run(passedParams, options); - const { fail: failReport, success: successReport } = - upgradeCommandRunner.migrationReport; - - expect(successReport.length).toBe(1); - expect(failReport.length).toBe(0); - - [upgradeCommandRunner.runOnWorkspace].forEach((fn) => - expect(fn).toHaveBeenCalledTimes(1), - ); - [workspaceRepository.update].forEach((fn) => expect(fn).not.toHaveBeenCalled(), ); @@ -251,16 +241,12 @@ describe('UpgradeCommandRunner', () => { // @ts-expect-error legacy noImplicitAny await upgradeCommandRunner.run(passedParams, options); - [upgradeCommandRunner.runOnWorkspace].forEach((fn) => - expect(fn).toHaveBeenCalledTimes(numberOfWorkspace), - ); expect(workspaceRepository.update).toHaveBeenNthCalledWith( numberOfWorkspace, { id: expect.any(String) }, { version: CURRENT_VERSION }, ); - expect(upgradeCommandRunner.migrationReport.success.length).toBe(42); - expect(upgradeCommandRunner.migrationReport.fail.length).toBe(0); + expect(workspaceRepository.update).toHaveBeenCalledTimes(numberOfWorkspace); }); describe('Workspace upgrade should succeed ', () => { @@ -315,15 +301,10 @@ describe('UpgradeCommandRunner', () => { // @ts-expect-error legacy noImplicitAny await upgradeCommandRunner.run(passedParams, options); - const { fail: failReport, success: successReport } = - upgradeCommandRunner.migrationReport; - - expect(failReport.length).toBe(0); - expect(successReport.length).toBe(1); - expect(coreMigrationRunnerService.run).toHaveBeenCalledTimes(1); - const { workspaceId } = successReport[0]; - - expect(workspaceId).toBe('workspace_0'); + expect(workspaceRepository.update).toHaveBeenCalledWith( + { id: 'workspace_0' }, + { version: expect.any(String) }, + ); }, ); }); @@ -331,10 +312,7 @@ describe('UpgradeCommandRunner', () => { describe('Workspace upgrade should fail', () => { const failingTestUseCases: EachTestingContext<{ input: Omit; - output?: { - failReportWorkspaceId: string; - expectedErrorMessage: string; - }; + expectedErrorMessage: string; }>[] = [ { title: 'when workspace version is not equal to fromVersion', @@ -344,10 +322,8 @@ describe('UpgradeCommandRunner', () => { version: '0.1.0', }, }, - output: { - failReportWorkspaceId: 'workspace_0', - expectedErrorMessage: `Unable to run the upgrade command. Aborting the upgrade process.\nPlease ensure that all workspaces are on at least the previous minor version (${PREVIOUS_VERSION}).\nIf any workspaces are not on the previous minor version, roll back to that version and run the upgrade command again.`, - }, + expectedErrorMessage: + 'Unable to run the upgrade command. Aborting the upgrade process.', }, }, { @@ -358,10 +334,8 @@ describe('UpgradeCommandRunner', () => { version: null, }, }, - output: { - failReportWorkspaceId: 'workspace_0', - expectedErrorMessage: `Unable to run the upgrade command. Aborting the upgrade process.\nPlease ensure that all workspaces are on at least the previous minor version (${PREVIOUS_VERSION}).\nIf any workspaces are not on the previous minor version, roll back to that version and run the upgrade command again.`, - }, + expectedErrorMessage: + 'Unable to run the upgrade command. Aborting the upgrade process.', }, }, { @@ -370,11 +344,8 @@ describe('UpgradeCommandRunner', () => { input: { appVersion: null, }, - output: { - failReportWorkspaceId: 'global', - expectedErrorMessage: - 'APP_VERSION is not defined, please double check your env variables', - }, + expectedErrorMessage: + 'APP_VERSION is not defined, please double check your env variables', }, }, { @@ -383,11 +354,8 @@ describe('UpgradeCommandRunner', () => { input: { appVersion: '42.0.0', }, - output: { - failReportWorkspaceId: 'global', - expectedErrorMessage: - 'No command found for version 42.0.0. Please check the commands record.', - }, + expectedErrorMessage: + 'No command found for version 42.0.0. Please check the commands record.', }, }, { @@ -396,33 +364,22 @@ describe('UpgradeCommandRunner', () => { input: { appVersion: UPGRADE_COMMAND_SUPPORTED_VERSIONS[0], }, - output: { - failReportWorkspaceId: 'global', - expectedErrorMessage: `No previous version found for version ${UPGRADE_COMMAND_SUPPORTED_VERSIONS[0]}. Available versions: ${UPGRADE_COMMAND_SUPPORTED_VERSIONS.join(', ')}`, - }, + expectedErrorMessage: `No previous version found for version ${UPGRADE_COMMAND_SUPPORTED_VERSIONS[0]}`, }, }, ]; it.each(eachTestingContextFilter(failingTestUseCases))( '$title', - async ({ context: { input, output } }) => { + async ({ context: { input, expectedErrorMessage } }) => { await buildModuleAndSetupSpies(input); const passedParams: string[] = []; const options = {}; - await upgradeCommandRunner.run(passedParams, options); - - const { fail: failReport, success: successReport } = - upgradeCommandRunner.migrationReport; - - expect(successReport.length).toBe(0); - expect(failReport.length).toBe(1); - const { workspaceId, error } = failReport[0]; - - expect(workspaceId).toBe(output?.failReportWorkspaceId ?? 'global'); - expect(error).toEqual(new Error(output?.expectedErrorMessage ?? '')); + await expect( + upgradeCommandRunner.run(passedParams, options), + ).rejects.toThrow(expectedErrorMessage); }, ); }); diff --git a/packages/twenty-server/src/database/commands/command-runners/active-or-suspended-workspace.command-runner.ts b/packages/twenty-server/src/database/commands/command-runners/active-or-suspended-workspace.command-runner.ts new file mode 100644 index 0000000000..df60e5d52e --- /dev/null +++ b/packages/twenty-server/src/database/commands/command-runners/active-or-suspended-workspace.command-runner.ts @@ -0,0 +1,23 @@ +import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; + +import { + WorkspaceCommandRunner, + type WorkspaceCommandOptions, +} from 'src/database/commands/command-runners/workspace.command-runner'; +import { type WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; + +export type ActiveOrSuspendedWorkspaceCommandOptions = WorkspaceCommandOptions; + +export abstract class ActiveOrSuspendedWorkspaceCommandRunner< + Options extends + ActiveOrSuspendedWorkspaceCommandOptions = ActiveOrSuspendedWorkspaceCommandOptions, +> extends WorkspaceCommandRunner { + constructor( + protected readonly workspaceIteratorService: WorkspaceIteratorService, + ) { + super(workspaceIteratorService, [ + WorkspaceActivationStatus.ACTIVE, + WorkspaceActivationStatus.SUSPENDED, + ]); + } +} diff --git a/packages/twenty-server/src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner.ts b/packages/twenty-server/src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner.ts deleted file mode 100644 index 9056c5959c..0000000000 --- a/packages/twenty-server/src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; -import { type Repository } from 'typeorm'; - -import { - WorkspacesMigrationCommandRunner, - type WorkspacesMigrationCommandOptions, -} from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { type DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { type GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; - -export type ActiveOrSuspendedWorkspacesMigrationCommandOptions = - WorkspacesMigrationCommandOptions; - -export abstract class ActiveOrSuspendedWorkspacesMigrationCommandRunner< - Options extends - ActiveOrSuspendedWorkspacesMigrationCommandOptions = ActiveOrSuspendedWorkspacesMigrationCommandOptions, -> extends WorkspacesMigrationCommandRunner { - constructor( - protected readonly workspaceRepository: Repository, - protected readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, - ) { - super(workspaceRepository, globalWorkspaceOrmManager, dataSourceService, [ - WorkspaceActivationStatus.ACTIVE, - WorkspaceActivationStatus.SUSPENDED, - ]); - } -} diff --git a/packages/twenty-server/src/database/commands/command-runners/migration.command-runner.ts b/packages/twenty-server/src/database/commands/command-runners/migration.command-runner.ts index df2a17779e..fbbc1a263a 100644 --- a/packages/twenty-server/src/database/commands/command-runners/migration.command-runner.ts +++ b/packages/twenty-server/src/database/commands/command-runners/migration.command-runner.ts @@ -52,11 +52,11 @@ export abstract class MigrationCommandRunner extends CommandRunner { try { await this.runMigrationCommand(passedParams, options); + + this.logger.log(chalk.blue('Command completed!')); } catch (error) { this.logger.error(chalk.red(`Command failed`)); throw error; - } finally { - this.logger.log(chalk.blue('Command completed!')); } } diff --git a/packages/twenty-server/src/database/commands/command-runners/upgrade.command-runner.ts b/packages/twenty-server/src/database/commands/command-runners/upgrade.command-runner.ts index 35a36337aa..89120392eb 100644 --- a/packages/twenty-server/src/database/commands/command-runners/upgrade.command-runner.ts +++ b/packages/twenty-server/src/database/commands/command-runners/upgrade.command-runner.ts @@ -1,104 +1,143 @@ import { InjectRepository } from '@nestjs/typeorm'; import chalk from 'chalk'; +import { CommandRunner, Option } from 'nest-commander'; import { SemVer } from 'semver'; -import { isDefined } from 'twenty-shared/utils'; +import { assertUnreachable, isDefined } from 'twenty-shared/utils'; import { Repository } from 'typeorm'; import { - ActiveOrSuspendedWorkspacesMigrationCommandOptions, - ActiveOrSuspendedWorkspacesMigrationCommandRunner, -} from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; + type RunOnWorkspaceArgs, + WorkspaceCommandRunner, +} from 'src/database/commands/command-runners/workspace.command-runner'; import { - RunOnWorkspaceArgs, - WorkspacesMigrationCommandRunner, -} from 'src/database/commands/command-runners/workspaces-migration.command-runner'; + type WorkspaceIteratorContext, + WorkspaceIteratorService, +} from 'src/database/commands/command-runners/workspace-iterator.service'; import { CoreMigrationRunnerService } from 'src/database/commands/core-migration-runner/services/core-migration-runner.service'; +import { CommandLogger } from 'src/database/commands/logger'; import { type UpgradeCommandVersion } from 'src/engine/constants/upgrade-command-supported-versions.constant'; import { CoreEngineVersionService } from 'src/engine/core-engine-version/services/core-engine-version.service'; -import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { type DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; import { WorkspaceVersionService } from 'src/engine/workspace-manager/workspace-version/services/workspace-version.service'; import { type CompareVersionMajorAndMinorReturnType, compareVersionMajorAndMinor, } from 'src/utils/version/compare-version-minor-and-major'; -export type VersionCommands = ( - | WorkspacesMigrationCommandRunner - | ActiveOrSuspendedWorkspacesMigrationCommandRunner -)[]; +export type VersionCommands = WorkspaceCommandRunner[]; export type AllCommands = Record; -export abstract class UpgradeCommandRunner extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { - private fromWorkspaceVersion: SemVer; - private currentAppVersion: SemVer; +export type UpgradeCommandOptions = { + workspaceId?: Set; + startFromWorkspaceId?: string; + workspaceCountLimit?: number; + dryRun?: boolean; + verbose?: boolean; +}; + +type VersionContext = { + fromWorkspaceVersion: SemVer; + currentAppVersion: SemVer; + commands: VersionCommands; +}; + +export abstract class UpgradeCommandRunner extends CommandRunner { + protected logger: CommandLogger; + public abstract allCommands: AllCommands; - public commands: VersionCommands; - public readonly VALIDATE_WORKSPACE_VERSION_FEATURE_FLAG?: true; constructor( @InjectRepository(WorkspaceEntity) protected readonly workspaceRepository: Repository, - protected readonly twentyConfigService: TwentyConfigService, - protected readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, protected readonly coreEngineVersionService: CoreEngineVersionService, protected readonly workspaceVersionService: WorkspaceVersionService, protected readonly coreMigrationRunnerService: CoreMigrationRunnerService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, ) { - super(workspaceRepository, globalWorkspaceOrmManager, dataSourceService); + super(); + this.logger = new CommandLogger({ + verbose: false, + constructorName: this.constructor.name, + }); } - private setUpgradeContextVersionsAndCommandsForCurrentAppVersion() { - const upgradeContextIsAlreadyDefined = [ - this.currentAppVersion, - this.commands, - this.fromWorkspaceVersion, - ].every(isDefined); - - if (upgradeContextIsAlreadyDefined) { - return; - } - - const currentAppVersion = this.coreEngineVersionService.getCurrentVersion(); - const currentVersionMajorMinor = - `${currentAppVersion.major}.${currentAppVersion.minor}.0` as UpgradeCommandVersion; - const currentCommands = this.allCommands[currentVersionMajorMinor]; - - if (!isDefined(currentCommands)) { - throw new Error( - `No command found for version ${currentAppVersion}. Please check the commands record.`, - ); - } - - const previousVersion = this.coreEngineVersionService.getPreviousVersion(); - - this.commands = currentCommands; - this.fromWorkspaceVersion = previousVersion; - this.currentAppVersion = currentAppVersion; - - const message = [ - 'Initialized upgrade context with:', - `- currentVersion (migrating to): ${currentAppVersion}`, - `- fromWorkspaceVersion: ${previousVersion}`, - `- ${this.commands.length} commands`, - ]; - - this.logger.log(chalk.blue(message.join('\n '))); + @Option({ + flags: '-d, --dry-run', + description: 'Simulate the command without making actual changes', + required: false, + }) + parseDryRun(): boolean { + return true; } - override async runMigrationCommand( - passedParams: string[], - options: ActiveOrSuspendedWorkspacesMigrationCommandOptions, + @Option({ + flags: '-v, --verbose', + description: 'Verbose output', + required: false, + }) + parseVerbose(): boolean { + return true; + } + + @Option({ + flags: '-w, --workspace-id [workspace_id]', + description: + 'workspace id. Command runs on all active/suspended workspaces if not provided.', + required: false, + }) + parseWorkspaceId(val: string, previous?: Set): Set { + const accumulator = previous ?? new Set(); + + accumulator.add(val); + + return accumulator; + } + + @Option({ + flags: '--start-from-workspace-id [workspace_id]', + description: + 'Start from a specific workspace id. Workspaces are processed in ascending order of id.', + required: false, + }) + parseStartFromWorkspaceId(val: string): string { + return val; + } + + @Option({ + flags: '--workspace-count-limit [count]', + description: + 'Limit the number of workspaces to process. Workspaces are processed in ascending order of id.', + required: false, + }) + parseWorkspaceCountLimit(val: string): number { + const limit = parseInt(val); + + if (isNaN(limit)) { + throw new Error('Workspace count limit must be a number'); + } + + if (limit <= 0) { + throw new Error('Workspace count limit must be greater than 0'); + } + + return limit; + } + + override async run( + _passedParams: string[], + options: UpgradeCommandOptions, ): Promise { - try { - this.setUpgradeContextVersionsAndCommandsForCurrentAppVersion(); + if (options.verbose) { + this.logger = new CommandLogger({ + verbose: true, + constructorName: this.constructor.name, + }); + } + + try { + const versionContext = this.resolveVersionContext(); - // On fresh installs there are no workspaces yet, so skip the - // per-workspace upgrade loop (core migrations already ran above). const hasWorkspaces = await this.workspaceVersionService.hasActiveOrSuspendedWorkspaces(); @@ -110,75 +149,129 @@ export abstract class UpgradeCommandRunner extends ActiveOrSuspendedWorkspacesMi return; } - const workspacesThatAreBelowFromWorkspaceVersion = + const workspacesBelowMinimumVersion = await this.workspaceVersionService.getWorkspacesBelowVersion( - this.fromWorkspaceVersion.version, + versionContext.fromWorkspaceVersion.version, ); - if (workspacesThatAreBelowFromWorkspaceVersion.length > 0) { - this.migrationReport.fail.push( - ...workspacesThatAreBelowFromWorkspaceVersion.map((workspace) => ({ - error: new Error( - `Unable to run the upgrade command. Aborting the upgrade process. -Please ensure that all workspaces are on at least the previous minor version (${this.fromWorkspaceVersion.version}). -If any workspaces are not on the previous minor version, roll back to that version and run the upgrade command again.`, - ), - workspaceId: workspace.id, - })), + if (workspacesBelowMinimumVersion.length > 0) { + const ineligibleIds = workspacesBelowMinimumVersion + .map((workspace) => workspace.id) + .join(', '); + + throw new Error( + `Unable to run the upgrade command. Aborting the upgrade process. +Workspaces below minimum version (${versionContext.fromWorkspaceVersion.version}): ${ineligibleIds}. +Please roll back to that version and run the upgrade command again.`, ); } - } catch (error) { - this.migrationReport.fail.push({ - error, - workspaceId: 'global', - }); - } - if (this.migrationReport.fail.length > 0) { - this.migrationReport.fail.forEach(({ error, workspaceId }) => + await this.coreMigrationRunnerService.run(); + + const iteratorReport = await this.workspaceIteratorService.iterate({ + workspaceIds: + options.workspaceId && options.workspaceId.size > 0 + ? Array.from(options.workspaceId) + : undefined, + startFromWorkspaceId: options.startFromWorkspaceId, + workspaceCountLimit: options.workspaceCountLimit, + dryRun: options.dryRun, + callback: async (context) => { + await this.runOnWorkspace(context, options, versionContext); + }, + }); + + if (iteratorReport.fail.length > 0) { this.logger.error( - `Error in workspace ${workspaceId}: ${error.message}`, + chalk.red( + `Upgrade completed with ${iteratorReport.fail.length} workspace failure(s)`, + ), + ); + } + + this.logger.log( + chalk.blue( + `Upgrade summary: ${iteratorReport.success.length} succeeded, ${iteratorReport.fail.length} failed`, ), ); - - return; + this.logger.log(chalk.blue('Command completed!')); + } catch (error) { + this.logger.error(chalk.red(`Upgrade failed: ${error.message}`)); + throw error; } - - await this.coreMigrationRunnerService.run(); - await super.runMigrationCommand(passedParams, options); } - override async runOnWorkspace(args: RunOnWorkspaceArgs): Promise { - this.setUpgradeContextVersionsAndCommandsForCurrentAppVersion(); + private resolveVersionContext(): VersionContext { + const currentAppVersion = this.coreEngineVersionService.getCurrentVersion(); + const currentVersionMajorMinor = + `${currentAppVersion.major}.${currentAppVersion.minor}.0` as UpgradeCommandVersion; + const commands = this.allCommands[currentVersionMajorMinor]; - const { workspaceId, index, total, options } = args; + if (!isDefined(commands)) { + throw new Error( + `No command found for version ${currentAppVersion}. Please check the commands record.`, + ); + } + + const fromWorkspaceVersion = + this.coreEngineVersionService.getPreviousVersion(); this.logger.log( chalk.blue( - `${options.dryRun ? '(dry run) ' : ''}Upgrading workspace ${workspaceId} from=${this.fromWorkspaceVersion} to=${this.currentAppVersion} ${index + 1}/${total}`, + [ + 'Initialized upgrade context with:', + `- currentVersion (migrating to): ${currentAppVersion}`, + `- fromWorkspaceVersion: ${fromWorkspaceVersion}`, + `- ${commands.length} commands`, + ].join('\n '), ), ); - const workspaceVersionCompareResult = - await this.retrieveWorkspaceVersionAndCompareToWorkspaceFromVersion( + return { fromWorkspaceVersion, currentAppVersion, commands }; + } + + private async runOnWorkspace( + iteratorContext: WorkspaceIteratorContext, + options: UpgradeCommandOptions, + versionContext: VersionContext, + ): Promise { + const { workspaceId, index, total } = iteratorContext; + const { fromWorkspaceVersion, currentAppVersion, commands } = + versionContext; + + this.logger.log( + chalk.blue( + `${options.dryRun ? '(dry run) ' : ''}Upgrading workspace ${workspaceId} from=${fromWorkspaceVersion} to=${currentAppVersion} ${index + 1}/${total}`, + ), + ); + + const versionCompareResult = + await this.compareWorkspaceVersionToFromVersion( workspaceId, + fromWorkspaceVersion, ); - switch (workspaceVersionCompareResult) { + switch (versionCompareResult) { case 'lower': { throw new Error( - `WORKSPACE_VERSION_MISSMATCH Upgrade for workspace ${workspaceId} failed as its version is beneath fromWorkspaceVersion=${this.fromWorkspaceVersion.version}`, + `WORKSPACE_VERSION_MISSMATCH Upgrade for workspace ${workspaceId} failed as its version is beneath fromWorkspaceVersion=${fromWorkspaceVersion.version}`, ); } case 'equal': { - for (const command of this.commands) { - await command.runOnWorkspace(args); + for (const command of commands) { + await command.runOnWorkspace({ + options: options as RunOnWorkspaceArgs['options'], + workspaceId, + dataSource: iteratorContext.dataSource, + index, + total, + }); } if (!options.dryRun) { await this.workspaceRepository.update( { id: workspaceId }, - { version: this.currentAppVersion.version }, + { version: currentAppVersion.version }, ); } @@ -198,15 +291,14 @@ If any workspaces are not on the previous minor version, roll back to that versi return; } default: { - throw new Error( - `Should never occur, encountered unexpected value from retrieveWorkspaceVersionAndCompareToWorkspaceFromVersion ${workspaceVersionCompareResult}`, - ); + assertUnreachable(versionCompareResult); } } } - private async retrieveWorkspaceVersionAndCompareToWorkspaceFromVersion( + private async compareWorkspaceVersionToFromVersion( workspaceId: string, + fromWorkspaceVersion: SemVer, ): Promise { const workspace = await this.workspaceRepository.findOneByOrFail({ id: workspaceId, @@ -219,7 +311,7 @@ If any workspaces are not on the previous minor version, roll back to that versi return compareVersionMajorAndMinor( currentWorkspaceVersion, - this.fromWorkspaceVersion.version, + fromWorkspaceVersion.version, ); } } diff --git a/packages/twenty-server/src/database/commands/command-runners/workspace-iterator.module.ts b/packages/twenty-server/src/database/commands/command-runners/workspace-iterator.module.ts new file mode 100644 index 0000000000..355640af9e --- /dev/null +++ b/packages/twenty-server/src/database/commands/command-runners/workspace-iterator.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; + +@Module({ + imports: [TypeOrmModule.forFeature([WorkspaceEntity]), DataSourceModule], + providers: [WorkspaceIteratorService], + exports: [WorkspaceIteratorService], +}) +export class WorkspaceIteratorModule {} diff --git a/packages/twenty-server/src/database/commands/command-runners/workspace-iterator.service.ts b/packages/twenty-server/src/database/commands/command-runners/workspace-iterator.service.ts new file mode 100644 index 0000000000..d5add51758 --- /dev/null +++ b/packages/twenty-server/src/database/commands/command-runners/workspace-iterator.service.ts @@ -0,0 +1,139 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; + +import chalk from 'chalk'; +import { isDefined } from 'twenty-shared/utils'; +import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; +import { In, MoreThanOrEqual, Repository } from 'typeorm'; + +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { GlobalWorkspaceDataSource } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource'; +import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; +import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util'; + +export type WorkspaceIteratorArgs = { + workspaceIds?: string[]; + activationStatuses?: WorkspaceActivationStatus[]; + startFromWorkspaceId?: string; + workspaceCountLimit?: number; + dryRun?: boolean; + callback: (context: WorkspaceIteratorContext) => Promise; +}; + +export type WorkspaceIteratorContext = { + workspaceId: string; + dataSource?: GlobalWorkspaceDataSource; + index: number; + total: number; +}; + +export type WorkspaceIteratorReport = { + fail: { + workspaceId: string; + error: Error; + }[]; + success: { + workspaceId: string; + }[]; +}; + +const DEFAULT_ACTIVATION_STATUSES = [ + WorkspaceActivationStatus.ACTIVE, + WorkspaceActivationStatus.SUSPENDED, +]; + +@Injectable() +export class WorkspaceIteratorService { + private readonly logger = new Logger(WorkspaceIteratorService.name); + + constructor( + @InjectRepository(WorkspaceEntity) + private readonly workspaceRepository: Repository, + private readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, + private readonly dataSourceService: DataSourceService, + ) {} + + async iterate(args: WorkspaceIteratorArgs): Promise { + const { callback, ...options } = args; + + const report: WorkspaceIteratorReport = { + fail: [], + success: [], + }; + + const workspaceIdsToProcess = + options.workspaceIds && options.workspaceIds.length > 0 + ? options.workspaceIds + : await this.fetchWorkspaceIds(options); + + if (options.dryRun) { + this.logger.log(chalk.yellow('Dry run mode: No changes will be applied')); + } + + for (const [index, workspaceId] of workspaceIdsToProcess.entries()) { + this.logger.log( + `Running on workspace ${workspaceId} ${index + 1}/${workspaceIdsToProcess.length}`, + ); + + try { + const authContext = buildSystemAuthContext(workspaceId); + + await this.globalWorkspaceOrmManager.executeInWorkspaceContext( + async () => { + const workspaceHasDataSource = + await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceId( + workspaceId, + ); + + const dataSource = isDefined(workspaceHasDataSource) + ? await this.globalWorkspaceOrmManager.getGlobalWorkspaceDataSource() + : undefined; + + await callback({ + workspaceId, + dataSource, + index, + total: workspaceIdsToProcess.length, + }); + }, + authContext, + ); + + report.success.push({ workspaceId }); + } catch (error: unknown) { + report.fail.push({ error: error as Error, workspaceId }); + } + } + + report.fail.forEach(({ error, workspaceId }) => + this.logger.error( + `Error in workspace ${workspaceId}: ${error.message}`, + error.stack, + ), + ); + + return report; + } + + private async fetchWorkspaceIds( + options: Omit, + ): Promise { + const activationStatuses = + options.activationStatuses ?? DEFAULT_ACTIVATION_STATUSES; + + const workspaces = await this.workspaceRepository.find({ + select: ['id'], + where: { + activationStatus: In(activationStatuses), + ...(options.startFromWorkspaceId + ? { id: MoreThanOrEqual(options.startFromWorkspaceId) } + : {}), + }, + order: { id: 'ASC' }, + take: options.workspaceCountLimit, + }); + + return workspaces.map((workspace) => workspace.id); + } +} diff --git a/packages/twenty-server/src/database/commands/command-runners/workspace.command-runner.ts b/packages/twenty-server/src/database/commands/command-runners/workspace.command-runner.ts new file mode 100644 index 0000000000..d3b70ae021 --- /dev/null +++ b/packages/twenty-server/src/database/commands/command-runners/workspace.command-runner.ts @@ -0,0 +1,140 @@ +import chalk from 'chalk'; +import { CommandRunner, Option } from 'nest-commander'; +import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; + +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { CommandLogger } from 'src/database/commands/logger'; +import { GlobalWorkspaceDataSource } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource'; + +export type WorkspaceCommandOptions = { + workspaceId?: Set; + startFromWorkspaceId?: string; + workspaceCountLimit?: number; + dryRun?: boolean; + verbose?: boolean; +}; + +export type RunOnWorkspaceArgs = { + options: WorkspaceCommandOptions; + workspaceId: string; + dataSource?: GlobalWorkspaceDataSource; + index: number; + total: number; +}; + +export abstract class WorkspaceCommandRunner< + Options extends WorkspaceCommandOptions = WorkspaceCommandOptions, +> extends CommandRunner { + protected logger: CommandLogger; + + constructor( + protected readonly workspaceIteratorService: WorkspaceIteratorService, + protected readonly activationStatuses: WorkspaceActivationStatus[], + ) { + super(); + this.logger = new CommandLogger({ + verbose: false, + constructorName: this.constructor.name, + }); + } + + @Option({ + flags: '-d, --dry-run', + description: 'Simulate the command without making actual changes', + required: false, + }) + parseDryRun(): boolean { + return true; + } + + @Option({ + flags: '-v, --verbose', + description: 'Verbose output', + required: false, + }) + parseVerbose(): boolean { + return true; + } + + @Option({ + flags: '--start-from-workspace-id [workspace_id]', + description: + 'Start from a specific workspace id. Workspaces are processed in ascending order of id.', + required: false, + }) + parseStartFromWorkspaceId(val: string): string { + return val; + } + + @Option({ + flags: '--workspace-count-limit [count]', + description: + 'Limit the number of workspaces to process. Workspaces are processed in ascending order of id.', + required: false, + }) + parseWorkspaceCountLimit(val: string): number { + const limit = parseInt(val); + + if (isNaN(limit)) { + throw new Error('Workspace count limit must be a number'); + } + + if (limit <= 0) { + throw new Error('Workspace count limit must be greater than 0'); + } + + return limit; + } + + @Option({ + flags: '-w, --workspace-id [workspace_id]', + description: + 'workspace id. Command runs on all workspaces matching the activation statuses if not provided.', + required: false, + }) + parseWorkspaceId(val: string, previous?: Set): Set { + const accumulator = previous ?? new Set(); + + accumulator.add(val); + + return accumulator; + } + + override async run(_passedParams: string[], options: Options): Promise { + if (options.verbose) { + this.logger = new CommandLogger({ + verbose: true, + constructorName: this.constructor.name, + }); + } + + try { + await this.workspaceIteratorService.iterate({ + workspaceIds: + options.workspaceId && options.workspaceId.size > 0 + ? Array.from(options.workspaceId) + : undefined, + activationStatuses: this.activationStatuses, + startFromWorkspaceId: options.startFromWorkspaceId, + workspaceCountLimit: options.workspaceCountLimit, + dryRun: options.dryRun, + callback: async (context) => { + await this.runOnWorkspace({ + options, + workspaceId: context.workspaceId, + dataSource: context.dataSource, + index: context.index, + total: context.total, + }); + }, + }); + + this.logger.log(chalk.blue('Command completed!')); + } catch (error) { + this.logger.error(chalk.red(`Command failed`)); + throw error; + } + } + + public abstract runOnWorkspace(args: RunOnWorkspaceArgs): Promise; +} diff --git a/packages/twenty-server/src/database/commands/command-runners/workspaces-migration.command-runner.ts b/packages/twenty-server/src/database/commands/command-runners/workspaces-migration.command-runner.ts deleted file mode 100644 index ea3b68f002..0000000000 --- a/packages/twenty-server/src/database/commands/command-runners/workspaces-migration.command-runner.ts +++ /dev/null @@ -1,189 +0,0 @@ -import chalk from 'chalk'; -import { Option } from 'nest-commander'; -import { isDefined } from 'twenty-shared/utils'; -import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; -import { In, MoreThanOrEqual, type Repository } from 'typeorm'; - -import { MigrationCommandRunner } from 'src/database/commands/command-runners/migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { type DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceDataSource } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource'; -import { type GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; -import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util'; - -export type WorkspacesMigrationCommandOptions = { - workspaceIds: string[]; - startFromWorkspaceId?: string; - workspaceCountLimit?: number; - dryRun?: boolean; - verbose?: boolean; -}; - -export type RunOnWorkspaceArgs = { - options: WorkspacesMigrationCommandOptions; - workspaceId: string; - dataSource?: GlobalWorkspaceDataSource; - index: number; - total: number; -}; - -export type WorkspaceMigrationReport = { - fail: { - workspaceId: string; - error: Error; - }[]; - success: { - workspaceId: string; - }[]; -}; - -export abstract class WorkspacesMigrationCommandRunner< - Options extends - WorkspacesMigrationCommandOptions = WorkspacesMigrationCommandOptions, -> extends MigrationCommandRunner { - protected workspaceIds: Set = new Set(); - private startFromWorkspaceId: string | undefined; - private workspaceCountLimit: number | undefined; - public migrationReport: WorkspaceMigrationReport = { - fail: [], - success: [], - }; - - constructor( - protected readonly workspaceRepository: Repository, - protected readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, - protected readonly activationStatuses: WorkspaceActivationStatus[], - ) { - super(); - } - - @Option({ - flags: '--start-from-workspace-id [workspace_id]', - description: - 'Start from a specific workspace id. Workspaces are processed in ascending order of id.', - required: false, - }) - parseStartFromWorkspaceId(val: string): string { - this.startFromWorkspaceId = val; - - return val; - } - - @Option({ - flags: '--workspace-count-limit [count]', - description: - 'Limit the number of workspaces to process. Workspaces are processed in ascending order of id.', - required: false, - }) - parseWorkspaceCountLimit(val: string): number { - this.workspaceCountLimit = parseInt(val); - - if (isNaN(this.workspaceCountLimit)) { - throw new Error('Workspace count limit must be a number'); - } - - if (this.workspaceCountLimit <= 0) { - throw new Error('Workspace count limit must be greater than 0'); - } - - return this.workspaceCountLimit; - } - - @Option({ - flags: '-w, --workspace-id [workspace_id]', - description: - 'workspace id. Command runs on all workspaces matching the activation statuses if not provided.', - required: false, - }) - parseWorkspaceId(val: string): Set { - this.workspaceIds.add(val); - - return this.workspaceIds; - } - - protected async fetchWorkspaceIds(): Promise { - const workspaces = await this.workspaceRepository.find({ - select: ['id'], - where: { - activationStatus: In(this.activationStatuses), - ...(this.startFromWorkspaceId - ? { id: MoreThanOrEqual(this.startFromWorkspaceId) } - : {}), - }, - order: { - id: 'ASC', - }, - take: this.workspaceCountLimit, - }); - - return workspaces.map((workspace) => workspace.id); - } - - override async runMigrationCommand( - _passedParams: string[], - options: Options, - ) { - const workspaceIdsToProcess = - this.workspaceIds.size > 0 - ? Array.from(this.workspaceIds) - : await this.fetchWorkspaceIds(); - - if (options.dryRun) { - this.logger.log(chalk.yellow('Dry run mode: No changes will be applied')); - } - - for (const [index, workspaceId] of workspaceIdsToProcess.entries()) { - this.logger.log( - `Upgrading workspace ${workspaceId} ${index + 1}/${workspaceIdsToProcess.length}`, - ); - - try { - const authContext = buildSystemAuthContext(workspaceId); - - await this.globalWorkspaceOrmManager.executeInWorkspaceContext( - async () => { - const workspaceHasDataSource = - await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceId( - workspaceId, - ); - - const dataSource = isDefined(workspaceHasDataSource) - ? await this.globalWorkspaceOrmManager.getGlobalWorkspaceDataSource() - : undefined; - - await this.runOnWorkspace({ - options, - workspaceId, - dataSource, - index: index, - total: workspaceIdsToProcess.length, - }); - }, - authContext, - ); - - this.migrationReport.success.push({ - workspaceId, - }); - } catch (error) { - this.migrationReport.fail.push({ - error, - workspaceId, - }); - this.logger.warn( - chalk.red(`Error in workspace ${workspaceId}: ${error.message}`), - ); - } - } - - this.migrationReport.fail.forEach(({ error, workspaceId }) => - this.logger.error( - `Error in workspace ${workspaceId}: ${error.message}`, - error.stack, - ), - ); - } - - public abstract runOnWorkspace(args: RunOnWorkspaceArgs): Promise; -} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-command-menu-items.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-command-menu-items.command.ts index 3d4b115fef..585f3c3e7d 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-command-menu-items.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-command-menu-items.command.ts @@ -1,21 +1,17 @@ -import { InjectRepository } from '@nestjs/typeorm'; - import { isNonEmptyString } from '@sniptt/guards'; import { Command } from 'nest-commander'; import { FeatureFlagKey } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; -import { Repository } from 'typeorm'; import { v4 as uuidv4 } from 'uuid'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { CommandMenuItemAvailabilityType } from 'src/engine/metadata-modules/command-menu-item/enums/command-menu-item-availability-type.enum'; import { EngineComponentKey } from 'src/engine/metadata-modules/command-menu-item/enums/engine-component-key.enum'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { type FlatCommandMenuItem } from 'src/engine/metadata-modules/flat-command-menu-item/types/flat-command-menu-item.type'; import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util'; @@ -38,19 +34,17 @@ import { description: 'Backfill missing standard and trigger workflow version command menu items for existing workspaces and enable IS_COMMAND_MENU_ITEM_ENABLED feature flag', }) -export class BackfillCommandMenuItemsCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class BackfillCommandMenuItemsCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + private readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, private readonly applicationService: ApplicationService, private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, private readonly featureFlagService: FeatureFlagService, private readonly workspaceCacheService: WorkspaceCacheService, private readonly workflowCommonWorkspaceService: WorkflowCommonWorkspaceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-navigation-menu-item-type.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-navigation-menu-item-type.command.ts index e2f7778abb..7053aaf292 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-navigation-menu-item-type.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-navigation-menu-item-type.command.ts @@ -1,32 +1,27 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { DataSource, Repository } from 'typeorm'; +import { DataSource } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { makeNavigationMenuItemTypeNotNullQueries } from 'src/database/typeorm/core/migrations/utils/1773681736596-makeNavigationMenuItemTypeNotNull.util'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @Command({ name: 'upgrade:1-20:backfill-navigation-menu-item-type', description: 'Backfill navigation menu item type based on existing columns, then apply NOT NULL and CHECK constraints', }) -export class BackfillNavigationMenuItemTypeCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class BackfillNavigationMenuItemTypeCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private hasRunOnce = false; constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-select-field-option-ids.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-select-field-option-ids.command.ts index ac47652464..35a6d54478 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-select-field-option-ids.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-backfill-select-field-option-ids.command.ts @@ -1,31 +1,26 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; import { isDefined } from 'twenty-shared/utils'; import { v4 } from 'uuid'; -import { DataSource, Repository } from 'typeorm'; +import { DataSource } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; @Command({ name: 'upgrade:1-20:backfill-select-field-option-ids', description: 'Backfill missing ids on SELECT and MULTI_SELECT field metadata options', }) -export class BackfillSelectFieldOptionIdsCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class BackfillSelectFieldOptionIdsCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-delete-orphan-navigation-menu-items.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-delete-orphan-navigation-menu-items.command.ts index 97dd250934..5551c1e4f8 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-delete-orphan-navigation-menu-items.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-delete-orphan-navigation-menu-items.command.ts @@ -1,4 +1,3 @@ -import { Logger } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; @@ -6,33 +5,24 @@ import { In, Repository } from 'typeorm'; import { isDefined } from 'twenty-shared/utils'; import { NavigationMenuItemType } from 'twenty-shared/types'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { NavigationMenuItemEntity } from 'src/engine/metadata-modules/navigation-menu-item/entities/navigation-menu-item.entity'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; @Command({ name: 'upgrade:1-20:delete-orphan-navigation-menu-items', description: 'Delete navigation menu items pointing to deleted views', }) -export class DeleteOrphanNavigationMenuItemsCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { - protected readonly logger = new Logger( - DeleteOrphanNavigationMenuItemsCommand.name, - ); - +export class DeleteOrphanNavigationMenuItemsCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectRepository(NavigationMenuItemEntity) private readonly navigationMenuItemRepository: Repository, private readonly workspaceCacheService: WorkspaceCacheService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-field-permission-metadata.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-field-permission-metadata.command.ts index 2c02554cd9..c4fdbc331d 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-field-permission-metadata.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-field-permission-metadata.command.ts @@ -1,35 +1,30 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { DataSource, IsNull, type Repository } from 'typeorm'; +import { DataSource, IsNull } from 'typeorm'; import { v4 } from 'uuid'; import { isDefined } from 'twenty-shared/utils'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { FieldPermissionEntity } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.entity'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @Command({ name: 'upgrade:1-20:identify-field-permission-metadata', description: 'Identify field permission metadata (backfill universalIdentifier and applicationId)', }) -export class IdentifyFieldPermissionMetadataCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class IdentifyFieldPermissionMetadataCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private hasRunOnce = false; constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-object-permission-metadata.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-object-permission-metadata.command.ts index 1155fb3c50..57b1885f0d 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-object-permission-metadata.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-object-permission-metadata.command.ts @@ -1,35 +1,30 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { DataSource, IsNull, type Repository } from 'typeorm'; +import { DataSource, IsNull } from 'typeorm'; import { v4 } from 'uuid'; import { isDefined } from 'twenty-shared/utils'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @Command({ name: 'upgrade:1-20:identify-object-permission-metadata', description: 'Identify object permission metadata (backfill universalIdentifier and applicationId)', }) -export class IdentifyObjectPermissionMetadataCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class IdentifyObjectPermissionMetadataCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private hasRunOnce = false; constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-permission-flag-metadata.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-permission-flag-metadata.command.ts index 9f526d40ad..a65ba15fb3 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-permission-flag-metadata.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-identify-permission-flag-metadata.command.ts @@ -1,35 +1,30 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { DataSource, IsNull, type Repository } from 'typeorm'; +import { DataSource, IsNull } from 'typeorm'; import { v4 } from 'uuid'; import { isDefined } from 'twenty-shared/utils'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @Command({ name: 'upgrade:1-20:identify-permission-flag-metadata', description: 'Identify permission flag metadata (backfill universalIdentifier and applicationId)', }) -export class IdentifyPermissionFlagMetadataCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class IdentifyPermissionFlagMetadataCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private hasRunOnce = false; constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-field-permission-universal-identifier-and-application-id-not-nullable-migration.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-field-permission-universal-identifier-and-application-id-not-nullable-migration.command.ts index 9fe57b8710..acbbd7ad16 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-field-permission-universal-identifier-and-application-id-not-nullable-migration.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-field-permission-universal-identifier-and-application-id-not-nullable-migration.command.ts @@ -1,32 +1,27 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { DataSource, type Repository } from 'typeorm'; +import { DataSource } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { makeFieldPermissionUniversalIdentifierAndApplicationIdNotNullQueries } from 'src/database/typeorm/core/migrations/utils/1773400000000-make-field-permission-universal-identifier-and-application-id-not-null.util'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @Command({ name: 'upgrade:1-20:make-field-permission-universal-identifier-and-application-id-not-nullable-migration', description: 'Set NOT NULL on fieldPermission universalIdentifier and applicationId, add unique index and FK (run identify-field-permission-metadata first)', }) -export class MakeFieldPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class MakeFieldPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private hasRunOnce = false; constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-object-permission-universal-identifier-and-application-id-not-nullable-migration.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-object-permission-universal-identifier-and-application-id-not-nullable-migration.command.ts index b980ea03a5..b0e3f9fbb8 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-object-permission-universal-identifier-and-application-id-not-nullable-migration.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-object-permission-universal-identifier-and-application-id-not-nullable-migration.command.ts @@ -1,32 +1,27 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { DataSource, type Repository } from 'typeorm'; +import { DataSource } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { makeObjectPermissionUniversalIdentifierAndApplicationIdNotNullQueries } from 'src/database/typeorm/core/migrations/utils/1773317160558-make-object-permission-universal-identifier-and-application-id-not-null.util'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @Command({ name: 'upgrade:1-20:make-object-permission-universal-identifier-and-application-id-not-nullable-migration', description: 'Set NOT NULL on objectPermission universalIdentifier and applicationId, add unique index and FK (run identify-object-permission-metadata first)', }) -export class MakeObjectPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class MakeObjectPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private hasRunOnce = false; constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-permission-flag-universal-identifier-and-application-id-not-nullable-migration.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-permission-flag-universal-identifier-and-application-id-not-nullable-migration.command.ts index 77bd5e2979..18b8f0aa70 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-permission-flag-universal-identifier-and-application-id-not-nullable-migration.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-permission-flag-universal-identifier-and-application-id-not-nullable-migration.command.ts @@ -1,32 +1,27 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { DataSource, type Repository } from 'typeorm'; +import { DataSource } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { makePermissionFlagUniversalIdentifierAndApplicationIdNotNullQueries } from 'src/database/typeorm/core/migrations/utils/1773232418467-make-permission-flag-universal-identifier-and-application-id-not-null.util'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @Command({ name: 'upgrade:1-20:make-permission-flag-universal-identifier-and-application-id-not-nullable-migration', description: 'Set NOT NULL on permissionFlag universalIdentifier and applicationId, add unique index and FK (run identify-permission-flag-metadata first)', }) -export class MakePermissionFlagUniversalIdentifierAndApplicationIdNotNullableMigrationCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class MakePermissionFlagUniversalIdentifierAndApplicationIdNotNullableMigrationCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private hasRunOnce = false; constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-workflow-searchable.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-workflow-searchable.command.ts index 0451b709cf..3a7450fc48 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-workflow-searchable.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-make-workflow-searchable.command.ts @@ -1,14 +1,12 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { DataSource, Repository } from 'typeorm'; +import { DataSource } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service'; import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; @@ -16,19 +14,16 @@ import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/works name: 'upgrade:1-20:make-workflow-searchable', description: 'Set isSearchable to true on the workflow object metadata', }) -export class MakeWorkflowSearchableCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class MakeWorkflowSearchableCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, private readonly workspaceCacheService: WorkspaceCacheService, private readonly workspaceCacheStorageService: WorkspaceCacheStorageService, private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-migrate-messaging-infrastructure-to-metadata.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-migrate-messaging-infrastructure-to-metadata.command.ts index 0fcba085e8..b3097d5847 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-migrate-messaging-infrastructure-to-metadata.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-migrate-messaging-infrastructure-to-metadata.command.ts @@ -5,14 +5,13 @@ import { Command } from 'nest-commander'; import { FeatureFlagKey } from 'twenty-shared/types'; import { Repository } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { CalendarChannelEntity } from 'src/engine/metadata-modules/calendar-channel/entities/calendar-channel.entity'; import { ConnectedAccountEntity } from 'src/engine/metadata-modules/connected-account/entities/connected-account.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { MessageChannelEntity } from 'src/engine/metadata-modules/message-channel/entities/message-channel.entity'; import { MessageFolderEntity } from 'src/engine/metadata-modules/message-folder/entities/message-folder.entity'; import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @@ -27,12 +26,9 @@ import { type WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-membe description: 'Backfill connectedAccount, messageChannel, calendarChannel, and messageFolder to core metadata schema', }) -export class MigrateMessagingInfrastructureToMetadataCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class MigrateMessagingInfrastructureToMetadataCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + private readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, @InjectRepository(ConnectedAccountEntity) private readonly connectedAccountRepository: Repository, @InjectRepository(MessageChannelEntity) @@ -44,8 +40,9 @@ export class MigrateMessagingInfrastructureToMetadataCommand extends ActiveOrSus @InjectRepository(UserWorkspaceEntity) private readonly userWorkspaceRepository: Repository, private readonly featureFlagService: FeatureFlagService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-migrate-rich-text-to-text.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-migrate-rich-text-to-text.command.ts index a2b8b4a412..5d9e0501f0 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-migrate-rich-text-to-text.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-migrate-rich-text-to-text.command.ts @@ -1,18 +1,16 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; import { FeatureFlagKey } from 'twenty-shared/types'; -import { DataSource, Repository } from 'typeorm'; +import { DataSource } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util'; import { getMetadataRelatedMetadataNames } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-related-metadata-names.util'; import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service'; import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; import { type WorkspaceCacheKeyName } from 'src/engine/workspace-cache/types/workspace-cache-key.type'; @@ -22,20 +20,17 @@ import { type WorkspaceCacheKeyName } from 'src/engine/workspace-cache/types/wor description: 'Migrate deprecated RICH_TEXT (V1) to TEXT and rename RICH_TEXT_V2 to RICH_TEXT. The underlying column type is already text, so only the metadata needs updating.', }) -export class MigrateRichTextToTextCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class MigrateRichTextToTextCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, private readonly featureFlagService: FeatureFlagService, private readonly workspaceCacheService: WorkspaceCacheService, private readonly workspaceCacheStorageService: WorkspaceCacheStorageService, private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-seed-cli-application-registration.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-seed-cli-application-registration.command.ts index 5fa095a95a..1271335115 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-seed-cli-application-registration.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-seed-cli-application-registration.command.ts @@ -1,31 +1,23 @@ -import { InjectRepository } from '@nestjs/typeorm'; - import { Command } from 'nest-commander'; -import { Repository } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { ApplicationRegistrationService } from 'src/engine/core-modules/application/application-registration/application-registration.service'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; @Command({ name: 'upgrade:1-20:seed-cli-application-registration', description: 'Seed the Twenty CLI application registration for OAuth-based CLI login', }) -export class SeedCliApplicationRegistrationCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class SeedCliApplicationRegistrationCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private hasRun = false; constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, private readonly applicationRegistrationService: ApplicationRegistrationService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-update-standard-index-view-names.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-update-standard-index-view-names.command.ts index 6a36b27cb1..c41ec889d3 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-update-standard-index-view-names.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-update-standard-index-view-names.command.ts @@ -1,29 +1,24 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { DataSource, Repository } from 'typeorm'; +import { DataSource } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; @Command({ name: 'upgrade:1-20:update-standard-index-view-names', description: 'Update standard index view names to use translatable template placeholders', }) -export class UpdateStandardIndexViewNamesCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class UpdateStandardIndexViewNamesCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-upgrade-version-command.module.ts index 1327f3dfd0..898d779f1f 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-upgrade-version-command.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-upgrade-version-command.module.ts @@ -1,6 +1,7 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module'; import { BackfillCommandMenuItemsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-backfill-command-menu-items.command'; import { BackfillNavigationMenuItemTypeCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-backfill-navigation-menu-item-type.command'; import { BackfillSelectFieldOptionIdsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-backfill-select-field-option-ids.command'; @@ -55,6 +56,7 @@ import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-commo WorkspaceMigrationModule, FeatureFlagModule, WorkflowCommonModule, + WorkspaceIteratorModule, ], providers: [ IdentifyPermissionFlagMetadataCommand, diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-add-global-key-value-pair-unique-index.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-add-global-key-value-pair-unique-index.command.ts index 286d990273..35680e9ee9 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-add-global-key-value-pair-unique-index.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-add-global-key-value-pair-unique-index.command.ts @@ -1,21 +1,19 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { DataSource, type Repository } from 'typeorm'; +import { DataSource } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; import { addGlobalKeyValuePairUniqueIndexQueries } from 'src/database/typeorm/core/migrations/utils/1774700000000-add-global-key-value-pair-unique-index.util'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @Command({ name: 'upgrade:1-21:add-global-key-value-pair-unique-index', description: 'Deduplicate global keyValuePair rows and add the null/null unique index', }) -export class AddGlobalKeyValuePairUniqueIndexCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class AddGlobalKeyValuePairUniqueIndexCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private hasRunOnce = false; private async deduplicateGlobalKeyValuePairs( @@ -44,14 +42,11 @@ export class AddGlobalKeyValuePairUniqueIndexCommand extends ActiveOrSuspendedWo } constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-backfill-datasource-to-workspace.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-backfill-datasource-to-workspace.command.ts index 616ab04c58..242dbb9b3e 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-backfill-datasource-to-workspace.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-backfill-datasource-to-workspace.command.ts @@ -5,28 +5,26 @@ import { Command } from 'nest-commander'; import { isDefined } from 'twenty-shared/utils'; import { Repository } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @Command({ name: 'upgrade:1-21:backfill-datasource-to-workspace', description: 'Backfill workspace.databaseSchema from the dataSource entity for workspaces that have not been migrated yet', }) -export class BackfillDatasourceToWorkspaceCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class BackfillDatasourceToWorkspaceCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, + private readonly workspaceRepository: Repository, @InjectRepository(DataSourceEntity) private readonly dataSourceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-backfill-page-layouts-and-fields-widget-view-fields.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-backfill-page-layouts-and-fields-widget-view-fields.command.ts index 56988d8758..98fcbd680a 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-backfill-page-layouts-and-fields-widget-view-fields.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-backfill-page-layouts-and-fields-widget-view-fields.command.ts @@ -1,5 +1,3 @@ -import { InjectRepository } from '@nestjs/typeorm'; - import { Command } from 'nest-commander'; import { CoreObjectNameSingular, @@ -9,16 +7,14 @@ import { ViewType, } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; -import { Repository } from 'typeorm'; import { v4 } from 'uuid'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; 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 { type FlatPageLayoutTab } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type'; @@ -31,7 +27,6 @@ import { FieldDisplayMode } from 'src/engine/metadata-modules/page-layout-widget import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type'; import { WidgetType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-type.enum'; import { PageLayoutType } from 'src/engine/metadata-modules/page-layout/enums/page-layout-type.enum'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; import { GRID_POSITIONS, @@ -91,18 +86,15 @@ const isRelationTargetAvailable = ( description: 'Backfill RECORD_PAGE page layouts, sync FIELDS_WIDGET view fields, create FIELD widgets, and enable IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED', }) -export class BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, private readonly applicationService: ApplicationService, private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, private readonly featureFlagService: FeatureFlagService, private readonly workspaceCacheService: WorkspaceCacheService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-deduplicate-engine-commands.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-deduplicate-engine-commands.command.ts index 28fde94772..c7cd51ea7e 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-deduplicate-engine-commands.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-deduplicate-engine-commands.command.ts @@ -1,15 +1,10 @@ -import { InjectRepository } from '@nestjs/typeorm'; - import { Command } from 'nest-commander'; import { isDefined } from 'twenty-shared/utils'; -import { Repository } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; 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'; @@ -38,17 +33,14 @@ const NEW_UNIVERSAL_IDENTIFIERS = new Set([ description: 'Merge single/multiple record engine command menu items into unified commands (delete, restore, destroy, export)', }) -export class DeduplicateEngineCommandsCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class DeduplicateEngineCommandsCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, private readonly applicationService: ApplicationService, private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, private readonly workspaceCacheService: WorkspaceCacheService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-migrate-ai-agent-text-to-json-response-format.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-migrate-ai-agent-text-to-json-response-format.command.ts index 21092ec493..323b6f1f75 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-migrate-ai-agent-text-to-json-response-format.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-migrate-ai-agent-text-to-json-response-format.command.ts @@ -1,14 +1,10 @@ -import { InjectRepository } from '@nestjs/typeorm'; - import { Command } from 'nest-commander'; import { isDefined } from 'twenty-shared/utils'; -import { Repository } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { type FlatAgent } from 'src/engine/metadata-modules/flat-agent/types/flat-agent.type'; import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; @@ -45,17 +41,15 @@ const TEXT_AGENT_DEFAULT_OUTPUT_SCHEMA = { description: 'Migrate AI agents with text response format to JSON with a default response field', }) -export class MigrateAiAgentTextToJsonResponseFormatCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class MigrateAiAgentTextToJsonResponseFormatCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, + private readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, private readonly workspaceCacheService: WorkspaceCacheService, private readonly applicationService: ApplicationService, private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-update-edit-layout-command-menu-item-label.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-update-edit-layout-command-menu-item-label.command.ts index de8cfc9dad..1c06e7decb 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-update-edit-layout-command-menu-item-label.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-update-edit-layout-command-menu-item-label.command.ts @@ -1,13 +1,11 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; +import { InjectDataSource } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { DataSource, Repository } from 'typeorm'; +import { DataSource } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; const EDIT_RECORD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIER = 'd9794c67-1799-424f-8871-5ea771dd4a6d'; @@ -16,16 +14,13 @@ const EDIT_RECORD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIER = name: 'upgrade:1-21:update-edit-layout-command-menu-item-label', description: 'Update Edit Page Layout command menu item label to Edit Layout', }) -export class UpdateEditLayoutCommandMenuItemLabelCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class UpdateEditLayoutCommandMenuItemLabelCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectDataSource() private readonly coreDataSource: DataSource, - protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, ) { - super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-upgrade-version-command.module.ts index f08bb8f738..893d3536ec 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-upgrade-version-command.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-21/1-21-upgrade-version-command.module.ts @@ -1,6 +1,7 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module'; import { AddGlobalKeyValuePairUniqueIndexCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-add-global-key-value-pair-unique-index.command'; import { BackfillDatasourceToWorkspaceCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-backfill-datasource-to-workspace.command'; import { BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-backfill-page-layouts-and-fields-widget-view-fields.command'; @@ -23,6 +24,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace ApplicationModule, WorkspaceMigrationModule, FeatureFlagModule, + WorkspaceIteratorModule, ], providers: [ AddGlobalKeyValuePairUniqueIndexCommand, diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts index 2edbc37f3e..c4d1628676 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts @@ -1,11 +1,12 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module'; +import { CoreMigrationRunnerModule } from 'src/database/commands/core-migration-runner/core-migration-runner.module'; import { V1_20_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/1-20/1-20-upgrade-version-command.module'; import { V1_21_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/1-21/1-21-upgrade-version-command.module'; import { UpgradeCommand } from 'src/database/commands/upgrade-version-command/upgrade.command'; import { CoreEngineVersionModule } from 'src/engine/core-engine-version/core-engine-version.module'; -import { CoreMigrationRunnerModule } from 'src/database/commands/core-migration-runner/core-migration-runner.module'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { WorkspaceVersionModule } from 'src/engine/workspace-manager/workspace-version/workspace-version.module'; @@ -19,6 +20,7 @@ import { WorkspaceVersionModule } from 'src/engine/workspace-manager/workspace-v CoreEngineVersionModule, CoreMigrationRunnerModule, WorkspaceVersionModule, + WorkspaceIteratorModule, ], providers: [UpgradeCommand], }) diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts index 678e8978be..70b8384534 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts @@ -3,16 +3,15 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; import { type Repository } from 'typeorm'; -import { type ActiveOrSuspendedWorkspacesMigrationCommandOptions } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; import { type AllCommands, UpgradeCommandRunner, type VersionCommands, } from 'src/database/commands/command-runners/upgrade.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; import { CoreMigrationRunnerService } from 'src/database/commands/core-migration-runner/services/core-migration-runner.service'; import { BackfillCommandMenuItemsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-backfill-command-menu-items.command'; import { BackfillNavigationMenuItemTypeCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-backfill-navigation-menu-item-type.command'; -import { AddGlobalKeyValuePairUniqueIndexCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-add-global-key-value-pair-unique-index.command'; import { BackfillSelectFieldOptionIdsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-backfill-select-field-option-ids.command'; import { DeleteOrphanNavigationMenuItemsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-delete-orphan-navigation-menu-items.command'; import { IdentifyFieldPermissionMetadataCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-identify-field-permission-metadata.command'; @@ -26,16 +25,14 @@ import { MigrateMessagingInfrastructureToMetadataCommand } from 'src/database/co import { MigrateRichTextToTextCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-migrate-rich-text-to-text.command'; import { SeedCliApplicationRegistrationCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-seed-cli-application-registration.command'; import { UpdateStandardIndexViewNamesCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-update-standard-index-view-names.command'; +import { AddGlobalKeyValuePairUniqueIndexCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-add-global-key-value-pair-unique-index.command'; import { BackfillDatasourceToWorkspaceCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-backfill-datasource-to-workspace.command'; import { BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-backfill-page-layouts-and-fields-widget-view-fields.command'; import { DeduplicateEngineCommandsCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-deduplicate-engine-commands.command'; import { MigrateAiAgentTextToJsonResponseFormatCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-migrate-ai-agent-text-to-json-response-format.command'; import { UpdateEditLayoutCommandMenuItemLabelCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-update-edit-layout-command-menu-item-label.command'; import { CoreEngineVersionService } from 'src/engine/core-engine-version/services/core-engine-version.service'; -import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; import { WorkspaceVersionService } from 'src/engine/workspace-manager/workspace-version/services/workspace-version.service'; @Command({ @@ -48,46 +45,42 @@ export class UpgradeCommand extends UpgradeCommandRunner { constructor( @InjectRepository(WorkspaceEntity) protected readonly workspaceRepository: Repository, - protected readonly twentyConfigService: TwentyConfigService, - protected readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, protected readonly coreEngineVersionService: CoreEngineVersionService, protected readonly workspaceVersionService: WorkspaceVersionService, protected readonly coreMigrationRunnerService: CoreMigrationRunnerService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, // 1.20 Commands - protected readonly identifyPermissionFlagMetadataCommand: IdentifyPermissionFlagMetadataCommand, - protected readonly makePermissionFlagUniversalIdentifierAndApplicationIdNotNullableMigrationCommand: MakePermissionFlagUniversalIdentifierAndApplicationIdNotNullableMigrationCommand, - protected readonly identifyObjectPermissionMetadataCommand: IdentifyObjectPermissionMetadataCommand, - protected readonly makeObjectPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand: MakeObjectPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand, - protected readonly identifyFieldPermissionMetadataCommand: IdentifyFieldPermissionMetadataCommand, - protected readonly makeFieldPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand: MakeFieldPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand, - protected readonly backfillNavigationMenuItemTypeCommand: BackfillNavigationMenuItemTypeCommand, - protected readonly backfillCommandMenuItemsCommand: BackfillCommandMenuItemsCommand, - protected readonly deleteOrphanNavigationMenuItemsCommand: DeleteOrphanNavigationMenuItemsCommand, - protected readonly seedCliApplicationRegistrationCommand: SeedCliApplicationRegistrationCommand, - protected readonly migrateRichTextToTextCommand: MigrateRichTextToTextCommand, - protected readonly migrateMessagingInfrastructureToMetadataCommand: MigrateMessagingInfrastructureToMetadataCommand, - protected readonly backfillSelectFieldOptionIdsCommand: BackfillSelectFieldOptionIdsCommand, - protected readonly updateStandardIndexViewNamesCommand: UpdateStandardIndexViewNamesCommand, - protected readonly makeWorkflowSearchableCommand: MakeWorkflowSearchableCommand, + private readonly identifyPermissionFlagMetadataCommand: IdentifyPermissionFlagMetadataCommand, + private readonly makePermissionFlagUniversalIdentifierAndApplicationIdNotNullableMigrationCommand: MakePermissionFlagUniversalIdentifierAndApplicationIdNotNullableMigrationCommand, + private readonly identifyObjectPermissionMetadataCommand: IdentifyObjectPermissionMetadataCommand, + private readonly makeObjectPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand: MakeObjectPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand, + private readonly identifyFieldPermissionMetadataCommand: IdentifyFieldPermissionMetadataCommand, + private readonly makeFieldPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand: MakeFieldPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand, + private readonly backfillNavigationMenuItemTypeCommand: BackfillNavigationMenuItemTypeCommand, + private readonly backfillCommandMenuItemsCommand: BackfillCommandMenuItemsCommand, + private readonly deleteOrphanNavigationMenuItemsCommand: DeleteOrphanNavigationMenuItemsCommand, + private readonly seedCliApplicationRegistrationCommand: SeedCliApplicationRegistrationCommand, + private readonly migrateRichTextToTextCommand: MigrateRichTextToTextCommand, + private readonly migrateMessagingInfrastructureToMetadataCommand: MigrateMessagingInfrastructureToMetadataCommand, + private readonly backfillSelectFieldOptionIdsCommand: BackfillSelectFieldOptionIdsCommand, + private readonly updateStandardIndexViewNamesCommand: UpdateStandardIndexViewNamesCommand, + private readonly makeWorkflowSearchableCommand: MakeWorkflowSearchableCommand, // 1.21 Commands - protected readonly addGlobalKeyValuePairUniqueIndexCommand: AddGlobalKeyValuePairUniqueIndexCommand, - protected readonly backfillDatasourceToWorkspaceCommand: BackfillDatasourceToWorkspaceCommand, - protected readonly backfillPageLayoutsAndFieldsWidgetViewFieldsCommand: BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand, - protected readonly deduplicateEngineCommandsCommand: DeduplicateEngineCommandsCommand, - protected readonly migrateAiAgentTextToJsonResponseFormatCommand: MigrateAiAgentTextToJsonResponseFormatCommand, - protected readonly updateEditLayoutCommandMenuItemLabelCommand: UpdateEditLayoutCommandMenuItemLabelCommand, + private readonly addGlobalKeyValuePairUniqueIndexCommand: AddGlobalKeyValuePairUniqueIndexCommand, + private readonly backfillDatasourceToWorkspaceCommand: BackfillDatasourceToWorkspaceCommand, + private readonly backfillPageLayoutsAndFieldsWidgetViewFieldsCommand: BackfillPageLayoutsAndFieldsWidgetViewFieldsCommand, + private readonly deduplicateEngineCommandsCommand: DeduplicateEngineCommandsCommand, + private readonly migrateAiAgentTextToJsonResponseFormatCommand: MigrateAiAgentTextToJsonResponseFormatCommand, + private readonly updateEditLayoutCommandMenuItemLabelCommand: UpdateEditLayoutCommandMenuItemLabelCommand, ) { super( workspaceRepository, - twentyConfigService, - globalWorkspaceOrmManager, - dataSourceService, coreEngineVersionService, workspaceVersionService, coreMigrationRunnerService, + workspaceIteratorService, ); const commands_1200: VersionCommands = [ @@ -126,11 +119,4 @@ export class UpgradeCommand extends UpgradeCommandRunner { '1.21.0': commands_1210, }; } - - override async runMigrationCommand( - passedParams: string[], - options: ActiveOrSuspendedWorkspacesMigrationCommandOptions, - ): Promise { - return await super.runMigrationCommand(passedParams, options); - } } diff --git a/packages/twenty-server/src/engine/core-modules/billing/billing.module.ts b/packages/twenty-server/src/engine/core-modules/billing/billing.module.ts index 3d409a4b4d..3494a98a2e 100644 --- a/packages/twenty-server/src/engine/core-modules/billing/billing.module.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/billing.module.ts @@ -3,6 +3,7 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module'; import { BillingGaugeService } from 'src/engine/core-modules/billing/billing-gauge.service'; import { BillingResolver } from 'src/engine/core-modules/billing/billing.resolver'; import { BillingSyncCustomerDataCommand } from 'src/engine/core-modules/billing/commands/billing-sync-customer-data.command'; @@ -68,6 +69,7 @@ import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permi DataSourceModule, MetricsModule, EnterpriseModule, + WorkspaceIteratorModule, ], providers: [ BillingSubscriptionService, diff --git a/packages/twenty-server/src/engine/core-modules/billing/commands/billing-sync-customer-data.command.ts b/packages/twenty-server/src/engine/core-modules/billing/commands/billing-sync-customer-data.command.ts index 4b6bc0341d..2c03d89d0d 100644 --- a/packages/twenty-server/src/engine/core-modules/billing/commands/billing-sync-customer-data.command.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/commands/billing-sync-customer-data.command.ts @@ -6,29 +6,24 @@ import chalk from 'chalk'; import { Command } from 'nest-commander'; import { Repository } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; import { BillingCustomerEntity } from 'src/engine/core-modules/billing/entities/billing-customer.entity'; import { StripeSubscriptionService } from 'src/engine/core-modules/billing/stripe/services/stripe-subscription.service'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @Command({ name: 'billing:sync-customer-data', description: 'Sync customer data from Stripe for all active workspaces', }) -export class BillingSyncCustomerDataCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class BillingSyncCustomerDataCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, + protected readonly workspaceIteratorService: WorkspaceIteratorService, private readonly stripeSubscriptionService: StripeSubscriptionService, @InjectRepository(BillingCustomerEntity) protected readonly billingCustomerRepository: Repository, - protected readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, ) { - super(workspaceRepository, globalWorkspaceOrmManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/engine/core-modules/billing/commands/billing-update-subscription-price.command.ts b/packages/twenty-server/src/engine/core-modules/billing/commands/billing-update-subscription-price.command.ts index 82e03993b6..4629c05ecc 100644 --- a/packages/twenty-server/src/engine/core-modules/billing/commands/billing-update-subscription-price.command.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/commands/billing-update-subscription-price.command.ts @@ -6,35 +6,30 @@ import { Command, Option } from 'nest-commander'; import { isDefined } from 'twenty-shared/utils'; import { Repository } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; import { BillingSubscriptionEntity } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service'; import { StripeSubscriptionItemService } from 'src/engine/core-modules/billing/stripe/services/stripe-subscription-item.service'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; @Command({ name: 'billing:update-subscription-price', description: 'Update subscription price', }) -export class BillingUpdateSubscriptionPriceCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class BillingUpdateSubscriptionPriceCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private stripePriceIdToUpdate: string; private newStripePriceId: string; private clearUsage = false; constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, + protected readonly workspaceIteratorService: WorkspaceIteratorService, @InjectRepository(BillingSubscriptionEntity) protected readonly billingSubscriptionRepository: Repository, private readonly billingSubscriptionService: BillingSubscriptionService, private readonly stripeSubscriptionItemService: StripeSubscriptionItemService, - protected readonly dataSourceService: DataSourceService, ) { - super(workspaceRepository, globalWorkspaceOrmManager, dataSourceService); + super(workspaceIteratorService); } @Option({ diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/commands/flat-cache-invalidate.command.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/commands/flat-cache-invalidate.command.ts index 6f4e5ceb18..986f79e9dc 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/commands/flat-cache-invalidate.command.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/commands/flat-cache-invalidate.command.ts @@ -1,47 +1,38 @@ -import { InjectRepository } from '@nestjs/typeorm'; - import { Command, Option } from 'nest-commander'; import { ALL_METADATA_NAME, type AllMetadataName, } from 'twenty-shared/metadata'; -import { Repository } from 'typeorm'; import { - ActiveOrSuspendedWorkspacesMigrationCommandRunner, - type ActiveOrSuspendedWorkspacesMigrationCommandOptions, -} from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; + ActiveOrSuspendedWorkspaceCommandRunner, + type ActiveOrSuspendedWorkspaceCommandOptions, +} from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type'; import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util'; import { getMetadataRelatedMetadataNames } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-related-metadata-names.util'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/services/workspace-migration-runner.service'; -type FlatCacheFlushCommandOptions = - ActiveOrSuspendedWorkspacesMigrationCommandOptions & { - allMetadata?: boolean; - }; +type FlatCacheFlushCommandOptions = ActiveOrSuspendedWorkspaceCommandOptions & { + metadataName?: string[]; + allMetadata?: boolean; +}; @Command({ name: 'cache:flat-cache-invalidate', description: 'Flush flat entity cache for specific metadata names and workspaces', }) -export class FlatCacheInvalidateCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { - private metadataNames: string[] = []; +export class FlatCacheInvalidateCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private flatMapsKeysToFlush: (keyof AllFlatEntityMaps)[] = []; constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + protected readonly workspaceIteratorService: WorkspaceIteratorService, private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService, ) { - super(workspaceRepository, globalWorkspaceOrmManager, dataSourceService); + super(workspaceIteratorService); } @Option({ @@ -50,10 +41,12 @@ export class FlatCacheInvalidateCommand extends ActiveOrSuspendedWorkspacesMigra 'Metadata name(s) to flush cache for. Can be specified multiple times.', required: false, }) - parseMetadataName(val: string): string[] { - this.metadataNames.push(val); + parseMetadataName(val: string, previous?: string[]): string[] { + const accumulator = previous ?? []; - return this.metadataNames; + accumulator.push(val); + + return accumulator; } @Option({ @@ -66,11 +59,13 @@ export class FlatCacheInvalidateCommand extends ActiveOrSuspendedWorkspacesMigra return true; } - override async runMigrationCommand( + override async run( passedParams: string[], options: FlatCacheFlushCommandOptions, ): Promise { - if (!options.allMetadata && this.metadataNames.length === 0) { + const metadataNames = options.metadataName ?? []; + + if (!options.allMetadata && metadataNames.length === 0) { this.logger.error( 'Either --all-metadata or at least one --metadataName must be provided.', ); @@ -79,7 +74,7 @@ export class FlatCacheInvalidateCommand extends ActiveOrSuspendedWorkspacesMigra } const validatedMetadataNames = this.validateAndExpandMetadataNames({ - inputMetadataNames: this.metadataNames, + inputMetadataNames: metadataNames, allMetadata: options.allMetadata, }); @@ -95,7 +90,7 @@ export class FlatCacheInvalidateCommand extends ActiveOrSuspendedWorkspacesMigra `Will flush cache for the following flat maps keys: ${this.flatMapsKeysToFlush.join(', ')}`, ); - await super.runMigrationCommand(passedParams, options); + await super.run(passedParams, options); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/workspace-migration-runner.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/workspace-migration-runner.module.ts index 0a7eb7d09d..bdf7cafcb2 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/workspace-migration-runner.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/workspace-migration-runner.module.ts @@ -2,6 +2,7 @@ import { Module } from '@nestjs/common'; import { DiscoveryModule } from '@nestjs/core'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; @@ -27,6 +28,7 @@ import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/wo WorkspaceCacheStorageModule, WorkspaceCacheModule, TypeOrmModule.forFeature([WorkspaceEntity]), + WorkspaceIteratorModule, ], providers: [ WorkspaceMigrationRunnerService, diff --git a/packages/twenty-server/src/modules/messaging/message-cleaner/commands/messaging-message-clearner-remove-orphans.command.ts b/packages/twenty-server/src/modules/messaging/message-cleaner/commands/messaging-message-clearner-remove-orphans.command.ts index 4234c3566d..42f9ae5cda 100644 --- a/packages/twenty-server/src/modules/messaging/message-cleaner/commands/messaging-message-clearner-remove-orphans.command.ts +++ b/packages/twenty-server/src/modules/messaging/message-cleaner/commands/messaging-message-clearner-remove-orphans.command.ts @@ -1,28 +1,20 @@ -import { InjectRepository } from '@nestjs/typeorm'; - import { Command } from 'nest-commander'; -import { Repository } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; import { MessagingMessageCleanerService } from 'src/modules/messaging/message-cleaner/services/messaging-message-cleaner.service'; @Command({ name: 'messaging:message-cleaner-remove-orphans', description: 'Remove orphan message and threads from messaging', }) -export class MessagingMessageCleanerRemoveOrphansCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class MessagingMessageCleanerRemoveOrphansCommand extends ActiveOrSuspendedWorkspaceCommandRunner { constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, + protected readonly workspaceIteratorService: WorkspaceIteratorService, private readonly messagingMessageCleanerService: MessagingMessageCleanerService, - protected readonly dataSourceService: DataSourceService, ) { - super(workspaceRepository, globalWorkspaceOrmManager, dataSourceService); + super(workspaceIteratorService); } override async runOnWorkspace({ diff --git a/packages/twenty-server/src/modules/messaging/message-cleaner/messaging-message-cleaner.module.ts b/packages/twenty-server/src/modules/messaging/message-cleaner/messaging-message-cleaner.module.ts index 7920b1c6e9..638a6d5b5d 100644 --- a/packages/twenty-server/src/modules/messaging/message-cleaner/messaging-message-cleaner.module.ts +++ b/packages/twenty-server/src/modules/messaging/message-cleaner/messaging-message-cleaner.module.ts @@ -1,6 +1,7 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; @@ -21,6 +22,7 @@ import { MessagingMessageCleanerService } from 'src/modules/messaging/message-cl FeatureFlagModule, MessagingCommonModule, MessageChannelDataAccessModule, + WorkspaceIteratorModule, ], providers: [ MessagingConnectedAccountDeletionCleanupJob, diff --git a/packages/twenty-server/src/modules/workflow/workflow-runner/workflow-run/command/delete-workflow-runs.command.ts b/packages/twenty-server/src/modules/workflow/workflow-runner/workflow-run/command/delete-workflow-runs.command.ts index f55ddca45e..dd2cfc2ccf 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-runner/workflow-run/command/delete-workflow-runs.command.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-runner/workflow-run/command/delete-workflow-runs.command.ts @@ -1,12 +1,9 @@ -import { InjectRepository } from '@nestjs/typeorm'; - import { Command, Option } from 'nest-commander'; -import { LessThan, Repository } from 'typeorm'; +import { LessThan } from 'typeorm'; -import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; -import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner'; +import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service'; +import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner'; import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util'; import { type WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity'; @@ -15,16 +12,14 @@ import { type WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/sta name: 'workflow:delete-workflow-runs', description: 'Delete all workflow runs', }) -export class DeleteWorkflowRunsCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { +export class DeleteWorkflowRunsCommand extends ActiveOrSuspendedWorkspaceCommandRunner { private createdBeforeDate: string | undefined; constructor( - @InjectRepository(WorkspaceEntity) - protected readonly workspaceRepository: Repository, - protected readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, - protected readonly dataSourceService: DataSourceService, + private readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager, + protected readonly workspaceIteratorService: WorkspaceIteratorService, ) { - super(workspaceRepository, globalWorkspaceOrmManager, dataSourceService); + super(workspaceIteratorService); } @Option({ diff --git a/packages/twenty-server/src/modules/workflow/workflow-runner/workflow-run/workflow-run.module.ts b/packages/twenty-server/src/modules/workflow/workflow-runner/workflow-run/workflow-run.module.ts index e5d3be5f8c..a729859008 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-runner/workflow-run/workflow-run.module.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-runner/workflow-run/workflow-run.module.ts @@ -2,6 +2,7 @@ import { Module } from '@nestjs/common'; import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; +import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module'; import { CacheLockModule } from 'src/engine/core-modules/cache-lock/cache-lock.module'; import { MetricsModule } from 'src/engine/core-modules/metrics/metrics.module'; import { RecordPositionModule } from 'src/engine/core-modules/record-position/record-position.module'; @@ -23,6 +24,7 @@ import { WorkflowRunWorkspaceService } from 'src/modules/workflow/workflow-runne CacheLockModule, MetricsModule, DataSourceModule, + WorkspaceIteratorModule, ], providers: [WorkflowRunWorkspaceService, DeleteWorkflowRunsCommand], exports: [WorkflowRunWorkspaceService, DeleteWorkflowRunsCommand],