From 23b3c31810d0770077e658aedaf2551264cac2f8 Mon Sep 17 00:00:00 2001 From: shancheas Date: Wed, 25 Jun 2025 14:52:41 +0700 Subject: [PATCH] refactor(SPG-1199): remove unique constraint on item name and update validation logic in item managers --- .../validation/validate-relation.helper.ts | 2 +- .../1750834308368-remove-item-name-unique.ts | 17 ++++++++++ .../item/data/models/item.model.ts | 2 +- .../usecases/managers/create-item.manager.ts | 31 +++++++++++++++++-- .../usecases/managers/update-item.manager.ts | 25 +++++++++++++-- 5 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 src/database/migrations/1750834308368-remove-item-name-unique.ts diff --git a/src/core/helpers/validation/validate-relation.helper.ts b/src/core/helpers/validation/validate-relation.helper.ts index 2468595..ae5b929 100644 --- a/src/core/helpers/validation/validate-relation.helper.ts +++ b/src/core/helpers/validation/validate-relation.helper.ts @@ -55,7 +55,7 @@ export class ValidateRelationHelper { const relationColumn = data[relation.relation]?.[`${relation.singleQuery[0]}`]; if ( - !!relationColumn && + // !!relationColumn && this.mappingValidator( relationColumn, relation.singleQuery[1], diff --git a/src/database/migrations/1750834308368-remove-item-name-unique.ts b/src/database/migrations/1750834308368-remove-item-name-unique.ts new file mode 100644 index 0000000..1c1b7c4 --- /dev/null +++ b/src/database/migrations/1750834308368-remove-item-name-unique.ts @@ -0,0 +1,17 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class RemoveItemNameUnique1750834308368 implements MigrationInterface { + name = 'RemoveItemNameUnique1750834308368'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "items" DROP CONSTRAINT "UQ_213736582899b3599acaade2cd1"`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "items" ADD CONSTRAINT "UQ_213736582899b3599acaade2cd1" UNIQUE ("name")`, + ); + } +} diff --git a/src/modules/item-related/item/data/models/item.model.ts b/src/modules/item-related/item/data/models/item.model.ts index 72b584b..b161c50 100644 --- a/src/modules/item-related/item/data/models/item.model.ts +++ b/src/modules/item-related/item/data/models/item.model.ts @@ -25,7 +25,7 @@ export class ItemModel extends BaseStatusModel implements ItemEntity { - @Column('varchar', { name: 'name', unique: true }) + @Column('varchar', { name: 'name' }) name: string; @Column('text', { name: 'booking_description', nullable: true }) diff --git a/src/modules/item-related/item/domain/usecases/managers/create-item.manager.ts b/src/modules/item-related/item/domain/usecases/managers/create-item.manager.ts index 2b9d9e0..db1c055 100644 --- a/src/modules/item-related/item/domain/usecases/managers/create-item.manager.ts +++ b/src/modules/item-related/item/domain/usecases/managers/create-item.manager.ts @@ -8,6 +8,7 @@ import { ItemEntity } from '../../entities/item.entity'; import { ItemModel } from '../../../data/models/item.model'; import { BaseCreateManager } from 'src/core/modules/domain/usecase/managers/base-create.manager'; import { ItemCreatedEvent } from '../../entities/event/item-created.event'; +import { STATUS } from 'src/core/strings/constants/base.constants'; @Injectable() export class CreateItemManager extends BaseCreateManager { @@ -29,11 +30,37 @@ export class CreateItemManager extends BaseCreateManager { } get validateRelations(): validateRelations[] { - return []; + const timeGroupId = this.data.time_group_id ?? this.data.time_group?.id; + const relation = + this.data.bundling_items?.length > 0 + ? 'bundling_items' + : 'bundling_parents'; + return timeGroupId != null + ? [ + { + relation: relation, + singleQuery: ['time_group_id', '!=', timeGroupId], + message: `Gagal Update! Time group item dan bundling item tidak sama`, + }, + ] + : []; } get uniqueColumns(): columnUniques[] { - return [{ column: 'name' }]; + const timeGroupId = this.data.time_group_id ?? this.data.time_group?.id; + return timeGroupId != null + ? [ + { + column: 'name', + query: `(status = '${STATUS.ACTIVE}' AND (${this.tableName}.time_group_id Is Null OR ${this.tableName}.time_group_id = '${timeGroupId}'))`, + }, + ] + : [ + { + column: 'name', + query: `(status = '${STATUS.ACTIVE}')`, + }, + ]; } get eventTopics(): EventTopics[] { diff --git a/src/modules/item-related/item/domain/usecases/managers/update-item.manager.ts b/src/modules/item-related/item/domain/usecases/managers/update-item.manager.ts index 510da69..bfc9620 100644 --- a/src/modules/item-related/item/domain/usecases/managers/update-item.manager.ts +++ b/src/modules/item-related/item/domain/usecases/managers/update-item.manager.ts @@ -8,6 +8,7 @@ import { columnUniques, validateRelations, } from 'src/core/strings/constants/interface.constants'; +import { STATUS } from 'src/core/strings/constants/base.constants'; @Injectable() export class UpdateItemManager extends BaseUpdateManager { @@ -39,11 +40,31 @@ export class UpdateItemManager extends BaseUpdateManager { } get validateRelations(): validateRelations[] { - return []; + const timeGroupId = this.data.time_group_id ?? this.data.time_group?.id; + const relation = + this.data.bundling_items?.length > 0 + ? 'bundling_items' + : 'bundling_parents'; + + return timeGroupId != null + ? [ + { + relation: relation, + singleQuery: ['time_group_id', '!=', timeGroupId], + message: `Gagal Update! Time group item dan bundling item tidak sama`, + }, + ] + : []; } get uniqueColumns(): columnUniques[] { - return []; + const timeGroupId = this.data.time_group_id ?? this.data.time_group?.id; + return [ + { + column: 'name', + query: `(status = '${STATUS.ACTIVE}' AND (${this.tableName}.time_group_id Is Null OR ${this.tableName}.time_group_id = '${timeGroupId}'))`, + }, + ]; } get entityTarget(): any {