From a12d8b5113cf6dacb0d39bd008aa309275fcf313 Mon Sep 17 00:00:00 2001 From: "Rahul R." Date: Wed, 19 Feb 2025 19:02:16 +0530 Subject: [PATCH 1/5] wip: alter "organization_team" entity column --- .../src/lib/organization-team.model.ts | 7 ++- .../organization-team.create.handler.ts | 58 +++++++++++-------- .../organization-team.entity.ts | 31 +++++----- .../organization-team.subscriber.ts | 2 +- 4 files changed, 56 insertions(+), 42 deletions(-) diff --git a/packages/contracts/src/lib/organization-team.model.ts b/packages/contracts/src/lib/organization-team.model.ts index 7df3d4bfc70..ba34d4e4120 100644 --- a/packages/contracts/src/lib/organization-team.model.ts +++ b/packages/contracts/src/lib/organization-team.model.ts @@ -9,8 +9,13 @@ import { CrudActionEnum } from './organization.model'; import { IOrganizationProject, IOrganizationProjectCreateInput } from './organization-projects.model'; import { IOrganizationProjectModule } from './organization-project-module.model'; import { IComment } from './comment.model'; +import { IHasUserCreator } from './user.model'; -export interface IOrganizationTeam extends IBasePerTenantAndOrganizationEntityModel, IRelationalImageAsset, ITaggable { +export interface IOrganizationTeam + extends IBasePerTenantAndOrganizationEntityModel, + IRelationalImageAsset, + ITaggable, + IHasUserCreator { name: string; color?: string; emoji?: string; diff --git a/packages/core/src/lib/organization-team/commands/handlers/organization-team.create.handler.ts b/packages/core/src/lib/organization-team/commands/handlers/organization-team.create.handler.ts index 97518ac5eac..b95f6bd0d72 100644 --- a/packages/core/src/lib/organization-team/commands/handlers/organization-team.create.handler.ts +++ b/packages/core/src/lib/organization-team/commands/handlers/organization-team.create.handler.ts @@ -1,4 +1,4 @@ -import { BadRequestException } from '@nestjs/common'; +import { BadRequestException, Logger } from '@nestjs/common'; import { CommandBus, CommandHandler, ICommandHandler } from '@nestjs/cqrs'; import { IOrganizationTeam } from '@gauzy/contracts'; import { OrganizationTeamCreateCommand } from '../organization-team.create.command'; @@ -9,44 +9,52 @@ import { OrganizationTeamTaskStatusBulkCreateCommand } from './../../../tasks/st import { OrganizationTeamIssueTypeBulkCreateCommand } from './../../../tasks/issue-type/commands'; @CommandHandler(OrganizationTeamCreateCommand) -export class OrganizationTeamCreateHandler - implements ICommandHandler -{ +export class OrganizationTeamCreateHandler implements ICommandHandler { + private readonly logger = new Logger(OrganizationTeamCreateHandler.name); + constructor( private readonly _commandBus: CommandBus, private readonly _organizationTeamService: OrganizationTeamService ) {} - public async execute( - command: OrganizationTeamCreateCommand - ): Promise { + /** + * Handles the creation of an organization team and initiates related background tasks. + * + * @param command - The command containing the input data for creating the team. + * @returns The created organization team. + */ + public async execute(command: OrganizationTeamCreateCommand): Promise { try { const { input } = command; const team = await this._organizationTeamService.create(input); - // 1. Create task statuses for relative organization team. - this._commandBus.execute( - new OrganizationTeamTaskStatusBulkCreateCommand(team) - ); - - // 2. Create task priorities for relative organization team. - this._commandBus.execute( - new OrganizationTeamTaskPriorityBulkCreateCommand(team) - ); + // Execute related commands in the background + this.executeBackgroundTasks(team); - // 3. Create task sizes for relative organization team. - this._commandBus.execute( - new OrganizationTeamTaskSizeBulkCreateCommand(team) - ); + return team; + } catch (error) { + this.logger.error('Error while creating organization team', error.stack); + throw new BadRequestException(`Error while creating organization team: ${error.message}`); + } + } - // 4. Create issue types for relative organization team. - this._commandBus.execute( + /** + * Executes related commands concurrently in the background. + * + * @param team - The organization team for which to execute the commands. + */ + private async executeBackgroundTasks(team: IOrganizationTeam): Promise { + try { + const commands = [ + new OrganizationTeamTaskStatusBulkCreateCommand(team), + new OrganizationTeamTaskPriorityBulkCreateCommand(team), + new OrganizationTeamTaskSizeBulkCreateCommand(team), new OrganizationTeamIssueTypeBulkCreateCommand(team) - ); + ]; - return team; + await Promise.all(commands.map((command) => this._commandBus.execute(command))); } catch (error) { - throw new BadRequestException(error); + console.log('Error while executing background tasks:', error); } } } diff --git a/packages/core/src/lib/organization-team/organization-team.entity.ts b/packages/core/src/lib/organization-team/organization-team.entity.ts index af8b0198637..238d834cfd1 100644 --- a/packages/core/src/lib/organization-team/organization-team.entity.ts +++ b/packages/core/src/lib/organization-team/organization-team.entity.ts @@ -158,41 +158,43 @@ export class OrganizationTeam extends TenantOrganizationBaseEntity implements IO | @ManyToOne |-------------------------------------------------------------------------- */ - /** - * User + * The user who created the Team. */ @MultiORMManyToOne(() => User, { - /** Indicates if relation column value can be nullable or not. */ + // The relationship is optional (nullable). nullable: true, - - /** Database cascade action on delete. */ + // On deletion of the user, set the foreign key value to NULL. onDelete: 'SET NULL' }) @JoinColumn() - createdBy?: IUser; + createdByUser?: IUser; - @RelationId((it: OrganizationTeam) => it.createdBy) + /** + * The ID of the user who created the Team. + */ + @RelationId((it: OrganizationTeam) => it.createdByUser) @ColumnIndex() @MultiORMColumn({ nullable: true, relationId: true }) - createdById?: ID; + createdByUserId?: ID; /** - * ImageAsset + * The ImageAsset that is associated with this OrganizationTeam. */ @MultiORMManyToOne(() => ImageAsset, { - /** Indicates if relation column value can be nullable or not. */ + // Indicates that the relation is optional (i.e. the value may be null). nullable: true, - - /** Database cascade action on delete. */ + // If the referenced ImageAsset is deleted, set this foreign key to NULL. onDelete: 'SET NULL', - - /** Eager relations are always loaded automatically when relation's owner entity is loaded using find* methods. */ + // The related ImageAsset is eagerly loaded, meaning it is automatically fetched with the OrganizationTeam entity. eager: true }) @JoinColumn() image?: IImageAsset; + /** + * The ID of the ImageAsset that is associated with this OrganizationTeam. + */ @ApiPropertyOptional({ type: () => String }) @IsOptional() @IsUUID() @@ -200,7 +202,6 @@ export class OrganizationTeam extends TenantOrganizationBaseEntity implements IO @ColumnIndex() @MultiORMColumn({ nullable: true, relationId: true }) imageId?: ID; - /* |-------------------------------------------------------------------------- | @OneToMany diff --git a/packages/core/src/lib/organization-team/organization-team.subscriber.ts b/packages/core/src/lib/organization-team/organization-team.subscriber.ts index a95bc1cd171..e16f3253d41 100644 --- a/packages/core/src/lib/organization-team/organization-team.subscriber.ts +++ b/packages/core/src/lib/organization-team/organization-team.subscriber.ts @@ -45,7 +45,7 @@ export class OrganizationTeamSubscriber extends BaseEntityEventSubscriber { try { // Assign the current user's ID as the creator - entity.createdById = RequestContext.currentUserId(); + entity.createdByUserId = RequestContext.currentUserId(); // Generate a slug for the profile link if (entity.profile_link || entity.name) { From 47101d3074b8384c3a9889973a47811fdc9574ea Mon Sep 17 00:00:00 2001 From: "Rahul R." Date: Thu, 20 Feb 2025 12:30:14 +0530 Subject: [PATCH 2/5] feat(migration): alter "organization_team" entity [table] for PostgreSQL --- .../src/lib/organization-team.model.ts | 43 ++--- ...39602849367-AlterActivityLogEntityTable.ts | 2 +- ...146994-AlterOrganizationTeamEntityTable.ts | 147 ++++++++++++++++++ 3 files changed, 164 insertions(+), 28 deletions(-) create mode 100644 packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts diff --git a/packages/contracts/src/lib/organization-team.model.ts b/packages/contracts/src/lib/organization-team.model.ts index ba34d4e4120..29dce8d9888 100644 --- a/packages/contracts/src/lib/organization-team.model.ts +++ b/packages/contracts/src/lib/organization-team.model.ts @@ -11,21 +11,22 @@ import { IOrganizationProjectModule } from './organization-project-module.model' import { IComment } from './comment.model'; import { IHasUserCreator } from './user.model'; -export interface IOrganizationTeam - extends IBasePerTenantAndOrganizationEntityModel, - IRelationalImageAsset, - ITaggable, - IHasUserCreator { +// Base interface for common properties +interface IBaseTeamProperties extends IBasePerTenantAndOrganizationEntityModel, IRelationalImageAsset, ITaggable { name: string; color?: string; emoji?: string; teamSize?: string; logo?: string; prefix?: string; - shareProfileView?: boolean; // If true, all members can view "Worked" tasks and "Daily Plan" tabs of all other employees, By default, it's true - requirePlanToTrack?: boolean; // If true, members can't be able to track time without have a "Daily Plan". By default, it's false + shareProfileView?: boolean; // Default is true + requirePlanToTrack?: boolean; // Default is false public?: boolean; profile_link?: string; +} + +// Interface for team members and related entities +interface ITeamAssociations { members?: IOrganizationTeamEmployee[]; managers?: IOrganizationTeamEmployee[]; projects?: IOrganizationProject[]; @@ -34,6 +35,10 @@ export interface IOrganizationTeam tasks?: ITask[]; } +// Main Organization Team interface +export interface IOrganizationTeam extends IBaseTeamProperties, ITeamAssociations, IHasUserCreator {} + +// Input interface for finding an organization team export interface IOrganizationTeamFindInput extends IBasePerTenantAndOrganizationEntityModel, IEmployeeEntityInput { name?: string; prefix?: string; @@ -42,29 +47,13 @@ export interface IOrganizationTeamFindInput extends IBasePerTenantAndOrganizatio members?: IOrganizationTeamEmployee; } -export interface IOrganizationTeamCreateInput - extends IBasePerTenantAndOrganizationEntityModel, - IRelationalImageAsset, - IMemberEntityBased, - ITaggable { - name: string; - emoji?: string; - teamSize?: string; - color?: string; - logo?: string; - prefix?: string; - shareProfileView?: boolean; - requirePlanToTrack?: boolean; - public?: boolean; - profile_link?: string; +// Input interface for creating an organization team +export interface IOrganizationTeamCreateInput extends IBaseTeamProperties, IMemberEntityBased { projects?: IOrganizationProjectCreateInput[]; } -export interface IOrganizationTeamUpdateInput extends Partial { - shareProfileView?: boolean; - requirePlanToTrack?: boolean; - public?: boolean; -} +// Input interface for updating an organization team +export interface IOrganizationTeamUpdateInput extends Partial {} export interface IOrganizationTeamStatisticInput extends ITimerStatusInput { withLastWorkedTask: boolean; diff --git a/packages/core/src/lib/database/migrations/1739602849367-AlterActivityLogEntityTable.ts b/packages/core/src/lib/database/migrations/1739602849367-AlterActivityLogEntityTable.ts index 8c38ccd8ded..f1bf7007650 100644 --- a/packages/core/src/lib/database/migrations/1739602849367-AlterActivityLogEntityTable.ts +++ b/packages/core/src/lib/database/migrations/1739602849367-AlterActivityLogEntityTable.ts @@ -62,7 +62,7 @@ export class AlterActivityLogEntityTable1739602849367 implements MigrationInterf await queryRunner.query(`ALTER TABLE "activity_log" DROP CONSTRAINT "FK_b6e9a5c3e1ee65a3bcb8a00de2b"`); // Step 2: Drop the existing index on "creatorId". - console.log('Step 2: Dropping index "IDX_b6e9a5c3e1ee65a3bcb8a00de2" from "activity_log"...'); + console.log('Step 2: Dropping index "creatorId" from "activity_log"...'); await queryRunner.query(`DROP INDEX "public"."IDX_b6e9a5c3e1ee65a3bcb8a00de2"`); // Step 3: Add new column "employeeId" of type uuid. diff --git a/packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts b/packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts new file mode 100644 index 00000000000..91c0d4b270c --- /dev/null +++ b/packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts @@ -0,0 +1,147 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; +import * as chalk from 'chalk'; +import { DatabaseTypeEnum } from '@gauzy/config'; + +export class AlterOrganizationTeamEntityTable1740034146994 implements MigrationInterface { + name = 'AlterOrganizationTeamEntityTable1740034146994'; + + /** + * Up Migration + * + * @param queryRunner + */ + public async up(queryRunner: QueryRunner): Promise { + console.log(chalk.yellow(this.name + ' start running!')); + + switch (queryRunner.connection.options.type) { + case DatabaseTypeEnum.sqlite: + case DatabaseTypeEnum.betterSqlite3: + await this.sqliteUpQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.postgres: + await this.postgresUpQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.mysql: + await this.mysqlUpQueryRunner(queryRunner); + break; + default: + throw Error(`Unsupported database: ${queryRunner.connection.options.type}`); + } + } + + /** + * Down Migration + * + * @param queryRunner + */ + public async down(queryRunner: QueryRunner): Promise { + switch (queryRunner.connection.options.type) { + case DatabaseTypeEnum.sqlite: + case DatabaseTypeEnum.betterSqlite3: + await this.sqliteDownQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.postgres: + await this.postgresDownQueryRunner(queryRunner); + break; + case DatabaseTypeEnum.mysql: + await this.mysqlDownQueryRunner(queryRunner); + break; + default: + throw Error(`Unsupported database: ${queryRunner.connection.options.type}`); + } + } + + /** + * PostgresDB Up Migration + * + * @param queryRunner + */ + public async postgresUpQueryRunner(queryRunner: QueryRunner): Promise { + // Step 1: Drop the existing foreign key constraint on "createdById" in the "organization_team" table. + console.log('Step 1: Dropping foreign key constraint on "createdById" from "organization_team"...'); + await queryRunner.query(`ALTER TABLE "organization_team" DROP CONSTRAINT "FK_da625f694eb1e23e585f3010082"`); + + // Step 2: Drop the existing index on "createdById". + console.log('Step 2: Dropping index "createdById" from "organization_team"...'); + await queryRunner.query(`DROP INDEX "public"."IDX_da625f694eb1e23e585f301008"`); + + // Step 3: Renaming column "createdById" to "createdByUserId" in the "organization_team" table. + console.log('Step 3: Renaming column "createdById" to "createdByUserId" in "organization_team"...'); + await queryRunner.query(`ALTER TABLE "organization_team" RENAME COLUMN "createdById" TO "createdByUserId"`); + + // Step 4: Create a new index for the "createdByUserId" column. + console.log('Step 4: Creating index "createdByUserId" on "organization_team"...'); + await queryRunner.query( + `CREATE INDEX "IDX_507bfec137b2f8bf283cb1f08d" ON "organization_team" ("createdByUserId") ` + ); + + // Step 5: Add a new foreign key constraint for the "createdByUserId" column. + console.log(`Step 5: Adding foreign key constraint for "createdByUserId"...`); + await queryRunner.query( + `ALTER TABLE "organization_team" + ADD CONSTRAINT "FK_507bfec137b2f8bf283cb1f08d0" FOREIGN KEY ("createdByUserId") REFERENCES "user"("id") + ON DELETE SET NULL ON UPDATE NO ACTION` + ); + } + + /** + * PostgresDB Down Migration + * + * @param queryRunner + */ + public async postgresDownQueryRunner(queryRunner: QueryRunner): Promise { + // Step 1: Drop the foreign key constraint on "createdByUserId" in the "organization_team" table. + console.log(`Step 1: Dropping foreign key constraint on "createdByUserId" from "organization_team"...`); + await queryRunner.query(`ALTER TABLE "organization_team" DROP CONSTRAINT "FK_507bfec137b2f8bf283cb1f08d0"`); + + // Step 2: Drop the index associated with the "createdByUserId" column. + console.log('Step 2: Dropping index "createdByUserId" from "organization_team"...'); + await queryRunner.query(`DROP INDEX "public"."IDX_507bfec137b2f8bf283cb1f08d"`); + + // Step 3: Rename the column "createdByUserId" to "createdById" in the "organization_team" table. + console.log('Step 3: Renaming column "createdByUserId" to "createdById" in "organization_team"...'); + await queryRunner.query(`ALTER TABLE "organization_team" RENAME COLUMN "createdByUserId" TO "createdById"`); + + // Step 4: Create a new index for the "createdById" column. + console.log('Step 4: Creating index "createdById" on "organization_team"...'); + await queryRunner.query( + `CREATE INDEX "IDX_da625f694eb1e23e585f301008" ON "organization_team" ("createdById") ` + ); + + // Step 5: Add a new foreign key constraint for the "createdById" column. + console.log(`Step 5: Adding foreign key constraint for "createdById"...`); + await queryRunner.query( + `ALTER TABLE "organization_team" + ADD CONSTRAINT "FK_da625f694eb1e23e585f3010082" FOREIGN KEY ("createdById") REFERENCES "user"("id") + ON DELETE SET NULL ON UPDATE NO ACTION` + ); + } + + /** + * SqliteDB and BetterSQlite3DB Up Migration + * + * @param queryRunner + */ + public async sqliteUpQueryRunner(queryRunner: QueryRunner): Promise {} + + /** + * SqliteDB and BetterSQlite3DB Down Migration + * + * @param queryRunner + */ + public async sqliteDownQueryRunner(queryRunner: QueryRunner): Promise {} + + /** + * MySQL Up Migration + * + * @param queryRunner + */ + public async mysqlUpQueryRunner(queryRunner: QueryRunner): Promise {} + + /** + * MySQL Down Migration + * + * @param queryRunner + */ + public async mysqlDownQueryRunner(queryRunner: QueryRunner): Promise {} +} From 13ea5640ad295cdcb3fb4f24985b8207ce622b29 Mon Sep 17 00:00:00 2001 From: "Rahul R." Date: Thu, 20 Feb 2025 13:25:33 +0530 Subject: [PATCH 3/5] feat(migration): alter "organization_team" entity [table] for MySQL --- ...146994-AlterOrganizationTeamEntityTable.ts | 64 ++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts b/packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts index 91c0d4b270c..9e0bab64e43 100644 --- a/packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts +++ b/packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts @@ -136,12 +136,72 @@ export class AlterOrganizationTeamEntityTable1740034146994 implements MigrationI * * @param queryRunner */ - public async mysqlUpQueryRunner(queryRunner: QueryRunner): Promise {} + public async mysqlUpQueryRunner(queryRunner: QueryRunner): Promise { + // Step 1: Drop the existing foreign key constraint on "createdById" in the "organization_team" table. + console.log('Step 1: Dropping foreign key constraint on "createdById" from "organization_team"...'); + await queryRunner.query( + `ALTER TABLE \`organization_team\` DROP FOREIGN KEY \`FK_da625f694eb1e23e585f3010082\`` + ); + + // Step 2: Drop the existing index on "createdById". + console.log('Step 2: Dropping index "createdById" from "organization_team"...'); + await queryRunner.query(`DROP INDEX \`IDX_da625f694eb1e23e585f301008\` ON \`organization_team\``); + + // Step 3: Renaming column "createdById" to "createdByUserId" in the "organization_team" table. + console.log('Step 3: Renaming column "createdById" to "createdByUserId" in "organization_team"...'); + await queryRunner.query( + `ALTER TABLE \`organization_team\` CHANGE \`createdById\` \`createdByUserId\` varchar(255) NULL` + ); + + // Step 4: Create a new index for the "createdByUserId" column. + console.log('Step 4: Creating index "createdByUserId" on "organization_team"...'); + await queryRunner.query( + `CREATE INDEX \`IDX_507bfec137b2f8bf283cb1f08d\` ON \`organization_team\` (\`createdByUserId\`)` + ); + + // Step 5: Add a new foreign key constraint for the "createdByUserId" column. + console.log(`Step 5: Adding foreign key constraint for "createdByUserId"...`); + await queryRunner.query( + `ALTER TABLE \`organization_team\` + ADD CONSTRAINT \`FK_507bfec137b2f8bf283cb1f08d0\` FOREIGN KEY (\`createdByUserId\`) REFERENCES \`user\`(\`id\`) + ON DELETE SET NULL ON UPDATE NO ACTION` + ); + } /** * MySQL Down Migration * * @param queryRunner */ - public async mysqlDownQueryRunner(queryRunner: QueryRunner): Promise {} + public async mysqlDownQueryRunner(queryRunner: QueryRunner): Promise { + // Step 1: Drop the foreign key constraint on "createdByUserId" in the "organization_team" table. + console.log(`Step 1: Dropping foreign key constraint on "createdByUserId" from "organization_team"...`); + await queryRunner.query( + `ALTER TABLE \`organization_team\` DROP FOREIGN KEY \`FK_507bfec137b2f8bf283cb1f08d0\`` + ); + + // Step 2: Drop the index associated with the "createdByUserId" column. + console.log('Step 2: Dropping index "createdByUserId" from "organization_team"...'); + await queryRunner.query(`DROP INDEX \`IDX_507bfec137b2f8bf283cb1f08d\` ON \`organization_team\``); + + // Step 3: Rename the column "createdByUserId" to "createdById" in the "organization_team" table. + console.log('Step 3: Renaming column "createdByUserId" to "createdById" in "organization_team"...'); + await queryRunner.query( + `ALTER TABLE \`organization_team\` CHANGE \`createdByUserId\` \`createdById\` varchar(255) NULL` + ); + + // Step 4: Create a new index for the "createdById" column. + console.log('Step 4: Creating index "createdById" on "organization_team"...'); + await queryRunner.query( + `CREATE INDEX \`IDX_da625f694eb1e23e585f301008\` ON \`organization_team\` (\`createdById\`)` + ); + + // Step 5: Add a new foreign key constraint for the "createdById" column. + console.log(`Step 5: Adding foreign key constraint for "createdById"...`); + await queryRunner.query( + `ALTER TABLE \`organization_team\` + ADD CONSTRAINT \`FK_da625f694eb1e23e585f3010082\` FOREIGN KEY (\`createdById\`) REFERENCES \`user\`(\`id\`) + ON DELETE SET NULL ON UPDATE NO ACTION` + ); + } } From 25bf96aee2842a9ba6fa3142f41539305cf85331 Mon Sep 17 00:00:00 2001 From: "Rahul R." Date: Thu, 20 Feb 2025 14:51:39 +0530 Subject: [PATCH 4/5] feat(migration): alter "organization_team" entity [table] for SQLite --- ...146994-AlterOrganizationTeamEntityTable.ts | 238 +++++++++++++++++- 1 file changed, 236 insertions(+), 2 deletions(-) diff --git a/packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts b/packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts index 9e0bab64e43..9987717f762 100644 --- a/packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts +++ b/packages/core/src/lib/database/migrations/1740034146994-AlterOrganizationTeamEntityTable.ts @@ -122,14 +122,248 @@ export class AlterOrganizationTeamEntityTable1740034146994 implements MigrationI * * @param queryRunner */ - public async sqliteUpQueryRunner(queryRunner: QueryRunner): Promise {} + public async sqliteUpQueryRunner(queryRunner: QueryRunner): Promise { + // Step 1: Drop all the indexes on the old "organization_team" table. + console.log(`Step 1: Drop all the indexes on the old "organization_team" table`); + await queryRunner.query(`DROP INDEX "IDX_38f1d96e8c2d59e4f0f84209ab"`); + await queryRunner.query(`DROP INDEX "IDX_722d648e0b83267d4a66332ccb"`); + await queryRunner.query(`DROP INDEX "IDX_51e91be110fa0b8e70066f5727"`); + await queryRunner.query(`DROP INDEX "IDX_da625f694eb1e23e585f301008"`); + await queryRunner.query(`DROP INDEX "IDX_103ae3eb65f4b091efc55cb532"`); + await queryRunner.query(`DROP INDEX "IDX_eef1c19a0cb5321223cfe3286c"`); + await queryRunner.query(`DROP INDEX "IDX_176f5ed3c4534f3110d423d569"`); + await queryRunner.query(`DROP INDEX "IDX_e22ab0f1236b1a07785b641727"`); + + // Step 2: Create a new temporary "temporary_organization_team" table. + console.log('Step 2: Creating temporary table: temporary_organization_team.'); + await queryRunner.query(` + CREATE TABLE "temporary_organization_team" ( + "id" varchar PRIMARY KEY NOT NULL, + "createdAt" datetime NOT NULL DEFAULT (datetime('now')), + "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), + "tenantId" varchar, + "organizationId" varchar, + "name" varchar NOT NULL, + "prefix" varchar, + "createdByUserId" varchar, + "public" boolean DEFAULT (0), + "profile_link" varchar, + "logo" varchar, + "imageId" varchar, + "color" varchar, + "emoji" varchar, + "teamSize" varchar, + "isActive" boolean DEFAULT (1), + "isArchived" boolean DEFAULT (0), + "deletedAt" datetime, + "shareProfileView" boolean DEFAULT (1), + "requirePlanToTrack" boolean NOT NULL DEFAULT (0), + "archivedAt" datetime, + CONSTRAINT "FK_51e91be110fa0b8e70066f5727f" FOREIGN KEY ("imageId") REFERENCES "image_asset" ("id") ON DELETE SET NULL ON UPDATE NO ACTION, + CONSTRAINT "FK_eef1c19a0cb5321223cfe3286c4" FOREIGN KEY ("organizationId") REFERENCES "organization" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT "FK_176f5ed3c4534f3110d423d5690" FOREIGN KEY ("tenantId") REFERENCES "tenant" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ); + `); + + // Step 3: Insert data from the old "organization_team" to the new temporary table. + console.log(`Insert data from the old "organization_team" to the new temporary table`); + await queryRunner.query(` + INSERT INTO "temporary_organization_team" ( + "id", + "createdAt", + "updatedAt", + "tenantId", + "organizationId", + "name", + "prefix", + "createdByUserId", + "public", + "profile_link", + "logo", + "imageId", + "color", + "emoji", + "teamSize", + "isActive", + "isArchived", + "deletedAt", + "shareProfileView", + "requirePlanToTrack", + "archivedAt" + ) + SELECT + "id", + "createdAt", + "updatedAt", + "tenantId", + "organizationId", + "name", + "prefix", + "createdById", + "public", + "profile_link", + "logo", + "imageId", + "color", + "emoji", + "teamSize", + "isActive", + "isArchived", + "deletedAt", + "shareProfileView", + "requirePlanToTrack", + "archivedAt" + FROM "organization_team"; + `); + + // Step 4: Drop the old "organization_team" table and rename the temporary table. + console.log(`Step 4: Drop the old "organization_team" table and rename the temporary table.`); + await queryRunner.query(`DROP TABLE "organization_team"`); + await queryRunner.query(`ALTER TABLE "temporary_organization_team" RENAME TO "organization_team"`); + + // Step 5: Create indexes on the new "organization_team" table. + console.log(`Create indexes on the new "organization_team" table`); + await queryRunner.query(`CREATE INDEX "IDX_38f1d96e8c2d59e4f0f84209ab" ON "organization_team" ("isArchived") `); + await queryRunner.query(`CREATE INDEX "IDX_722d648e0b83267d4a66332ccb" ON "organization_team" ("isActive") `); + await queryRunner.query(`CREATE INDEX "IDX_51e91be110fa0b8e70066f5727" ON "organization_team" ("imageId") `); + await queryRunner.query(`CREATE INDEX "IDX_103ae3eb65f4b091efc55cb532" ON "organization_team" ("name") `); + await queryRunner.query( + `CREATE INDEX "IDX_eef1c19a0cb5321223cfe3286c" ON "organization_team" ("organizationId") ` + ); + await queryRunner.query(`CREATE INDEX "IDX_176f5ed3c4534f3110d423d569" ON "organization_team" ("tenantId") `); + await queryRunner.query( + `CREATE INDEX "IDX_e22ab0f1236b1a07785b641727" ON "organization_team" ("profile_link") ` + ); + await queryRunner.query( + `CREATE INDEX "IDX_507bfec137b2f8bf283cb1f08d" ON "organization_team" ("createdByUserId") ` + ); + } /** * SqliteDB and BetterSQlite3DB Down Migration * * @param queryRunner */ - public async sqliteDownQueryRunner(queryRunner: QueryRunner): Promise {} + public async sqliteDownQueryRunner(queryRunner: QueryRunner): Promise { + // Step 1: Drop all the indexes on the old "organization_team" table. + console.log(`Step 1: Drop all the indexes on the old "organization_team" table`); + await queryRunner.query(`DROP INDEX "IDX_507bfec137b2f8bf283cb1f08d"`); + await queryRunner.query(`DROP INDEX "IDX_e22ab0f1236b1a07785b641727"`); + await queryRunner.query(`DROP INDEX "IDX_176f5ed3c4534f3110d423d569"`); + await queryRunner.query(`DROP INDEX "IDX_eef1c19a0cb5321223cfe3286c"`); + await queryRunner.query(`DROP INDEX "IDX_103ae3eb65f4b091efc55cb532"`); + await queryRunner.query(`DROP INDEX "IDX_51e91be110fa0b8e70066f5727"`); + await queryRunner.query(`DROP INDEX "IDX_722d648e0b83267d4a66332ccb"`); + await queryRunner.query(`DROP INDEX "IDX_38f1d96e8c2d59e4f0f84209ab"`); + + // Step 2: Rename the current "organization_team" table to "temporary_organization_team". + console.log('Step 2: Renaming "organization_team" to "temporary_organization_team"...'); + await queryRunner.query(`ALTER TABLE "organization_team" RENAME TO "temporary_organization_team"`); + + // Step 3: Create the new "organization_team" table with the restored schema. + console.log('Step 3: Creating new "organization_team" table with restored schema...'); + await queryRunner.query(` + CREATE TABLE "organization_team" ( + "id" varchar PRIMARY KEY NOT NULL, + "createdAt" datetime NOT NULL DEFAULT (datetime('now')), + "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), + "tenantId" varchar, + "organizationId" varchar, + "name" varchar NOT NULL, + "prefix" varchar, + "createdById" varchar, + "public" boolean DEFAULT (0), + "profile_link" varchar, + "logo" varchar, + "imageId" varchar, + "color" varchar, + "emoji" varchar, + "teamSize" varchar, + "isActive" boolean DEFAULT (1), + "isArchived" boolean DEFAULT (0), + "deletedAt" datetime, + "shareProfileView" boolean DEFAULT (1), + "requirePlanToTrack" boolean NOT NULL DEFAULT (0), + "archivedAt" datetime, + CONSTRAINT "FK_51e91be110fa0b8e70066f5727f" FOREIGN KEY ("imageId") REFERENCES "image_asset" ("id") ON DELETE SET NULL ON UPDATE NO ACTION, + CONSTRAINT "FK_da625f694eb1e23e585f3010082" FOREIGN KEY ("createdById") REFERENCES "user" ("id") ON DELETE SET NULL ON UPDATE NO ACTION, + CONSTRAINT "FK_eef1c19a0cb5321223cfe3286c4" FOREIGN KEY ("organizationId") REFERENCES "organization" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT "FK_176f5ed3c4534f3110d423d5690" FOREIGN KEY ("tenantId") REFERENCES "tenant" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + + // Step 4: Insert data into the new "organization_team" table from "temporary_organization_team". + console.log('Step 4: Inserting data into "organization_team" from "temporary_organization_team"...'); + await queryRunner.query(` + INSERT INTO "organization_team" ( + "id", + "createdAt", + "updatedAt", + "tenantId", + "organizationId", + "name", + "prefix", + "createdById", + "public", + "profile_link", + "logo", + "imageId", + "color", + "emoji", + "teamSize", + "isActive", + "isArchived", + "deletedAt", + "shareProfileView", + "requirePlanToTrack", + "archivedAt" + ) + SELECT + "id", + "createdAt", + "updatedAt", + "tenantId", + "organizationId", + "name", + "prefix", + "createdByUserId", + "public", + "profile_link", + "logo", + "imageId", + "color", + "emoji", + "teamSize", + "isActive", + "isArchived", + "deletedAt", + "shareProfileView", + "requirePlanToTrack", + "archivedAt" + FROM "temporary_organization_team"; + `); + + // Step 5: Drop the old "organization_team" table and rename the temporary table. + console.log('Step 5: Dropping the old "temporary_organization_team" table...'); + await queryRunner.query(`DROP TABLE "temporary_organization_team"`); + + // Step 6: Create final indexes on the new "organization_team" table. + console.log('Step 6: Creating indexes on the new "organization_team" table...'); + await queryRunner.query( + `CREATE INDEX "IDX_e22ab0f1236b1a07785b641727" ON "organization_team" ("profile_link") ` + ); + await queryRunner.query(`CREATE INDEX "IDX_176f5ed3c4534f3110d423d569" ON "organization_team" ("tenantId") `); + await queryRunner.query( + `CREATE INDEX "IDX_eef1c19a0cb5321223cfe3286c" ON "organization_team" ("organizationId") ` + ); + await queryRunner.query(`CREATE INDEX "IDX_103ae3eb65f4b091efc55cb532" ON "organization_team" ("name") `); + await queryRunner.query( + `CREATE INDEX "IDX_da625f694eb1e23e585f301008" ON "organization_team" ("createdById") ` + ); + await queryRunner.query(`CREATE INDEX "IDX_51e91be110fa0b8e70066f5727" ON "organization_team" ("imageId") `); + await queryRunner.query(`CREATE INDEX "IDX_722d648e0b83267d4a66332ccb" ON "organization_team" ("isActive") `); + await queryRunner.query(`CREATE INDEX "IDX_38f1d96e8c2d59e4f0f84209ab" ON "organization_team" ("isArchived") `); + } /** * MySQL Up Migration From ce275d76231cece7a7cb6e32c7f7c0a427f0ad64 Mon Sep 17 00:00:00 2001 From: "Rahul R." Date: Thu, 20 Feb 2025 15:13:34 +0530 Subject: [PATCH 5/5] fix: rename "video" table entity migration --- ...erTableVideo.ts => 1739958417359-AlterVideoEntityTable.ts} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename packages/core/src/lib/database/migrations/{1739958417359-AlterTableVideo.ts => 1739958417359-AlterVideoEntityTable.ts} (98%) diff --git a/packages/core/src/lib/database/migrations/1739958417359-AlterTableVideo.ts b/packages/core/src/lib/database/migrations/1739958417359-AlterVideoEntityTable.ts similarity index 98% rename from packages/core/src/lib/database/migrations/1739958417359-AlterTableVideo.ts rename to packages/core/src/lib/database/migrations/1739958417359-AlterVideoEntityTable.ts index 806ab3eaf62..61e5b14c8f0 100644 --- a/packages/core/src/lib/database/migrations/1739958417359-AlterTableVideo.ts +++ b/packages/core/src/lib/database/migrations/1739958417359-AlterVideoEntityTable.ts @@ -2,8 +2,8 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; import * as chalk from 'chalk'; import { DatabaseTypeEnum } from '@gauzy/config'; -export class AlterTableVideo1739958417359 implements MigrationInterface { - name = 'AlterTableVideo1739958417359'; +export class AlterVideoEntityTable1739958417359 implements MigrationInterface { + name = 'AlterVideoEntityTable1739958417359'; /** * Up Migration