From 776983b5879c63be9df5f4fc2e766af4f4936805 Mon Sep 17 00:00:00 2001 From: sbriat Date: Tue, 6 Jun 2023 11:09:04 +0200 Subject: [PATCH] refactor and fixes --- .../ad/adapters/secondaries/ads.repository.ts | 2 +- .../secondaries/default-params.provider.ts | 30 ++++++------- src/modules/ad/domain/dtos/ad.creation.ts | 44 ------------------- .../ad/domain/dtos/create-ad.request.ts | 1 + .../is-punctual-or-recurrent.validator.ts | 2 +- .../ad/domain/usecases/create-ad.usecase.ts | 20 ++++----- src/modules/ad/mappers/ad.profile.ts | 15 +++---- .../unit/domain/frequency.mapping.spec.ts | 2 +- .../domain/is-punctual-or-reccurent.spec.ts | 4 +- .../secondaries/prisma-repository.abstract.ts | 28 ++++++------ .../tests/unit/prisma-repository.spec.ts | 2 +- 11 files changed, 51 insertions(+), 99 deletions(-) diff --git a/src/modules/ad/adapters/secondaries/ads.repository.ts b/src/modules/ad/adapters/secondaries/ads.repository.ts index 3b0ea0f..a4b0b28 100644 --- a/src/modules/ad/adapters/secondaries/ads.repository.ts +++ b/src/modules/ad/adapters/secondaries/ads.repository.ts @@ -4,5 +4,5 @@ import { Ad } from '../../domain/entities/ad'; //TODO : properly implement mutate operation to prisma @Injectable() export class AdsRepository extends AdRepository { - protected _model = 'ad'; + protected model = 'ad'; } diff --git a/src/modules/ad/adapters/secondaries/default-params.provider.ts b/src/modules/ad/adapters/secondaries/default-params.provider.ts index 85cd851..1dc0f09 100644 --- a/src/modules/ad/adapters/secondaries/default-params.provider.ts +++ b/src/modules/ad/adapters/secondaries/default-params.provider.ts @@ -6,20 +6,18 @@ import { IProvideParams } from '../../domain/interfaces/param-provider.interface @Injectable() export class DefaultParamsProvider implements IProvideParams { constructor(private readonly configService: ConfigService) {} - getParams = (): DefaultParams => { - return { - MON_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), - TUE_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), - WED_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), - THU_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), - FRI_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), - SAT_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), - SUN_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), - DRIVER: this.configService.get('ROLE') == 'driver' ? true : false, - SEATS_PROVIDED: parseInt(this.configService.get('SEATS_PROVIDED')), - PASSENGER: this.configService.get('ROLE') == 'passenger' ? true : false, - SEATS_REQUESTED: parseInt(this.configService.get('SEATS_REQUESTED')), - STRICT: false, - }; - }; + getParams = (): DefaultParams => ({ + MON_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), + TUE_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), + WED_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), + THU_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), + FRI_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), + SAT_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), + SUN_MARGIN: parseInt(this.configService.get('DEPARTURE_MARGIN')), + DRIVER: this.configService.get('ROLE') == 'driver', + SEATS_PROVIDED: parseInt(this.configService.get('SEATS_PROVIDED')), + PASSENGER: this.configService.get('ROLE') == 'passenger', + SEATS_REQUESTED: parseInt(this.configService.get('SEATS_REQUESTED')), + STRICT: this.configService.get('STRICT_FREQUENCY') == 'true', + }); } diff --git a/src/modules/ad/domain/dtos/ad.creation.ts b/src/modules/ad/domain/dtos/ad.creation.ts index bb34c67..dd0bdeb 100644 --- a/src/modules/ad/domain/dtos/ad.creation.ts +++ b/src/modules/ad/domain/dtos/ad.creation.ts @@ -1,130 +1,86 @@ import { AutoMap } from '@automapper/classes'; -import { - IsOptional, - IsString, - IsBoolean, - IsDate, - IsInt, - IsEnum, - ValidateNested, - IsUUID, -} from 'class-validator'; import { Frequency } from '../types/frequency.enum'; import { Address } from '../entities/address'; export class AdCreation { - @IsUUID(4) @AutoMap() uuid: string; - @IsUUID(4) @AutoMap() userUuid: string; - @IsBoolean() @AutoMap() driver: boolean; - @IsBoolean() @AutoMap() passenger: boolean; - @IsEnum(Frequency) @AutoMap() frequency: Frequency; - @IsDate() @AutoMap() fromDate: Date; - @IsDate() @AutoMap() toDate: Date; - @IsOptional() - @IsDate() @AutoMap() monTime?: string; - @IsOptional() - @IsString() @AutoMap() tueTime?: string; - @IsOptional() - @IsString() @AutoMap() wedTime?: string; - @IsOptional() - @IsString() @AutoMap() thuTime?: string; - @IsOptional() - @IsString() @AutoMap() friTime?: string; - @IsOptional() - @IsString() @AutoMap() satTime?: string; - @IsOptional() - @IsString() @AutoMap() sunTime?: string; - @IsInt() @AutoMap() monMargin: number; - @IsInt() @AutoMap() tueMargin: number; - @IsInt() @AutoMap() wedMargin: number; - @IsInt() @AutoMap() thuMargin: number; - @IsInt() @AutoMap() friMargin: number; - @IsInt() @AutoMap() satMargin: number; - @IsInt() @AutoMap() sunMargin: number; - @IsInt() @AutoMap() seatsDriver: number; - @IsInt() @AutoMap() seatsPassenger: number; - @IsBoolean() @AutoMap() strict: boolean; - @IsDate() @AutoMap() createdAt: Date; - @IsDate() @AutoMap() updatedAt?: Date; - @ValidateNested({ each: true }) @AutoMap() addresses: { create: Address[] }; } diff --git a/src/modules/ad/domain/dtos/create-ad.request.ts b/src/modules/ad/domain/dtos/create-ad.request.ts index 864507a..ac73eea 100644 --- a/src/modules/ad/domain/dtos/create-ad.request.ts +++ b/src/modules/ad/domain/dtos/create-ad.request.ts @@ -68,6 +68,7 @@ export class CreateAdRequest { @AutoMap() toDate?: Date; + @IsOptional() @Type(() => ScheduleDTO) @IsPunctualOrRecurrent() @ValidateNested({ each: true }) diff --git a/src/modules/ad/domain/dtos/validators/decorators/is-punctual-or-recurrent.validator.ts b/src/modules/ad/domain/dtos/validators/decorators/is-punctual-or-recurrent.validator.ts index b9375b2..e060e64 100644 --- a/src/modules/ad/domain/dtos/validators/decorators/is-punctual-or-recurrent.validator.ts +++ b/src/modules/ad/domain/dtos/validators/decorators/is-punctual-or-recurrent.validator.ts @@ -18,7 +18,7 @@ export const IsPunctualOrRecurrent = ( isPunctualOrRecurrent(args), defaultMessage: buildMessage( () => - `the departure, from date, to date and schedule must be properly set on reccurent or punctual ad`, + `the departure, from date, to date and schedule must be properly set on recurrent or punctual ad`, validationOptions, ), }, diff --git a/src/modules/ad/domain/usecases/create-ad.usecase.ts b/src/modules/ad/domain/usecases/create-ad.usecase.ts index ea30327..6485953 100644 --- a/src/modules/ad/domain/usecases/create-ad.usecase.ts +++ b/src/modules/ad/domain/usecases/create-ad.usecase.ts @@ -31,7 +31,7 @@ export class CreateAdUseCase { CreateAdRequest, AdCreation, ); - this.setDefaultSchedule(); + this.setDefaultMarginDurations(); this.setDefaultAddressesPosition(); this.setDefaultDriverAndPassengerParameters(); this.setDefaultStrict(); @@ -60,7 +60,7 @@ export class CreateAdUseCase { } } - private setDefaultSchedule = (): void => { + private setDefaultMarginDurations = (): void => { if (this.ad.monMargin === undefined) this.ad.monMargin = this.defaultParams.MON_MARGIN; if (this.ad.tueMargin === undefined) @@ -83,21 +83,19 @@ export class CreateAdUseCase { }; private setDefaultDriverAndPassengerParameters = (): void => { + this.ad.driver = !!this.ad.driver; + this.ad.passenger = !!this.ad.passenger; if (!this.ad.driver && !this.ad.passenger) { this.ad.driver = this.defaultParams.DRIVER; this.ad.seatsDriver = this.defaultParams.SEATS_PROVIDED; this.ad.passenger = this.defaultParams.PASSENGER; this.ad.seatsPassenger = this.defaultParams.SEATS_REQUESTED; - } else { - if (!this.ad.driver) { - this.ad.driver = false; - this.ad.seatsDriver = 0; - } - if (!this.ad.passenger) { - this.ad.passenger = false; - this.ad.seatsPassenger = 0; - } + return; } + if (!this.ad.seatsDriver || this.ad.seatsDriver <= 0) + this.ad.seatsDriver = this.defaultParams.SEATS_PROVIDED; + if (!this.ad.seatsPassenger || this.ad.seatsPassenger <= 0) + this.ad.seatsPassenger = this.defaultParams.SEATS_REQUESTED; }; private setDefaultAddressesPosition = (): void => { diff --git a/src/modules/ad/mappers/ad.profile.ts b/src/modules/ad/mappers/ad.profile.ts index 96a2f2b..106b58a 100644 --- a/src/modules/ad/mappers/ad.profile.ts +++ b/src/modules/ad/mappers/ad.profile.ts @@ -21,34 +21,33 @@ export class AdProfile extends AutomapperProfile { mapper, CreateAdRequest, AdCreation, - forMember( (destination) => destination.monMargin, - mapFrom((source) => source.marginDurations.mon), + mapFrom((source) => source.marginDurations?.mon), ), forMember( (destination) => destination.tueMargin, - mapFrom((source) => source.marginDurations.tue), + mapFrom((source) => source.marginDurations?.tue), ), forMember( (destination) => destination.wedMargin, - mapFrom((source) => source.marginDurations.wed), + mapFrom((source) => source.marginDurations?.wed), ), forMember( (destination) => destination.thuMargin, - mapFrom((source) => source.marginDurations.thu), + mapFrom((source) => source.marginDurations?.thu), ), forMember( (destination) => destination.friMargin, - mapFrom((source) => source.marginDurations.fri), + mapFrom((source) => source.marginDurations?.fri), ), forMember( (destination) => destination.satMargin, - mapFrom((source) => source.marginDurations.sat), + mapFrom((source) => source.marginDurations?.sat), ), forMember( (destination) => destination.sunMargin, - mapFrom((source) => source.marginDurations.sun), + mapFrom((source) => source.marginDurations?.sun), ), forMember( (destination) => destination.monTime, diff --git a/src/modules/ad/tests/unit/domain/frequency.mapping.spec.ts b/src/modules/ad/tests/unit/domain/frequency.mapping.spec.ts index 0df3372..6a08276 100644 --- a/src/modules/ad/tests/unit/domain/frequency.mapping.spec.ts +++ b/src/modules/ad/tests/unit/domain/frequency.mapping.spec.ts @@ -5,7 +5,7 @@ describe('frequency mapping function ', () => { it('should return punctual', () => { expect(intToFrequency(1)).toBe(Frequency.PUNCTUAL); }); - it('should return recurent', () => { + it('should return recurrent', () => { expect(intToFrequency(2)).toBe(Frequency.RECURRENT); }); it('should return undefined', () => { diff --git a/src/modules/ad/tests/unit/domain/is-punctual-or-reccurent.spec.ts b/src/modules/ad/tests/unit/domain/is-punctual-or-reccurent.spec.ts index 2678862..c545407 100644 --- a/src/modules/ad/tests/unit/domain/is-punctual-or-reccurent.spec.ts +++ b/src/modules/ad/tests/unit/domain/is-punctual-or-reccurent.spec.ts @@ -1,7 +1,7 @@ import { isPunctualOrRecurrent } from '../../../domain/dtos/validators/is-punctual-or-recurrent'; import { Frequency } from '../../../domain/types/frequency.enum'; -describe('punctual or reccurent validators', () => { +describe('punctual or recurrent validators', () => { describe('punctual case ', () => { describe('valid cases', () => { it('should validate with valid departure and empty schedule ', () => { @@ -55,7 +55,7 @@ describe('punctual or reccurent validators', () => { }); }); }); - describe('reccurent case ', () => { + describe('recurrent case ', () => { describe('valid cases', () => { it('should validate with valid from date, to date and non empty schedule ', () => { expect( diff --git a/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts b/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts index c43dfec..b5b9700 100644 --- a/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts +++ b/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts @@ -6,11 +6,11 @@ import { IRepository } from '../../interfaces/repository.interface'; import { PrismaService } from './prisma-service'; /** - * Child classes MUST redefined _model property with appropriate model name + * Child classes MUST redefined model property with appropriate model name */ @Injectable() export abstract class PrismaRepository implements IRepository { - protected _model: string; + protected model: string; constructor(protected readonly _prisma: PrismaService) {} @@ -21,13 +21,13 @@ export abstract class PrismaRepository implements IRepository { include?: any, ): Promise> { const [data, total] = await this._prisma.$transaction([ - this._prisma[this._model].findMany({ + this._prisma[this.model].findMany({ where, include, skip: (page - 1) * perPage, take: perPage, }), - this._prisma[this._model].count({ + this._prisma[this.model].count({ where, }), ]); @@ -39,7 +39,7 @@ export abstract class PrismaRepository implements IRepository { async findOneByUuid(uuid: string): Promise { try { - const entity = await this._prisma[this._model].findUnique({ + const entity = await this._prisma[this.model].findUnique({ where: { uuid }, }); @@ -59,7 +59,7 @@ export abstract class PrismaRepository implements IRepository { async findOne(where: any, include?: any): Promise { try { - const entity = await this._prisma[this._model].findFirst({ + const entity = await this._prisma[this.model].findFirst({ where: where, include: include, }); @@ -81,7 +81,7 @@ export abstract class PrismaRepository implements IRepository { // TODO : Refactor for good clean architecture ? async create(entity: Partial | any, include?: any): Promise { try { - const res = await this._prisma[this._model].create({ + const res = await this._prisma[this.model].create({ data: entity, include: include, }); @@ -101,7 +101,7 @@ export abstract class PrismaRepository implements IRepository { async update(uuid: string, entity: Partial): Promise { try { - const updatedEntity = await this._prisma[this._model].update({ + const updatedEntity = await this._prisma[this.model].update({ where: { uuid }, data: entity, }); @@ -125,7 +125,7 @@ export abstract class PrismaRepository implements IRepository { include?: any, ): Promise { try { - const updatedEntity = await this._prisma[this._model].update({ + const updatedEntity = await this._prisma[this.model].update({ where: where, data: entity, include: include, @@ -147,7 +147,7 @@ export abstract class PrismaRepository implements IRepository { async delete(uuid: string): Promise { try { - const entity = await this._prisma[this._model].delete({ + const entity = await this._prisma[this.model].delete({ where: { uuid }, }); @@ -167,7 +167,7 @@ export abstract class PrismaRepository implements IRepository { async deleteMany(where: any): Promise { try { - const entity = await this._prisma[this._model].deleteMany({ + const entity = await this._prisma[this.model].deleteMany({ where: where, }); @@ -190,7 +190,7 @@ export abstract class PrismaRepository implements IRepository { where: string[], ): Promise> { const query = `SELECT ${include.join(',')} FROM ${ - this._model + this.model } WHERE ${where.join(' AND ')}`; const data: T[] = await this._prisma.$queryRawUnsafe(query); return Promise.resolve({ @@ -201,7 +201,7 @@ export abstract class PrismaRepository implements IRepository { async createWithFields(fields: object): Promise { 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(',')})`; return await this._prisma.$executeRawUnsafe(command); @@ -222,7 +222,7 @@ export abstract class PrismaRepository implements IRepository { entity['"updatedAt"'] = `to_timestamp(${Date.now()} / 1000.0)`; const values = Object.keys(entity).map((key) => `${key} = ${entity[key]}`); try { - const command = `UPDATE ${this._model} SET ${values.join( + const command = `UPDATE ${this.model} SET ${values.join( ', ', )} WHERE uuid = '${uuid}'`; return await this._prisma.$executeRawUnsafe(command); diff --git a/src/modules/database/tests/unit/prisma-repository.spec.ts b/src/modules/database/tests/unit/prisma-repository.spec.ts index 984c69d..eb3bad0 100644 --- a/src/modules/database/tests/unit/prisma-repository.spec.ts +++ b/src/modules/database/tests/unit/prisma-repository.spec.ts @@ -41,7 +41,7 @@ Array.from({ length: 10 }).forEach(() => { @Injectable() class FakePrismaRepository extends PrismaRepository { - protected _model = 'fake'; + protected model = 'fake'; } class FakePrismaService extends PrismaService {