feat(SPG-123) Abstraction Transaction Data
parent
38e420856e
commit
11cd564433
|
@ -0,0 +1,6 @@
|
|||
import { STATUS } from "src/core/strings/constants/base.constants";
|
||||
import { BaseEntity } from "./base.entity";
|
||||
|
||||
export interface BaseStatusEntity extends BaseEntity {
|
||||
status: STATUS;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import { BaseCoreEntity } from "./base-core.entity";
|
||||
|
||||
export interface BaseEntity extends BaseCoreEntity {
|
||||
creator_id: string;
|
||||
creator_name: string;
|
||||
editor_id: string;
|
||||
editor_name: string;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import { Inject, Injectable, Logger } from "@nestjs/common";
|
||||
import { UserProvider, UsersSession } from "src/core/sessions";
|
||||
import { BLANK_USER } from "src/core/strings/constants/base.constants";
|
||||
import { TABLE_NAME } from "src/core/strings/constants/table.constants";
|
||||
|
||||
@Injectable()
|
||||
export abstract class BaseReadManager {
|
||||
|
||||
public user: UsersSession;
|
||||
public dataService: any;
|
||||
public queryBuilder: any;
|
||||
protected tableName: TABLE_NAME;
|
||||
@Inject()
|
||||
protected userProvider: UserProvider;
|
||||
|
||||
private readonly baseLog = new Logger(BaseReadManager.name);
|
||||
|
||||
setUser() {
|
||||
try {
|
||||
this.user = this.userProvider?.user;
|
||||
} catch (error) {
|
||||
this.user = BLANK_USER;
|
||||
}
|
||||
}
|
||||
|
||||
setService(dataService) {
|
||||
this.dataService = dataService;
|
||||
this.queryBuilder = this.dataService.getRepository().createQueryBuilder(this.tableName);
|
||||
}
|
||||
|
||||
async execute(): Promise<void> {
|
||||
this.baseLog.log(`prepareData`, BaseReadManager.name);
|
||||
await this.prepareData();
|
||||
|
||||
this.baseLog.log(`beforeProcess`, BaseReadManager.name);
|
||||
await this.beforeProcess();
|
||||
|
||||
this.baseLog.log('process', BaseReadManager.name);
|
||||
await this.process();
|
||||
|
||||
this.baseLog.log('afterProcess', BaseReadManager.name);
|
||||
await this.afterProcess();
|
||||
}
|
||||
|
||||
abstract prepareData(): Promise<void>;
|
||||
|
||||
abstract beforeProcess(): Promise<void>;
|
||||
|
||||
abstract process(): Promise<void>;
|
||||
|
||||
abstract afterProcess(): Promise<void>;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
import { BadRequestException, 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 { QueryRunner } from "typeorm";
|
||||
|
||||
@Injectable()
|
||||
export abstract class BaseManager {
|
||||
public user: UsersSession;
|
||||
public queryRunner: QueryRunner;
|
||||
public dataService: any;
|
||||
protected data: any;
|
||||
@Inject()
|
||||
protected userProvider: UserProvider;
|
||||
@Inject()
|
||||
protected eventBus: EventBus;
|
||||
|
||||
private readonly baseLog = new Logger(BaseManager.name);
|
||||
|
||||
setUser() {
|
||||
try {
|
||||
this.user = this.userProvider?.user;
|
||||
} catch (error) {
|
||||
this.user = BLANK_USER;
|
||||
}
|
||||
}
|
||||
|
||||
setService(dataService) {
|
||||
this.dataService = dataService;
|
||||
this.queryRunner = this.dataService.getRepository().manager.connection.createQueryRunner();
|
||||
}
|
||||
|
||||
abstract get eventTopics(): EventTopics[];
|
||||
|
||||
async execute(): Promise<void> {
|
||||
try {
|
||||
this.setUser();
|
||||
|
||||
this.queryRunner.startTransaction();
|
||||
this.baseLog.verbose('prepareData');
|
||||
await this.prepareData();
|
||||
|
||||
if (!this.data || !this.dataService) {
|
||||
throw new Error("data or service not implemented.");
|
||||
}
|
||||
|
||||
this.baseLog.verbose('validateProcess');
|
||||
await this.validateProcess();
|
||||
|
||||
this.baseLog.verbose('beforeProcess');
|
||||
await this.beforeProcess();
|
||||
|
||||
this.baseLog.verbose('process');
|
||||
await this.process();
|
||||
|
||||
this.baseLog.verbose('afterProcess');
|
||||
await this.afterProcess();
|
||||
|
||||
this.baseLog.verbose('commitTransaction');
|
||||
await this.queryRunner.commitTransaction();
|
||||
|
||||
this.publishEvents();
|
||||
|
||||
await this.queryRunner.release();
|
||||
} catch (e) {
|
||||
if (e.response) throw new Error(JSON.stringify(e.response));
|
||||
else throw new Error(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
abstract prepareData(): Promise<void>;
|
||||
|
||||
abstract validateProcess(): Promise<void>;
|
||||
|
||||
abstract beforeProcess(): Promise<void>;
|
||||
|
||||
abstract process(): Promise<void>;
|
||||
|
||||
abstract afterProcess(): Promise<void>;
|
||||
|
||||
async publishEvents() {
|
||||
if (!this.eventTopics.length) return
|
||||
};
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import { BaseManager } from "../base.manager";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
@Injectable()
|
||||
export abstract class BaseCreateManager<Entity> extends BaseManager {
|
||||
|
||||
protected result: Entity;
|
||||
protected duplicateColumn: string[];
|
||||
abstract get entityTarget(): any;
|
||||
|
||||
setData(entity: Entity): void {
|
||||
this.data = entity;
|
||||
}
|
||||
|
||||
async prepareData(): Promise<void> {
|
||||
Object.assign(this.data, {
|
||||
creator_id: this.user.id,
|
||||
creator_name: this.user.name,
|
||||
created_at: new Date().getTime(),
|
||||
updated_at: new Date().getTime(),
|
||||
});
|
||||
}
|
||||
|
||||
async process(): Promise<void> {
|
||||
this.result = await this.dataService.create(
|
||||
this.queryRunner,
|
||||
this.entityTarget,
|
||||
this.data,
|
||||
);
|
||||
}
|
||||
|
||||
async getResult(): Promise<Entity> {
|
||||
return await this.dataService.getOneByOptions({
|
||||
where: {
|
||||
id: this.result['id']
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import { HttpStatus, Injectable, UnauthorizedException, UnprocessableEntityException } from "@nestjs/common";
|
||||
import { BaseManager } from "../base.manager";
|
||||
|
||||
@Injectable()
|
||||
export abstract class BaseDeleteManager<Entity> extends BaseManager {
|
||||
|
||||
protected dataId: string;
|
||||
protected result: Entity;
|
||||
abstract get entityTarget(): any;
|
||||
|
||||
setData(id: string): void {
|
||||
this.dataId = id;
|
||||
}
|
||||
|
||||
async prepareData(): Promise<void> {
|
||||
this.data = await this.dataService.getOneByOptions({
|
||||
where: {
|
||||
id: this.dataId
|
||||
}
|
||||
})
|
||||
|
||||
if (!this.data)
|
||||
throw new UnprocessableEntityException({
|
||||
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
|
||||
message: `Data with id ${this.dataId} not found`,
|
||||
error: 'Unprocessable Entity',
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
async process(): Promise<void> {
|
||||
await this.dataService.deleteById(
|
||||
this.queryRunner,
|
||||
this.entityTarget,
|
||||
this.dataId,
|
||||
);
|
||||
}
|
||||
|
||||
abstract getResult(): string;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { BaseReadManager } from "../base-read.manager";
|
||||
|
||||
export abstract class BaseDetailManager<Entity> extends BaseReadManager {
|
||||
|
||||
protected dataId: string;
|
||||
protected result: Entity;
|
||||
|
||||
abstract get selectData(): string[];
|
||||
abstract get relationData(): string[];
|
||||
abstract get setFindProperties(): any;
|
||||
|
||||
setData(dataId: string): void {
|
||||
this.dataId = dataId;
|
||||
}
|
||||
|
||||
async process(): Promise<void> {
|
||||
this.queryBuilder.select(this.selectData).where(this.setFindProperties);
|
||||
this.result = await this.queryBuilder.getOne();
|
||||
}
|
||||
|
||||
getResult(): Entity {
|
||||
return this.result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import { PaginationResponse } from "src/core/response/domain/ok-response.interface";
|
||||
import { BaseReadManager } from "../base-read.manager";
|
||||
import { SelectQueryBuilder } from "typeorm";
|
||||
import { BaseFilterEntity } from "../../entities/base-filter.entity";
|
||||
import { Param, SpecificSearchFilter } from "src/core/helpers/query/specific-search.helper";
|
||||
|
||||
export abstract class BaseIndexManager<Entity> extends BaseReadManager {
|
||||
|
||||
protected result: PaginationResponse<Entity>;
|
||||
public filterParam: BaseFilterEntity;
|
||||
abstract get specificFilter(): Param[];
|
||||
|
||||
setFilterParam(param: BaseFilterEntity): void {
|
||||
this.filterParam = param;
|
||||
}
|
||||
|
||||
async process(): Promise<void> {
|
||||
// const filterSearch: string[] = this.setFilterSearch();
|
||||
|
||||
// this.queryBuilder.andWhere(
|
||||
// new Brackets((qb) => {
|
||||
// filterSearch.map((fSearch) => {
|
||||
// qb.orWhere(`${fSearch} ILIKE :query`, {
|
||||
// query: `%${
|
||||
// this.filterParam.q.trim().replace(/\s+/g, ' ') ?? ''
|
||||
// }%`,
|
||||
// });
|
||||
// });
|
||||
// }),
|
||||
// );
|
||||
|
||||
new SpecificSearchFilter<Entity>(this.queryBuilder, this.tableName, this.specificFilter).getFilter();
|
||||
this.setQueryFilter(this.queryBuilder);
|
||||
|
||||
this.result = await this.dataService.getIndex(
|
||||
this.queryBuilder,
|
||||
this.filterParam,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
setFilterSearch(): string[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
abstract setQueryFilter(
|
||||
queryBuilder: SelectQueryBuilder<Entity>,
|
||||
): SelectQueryBuilder<Entity>;
|
||||
|
||||
|
||||
getResult(): PaginationResponse<Entity> {
|
||||
return this.result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import { Injectable } from "@nestjs/common";
|
||||
import { BaseManager } from "../base.manager";
|
||||
import { STATUS } from "src/core/strings/constants/base.constants";
|
||||
import { UserPrivilegeModel } from "src/modules/user-related/user-privilege/data/model/user-privilege.model";
|
||||
|
||||
@Injectable()
|
||||
export abstract class BaseUpdateStatusManager<Entity> extends BaseManager {
|
||||
|
||||
protected dataId: string;
|
||||
protected result: Entity;
|
||||
protected dataStatus: STATUS;
|
||||
protected duplicateColumn: string[];
|
||||
abstract get entityTarget(): any;
|
||||
|
||||
setData(id: string, status: STATUS): void {
|
||||
this.dataId = id;
|
||||
this.dataStatus = status;
|
||||
}
|
||||
|
||||
async prepareData(): Promise<void> {
|
||||
this.data = new UserPrivilegeModel();
|
||||
|
||||
Object.assign(this.data, {
|
||||
editor_id: this.user.id,
|
||||
editor_name: this.user.name,
|
||||
updated_at: new Date().getTime(),
|
||||
id: this.dataId,
|
||||
status: this.dataStatus,
|
||||
});
|
||||
}
|
||||
|
||||
async process(): Promise<void> {
|
||||
this.result = await this.dataService.update(
|
||||
this.queryRunner,
|
||||
this.entityTarget,
|
||||
{ id: this.dataId },
|
||||
this.data,
|
||||
);
|
||||
}
|
||||
|
||||
abstract getResult(): string;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import { Injectable } from "@nestjs/common";
|
||||
import { BaseManager } from "../base.manager";
|
||||
|
||||
@Injectable()
|
||||
export abstract class BaseUpdateManager<Entity> extends BaseManager {
|
||||
|
||||
protected dataId: string;
|
||||
protected result: Entity;
|
||||
protected duplicateColumn: string[];
|
||||
abstract get entityTarget(): any;
|
||||
|
||||
setData(id: string, entity: Entity): void {
|
||||
this.dataId = id;
|
||||
this.data = entity;
|
||||
}
|
||||
|
||||
async prepareData(): Promise<void> {
|
||||
Object.assign(this.data, {
|
||||
editor_id: this.user.id,
|
||||
editor_name: this.user.name,
|
||||
updated_at: new Date().getTime(),
|
||||
});
|
||||
}
|
||||
|
||||
async process(): Promise<void> {
|
||||
this.result = await this.dataService.update(
|
||||
this.queryRunner,
|
||||
this.entityTarget,
|
||||
{ id: this.dataId },
|
||||
this.data,
|
||||
);
|
||||
}
|
||||
|
||||
async getResult(): Promise<Entity> {
|
||||
return await this.dataService.getOneByOptions({
|
||||
where: {
|
||||
id: this.dataId
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { BaseDataOrchestrator } from "./base-data.orchestrator";
|
||||
|
||||
export abstract class BaseDataTransactionOrchestrator<Entity> extends BaseDataOrchestrator<Entity> {
|
||||
abstract active(dataId: string): Promise<String>;
|
||||
abstract confirm(dataId: string): Promise<String>;
|
||||
abstract inactive(dataId: string): Promise<String>;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export abstract class BaseDataOrchestrator<Entity> {
|
||||
|
||||
abstract create(data: Entity): Promise<Entity>;
|
||||
abstract update(dataId: string, data: Entity): Promise<Entity>;
|
||||
abstract delete(dataId: string): Promise<String>;
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
import { PaginationResponse } from "src/core/response/domain/ok-response.interface";
|
||||
|
||||
export abstract class BaseReadOrchestrator<Entity> {
|
||||
abstract index(params): Promise<PaginationResponse<Entity>>;
|
||||
abstract detail(dataId: string): Promise<Entity>;
|
||||
}
|
Loading…
Reference in New Issue