new command for context creation

This commit is contained in:
guillim
2025-01-31 13:14:03 +01:00
parent 13f51db683
commit 9f1087b180
3 changed files with 169 additions and 0 deletions
@@ -0,0 +1,157 @@
import { InjectRepository } from '@nestjs/typeorm';
import chalk from 'chalk';
import { Command } from 'nest-commander';
import { FieldMetadataType } from 'twenty-shared';
import { Repository, TableColumn } from 'typeorm';
import {
ActiveWorkspacesCommandOptions,
ActiveWorkspacesCommandRunner,
} from 'src/database/commands/active-workspaces.command';
import { CommandLogger } from 'src/database/commands/logger';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { computeTableName } from 'src/engine/utils/compute-table-name.util';
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
@Command({
name: 'upgrade-0.40:add-context-to-actor-composite-type',
description: 'Add context to actor composite type.',
})
export class AddContextToActorCompositeTypeCommand extends ActiveWorkspacesCommandRunner {
protected readonly logger;
constructor(
@InjectRepository(Workspace, 'core')
protected readonly workspaceRepository: Repository<Workspace>,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
@InjectRepository(FieldMetadataEntity, 'metadata')
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
) {
super(workspaceRepository);
this.logger = new CommandLogger({
constructorName: this.constructor.name,
verbose: false,
});
this.logger.setVerbose(false);
}
async executeActiveWorkspacesCommand(
_passedParam: string[],
options: ActiveWorkspacesCommandOptions,
workspaceIds: string[],
): Promise<void> {
this.logger.log(`Running add-context-to-actor-composite-type command`);
if (options?.dryRun) {
this.logger.log(chalk.yellow('Dry run mode: No changes will be applied'));
}
for (const workspaceId of workspaceIds) {
try {
await this.execute(workspaceId, options?.dryRun);
this.logger.verbose(`Added for workspace: ${workspaceId}`);
} catch (error) {
this.logger.error(`Error for workspace: ${workspaceId}`, error);
}
}
}
private async execute(workspaceId: string, dryRun = false): Promise<void> {
this.logger.verbose(`Adding for workspace: ${workspaceId}`);
const actorFields = await this.fieldMetadataRepository.find({
where: {
type: FieldMetadataType.ACTOR,
workspaceId,
},
relations: ['object'],
});
// Filter and update fields with EMAIL or CALENDAR source
for (const field of actorFields) {
if (!field || !field.object) {
this.logger.verbose(
'field.objectMetadata is null',
workspaceId,
field.id,
);
continue;
}
await this.addContextColumn(
field,
`${field.name}Context`,
workspaceId,
dryRun,
);
}
}
private async addContextColumn(
field: FieldMetadataEntity,
newColumnName: string,
workspaceId: string,
dryRun = false,
): Promise<void> {
const workspaceDataSource =
await this.workspaceDataSourceService.connectToWorkspaceDataSource(
workspaceId,
);
if (!workspaceDataSource) {
this.logger.verbose('No workspace data source found');
return;
}
const queryRunner = workspaceDataSource?.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
const schemaName =
this.workspaceDataSourceService.getSchemaName(workspaceId);
try {
const hasColumn = await queryRunner.hasColumn(
`${schemaName}.${computeTableName(
field.object.nameSingular,
field?.object?.isCustom,
)}`,
newColumnName,
);
if (hasColumn) {
return;
}
if (!dryRun) {
await queryRunner.addColumn(
`${schemaName}.${computeTableName(
field.object.nameSingular,
field?.object?.isCustom,
)}`,
new TableColumn({
name: newColumnName,
type: 'jsonb',
default: `'{}'::"jsonb"`,
isNullable: true,
}),
);
await queryRunner.commitTransaction();
}
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
}
}
@@ -5,6 +5,7 @@ import { Repository } from 'typeorm';
import { ActiveWorkspacesCommandRunner } from 'src/database/commands/active-workspaces.command';
import { BaseCommandOptions } from 'src/database/commands/base.command';
import { AddContextToActorCompositeTypeCommand } from 'src/database/commands/upgrade-version/0-40/0-40-add-context-to-actor-composite-type';
import { MigrateAggregateOperationOptionsCommand } from 'src/database/commands/upgrade-version/0-40/0-40-migrate-aggregate-operations-options.command';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@@ -17,6 +18,7 @@ export class UpgradeTo0_40Command extends ActiveWorkspacesCommandRunner {
@InjectRepository(Workspace, 'core')
protected readonly workspaceRepository: Repository<Workspace>,
private readonly migrateAggregateOperationOptionsCommand: MigrateAggregateOperationOptionsCommand,
private readonly addContextToActorCompositeTypeCommand: AddContextToActorCompositeTypeCommand,
) {
super(workspaceRepository);
}
@@ -33,5 +35,11 @@ export class UpgradeTo0_40Command extends ActiveWorkspacesCommandRunner {
options,
workspaceIds,
);
await this.addContextToActorCompositeTypeCommand.executeActiveWorkspacesCommand(
passedParam,
options,
workspaceIds,
);
}
}
@@ -1,5 +1,6 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AddContextToActorCompositeTypeCommand } from 'src/database/commands/upgrade-version/0-40/0-40-add-context-to-actor-composite-type';
import { MigrateAggregateOperationOptionsCommand } from 'src/database/commands/upgrade-version/0-40/0-40-migrate-aggregate-operations-options.command';
import { UpdateInactiveWorkspaceStatusCommand } from 'src/database/commands/upgrade-version/0-40/0-40-update-inactive-workspace-status.command';
@@ -17,6 +18,7 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module';
import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module';
@Module({
@@ -44,12 +46,14 @@ import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/wor
WorkspaceMigrationRunnerModule,
WorkspaceMigrationModule,
WorkspaceMetadataVersionModule,
WorkspaceDataSourceModule,
TypeORMModule,
],
providers: [
UpgradeTo0_40Command,
MigrateAggregateOperationOptionsCommand,
UpdateInactiveWorkspaceStatusCommand,
AddContextToActorCompositeTypeCommand,
],
})
export class UpgradeTo0_40CommandModule {}