From cd23a2bc8053a66a4a071a81a7dcdddc71be43d3 Mon Sep 17 00:00:00 2001 From: Paul Rastoin <45004772+prastoin@users.noreply.github.com> Date: Thu, 2 Apr 2026 15:24:55 +0200 Subject: [PATCH] Cleaning `UpgradeCommand` code flow (#19241) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Introduction Currently preparing the `UpgradeCommand` refactor, in this way started by cleaning up the existing avoiding unecessary dependencies to others services allowing easier readability and concern centralization for upcoming refactor The UpgradeCommand was extending up to five classes, overriding abstracted class and so on. It was also cascade injecting 3 services Introducing the `WorkspaceIteratorService` that centralize the commands set to run over a single workspace logic shared between both atomic upgrade command call and global upgradeCommand ## Tradeoff Duplicated `@Option` between both `UpgradeCommandRunner` and `WorkspaceMigrationRunner` ## Before ``` UpgradeCommand └─ extends UpgradeCommandRunner └─ extends ActiveOrSuspendedWorkspacesMigrationCommandRunner └─ extends WorkspacesMigrationCommandRunner (owns workspace iteration loop + ORM deps) └─ extends MigrationCommandRunner (dry-run, verbose, error handling) └─ extends CommandRunner (nest-commander) ``` ## Now ``` UpgradeCommand └─ extends UpgradeCommandRunner └─ extends CommandRunner (nest-commander) uses ─► Services (via composition) ``` ## Logging management At the moment all services are logging, in the best of the world only the runners should be doing so --- .../__tests__/upgrade.command-runner.spec.ts | 151 +++------ ...e-or-suspended-workspace.command-runner.ts | 23 ++ ...ded-workspaces-migration.command-runner.ts | 29 -- .../migration.command-runner.ts | 4 +- .../command-runners/upgrade.command-runner.ts | 308 ++++++++++++------ .../workspace-iterator.module.ts | 13 + .../workspace-iterator.service.ts | 139 ++++++++ .../workspace.command-runner.ts | 140 ++++++++ .../workspaces-migration.command-runner.ts | 189 ----------- ...-20-backfill-command-menu-items.command.ts | 20 +- ...kfill-navigation-menu-item-type.command.ts | 21 +- ...ackfill-select-field-option-ids.command.ts | 21 +- ...te-orphan-navigation-menu-items.command.ts | 22 +- ...ntify-field-permission-metadata.command.ts | 21 +- ...tify-object-permission-metadata.command.ts | 21 +- ...entify-permission-flag-metadata.command.ts | 21 +- ...ation-id-not-nullable-migration.command.ts | 21 +- ...ation-id-not-nullable-migration.command.ts | 21 +- ...ation-id-not-nullable-migration.command.ts | 21 +- .../1-20-make-workflow-searchable.command.ts | 21 +- ...ging-infrastructure-to-metadata.command.ts | 17 +- .../1-20-migrate-rich-text-to-text.command.ts | 21 +- ...ed-cli-application-registration.command.ts | 20 +- ...pdate-standard-index-view-names.command.ts | 21 +- .../1-20-upgrade-version-command.module.ts | 2 + ...bal-key-value-pair-unique-index.command.ts | 21 +- ...ackfill-datasource-to-workspace.command.ts | 16 +- ...s-and-fields-widget-view-fields.command.ts | 20 +- ...-21-deduplicate-engine-commands.command.ts | 20 +- ...nt-text-to-json-response-format.command.ts | 20 +- ...-layout-command-menu-item-label.command.ts | 21 +- .../1-21-upgrade-version-command.module.ts | 2 + .../upgrade-version-command.module.ts | 4 +- .../upgrade.command.ts | 64 ++-- .../core-modules/billing/billing.module.ts | 2 + .../billing-sync-customer-data.command.ts | 17 +- ...lling-update-subscription-price.command.ts | 17 +- .../commands/flat-cache-invalidate.command.ts | 51 ++- .../workspace-migration-runner.module.ts | 2 + ...message-clearner-remove-orphans.command.ts | 20 +- .../messaging-message-cleaner.module.ts | 2 + .../command/delete-workflow-runs.command.ts | 21 +- .../workflow-run/workflow-run.module.ts | 2 + 43 files changed, 816 insertions(+), 814 deletions(-) create mode 100644 packages/twenty-server/src/database/commands/command-runners/active-or-suspended-workspace.command-runner.ts delete mode 100644 packages/twenty-server/src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner.ts create mode 100644 packages/twenty-server/src/database/commands/command-runners/workspace-iterator.module.ts create mode 100644 packages/twenty-server/src/database/commands/command-runners/workspace-iterator.service.ts create mode 100644 packages/twenty-server/src/database/commands/command-runners/workspace.command-runner.ts delete mode 100644 packages/twenty-server/src/database/commands/command-runners/workspaces-migration.command-runner.ts 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],