feat: populate relation join column (#10212)
Fix https://github.com/twentyhq/core-team-issues/issues/241#issue-2793030259
This commit is contained in:
@ -4,19 +4,23 @@ import { WorkspaceActivationStatus } from 'twenty-shared';
|
||||
import { In, MoreThanOrEqual, Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
BaseCommandOptions,
|
||||
BaseCommandRunner,
|
||||
} from 'src/database/commands/base.command';
|
||||
MigrationCommandOptions,
|
||||
MigrationCommandRunner,
|
||||
} from 'src/database/commands/migration-command/migration-command.runner';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
export type ActiveWorkspacesCommandOptions = BaseCommandOptions & {
|
||||
workspaceId?: string;
|
||||
startFromWorkspaceId?: string;
|
||||
workspaceCountLimit?: number;
|
||||
};
|
||||
|
||||
export abstract class ActiveWorkspacesCommandRunner extends BaseCommandRunner {
|
||||
export type ActiveWorkspacesMigrationCommandOptions =
|
||||
MigrationCommandOptions & {
|
||||
workspaceId?: string;
|
||||
startFromWorkspaceId?: string;
|
||||
workspaceCountLimit?: number;
|
||||
};
|
||||
|
||||
export abstract class ActiveWorkspacesMigrationCommandRunner<
|
||||
Options extends
|
||||
ActiveWorkspacesMigrationCommandOptions = ActiveWorkspacesMigrationCommandOptions,
|
||||
> extends MigrationCommandRunner<Options> {
|
||||
private workspaceIds: string[] = [];
|
||||
private startFromWorkspaceId: string | undefined;
|
||||
private workspaceCountLimit: number | undefined;
|
||||
@ -105,9 +109,9 @@ export abstract class ActiveWorkspacesCommandRunner extends BaseCommandRunner {
|
||||
}
|
||||
}
|
||||
|
||||
override async executeBaseCommand(
|
||||
override async runMigrationCommand(
|
||||
passedParams: string[],
|
||||
options: BaseCommandOptions,
|
||||
options: Options,
|
||||
): Promise<void> {
|
||||
const activeWorkspaceIds =
|
||||
this.workspaceIds.length > 0
|
||||
@ -120,64 +124,16 @@ export abstract class ActiveWorkspacesCommandRunner extends BaseCommandRunner {
|
||||
this.logger.log(chalk.yellow('Dry run mode: No changes will be applied'));
|
||||
}
|
||||
|
||||
await this.executeActiveWorkspacesCommand(
|
||||
await this.runMigrationCommandOnActiveWorkspaces(
|
||||
passedParams,
|
||||
options,
|
||||
activeWorkspaceIds,
|
||||
);
|
||||
}
|
||||
|
||||
protected async processEachWorkspaceWithWorkspaceDataSource(
|
||||
workspaceIds: string[],
|
||||
callback: ({
|
||||
workspaceId,
|
||||
index,
|
||||
total,
|
||||
dataSource,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
index: number;
|
||||
total: number;
|
||||
dataSource: WorkspaceDataSource;
|
||||
}) => Promise<void>,
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
chalk.green(`Running command on ${workspaceIds.length} workspaces`),
|
||||
);
|
||||
for (const [index, workspaceId] of workspaceIds.entries()) {
|
||||
this.logger.log(
|
||||
chalk.green(
|
||||
`Processing workspace ${workspaceId} (${index + 1}/${
|
||||
workspaceIds.length
|
||||
})`,
|
||||
),
|
||||
);
|
||||
|
||||
const dataSource =
|
||||
await this.twentyORMGlobalManager.getDataSourceForWorkspace(
|
||||
workspaceId,
|
||||
false,
|
||||
);
|
||||
|
||||
try {
|
||||
await callback({
|
||||
workspaceId,
|
||||
index,
|
||||
total: workspaceIds.length,
|
||||
dataSource,
|
||||
});
|
||||
} catch (error) {
|
||||
this.logger.error(`Error in workspace ${workspaceId}: ${error}`);
|
||||
}
|
||||
await this.twentyORMGlobalManager.destroyDataSourceForWorkspace(
|
||||
workspaceId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract executeActiveWorkspacesCommand(
|
||||
protected abstract runMigrationCommandOnActiveWorkspaces(
|
||||
passedParams: string[],
|
||||
options: BaseCommandOptions,
|
||||
options: Options,
|
||||
activeWorkspaceIds: string[],
|
||||
): Promise<void>;
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
import chalk from 'chalk';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
ActiveWorkspacesMigrationCommandOptions,
|
||||
ActiveWorkspacesMigrationCommandRunner,
|
||||
} from 'src/database/commands/migration-command/active-workspaces-migration-command.runner';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
|
||||
export abstract class BatchActiveWorkspacesMigrationCommandRunner<
|
||||
Options extends
|
||||
ActiveWorkspacesMigrationCommandOptions = ActiveWorkspacesMigrationCommandOptions,
|
||||
> extends ActiveWorkspacesMigrationCommandRunner<Options> {
|
||||
constructor(
|
||||
protected readonly workspaceRepository: Repository<Workspace>,
|
||||
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
) {
|
||||
super(workspaceRepository, twentyORMGlobalManager);
|
||||
}
|
||||
|
||||
async runMigrationCommandOnActiveWorkspaces(
|
||||
_passedParams: string[],
|
||||
_options: Options,
|
||||
activeWorkspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
chalk.green(`Running command on ${activeWorkspaceIds.length} workspaces`),
|
||||
);
|
||||
for (const [index, workspaceId] of activeWorkspaceIds.entries()) {
|
||||
this.logger.log(
|
||||
chalk.green(
|
||||
`Processing workspace ${workspaceId} (${index + 1}/${
|
||||
activeWorkspaceIds.length
|
||||
})`,
|
||||
),
|
||||
);
|
||||
|
||||
const dataSource =
|
||||
await this.twentyORMGlobalManager.getDataSourceForWorkspace(
|
||||
workspaceId,
|
||||
false,
|
||||
);
|
||||
|
||||
try {
|
||||
await this.runMigrationCommandOnWorkspace(
|
||||
workspaceId,
|
||||
index,
|
||||
activeWorkspaceIds.length,
|
||||
dataSource,
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error(`Error in workspace ${workspaceId}: ${error}`);
|
||||
}
|
||||
await this.twentyORMGlobalManager.destroyDataSourceForWorkspace(
|
||||
workspaceId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract runMigrationCommandOnWorkspace(
|
||||
workspaceId: string,
|
||||
index: number,
|
||||
total: number,
|
||||
dataSource: WorkspaceDataSource,
|
||||
): Promise<void>;
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
import { Inject } from '@nestjs/common';
|
||||
|
||||
import { Command } from 'nest-commander';
|
||||
|
||||
import { MigrationCommandInterface } from 'src/database/commands/migration-command/interfaces/migration-command.interface';
|
||||
|
||||
import { MIGRATION_COMMAND_INJECTION_TOKEN } from 'src/database/commands/migration-command/migration-command.constants';
|
||||
import { MigrationCommandRunner } from 'src/database/commands/migration-command/migration-command.runner';
|
||||
|
||||
export function createUpgradeAllCommand(
|
||||
version: string,
|
||||
): new (...args: unknown[]) => MigrationCommandRunner {
|
||||
@Command({
|
||||
name: `upgrade-${version}`,
|
||||
description: `Upgrade to version ${version}`,
|
||||
})
|
||||
class UpgradeCommand extends MigrationCommandRunner {
|
||||
constructor(
|
||||
@Inject(MIGRATION_COMMAND_INJECTION_TOKEN)
|
||||
private readonly subCommands: MigrationCommandInterface[],
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async runMigrationCommand(
|
||||
passedParams: string[],
|
||||
options: Record<string, unknown>,
|
||||
): Promise<void> {
|
||||
this.logger.log(`Running upgrade command for version ${version}`);
|
||||
|
||||
for (const command of this.subCommands) {
|
||||
await command.runMigrationCommand(passedParams, options);
|
||||
}
|
||||
|
||||
this.logger.log(`Upgrade ${version} command completed!`);
|
||||
}
|
||||
}
|
||||
|
||||
return UpgradeCommand;
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
// migration-command.decorator.ts
|
||||
import { Type } from '@nestjs/common';
|
||||
|
||||
import { Command, CommandMetadata } from 'nest-commander';
|
||||
import 'reflect-metadata';
|
||||
|
||||
import { MigrationCommandRunner } from 'src/database/commands/migration-command/migration-command.runner';
|
||||
|
||||
export interface MigrationCommandMetadata extends CommandMetadata {
|
||||
version: string;
|
||||
}
|
||||
|
||||
const MIGRATION_COMMANDS = new Map<
|
||||
string,
|
||||
Array<Type<MigrationCommandRunner>>
|
||||
>();
|
||||
|
||||
export function MigrationCommand(
|
||||
options: MigrationCommandMetadata,
|
||||
): <T extends Type<MigrationCommandRunner>>(target: T) => T | void {
|
||||
return <T extends Type<MigrationCommandRunner>>(target: T): T | void => {
|
||||
const { version, name, ...commandOptions } = options;
|
||||
|
||||
if (!MIGRATION_COMMANDS.has(version)) {
|
||||
MIGRATION_COMMANDS.set(version, []);
|
||||
}
|
||||
|
||||
MIGRATION_COMMANDS.get(version)?.push(target);
|
||||
|
||||
return Command({
|
||||
name: `upgrade-${version}:${name}`,
|
||||
...commandOptions,
|
||||
})(target);
|
||||
};
|
||||
}
|
||||
|
||||
export function getMigrationCommandsForVersion(
|
||||
version: string,
|
||||
): Array<Type<MigrationCommandRunner>> {
|
||||
return MIGRATION_COMMANDS.get(version) || [];
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
export interface MigrationCommandInterface<
|
||||
Options extends Record<string, unknown> = Record<string, unknown>,
|
||||
> {
|
||||
runMigrationCommand(passedParams: string[], options: Options): Promise<void>;
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
export const MIGRATION_COMMAND_INJECTION_TOKEN = 'MIGRATION_COMMANDS';
|
||||
@ -3,14 +3,22 @@ import { Logger } from '@nestjs/common';
|
||||
import chalk from 'chalk';
|
||||
import { CommandRunner, Option } from 'nest-commander';
|
||||
|
||||
import { CommandLogger } from './logger';
|
||||
export type BaseCommandOptions = {
|
||||
import { MigrationCommandInterface } from 'src/database/commands/migration-command/interfaces/migration-command.interface';
|
||||
|
||||
import { CommandLogger } from 'src/database/commands/logger';
|
||||
|
||||
export type MigrationCommandOptions = {
|
||||
workspaceId?: string;
|
||||
dryRun?: boolean;
|
||||
verbose?: boolean;
|
||||
};
|
||||
|
||||
export abstract class BaseCommandRunner extends CommandRunner {
|
||||
export abstract class MigrationCommandRunner<
|
||||
Options extends MigrationCommandOptions = MigrationCommandOptions,
|
||||
>
|
||||
extends CommandRunner
|
||||
implements MigrationCommandInterface<Options>
|
||||
{
|
||||
protected logger: CommandLogger | Logger;
|
||||
constructor() {
|
||||
super();
|
||||
@ -38,10 +46,7 @@ export abstract class BaseCommandRunner extends CommandRunner {
|
||||
return true;
|
||||
}
|
||||
|
||||
override async run(
|
||||
passedParams: string[],
|
||||
options: BaseCommandOptions,
|
||||
): Promise<void> {
|
||||
override async run(passedParams: string[], options: Options): Promise<void> {
|
||||
if (options.verbose) {
|
||||
this.logger = new CommandLogger({
|
||||
verbose: true,
|
||||
@ -50,7 +55,7 @@ export abstract class BaseCommandRunner extends CommandRunner {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.executeBaseCommand(passedParams, options);
|
||||
await this.runMigrationCommand(passedParams, options);
|
||||
} catch (error) {
|
||||
this.logger.error(chalk.red(`Command failed`));
|
||||
throw error;
|
||||
@ -59,8 +64,8 @@ export abstract class BaseCommandRunner extends CommandRunner {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract executeBaseCommand(
|
||||
abstract runMigrationCommand(
|
||||
passedParams: string[],
|
||||
options: BaseCommandOptions,
|
||||
options: Options,
|
||||
): Promise<void>;
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
import { DynamicModule, Module, ModuleMetadata } from '@nestjs/common';
|
||||
|
||||
import { MigrationCommandInterface } from 'src/database/commands/migration-command/interfaces/migration-command.interface';
|
||||
|
||||
import { createUpgradeAllCommand } from 'src/database/commands/migration-command/create-upgrade-all-command.factory';
|
||||
import { getMigrationCommandsForVersion } from 'src/database/commands/migration-command/decorators/migration-command.decorator';
|
||||
import { MIGRATION_COMMAND_INJECTION_TOKEN } from 'src/database/commands/migration-command/migration-command.constants';
|
||||
|
||||
@Module({})
|
||||
export class MigrationCommandModule {
|
||||
static register(
|
||||
version: string,
|
||||
moduleMetadata: ModuleMetadata,
|
||||
): DynamicModule {
|
||||
const commandClasses = getMigrationCommandsForVersion(version);
|
||||
const upgradeAllCommand = createUpgradeAllCommand(version);
|
||||
|
||||
return {
|
||||
module: MigrationCommandModule,
|
||||
imports: moduleMetadata.imports,
|
||||
providers: [
|
||||
...(moduleMetadata.providers ?? []),
|
||||
...commandClasses,
|
||||
{
|
||||
provide: MIGRATION_COMMAND_INJECTION_TOKEN,
|
||||
useFactory: (
|
||||
...instances: MigrationCommandInterface[]
|
||||
): MigrationCommandInterface[] => {
|
||||
return instances;
|
||||
},
|
||||
inject: commandClasses,
|
||||
},
|
||||
upgradeAllCommand,
|
||||
],
|
||||
exports: [
|
||||
...(moduleMetadata.exports ?? []),
|
||||
MIGRATION_COMMAND_INJECTION_TOKEN,
|
||||
...commandClasses,
|
||||
upgradeAllCommand,
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -4,11 +4,11 @@ import chalk from 'chalk';
|
||||
import { Command } from 'nest-commander';
|
||||
import { In, Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
ActiveWorkspacesCommandOptions,
|
||||
ActiveWorkspacesCommandRunner,
|
||||
} from 'src/database/commands/active-workspaces.command';
|
||||
import { isCommandLogger } from 'src/database/commands/logger';
|
||||
import {
|
||||
ActiveWorkspacesMigrationCommandOptions,
|
||||
ActiveWorkspacesMigrationCommandRunner,
|
||||
} from 'src/database/commands/migration-command/active-workspaces-migration-command.runner';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service';
|
||||
@ -20,7 +20,7 @@ import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.work
|
||||
name: 'upgrade-0.42:fix-body-v2-view-field-position',
|
||||
description: 'Make bodyV2 field position to match body field position',
|
||||
})
|
||||
export class FixBodyV2ViewFieldPositionCommand extends ActiveWorkspacesCommandRunner {
|
||||
export class FixBodyV2ViewFieldPositionCommand extends ActiveWorkspacesMigrationCommandRunner {
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
protected readonly workspaceRepository: Repository<Workspace>,
|
||||
@ -32,9 +32,9 @@ export class FixBodyV2ViewFieldPositionCommand extends ActiveWorkspacesCommandRu
|
||||
super(workspaceRepository, twentyORMGlobalManager);
|
||||
}
|
||||
|
||||
async executeActiveWorkspacesCommand(
|
||||
async runMigrationCommandOnActiveWorkspaces(
|
||||
_passedParam: string[],
|
||||
options: ActiveWorkspacesCommandOptions,
|
||||
options: ActiveWorkspacesMigrationCommandOptions,
|
||||
workspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log('Running command to fix bodyV2 field position');
|
||||
|
||||
@ -1,25 +1,26 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import chalk from 'chalk';
|
||||
import { Command } from 'nest-commander';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
ActiveWorkspacesCommandOptions,
|
||||
ActiveWorkspacesCommandRunner,
|
||||
} from 'src/database/commands/active-workspaces.command';
|
||||
import { CommandLogger } from 'src/database/commands/logger';
|
||||
import {
|
||||
ActiveWorkspacesMigrationCommandOptions,
|
||||
ActiveWorkspacesMigrationCommandRunner,
|
||||
} from 'src/database/commands/migration-command/active-workspaces-migration-command.runner';
|
||||
import { MigrationCommand } from 'src/database/commands/migration-command/decorators/migration-command.decorator';
|
||||
import { settings } from 'src/engine/constants/settings';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { ViewFieldWorkspaceEntity } from 'src/modules/view/standard-objects/view-field.workspace-entity';
|
||||
import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.workspace-entity';
|
||||
|
||||
@Command({
|
||||
name: 'upgrade-0.42:limit-amount-of-view-field',
|
||||
@MigrationCommand({
|
||||
name: 'limit-amount-of-view-field',
|
||||
description: 'Limit amount of view field.',
|
||||
version: '0.42',
|
||||
})
|
||||
export class LimitAmountOfViewFieldCommand extends ActiveWorkspacesCommandRunner {
|
||||
export class LimitAmountOfViewFieldCommand extends ActiveWorkspacesMigrationCommandRunner {
|
||||
protected readonly logger: CommandLogger;
|
||||
|
||||
constructor(
|
||||
@ -35,7 +36,7 @@ export class LimitAmountOfViewFieldCommand extends ActiveWorkspacesCommandRunner
|
||||
this.logger.setVerbose(false);
|
||||
}
|
||||
|
||||
async execute(workspaceId: string, dryRun?: boolean): Promise<void> {
|
||||
async runOnWorkspace(workspaceId: string, dryRun?: boolean): Promise<void> {
|
||||
this.logger.log(
|
||||
`Processing workspace ${workspaceId} for view field limitation`,
|
||||
);
|
||||
@ -94,9 +95,9 @@ export class LimitAmountOfViewFieldCommand extends ActiveWorkspacesCommandRunner
|
||||
}
|
||||
}
|
||||
|
||||
async executeActiveWorkspacesCommand(
|
||||
async runMigrationCommandOnActiveWorkspaces(
|
||||
_passedParam: string[],
|
||||
options: ActiveWorkspacesCommandOptions,
|
||||
options: ActiveWorkspacesMigrationCommandOptions,
|
||||
workspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log(`Running limit-amount-of-view-field command`);
|
||||
@ -107,7 +108,7 @@ export class LimitAmountOfViewFieldCommand extends ActiveWorkspacesCommandRunner
|
||||
|
||||
for (const [index, workspaceId] of workspaceIds.entries()) {
|
||||
try {
|
||||
await this.execute(workspaceId, options?.dryRun);
|
||||
await this.runOnWorkspace(workspaceId, options?.dryRun);
|
||||
this.logger.verbose(
|
||||
`Processed workspace: ${workspaceId} (${index + 1}/${
|
||||
workspaceIds.length
|
||||
|
||||
@ -2,13 +2,16 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { ServerBlockNoteEditor } from '@blocknote/server-util';
|
||||
import chalk from 'chalk';
|
||||
import { Command, Option } from 'nest-commander';
|
||||
import { Option } from 'nest-commander';
|
||||
import { FieldMetadataType, isDefined } from 'twenty-shared';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { ActiveWorkspacesCommandRunner } from 'src/database/commands/active-workspaces.command';
|
||||
import { isCommandLogger } from 'src/database/commands/logger';
|
||||
import { Upgrade042CommandOptions } from 'src/database/commands/upgrade-version/0-42/0-42-upgrade-version.command';
|
||||
import {
|
||||
ActiveWorkspacesMigrationCommandOptions,
|
||||
ActiveWorkspacesMigrationCommandRunner,
|
||||
} from 'src/database/commands/migration-command/active-workspaces-migration-command.runner';
|
||||
import { MigrationCommand } from 'src/database/commands/migration-command/decorators/migration-command.decorator';
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
@ -55,12 +58,19 @@ type ProcessRichTextFieldsArgs = {
|
||||
workspaceId: string;
|
||||
};
|
||||
|
||||
@Command({
|
||||
name: 'upgrade-0.42:migrate-rich-text-field',
|
||||
type MigrateRichTextFieldCommandOptions =
|
||||
ActiveWorkspacesMigrationCommandOptions & {
|
||||
force?: boolean;
|
||||
};
|
||||
|
||||
@MigrationCommand({
|
||||
name: 'migrate-rich-text-field',
|
||||
description: 'Migrate RICH_TEXT fields to new composite structure',
|
||||
version: '0.42',
|
||||
})
|
||||
export class MigrateRichTextFieldCommand extends ActiveWorkspacesCommandRunner {
|
||||
private options: Upgrade042CommandOptions;
|
||||
export class MigrateRichTextFieldCommand extends ActiveWorkspacesMigrationCommandRunner<MigrateRichTextFieldCommandOptions> {
|
||||
private options: MigrateRichTextFieldCommandOptions;
|
||||
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
protected readonly workspaceRepository: Repository<Workspace>,
|
||||
@ -89,9 +99,9 @@ export class MigrateRichTextFieldCommand extends ActiveWorkspacesCommandRunner {
|
||||
return val ?? false;
|
||||
}
|
||||
|
||||
async executeActiveWorkspacesCommand(
|
||||
async runMigrationCommandOnActiveWorkspaces(
|
||||
_passedParam: string[],
|
||||
options: Upgrade042CommandOptions,
|
||||
options: MigrateRichTextFieldCommandOptions,
|
||||
workspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
@ -343,7 +353,7 @@ export class MigrateRichTextFieldCommand extends ActiveWorkspacesCommandRunner {
|
||||
});
|
||||
|
||||
richTextFieldsWithHasCreatedColumns.push({
|
||||
hasCreatedColumns,
|
||||
hasCreatedColumns: hasCreatedColumns ?? false,
|
||||
richTextField,
|
||||
objectMetadata,
|
||||
});
|
||||
|
||||
@ -1,25 +1,26 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import chalk from 'chalk';
|
||||
import { Command } from 'nest-commander';
|
||||
import { FieldMetadataType } from 'twenty-shared';
|
||||
import { IsNull, Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
ActiveWorkspacesCommandOptions,
|
||||
ActiveWorkspacesCommandRunner,
|
||||
} from 'src/database/commands/active-workspaces.command';
|
||||
import { CommandLogger } from 'src/database/commands/logger';
|
||||
import {
|
||||
ActiveWorkspacesMigrationCommandOptions,
|
||||
ActiveWorkspacesMigrationCommandRunner,
|
||||
} from 'src/database/commands/migration-command/active-workspaces-migration-command.runner';
|
||||
import { MigrationCommand } from 'src/database/commands/migration-command/decorators/migration-command.decorator';
|
||||
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';
|
||||
|
||||
@Command({
|
||||
name: 'upgrade-0.42:standardization-of-actor-composite-context-type',
|
||||
@MigrationCommand({
|
||||
name: 'standardization-of-actor-composite-context-type',
|
||||
description: 'Add context to actor composite type.',
|
||||
version: '0.42',
|
||||
})
|
||||
export class StandardizationOfActorCompositeContextTypeCommand extends ActiveWorkspacesCommandRunner {
|
||||
export class StandardizationOfActorCompositeContextTypeCommand extends ActiveWorkspacesMigrationCommandRunner {
|
||||
protected readonly logger;
|
||||
|
||||
constructor(
|
||||
@ -39,9 +40,9 @@ export class StandardizationOfActorCompositeContextTypeCommand extends ActiveWor
|
||||
this.logger.setVerbose(false);
|
||||
}
|
||||
|
||||
async executeActiveWorkspacesCommand(
|
||||
async runMigrationCommandOnActiveWorkspaces(
|
||||
_passedParam: string[],
|
||||
options: ActiveWorkspacesCommandOptions,
|
||||
options: ActiveWorkspacesMigrationCommandOptions,
|
||||
workspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log(`Running add-context-to-actor-composite-type command`);
|
||||
@ -52,7 +53,7 @@ export class StandardizationOfActorCompositeContextTypeCommand extends ActiveWor
|
||||
|
||||
for (const [index, workspaceId] of workspaceIds.entries()) {
|
||||
try {
|
||||
await this.execute(workspaceId, options?.dryRun);
|
||||
await this.runOnWorkspace(workspaceId, options?.dryRun);
|
||||
this.logger.verbose(
|
||||
`[${index + 1}/${workspaceIds.length}] Added for workspace: ${workspaceId}`,
|
||||
);
|
||||
@ -62,7 +63,10 @@ export class StandardizationOfActorCompositeContextTypeCommand extends ActiveWor
|
||||
}
|
||||
}
|
||||
|
||||
private async execute(workspaceId: string, dryRun = false): Promise<void> {
|
||||
private async runOnWorkspace(
|
||||
workspaceId: string,
|
||||
dryRun = false,
|
||||
): Promise<void> {
|
||||
this.logger.verbose(`Adding for workspace: ${workspaceId}`);
|
||||
const actorFields = await this.fieldMetadataRepository.find({
|
||||
where: {
|
||||
|
||||
@ -1,89 +0,0 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Command, Option } from 'nest-commander';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { ActiveWorkspacesCommandRunner } from 'src/database/commands/active-workspaces.command';
|
||||
import { BaseCommandOptions } from 'src/database/commands/base.command';
|
||||
import { FixBodyV2ViewFieldPositionCommand } from 'src/database/commands/upgrade-version/0-42/0-42-fix-body-v2-view-field-position.command';
|
||||
import { LimitAmountOfViewFieldCommand } from 'src/database/commands/upgrade-version/0-42/0-42-limit-amount-of-view-field';
|
||||
import { MigrateRichTextFieldCommand } from 'src/database/commands/upgrade-version/0-42/0-42-migrate-rich-text-field.command';
|
||||
import { StandardizationOfActorCompositeContextTypeCommand } from 'src/database/commands/upgrade-version/0-42/0-42-standardization-of-actor-composite-context-type';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { SyncWorkspaceMetadataCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command';
|
||||
|
||||
type Upgrade042CommandCustomOptions = {
|
||||
force: boolean;
|
||||
};
|
||||
export type Upgrade042CommandOptions = BaseCommandOptions &
|
||||
Upgrade042CommandCustomOptions;
|
||||
@Command({
|
||||
name: 'upgrade-0.42',
|
||||
description: 'Upgrade to 0.42',
|
||||
})
|
||||
export class UpgradeTo0_42Command extends ActiveWorkspacesCommandRunner {
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
protected readonly workspaceRepository: Repository<Workspace>,
|
||||
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly migrateRichTextFieldCommand: MigrateRichTextFieldCommand,
|
||||
private readonly fixBodyV2ViewFieldPositionCommand: FixBodyV2ViewFieldPositionCommand,
|
||||
private readonly limitAmountOfViewFieldCommand: LimitAmountOfViewFieldCommand,
|
||||
private readonly syncWorkspaceMetadataCommand: SyncWorkspaceMetadataCommand,
|
||||
private readonly standardizationOfActorCompositeContextType: StandardizationOfActorCompositeContextTypeCommand,
|
||||
) {
|
||||
super(workspaceRepository, twentyORMGlobalManager);
|
||||
}
|
||||
|
||||
@Option({
|
||||
flags: '-f, --force [boolean]',
|
||||
description:
|
||||
'Force RICH_TEXT_FIELD value update even if column migration has already be run',
|
||||
required: false,
|
||||
})
|
||||
parseForceValue(val?: boolean): boolean {
|
||||
return val ?? false;
|
||||
}
|
||||
|
||||
async executeActiveWorkspacesCommand(
|
||||
passedParam: string[],
|
||||
options: Upgrade042CommandOptions,
|
||||
workspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log('Running command to upgrade to 0.42');
|
||||
|
||||
await this.migrateRichTextFieldCommand.executeActiveWorkspacesCommand(
|
||||
passedParam,
|
||||
options,
|
||||
workspaceIds,
|
||||
);
|
||||
|
||||
await this.fixBodyV2ViewFieldPositionCommand.executeActiveWorkspacesCommand(
|
||||
passedParam,
|
||||
options,
|
||||
workspaceIds,
|
||||
);
|
||||
|
||||
await this.limitAmountOfViewFieldCommand.executeActiveWorkspacesCommand(
|
||||
passedParam,
|
||||
options,
|
||||
workspaceIds,
|
||||
);
|
||||
|
||||
await this.syncWorkspaceMetadataCommand.executeActiveWorkspacesCommand(
|
||||
passedParam,
|
||||
{
|
||||
...options,
|
||||
force: true,
|
||||
},
|
||||
workspaceIds,
|
||||
);
|
||||
|
||||
await this.standardizationOfActorCompositeContextType.executeActiveWorkspacesCommand(
|
||||
passedParam,
|
||||
options,
|
||||
workspaceIds,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { MigrationCommandModule } from 'src/database/commands/migration-command/miration-command.module';
|
||||
import { FixBodyV2ViewFieldPositionCommand } from 'src/database/commands/upgrade-version/0-42/0-42-fix-body-v2-view-field-position.command';
|
||||
import { LimitAmountOfViewFieldCommand } from 'src/database/commands/upgrade-version/0-42/0-42-limit-amount-of-view-field';
|
||||
import { MigrateRichTextFieldCommand } from 'src/database/commands/upgrade-version/0-42/0-42-migrate-rich-text-field.command';
|
||||
import { StandardizationOfActorCompositeContextTypeCommand } from 'src/database/commands/upgrade-version/0-42/0-42-standardization-of-actor-composite-context-type';
|
||||
import { UpgradeTo0_42Command } from 'src/database/commands/upgrade-version/0-42/0-42-upgrade-version.command';
|
||||
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
@ -19,24 +19,27 @@ import { WorkspaceSyncMetadataCommandsModule } from 'src/engine/workspace-manage
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([Workspace, FeatureFlag], 'core'),
|
||||
TypeOrmModule.forFeature(
|
||||
[ObjectMetadataEntity, FieldMetadataEntity],
|
||||
'metadata',
|
||||
),
|
||||
WorkspaceSyncMetadataCommandsModule,
|
||||
WorkspaceMigrationRunnerModule,
|
||||
WorkspaceMigrationModule,
|
||||
WorkspaceMetadataVersionModule,
|
||||
WorkspaceDataSourceModule,
|
||||
FeatureFlagModule,
|
||||
],
|
||||
providers: [
|
||||
UpgradeTo0_42Command,
|
||||
MigrateRichTextFieldCommand,
|
||||
FixBodyV2ViewFieldPositionCommand,
|
||||
LimitAmountOfViewFieldCommand,
|
||||
StandardizationOfActorCompositeContextTypeCommand,
|
||||
MigrationCommandModule.register('0.42', {
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([Workspace, FeatureFlag], 'core'),
|
||||
TypeOrmModule.forFeature(
|
||||
[ObjectMetadataEntity, FieldMetadataEntity],
|
||||
'metadata',
|
||||
),
|
||||
WorkspaceSyncMetadataCommandsModule,
|
||||
WorkspaceMigrationRunnerModule,
|
||||
WorkspaceMigrationModule,
|
||||
WorkspaceMetadataVersionModule,
|
||||
WorkspaceDataSourceModule,
|
||||
FeatureFlagModule,
|
||||
],
|
||||
providers: [
|
||||
MigrateRichTextFieldCommand,
|
||||
FixBodyV2ViewFieldPositionCommand,
|
||||
LimitAmountOfViewFieldCommand,
|
||||
StandardizationOfActorCompositeContextTypeCommand,
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
export class UpgradeTo0_42CommandModule {}
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import chalk from 'chalk';
|
||||
import { Command } from 'nest-commander';
|
||||
import { Repository } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import {
|
||||
ActiveWorkspacesCommandOptions,
|
||||
ActiveWorkspacesCommandRunner,
|
||||
} from 'src/database/commands/active-workspaces.command';
|
||||
import { isCommandLogger } from 'src/database/commands/logger';
|
||||
import {
|
||||
ActiveWorkspacesMigrationCommandOptions,
|
||||
ActiveWorkspacesMigrationCommandRunner,
|
||||
} from 'src/database/commands/migration-command/active-workspaces-migration-command.runner';
|
||||
import { MigrationCommand } from 'src/database/commands/migration-command/decorators/migration-command.decorator';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { FieldMetadataDefaultOption } from 'src/engine/metadata-modules/field-metadata/dtos/options.input';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
@ -24,11 +24,12 @@ import { ViewFilterWorkspaceEntity } from 'src/modules/view/standard-objects/vie
|
||||
import { ViewGroupWorkspaceEntity } from 'src/modules/view/standard-objects/view-group.workspace-entity';
|
||||
import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.workspace-entity';
|
||||
|
||||
@Command({
|
||||
name: 'upgrade-0.43:add-tasks-assigned-to-me-view',
|
||||
@MigrationCommand({
|
||||
name: 'add-tasks-assigned-to-me-view',
|
||||
description: 'Add tasks assigned to me view',
|
||||
version: '0.43',
|
||||
})
|
||||
export class AddTasksAssignedToMeViewCommand extends ActiveWorkspacesCommandRunner {
|
||||
export class AddTasksAssignedToMeViewCommand extends ActiveWorkspacesMigrationCommandRunner {
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
protected readonly workspaceRepository: Repository<Workspace>,
|
||||
@ -42,9 +43,9 @@ export class AddTasksAssignedToMeViewCommand extends ActiveWorkspacesCommandRunn
|
||||
super(workspaceRepository, twentyORMGlobalManager);
|
||||
}
|
||||
|
||||
async executeActiveWorkspacesCommand(
|
||||
async runMigrationCommandOnActiveWorkspaces(
|
||||
_passedParam: string[],
|
||||
options: ActiveWorkspacesCommandOptions,
|
||||
options: ActiveWorkspacesMigrationCommandOptions,
|
||||
workspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log('Running command to create many to one relations');
|
||||
|
||||
@ -0,0 +1,169 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import chalk from 'chalk';
|
||||
import { FieldMetadataType } from 'twenty-shared';
|
||||
import { In, Repository } from 'typeorm';
|
||||
|
||||
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
|
||||
import { isCommandLogger } from 'src/database/commands/logger';
|
||||
import {
|
||||
ActiveWorkspacesMigrationCommandOptions,
|
||||
ActiveWorkspacesMigrationCommandRunner,
|
||||
} from 'src/database/commands/migration-command/active-workspaces-migration-command.runner';
|
||||
import { MigrationCommand } from 'src/database/commands/migration-command/decorators/migration-command.decorator';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import {
|
||||
RelationDirection,
|
||||
deduceRelationDirection,
|
||||
} from 'src/engine/utils/deduce-relation-direction.util';
|
||||
import { isFieldMetadataOfType } from 'src/engine/utils/is-field-metadata-of-type.util';
|
||||
|
||||
@MigrationCommand({
|
||||
name: 'migrate-relations-to-field-metadata',
|
||||
description: 'Migrate relations to field metadata',
|
||||
version: '0.43',
|
||||
})
|
||||
export class MigrateRelationsToFieldMetadataCommand extends ActiveWorkspacesMigrationCommandRunner {
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
protected readonly workspaceRepository: Repository<Workspace>,
|
||||
@InjectRepository(FieldMetadataEntity, 'metadata')
|
||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
) {
|
||||
super(workspaceRepository, twentyORMGlobalManager);
|
||||
}
|
||||
|
||||
async runMigrationCommandOnActiveWorkspaces(
|
||||
_passedParam: string[],
|
||||
options: ActiveWorkspacesMigrationCommandOptions,
|
||||
workspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log('Running command to create many to one relations');
|
||||
|
||||
if (isCommandLogger(this.logger)) {
|
||||
this.logger.setVerbose(options.verbose ?? false);
|
||||
}
|
||||
|
||||
try {
|
||||
for (const [index, workspaceId] of workspaceIds.entries()) {
|
||||
await this.processWorkspace(workspaceId, index, workspaceIds.length);
|
||||
}
|
||||
|
||||
this.logger.log(chalk.green('Command completed!'));
|
||||
} catch (error) {
|
||||
this.logger.log(chalk.red('Error in workspace'));
|
||||
}
|
||||
}
|
||||
|
||||
private async processWorkspace(
|
||||
workspaceId: string,
|
||||
index: number,
|
||||
total: number,
|
||||
): Promise<void> {
|
||||
try {
|
||||
this.logger.log(
|
||||
`Running command for workspace ${workspaceId} ${index + 1}/${total}`,
|
||||
);
|
||||
|
||||
const fieldMetadataCollection = await this.fieldMetadataRepository.find({
|
||||
where: {
|
||||
workspaceId,
|
||||
type: In([FieldMetadataType.RELATION, FieldMetadataType.UUID]),
|
||||
},
|
||||
relations: ['fromRelationMetadata', 'toRelationMetadata'],
|
||||
});
|
||||
|
||||
if (!fieldMetadataCollection.length) {
|
||||
this.logger.log(
|
||||
chalk.yellow(
|
||||
`No relation field metadata found for workspace ${workspaceId}.`,
|
||||
),
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const joinColumnFieldMetadataCollection = fieldMetadataCollection.filter(
|
||||
(fieldMetadata) =>
|
||||
isFieldMetadataOfType(fieldMetadata, FieldMetadataType.UUID),
|
||||
// TODO: Fix this, it's working in other places but not here
|
||||
) as FieldMetadataEntity<FieldMetadataType.UUID>[];
|
||||
|
||||
const fieldMetadataToUpdateCollection = fieldMetadataCollection
|
||||
.filter((fieldMetadata) =>
|
||||
isFieldMetadataOfType(fieldMetadata, FieldMetadataType.RELATION),
|
||||
)
|
||||
.map((fieldMetadata) =>
|
||||
this.updateRelationFieldMetadata(
|
||||
joinColumnFieldMetadataCollection,
|
||||
// TODO: Fix this, it's working in other places but not here
|
||||
fieldMetadata as FieldMetadataEntity<FieldMetadataType.RELATION>,
|
||||
),
|
||||
);
|
||||
|
||||
if (fieldMetadataToUpdateCollection.length > 0) {
|
||||
await this.fieldMetadataRepository.save(
|
||||
fieldMetadataToUpdateCollection,
|
||||
);
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
chalk.green(`Command completed for workspace ${workspaceId}.`),
|
||||
);
|
||||
} catch {
|
||||
this.logger.log(chalk.red(`Error in workspace ${workspaceId}.`));
|
||||
}
|
||||
}
|
||||
|
||||
private updateRelationFieldMetadata(
|
||||
joinColumnFieldMetadataCollection: FieldMetadataEntity<FieldMetadataType.UUID>[],
|
||||
fieldMetadata: FieldMetadataEntity<FieldMetadataType.RELATION>,
|
||||
): FieldMetadataEntity<FieldMetadataType.RELATION> {
|
||||
const relationMetadata =
|
||||
fieldMetadata.fromRelationMetadata ?? fieldMetadata.toRelationMetadata;
|
||||
const joinColumnFieldMetadata = joinColumnFieldMetadataCollection.find(
|
||||
(joinColumnFieldMetadata) =>
|
||||
// We're deducing the field based on the name of the relation field
|
||||
// This is not the best way to do this but we don't have a better way
|
||||
joinColumnFieldMetadata.name === `${fieldMetadata.name}Id`,
|
||||
);
|
||||
|
||||
const relationDirection = deduceRelationDirection(
|
||||
fieldMetadata,
|
||||
relationMetadata,
|
||||
);
|
||||
let relationType = relationMetadata.relationType as unknown as RelationType;
|
||||
|
||||
if (
|
||||
relationDirection === RelationDirection.TO &&
|
||||
relationType === RelationType.ONE_TO_MANY
|
||||
) {
|
||||
relationType = RelationType.MANY_TO_ONE;
|
||||
}
|
||||
|
||||
const relationTargetFieldMetadataId =
|
||||
relationDirection === RelationDirection.FROM
|
||||
? relationMetadata.toFieldMetadataId
|
||||
: relationMetadata.fromFieldMetadataId;
|
||||
|
||||
const relationTargetObjectMetadataId =
|
||||
relationDirection === RelationDirection.FROM
|
||||
? relationMetadata.toObjectMetadataId
|
||||
: relationMetadata.fromObjectMetadataId;
|
||||
|
||||
return {
|
||||
...fieldMetadata,
|
||||
settings: {
|
||||
relationType,
|
||||
onDelete: relationMetadata.onDeleteAction,
|
||||
joinColumnName: joinColumnFieldMetadata?.name,
|
||||
},
|
||||
relationTargetFieldMetadataId,
|
||||
relationTargetObjectMetadataId,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,13 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import chalk from 'chalk';
|
||||
import { Command } from 'nest-commander';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
ActiveWorkspacesCommandOptions,
|
||||
ActiveWorkspacesCommandRunner,
|
||||
} from 'src/database/commands/active-workspaces.command';
|
||||
ActiveWorkspacesMigrationCommandOptions,
|
||||
ActiveWorkspacesMigrationCommandRunner,
|
||||
} from 'src/database/commands/migration-command/active-workspaces-migration-command.runner';
|
||||
import { MigrationCommand } from 'src/database/commands/migration-command/decorators/migration-command.decorator';
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
@ -19,11 +19,12 @@ import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/wo
|
||||
import { SEARCH_FIELDS_FOR_NOTES } from 'src/modules/note/standard-objects/note.workspace-entity';
|
||||
import { SEARCH_FIELDS_FOR_TASKS } from 'src/modules/task/standard-objects/task.workspace-entity';
|
||||
|
||||
@Command({
|
||||
name: 'upgrade-0.43:migrate-search-vector-on-note-and-task-entities',
|
||||
@MigrationCommand({
|
||||
name: 'migrate-search-vector-on-note-and-task-entities',
|
||||
description: 'Migrate search vector on note and task entities',
|
||||
version: '0.43',
|
||||
})
|
||||
export class MigrateSearchVectorOnNoteAndTaskEntitiesCommand extends ActiveWorkspacesCommandRunner {
|
||||
export class MigrateSearchVectorOnNoteAndTaskEntitiesCommand extends ActiveWorkspacesMigrationCommandRunner {
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
protected readonly workspaceRepository: Repository<Workspace>,
|
||||
@ -39,9 +40,9 @@ export class MigrateSearchVectorOnNoteAndTaskEntitiesCommand extends ActiveWorks
|
||||
super(workspaceRepository, twentyORMGlobalManager);
|
||||
}
|
||||
|
||||
async executeActiveWorkspacesCommand(
|
||||
async runMigrationCommandOnActiveWorkspaces(
|
||||
_passedParam: string[],
|
||||
options: ActiveWorkspacesCommandOptions,
|
||||
options: ActiveWorkspacesMigrationCommandOptions,
|
||||
workspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
|
||||
@ -1,59 +1,34 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import chalk from 'chalk';
|
||||
import { Command } from 'nest-commander';
|
||||
import { In, Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
ActiveWorkspacesCommandOptions,
|
||||
ActiveWorkspacesCommandRunner,
|
||||
} from 'src/database/commands/active-workspaces.command';
|
||||
import { BatchActiveWorkspacesMigrationCommandRunner } from 'src/database/commands/migration-command/batch-active-workspaces-migration-command.runner';
|
||||
import { MigrationCommand } from 'src/database/commands/migration-command/decorators/migration-command.decorator';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-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 { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
|
||||
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
|
||||
import { ViewOpenRecordInType } from 'src/modules/view/standard-objects/view.workspace-entity';
|
||||
|
||||
@Command({
|
||||
name: 'upgrade-0.43:update-default-view-record-opening-on-workflow-objects',
|
||||
@MigrationCommand({
|
||||
name: 'update-default-view-record-opening-on-workflow-objects',
|
||||
description:
|
||||
'Update default view record opening on workflow objects to record page',
|
||||
version: '0.43',
|
||||
})
|
||||
export class UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand extends ActiveWorkspacesCommandRunner {
|
||||
export class UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand extends BatchActiveWorkspacesMigrationCommandRunner {
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
protected readonly workspaceRepository: Repository<Workspace>,
|
||||
@InjectRepository(ObjectMetadataEntity, 'metadata')
|
||||
protected readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService,
|
||||
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
|
||||
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
) {
|
||||
super(workspaceRepository, twentyORMGlobalManager);
|
||||
}
|
||||
|
||||
async executeActiveWorkspacesCommand(
|
||||
_passedParam: string[],
|
||||
_options: ActiveWorkspacesCommandOptions,
|
||||
workspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
'Running command to update default view record opening on workflow objects to record page',
|
||||
);
|
||||
|
||||
this.processEachWorkspaceWithWorkspaceDataSource(
|
||||
workspaceIds,
|
||||
async ({ workspaceId, index, total }) => {
|
||||
await this.processWorkspace(workspaceId, index, total);
|
||||
},
|
||||
);
|
||||
|
||||
this.logger.log(chalk.green('Command completed!'));
|
||||
}
|
||||
|
||||
async processWorkspace(
|
||||
async runMigrationCommandOnWorkspace(
|
||||
workspaceId: string,
|
||||
index: number,
|
||||
total: number,
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Command } from 'nest-commander';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { ActiveWorkspacesCommandRunner } from 'src/database/commands/active-workspaces.command';
|
||||
import { BaseCommandOptions } from 'src/database/commands/base.command';
|
||||
import { StandardizationOfActorCompositeContextTypeCommand } from 'src/database/commands/upgrade-version/0-42/0-42-standardization-of-actor-composite-context-type';
|
||||
import { AddTasksAssignedToMeViewCommand } from 'src/database/commands/upgrade-version/0-43/0-43-add-tasks-assigned-to-me-view.command';
|
||||
import { MigrateSearchVectorOnNoteAndTaskEntitiesCommand } from 'src/database/commands/upgrade-version/0-43/0-43-migrate-search-vector-on-note-and-task-entities.command';
|
||||
import { UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand } from 'src/database/commands/upgrade-version/0-43/0-43-update-default-view-record-opening-on-workflow-objects.command';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
|
||||
@Command({
|
||||
name: 'upgrade-0.43',
|
||||
description: 'Upgrade to 0.43',
|
||||
})
|
||||
export class UpgradeTo0_43Command extends ActiveWorkspacesCommandRunner {
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
protected readonly workspaceRepository: Repository<Workspace>,
|
||||
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly addTasksAssignedToMeViewCommand: AddTasksAssignedToMeViewCommand,
|
||||
private readonly migrateSearchVectorOnNoteAndTaskEntitiesCommand: MigrateSearchVectorOnNoteAndTaskEntitiesCommand,
|
||||
private readonly updateDefaultViewRecordOpeningOnWorkflowObjectsCommand: UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand,
|
||||
private readonly standardizationOfActorCompositeContextTypeCommand: StandardizationOfActorCompositeContextTypeCommand,
|
||||
) {
|
||||
super(workspaceRepository, twentyORMGlobalManager);
|
||||
}
|
||||
|
||||
async executeActiveWorkspacesCommand(
|
||||
passedParam: string[],
|
||||
options: BaseCommandOptions,
|
||||
workspaceIds: string[],
|
||||
): Promise<void> {
|
||||
this.logger.log('Running command to upgrade to 0.43');
|
||||
|
||||
await this.addTasksAssignedToMeViewCommand.executeActiveWorkspacesCommand(
|
||||
passedParam,
|
||||
options,
|
||||
workspaceIds,
|
||||
);
|
||||
|
||||
await this.migrateSearchVectorOnNoteAndTaskEntitiesCommand.executeActiveWorkspacesCommand(
|
||||
passedParam,
|
||||
options,
|
||||
workspaceIds,
|
||||
);
|
||||
|
||||
await this.updateDefaultViewRecordOpeningOnWorkflowObjectsCommand.executeActiveWorkspacesCommand(
|
||||
passedParam,
|
||||
options,
|
||||
workspaceIds,
|
||||
);
|
||||
|
||||
// Note: Introduced in 0.42, ran manually on prod. Introduced to self-host globally on 0.43
|
||||
await this.standardizationOfActorCompositeContextTypeCommand.executeActiveWorkspacesCommand(
|
||||
passedParam,
|
||||
options,
|
||||
workspaceIds,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,12 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { MigrationCommandModule } from 'src/database/commands/migration-command/miration-command.module';
|
||||
import { StandardizationOfActorCompositeContextTypeCommand } from 'src/database/commands/upgrade-version/0-42/0-42-standardization-of-actor-composite-context-type';
|
||||
import { AddTasksAssignedToMeViewCommand } from 'src/database/commands/upgrade-version/0-43/0-43-add-tasks-assigned-to-me-view.command';
|
||||
import { MigrateRelationsToFieldMetadataCommand } from 'src/database/commands/upgrade-version/0-43/0-43-migrate-relations-to-field-metadata.command';
|
||||
import { MigrateSearchVectorOnNoteAndTaskEntitiesCommand } from 'src/database/commands/upgrade-version/0-43/0-43-migrate-search-vector-on-note-and-task-entities.command';
|
||||
import { UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand } from 'src/database/commands/upgrade-version/0-43/0-43-update-default-view-record-opening-on-workflow-objects.command';
|
||||
import { UpgradeTo0_43Command } from 'src/database/commands/upgrade-version/0-43/0-43-upgrade-version.command';
|
||||
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
@ -17,22 +18,26 @@ import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/wor
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([Workspace, FeatureFlag], 'core'),
|
||||
TypeOrmModule.forFeature(
|
||||
[ObjectMetadataEntity, FieldMetadataEntity],
|
||||
'metadata',
|
||||
),
|
||||
SearchModule,
|
||||
WorkspaceMigrationRunnerModule,
|
||||
WorkspaceMigrationModule,
|
||||
WorkspaceMetadataVersionModule,
|
||||
],
|
||||
providers: [
|
||||
UpgradeTo0_43Command,
|
||||
AddTasksAssignedToMeViewCommand,
|
||||
MigrateSearchVectorOnNoteAndTaskEntitiesCommand,
|
||||
UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand,
|
||||
StandardizationOfActorCompositeContextTypeCommand,
|
||||
MigrationCommandModule.register('0.43', {
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([Workspace, FeatureFlag], 'core'),
|
||||
TypeOrmModule.forFeature(
|
||||
[ObjectMetadataEntity, FieldMetadataEntity],
|
||||
'metadata',
|
||||
),
|
||||
SearchModule,
|
||||
WorkspaceMigrationRunnerModule,
|
||||
WorkspaceMigrationModule,
|
||||
WorkspaceMetadataVersionModule,
|
||||
],
|
||||
providers: [
|
||||
AddTasksAssignedToMeViewCommand,
|
||||
MigrateSearchVectorOnNoteAndTaskEntitiesCommand,
|
||||
UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand,
|
||||
StandardizationOfActorCompositeContextTypeCommand,
|
||||
MigrateRelationsToFieldMetadataCommand,
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
export class UpgradeTo0_43CommandModule {}
|
||||
|
||||
Reference in New Issue
Block a user