refactor common modules

This commit is contained in:
sbriat 2023-05-25 09:07:31 +02:00
parent 0297055ece
commit da9d1ba1ca
7 changed files with 57 additions and 63 deletions

View File

@ -9,9 +9,7 @@ export class RedisConfigurationRepository extends IConfigurationRepository {
super(); super();
} }
get = async (key: string): Promise<string> => { get = async (key: string): Promise<string> => await this.redis.get(key);
return await this.redis.get(key);
};
set = async (key: string, value: string): Promise<void> => { set = async (key: string, value: string): Promise<void> => {
await this.redis.set(key, value); await this.redis.set(key, value);

View File

@ -12,22 +12,22 @@ import { PrismaService } from './prisma-service';
export abstract class PrismaRepository<T> implements IRepository<T> { export abstract class PrismaRepository<T> implements IRepository<T> {
protected model: string; protected model: string;
constructor(protected readonly _prisma: PrismaService) {} constructor(protected readonly prisma: PrismaService) {}
async findAll( findAll = async (
page = 1, page = 1,
perPage = 10, perPage = 10,
where?: any, where?: any,
include?: any, include?: any,
): Promise<ICollection<T>> { ): Promise<ICollection<T>> => {
const [data, total] = await this._prisma.$transaction([ const [data, total] = await this.prisma.$transaction([
this._prisma[this.model].findMany({ this.prisma[this.model].findMany({
where, where,
include, include,
skip: (page - 1) * perPage, skip: (page - 1) * perPage,
take: perPage, take: perPage,
}), }),
this._prisma[this.model].count({ this.prisma[this.model].count({
where, where,
}), }),
]); ]);
@ -35,11 +35,11 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
data, data,
total, total,
}); });
} };
async findOneByUuid(uuid: string): Promise<T> { findOneByUuid = async (uuid: string): Promise<T> => {
try { try {
const entity = await this._prisma[this.model].findUnique({ const entity = await this.prisma[this.model].findUnique({
where: { uuid }, where: { uuid },
}); });
@ -55,11 +55,11 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
throw new DatabaseException(); throw new DatabaseException();
} }
} }
} };
async findOne(where: any, include?: any): Promise<T> { findOne = async (where: any, include?: any): Promise<T> => {
try { try {
const entity = await this._prisma[this.model].findFirst({ const entity = await this.prisma[this.model].findFirst({
where: where, where: where,
include: include, include: include,
}); });
@ -75,13 +75,13 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
throw new DatabaseException(); throw new DatabaseException();
} }
} }
} };
// TODO : using any is not good, but needed for nested entities // TODO : using any is not good, but needed for nested entities
// TODO : Refactor for good clean architecture ? // TODO : Refactor for good clean architecture ?
async create(entity: Partial<T> | any, include?: any): Promise<T> { async create(entity: Partial<T> | any, include?: any): Promise<T> {
try { try {
const res = await this._prisma[this.model].create({ const res = await this.prisma[this.model].create({
data: entity, data: entity,
include: include, include: include,
}); });
@ -100,9 +100,9 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
} }
} }
async update(uuid: string, entity: Partial<T>): Promise<T> { update = async (uuid: string, entity: Partial<T>): Promise<T> => {
try { try {
const updatedEntity = await this._prisma[this.model].update({ const updatedEntity = await this.prisma[this.model].update({
where: { uuid }, where: { uuid },
data: entity, data: entity,
}); });
@ -118,15 +118,15 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
throw new DatabaseException(); throw new DatabaseException();
} }
} }
} };
async updateWhere( updateWhere = async (
where: any, where: any,
entity: Partial<T> | any, entity: Partial<T> | any,
include?: any, include?: any,
): Promise<T> { ): Promise<T> => {
try { try {
const updatedEntity = await this._prisma[this.model].update({ const updatedEntity = await this.prisma[this.model].update({
where: where, where: where,
data: entity, data: entity,
include: include, include: include,
@ -144,11 +144,11 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
throw new DatabaseException(); throw new DatabaseException();
} }
} }
} };
async delete(uuid: string): Promise<T> { delete = async (uuid: string): Promise<T> => {
try { try {
const entity = await this._prisma[this.model].delete({ const entity = await this.prisma[this.model].delete({
where: { uuid }, where: { uuid },
}); });
@ -164,11 +164,11 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
throw new DatabaseException(); throw new DatabaseException();
} }
} }
} };
async deleteMany(where: any): Promise<void> { deleteMany = async (where: any): Promise<void> => {
try { try {
const entity = await this._prisma[this.model].deleteMany({ const entity = await this.prisma[this.model].deleteMany({
where: where, where: where,
}); });
@ -184,28 +184,28 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
throw new DatabaseException(); throw new DatabaseException();
} }
} }
} };
async findAllByQuery( findAllByQuery = async (
include: string[], include: string[],
where: string[], where: string[],
): Promise<ICollection<T>> { ): Promise<ICollection<T>> => {
const query = `SELECT ${include.join(',')} FROM ${ const query = `SELECT ${include.join(',')} FROM ${
this.model this.model
} WHERE ${where.join(' AND ')}`; } WHERE ${where.join(' AND ')}`;
const data: T[] = await this._prisma.$queryRawUnsafe(query); const data: T[] = await this.prisma.$queryRawUnsafe(query);
return Promise.resolve({ return Promise.resolve({
data, data,
total: data.length, total: data.length,
}); });
} };
async createWithFields(fields: object): Promise<number> { createWithFields = async (fields: object): Promise<number> => {
try { try {
const command = `INSERT INTO ${this.model} ("${Object.keys(fields).join( const command = `INSERT INTO ${this.model} ("${Object.keys(fields).join(
'","', '","',
)}") VALUES (${Object.values(fields).join(',')})`; )}") VALUES (${Object.values(fields).join(',')})`;
return await this._prisma.$executeRawUnsafe(command); return await this.prisma.$executeRawUnsafe(command);
} catch (e) { } catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) { if (e instanceof Prisma.PrismaClientKnownRequestError) {
throw new DatabaseException( throw new DatabaseException(
@ -217,16 +217,16 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
throw new DatabaseException(); throw new DatabaseException();
} }
} }
} };
async updateWithFields(uuid: string, entity: object): Promise<number> { updateWithFields = async (uuid: string, entity: object): Promise<number> => {
entity['"updatedAt"'] = `to_timestamp(${Date.now()} / 1000.0)`; entity['"updatedAt"'] = `to_timestamp(${Date.now()} / 1000.0)`;
const values = Object.keys(entity).map((key) => `${key} = ${entity[key]}`); const values = Object.keys(entity).map((key) => `${key} = ${entity[key]}`);
try { try {
const command = `UPDATE ${this.model} SET ${values.join( const command = `UPDATE ${this.model} SET ${values.join(
', ', ', ',
)} WHERE uuid = '${uuid}'`; )} WHERE uuid = '${uuid}'`;
return await this._prisma.$executeRawUnsafe(command); return await this.prisma.$executeRawUnsafe(command);
} catch (e) { } catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) { if (e instanceof Prisma.PrismaClientKnownRequestError) {
throw new DatabaseException( throw new DatabaseException(
@ -238,11 +238,11 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
throw new DatabaseException(); throw new DatabaseException();
} }
} }
} };
async healthCheck(): Promise<boolean> { healthCheck = async (): Promise<boolean> => {
try { try {
await this._prisma.$queryRaw`SELECT 1`; await this.prisma.$queryRaw`SELECT 1`;
return true; return true;
} catch (e) { } catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) { if (e instanceof Prisma.PrismaClientKnownRequestError) {
@ -255,5 +255,5 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
throw new DatabaseException(); throw new DatabaseException();
} }
} }
} };
} }

View File

@ -1,4 +0,0 @@
export type Point = {
lon: number;
lat: number;
};

View File

@ -19,7 +19,7 @@ interface HealthCheckResponse {
@Controller() @Controller()
export class HealthServerController { export class HealthServerController {
constructor( constructor(
private readonly _prismaHealthIndicatorUseCase: PrismaHealthIndicatorUseCase, private readonly prismaHealthIndicatorUseCase: PrismaHealthIndicatorUseCase,
) {} ) {}
@GrpcMethod('Health', 'Check') @GrpcMethod('Health', 'Check')
@ -29,7 +29,7 @@ export class HealthServerController {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
metadata: any, metadata: any,
): Promise<HealthCheckResponse> { ): Promise<HealthCheckResponse> {
const healthCheck = await this._prismaHealthIndicatorUseCase.isHealthy( const healthCheck = await this.prismaHealthIndicatorUseCase.isHealthy(
'prisma', 'prisma',
); );
return { return {

View File

@ -10,21 +10,21 @@ import { PrismaHealthIndicatorUseCase } from '../../domain/usecases/prisma.healt
@Controller('health') @Controller('health')
export class HealthController { export class HealthController {
constructor( constructor(
private readonly _prismaHealthIndicatorUseCase: PrismaHealthIndicatorUseCase, private readonly prismaHealthIndicatorUseCase: PrismaHealthIndicatorUseCase,
private _healthCheckService: HealthCheckService, private healthCheckService: HealthCheckService,
private _messager: Messager, private messager: Messager,
) {} ) {}
@Get() @Get()
@HealthCheck() @HealthCheck()
async check() { async check() {
try { try {
return await this._healthCheckService.check([ return await this.healthCheckService.check([
async () => this._prismaHealthIndicatorUseCase.isHealthy('prisma'), async () => this.prismaHealthIndicatorUseCase.isHealthy('prisma'),
]); ]);
} catch (error) { } catch (error) {
const healthCheckResult: HealthCheckResult = error.response; const healthCheckResult: HealthCheckResult = error.response;
this._messager.publish( this.messager.publish(
'logging.matcher.health.crit', 'logging.matcher.health.crit',
JSON.stringify(healthCheckResult.error), JSON.stringify(healthCheckResult.error),
); );

View File

@ -6,13 +6,13 @@ import { IMessageBroker } from './message-broker';
@Injectable() @Injectable()
export class Messager extends IMessageBroker { export class Messager extends IMessageBroker {
constructor( constructor(
private readonly _amqpConnection: AmqpConnection, private readonly amqpConnection: AmqpConnection,
configService: ConfigService, configService: ConfigService,
) { ) {
super(configService.get<string>('RMQ_EXCHANGE')); super(configService.get<string>('RMQ_EXCHANGE'));
} }
publish(routingKey: string, message: string): void { publish = (routingKey: string, message: string): void => {
this._amqpConnection.publish(this.exchange, routingKey, message); this.amqpConnection.publish(this.exchange, routingKey, message);
} };
} }

View File

@ -8,18 +8,18 @@ import { AdRepository } from '../../../ad/adapters/secondaries/ad.repository';
@Injectable() @Injectable()
export class PrismaHealthIndicatorUseCase extends HealthIndicator { export class PrismaHealthIndicatorUseCase extends HealthIndicator {
constructor(private readonly _repository: AdRepository) { constructor(private readonly repository: AdRepository) {
super(); super();
} }
async isHealthy(key: string): Promise<HealthIndicatorResult> { isHealthy = async (key: string): Promise<HealthIndicatorResult> => {
try { try {
await this._repository.healthCheck(); await this.repository.healthCheck();
return this.getStatus(key, true); return this.getStatus(key, true);
} catch (e) { } catch (e) {
throw new HealthCheckError('Prisma', { throw new HealthCheckError('Prisma', {
prisma: e.message, prisma: e.message,
}); });
} }
} };
} }