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