From c5c576282341a33293add194a20d4a72854d2073 Mon Sep 17 00:00:00 2001 From: ashar Date: Thu, 6 Jun 2024 14:59:51 +0700 Subject: [PATCH] feat(SPG-7) Data Validation --- .../validation/validate-relation.helper.ts | 43 +++++++++++++++++++ .../modules/domain/usecase/base.manager.ts | 6 ++- .../managers/base-batch-delete.manager.ts | 8 ++++ .../base-batch-update-status.manager.ts | 8 ++++ .../usecase/managers/base-create.manager.ts | 5 +++ .../usecase/managers/base-custom.manager.ts | 5 +++ .../usecase/managers/base-delete.manager.ts | 8 ++++ .../managers/base-update-status.manager.ts | 8 ++++ .../usecase/managers/base-update.manager.ts | 8 ++++ .../strings/constants/interface.constants.ts | 5 +++ ...te-user-privilege-configuration.manager.ts | 9 +++- .../managers/active-user-privilege.manager.ts | 9 +++- .../batch-active-user-privilege.manager.ts | 9 +++- .../batch-confirm-user-privilege.manager.ts | 9 +++- .../batch-delete-user-privilege.manager.ts | 9 +++- .../batch-inactive-user-privilege.manager.ts | 9 +++- .../confirm-user-privilege.manager.ts | 9 +++- .../managers/delete-user-privilege.manager.ts | 9 +++- .../inactive-user-privilege.manager.ts | 9 +++- .../managers/update-user-privilege.manager.ts | 9 +++- 20 files changed, 183 insertions(+), 11 deletions(-) create mode 100644 src/core/helpers/validation/validate-relation.helper.ts diff --git a/src/core/helpers/validation/validate-relation.helper.ts b/src/core/helpers/validation/validate-relation.helper.ts new file mode 100644 index 0000000..bcb19e1 --- /dev/null +++ b/src/core/helpers/validation/validate-relation.helper.ts @@ -0,0 +1,43 @@ +import { Injectable, UnprocessableEntityException } from '@nestjs/common'; +import { BaseDataService } from 'src/core/modules/data/service/base-data.service'; +import { validateRelations } from 'src/core/strings/constants/interface.constants'; + +@Injectable() +export class ValidateRelationHelper { + constructor( + private dataId: string, + private dataService: BaseDataService, + private relations: validateRelations[], + private tableName: string, + ) {} + + async execute() { + const repository = this.dataService.getRepository(); + const queryBuilder = repository.createQueryBuilder(this.tableName); + + // load relation + for (const relation of this.relations) { + queryBuilder.loadRelationCountAndMap( + `${this.tableName}.total_${relation.relation}`, + `${this.tableName}.${relation.relation}`, + `total_${relation.relation}`, + ); + } + + // filtering data only with specific data + queryBuilder.where(`${this.tableName}.id in ('${this.dataId}')`); + + // get data + const data = await queryBuilder.getOne(); + + // process validasi + for (const relation of this.relations) { + const message = + relation.message ?? + `Failed! this data already connected to ${relation.relation}`; + + if (data[`total_${relation.relation}`]) + throw new UnprocessableEntityException(message); + } + } +} diff --git a/src/core/modules/domain/usecase/base.manager.ts b/src/core/modules/domain/usecase/base.manager.ts index 96b38f3..e4101b6 100644 --- a/src/core/modules/domain/usecase/base.manager.ts +++ b/src/core/modules/domain/usecase/base.manager.ts @@ -2,7 +2,10 @@ import { Inject, Injectable, Logger } from '@nestjs/common'; import { EventBus } from '@nestjs/cqrs'; import { UserProvider, UsersSession } from 'src/core/sessions'; import { BLANK_USER } from 'src/core/strings/constants/base.constants'; -import { EventTopics } from 'src/core/strings/constants/interface.constants'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; import { QueryRunner } from 'typeorm'; @@ -17,6 +20,7 @@ export abstract class BaseManager { protected userProvider: UserProvider; @Inject() protected eventBus: EventBus; + abstract get validateRelations(): validateRelations[]; private readonly baseLog = new Logger(BaseManager.name); diff --git a/src/core/modules/domain/usecase/managers/base-batch-delete.manager.ts b/src/core/modules/domain/usecase/managers/base-batch-delete.manager.ts index 5a28f2d..55d95fa 100644 --- a/src/core/modules/domain/usecase/managers/base-batch-delete.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-batch-delete.manager.ts @@ -1,6 +1,7 @@ import { BatchResult } from 'src/core/response/domain/ok-response.interface'; import { BaseManager } from '../base.manager'; import { HttpStatus, NotFoundException } from '@nestjs/common'; +import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper'; export abstract class BaseBatchDeleteManager extends BaseManager { protected dataIds: string[]; @@ -41,6 +42,13 @@ export abstract class BaseBatchDeleteManager extends BaseManager { } await this.validateData(entity); + await new ValidateRelationHelper( + id, + this.dataService, + this.validateRelations, + this.tableName, + ).execute(); + await this.dataService.deleteById( this.queryRunner, this.entityTarget, diff --git a/src/core/modules/domain/usecase/managers/base-batch-update-status.manager.ts b/src/core/modules/domain/usecase/managers/base-batch-update-status.manager.ts index 4e4cfb1..c8ce36a 100644 --- a/src/core/modules/domain/usecase/managers/base-batch-update-status.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-batch-update-status.manager.ts @@ -2,6 +2,7 @@ import { BatchResult } from 'src/core/response/domain/ok-response.interface'; import { BaseManager } from '../base.manager'; import { HttpStatus, NotFoundException } from '@nestjs/common'; import { STATUS } from 'src/core/strings/constants/base.constants'; +import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper'; export abstract class BaseBatchUpdateStatusManager extends BaseManager { protected dataIds: string[]; @@ -44,6 +45,13 @@ export abstract class BaseBatchUpdateStatusManager extends BaseManager { } await this.validateData(entity); + await new ValidateRelationHelper( + id, + this.dataService, + this.validateRelations, + this.tableName, + ).execute(); + await this.dataService.update( this.queryRunner, this.entityTarget, diff --git a/src/core/modules/domain/usecase/managers/base-create.manager.ts b/src/core/modules/domain/usecase/managers/base-create.manager.ts index 9bf8f20..c7b7f59 100644 --- a/src/core/modules/domain/usecase/managers/base-create.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-create.manager.ts @@ -2,6 +2,7 @@ import { CheckDuplicateHelper } from 'src/core/helpers/query/check-duplicate.hel import { BaseManager } from '../base.manager'; import { RecordLog } from 'src/modules/configuration/log/domain/entities/log.event'; import { OPERATION } from 'src/core/strings/constants/base.constants'; +import { validateRelations } from 'src/core/strings/constants/interface.constants'; export abstract class BaseCreateManager extends BaseManager { protected result: Entity; @@ -13,6 +14,10 @@ export abstract class BaseCreateManager extends BaseManager { this.data = entity; } + get validateRelations(): validateRelations[] { + return []; + } + async prepareData(): Promise { Object.assign(this.data, { creator_id: this.user.id, diff --git a/src/core/modules/domain/usecase/managers/base-custom.manager.ts b/src/core/modules/domain/usecase/managers/base-custom.manager.ts index f066360..20416df 100644 --- a/src/core/modules/domain/usecase/managers/base-custom.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-custom.manager.ts @@ -1,3 +1,4 @@ +import { validateRelations } from 'src/core/strings/constants/interface.constants'; import { BaseManager } from '../base.manager'; export abstract class BaseCustomManager extends BaseManager { @@ -8,6 +9,10 @@ export abstract class BaseCustomManager extends BaseManager { this.data = entity; } + get validateRelations(): validateRelations[] { + return []; + } + async prepareData(): Promise { if (this.data) Object.assign(this.data, { diff --git a/src/core/modules/domain/usecase/managers/base-delete.manager.ts b/src/core/modules/domain/usecase/managers/base-delete.manager.ts index 2841d6e..bd6e46d 100644 --- a/src/core/modules/domain/usecase/managers/base-delete.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-delete.manager.ts @@ -1,5 +1,6 @@ import { HttpStatus, UnprocessableEntityException } from '@nestjs/common'; import { BaseManager } from '../base.manager'; +import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper'; export abstract class BaseDeleteManager extends BaseManager { protected dataId: string; @@ -28,6 +29,13 @@ export abstract class BaseDeleteManager extends BaseManager { } async process(): Promise { + await new ValidateRelationHelper( + this.dataId, + this.dataService, + this.validateRelations, + this.tableName, + ).execute(); + await this.dataService.deleteById( this.queryRunner, this.entityTarget, diff --git a/src/core/modules/domain/usecase/managers/base-update-status.manager.ts b/src/core/modules/domain/usecase/managers/base-update-status.manager.ts index ac27977..6a593eb 100644 --- a/src/core/modules/domain/usecase/managers/base-update-status.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-update-status.manager.ts @@ -1,3 +1,4 @@ +import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper'; import { BaseManager } from '../base.manager'; import { STATUS } from 'src/core/strings/constants/base.constants'; import { UserPrivilegeModel } from 'src/modules/user-related/user-privilege/data/models/user-privilege.model'; @@ -27,6 +28,13 @@ export abstract class BaseUpdateStatusManager extends BaseManager { } async process(): Promise { + await new ValidateRelationHelper( + this.dataId, + this.dataService, + this.validateRelations, + this.tableName, + ).execute(); + this.result = await this.dataService.update( this.queryRunner, this.entityTarget, diff --git a/src/core/modules/domain/usecase/managers/base-update.manager.ts b/src/core/modules/domain/usecase/managers/base-update.manager.ts index 2c15838..d96a2f4 100644 --- a/src/core/modules/domain/usecase/managers/base-update.manager.ts +++ b/src/core/modules/domain/usecase/managers/base-update.manager.ts @@ -1,5 +1,6 @@ import { CheckDuplicateHelper } from 'src/core/helpers/query/check-duplicate.helpers'; import { BaseManager } from '../base.manager'; +import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper'; export abstract class BaseUpdateManager extends BaseManager { protected dataId: string; @@ -31,6 +32,13 @@ export abstract class BaseUpdateManager extends BaseManager { } async process(): Promise { + await new ValidateRelationHelper( + this.dataId, + this.dataService, + this.validateRelations, + this.tableName, + ).execute(); + this.result = await this.dataService.update( this.queryRunner, this.entityTarget, diff --git a/src/core/strings/constants/interface.constants.ts b/src/core/strings/constants/interface.constants.ts index 08d1a7d..61d34ac 100644 --- a/src/core/strings/constants/interface.constants.ts +++ b/src/core/strings/constants/interface.constants.ts @@ -6,6 +6,11 @@ export interface EventTopics { data?: any; } +export interface validateRelations { + relation: string; + message?: string; +} + export interface IEvent { id: string; old: null | Entity; diff --git a/src/modules/user-related/user-privilege/domain/usecases/user-privilege-configuration/managers/update-user-privilege-configuration.manager.ts b/src/modules/user-related/user-privilege/domain/usecases/user-privilege-configuration/managers/update-user-privilege-configuration.manager.ts index 4977ed0..d4a22b3 100644 --- a/src/modules/user-related/user-privilege/domain/usecases/user-privilege-configuration/managers/update-user-privilege-configuration.manager.ts +++ b/src/modules/user-related/user-privilege/domain/usecases/user-privilege-configuration/managers/update-user-privilege-configuration.manager.ts @@ -1,6 +1,9 @@ import { Injectable } from '@nestjs/common'; import { UserPrivilegeConfigurationEntity } from '../../../entities/user-privilege-configuration.entity'; -import { EventTopics } from 'src/core/strings/constants/interface.constants'; +import { + EventTopics, + validateRelations, +} from 'src/core/strings/constants/interface.constants'; import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager'; import { UserPrivilegeConfigurationModel } from 'src/modules/user-related/user-privilege/data/models/user-privilege-configuration.model'; @@ -28,6 +31,10 @@ export class UpdateUserPrivilegeConfigurationManager extends BaseCustomManager