WIP validation pipes
This commit is contained in:
parent
1db7dc1104
commit
ad10320f5f
|
@ -8,6 +8,7 @@ import { AdProfile } from './mappers/ad.profile';
|
|||
import { AdsRepository } from './adapters/secondaries/ads.repository';
|
||||
import { Messager } from './adapters/secondaries/messager';
|
||||
import { FindAdByUuidUseCase } from './domain/usecases/find-ad-by-uuid.usecase';
|
||||
import { CreateAdUseCase } from './domain/usecases/create-ad.usecase';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
|
@ -29,6 +30,12 @@ import { FindAdByUuidUseCase } from './domain/usecases/find-ad-by-uuid.usecase';
|
|||
}),
|
||||
],
|
||||
controllers: [AdController],
|
||||
providers: [AdProfile, AdsRepository, Messager, FindAdByUuidUseCase],
|
||||
providers: [
|
||||
AdProfile,
|
||||
AdsRepository,
|
||||
Messager,
|
||||
FindAdByUuidUseCase,
|
||||
CreateAdUseCase,
|
||||
],
|
||||
})
|
||||
export class AdModule {}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
import { Mapper } from '@automapper/core';
|
||||
import { InjectMapper } from '@automapper/nestjs';
|
||||
import { Controller, UsePipes } from '@nestjs/common';
|
||||
import { QueryBus } from '@nestjs/cqrs';
|
||||
import { CommandBus, QueryBus } from '@nestjs/cqrs';
|
||||
import { GrpcMethod, RpcException } from '@nestjs/microservices';
|
||||
import { RpcValidationPipe } from '../../../../utils/pipes/rpc.validation-pipe';
|
||||
import { FindAdByUuidRequest } from '../../domain/dtos/find-ad-by-uuid.request';
|
||||
import { AdPresenter } from './ad.presenter';
|
||||
import { FindAdByUuidQuery } from '../../queries/find-ad-by-uuid.query';
|
||||
import { Ad } from '../../domain/entities/ad';
|
||||
import { CreateAdRequest } from '../../domain/dtos/create-ad.request';
|
||||
import { CreateAdCommand } from '../../commands/create-ad.command';
|
||||
import { DatabaseException } from 'src/modules/database/exceptions/database.exception';
|
||||
|
||||
@UsePipes(
|
||||
new RpcValidationPipe({
|
||||
|
@ -18,6 +21,7 @@ import { Ad } from '../../domain/entities/ad';
|
|||
@Controller()
|
||||
export class AdController {
|
||||
constructor(
|
||||
private readonly _commandBus: CommandBus,
|
||||
private readonly queryBus: QueryBus,
|
||||
@InjectMapper() private readonly _mapper: Mapper,
|
||||
) {}
|
||||
|
@ -34,4 +38,22 @@ export class AdController {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
@GrpcMethod('AdsService', 'Create')
|
||||
async createAd(data: CreateAdRequest): Promise<AdPresenter> {
|
||||
try {
|
||||
const ad = await this._commandBus.execute(new CreateAdCommand(data));
|
||||
return this._mapper.map(ad, Ad, AdPresenter);
|
||||
} catch (e) {
|
||||
if (e instanceof DatabaseException) {
|
||||
if (e.message.includes('Already exists')) {
|
||||
throw new RpcException({
|
||||
code: 6,
|
||||
message: 'Ad already exists',
|
||||
});
|
||||
}
|
||||
}
|
||||
throw new RpcException({});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,15 +19,15 @@ message Ad {
|
|||
string userUuid = 2;
|
||||
bool driver = 3;
|
||||
bool passenger = 4;
|
||||
int32 frequency = 5;
|
||||
Frequency frequency = 5;
|
||||
string fromDate = 6;
|
||||
string toDate = 7;
|
||||
Schedule schedule = 8;
|
||||
MarginDurations marginDurations = 9;
|
||||
int32 seatsPassenger = 10;
|
||||
int32 seatsDriver = 11;
|
||||
optional int32 seatsPassenger = 10;
|
||||
optional int32 seatsDriver = 11;
|
||||
bool strict = 12;
|
||||
Addresses addresses = 13;
|
||||
repeated Address addresses = 13;
|
||||
}
|
||||
|
||||
message Schedule {
|
||||
|
@ -50,10 +50,6 @@ message MarginDurations {
|
|||
int32 sun = 7;
|
||||
}
|
||||
|
||||
message Addresses {
|
||||
repeated Address address = 1;
|
||||
}
|
||||
|
||||
message Address {
|
||||
float lon = 1;
|
||||
float lat = 2;
|
||||
|
@ -73,6 +69,11 @@ enum AddressType {
|
|||
OTHER = 5;
|
||||
}
|
||||
|
||||
enum Frequency {
|
||||
PUNCTUAL = 1;
|
||||
RECURRENT = 2;
|
||||
}
|
||||
|
||||
message AdFilter {
|
||||
optional int32 page = 1;
|
||||
optional int32 perPage = 2;
|
||||
|
|
|
@ -5,10 +5,12 @@ import {
|
|||
IsBoolean,
|
||||
IsDate,
|
||||
IsInt,
|
||||
MinLength,
|
||||
ValidateIf,
|
||||
ArrayMinSize,
|
||||
IsArray,
|
||||
IsEnum,
|
||||
} from 'class-validator';
|
||||
import { FrequencyType } from '../entities/frequencyEnum';
|
||||
import { Frequency } from '../entities/frequency.enum';
|
||||
import { Address } from '../entities/address';
|
||||
|
||||
export class CreateAdRequest {
|
||||
|
@ -22,21 +24,26 @@ export class CreateAdRequest {
|
|||
userUuid: string;
|
||||
|
||||
@ValidateIf((ad) => (ad.passenger ? false : true))
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
@AutoMap()
|
||||
driver?: boolean;
|
||||
|
||||
@ValidateIf((ad) => (ad.driver ? false : true))
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
@AutoMap()
|
||||
passenger?: boolean;
|
||||
|
||||
@AutoMap()
|
||||
frequency: FrequencyType;
|
||||
@IsEnum(Frequency)
|
||||
frequency: Frequency;
|
||||
|
||||
@IsDate()
|
||||
@AutoMap()
|
||||
fromDate: Date;
|
||||
|
||||
@IsDate()
|
||||
@AutoMap()
|
||||
toDate: Date;
|
||||
|
||||
|
@ -111,11 +118,13 @@ export class CreateAdRequest {
|
|||
sunMargin?: number;
|
||||
|
||||
@ValidateIf((ad) => (ad.passenger ? false : true))
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
@AutoMap()
|
||||
seatsDriver?: number;
|
||||
|
||||
@ValidateIf((ad) => (ad.driver ? false : true))
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
@AutoMap()
|
||||
seatsPassenger?: number;
|
||||
|
@ -130,7 +139,7 @@ export class CreateAdRequest {
|
|||
@AutoMap()
|
||||
updatedAt?: Date;
|
||||
|
||||
@MinLength(2)
|
||||
@AutoMap()
|
||||
@IsArray()
|
||||
@AutoMap(() => [Address])
|
||||
addresses?: Array<Address>;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
MinLength,
|
||||
ValidateIf,
|
||||
} from 'class-validator';
|
||||
import { FrequencyType } from '../entities/frequencyEnum';
|
||||
import { Frequency } from './frequency.enum';
|
||||
import { Address } from '../entities/address';
|
||||
|
||||
export class Ad {
|
||||
|
@ -31,7 +31,7 @@ export class Ad {
|
|||
passenger?: boolean;
|
||||
|
||||
@AutoMap()
|
||||
frequency: FrequencyType;
|
||||
frequency: string;
|
||||
|
||||
@AutoMap()
|
||||
fromDate: Date;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { AutoMap } from '@automapper/classes';
|
||||
import { AddressType } from './addressEnum';
|
||||
import { AddressType } from './address.enum';
|
||||
|
||||
export class Address {
|
||||
@AutoMap()
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
export enum Frequency {
|
||||
PUNCTUAL = 1,
|
||||
RECURRENT = 2,
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
export enum FrequencyType {
|
||||
PUNCTUAL = 'PUNCTUAL',
|
||||
RECURRENT = 'RECURRENT',
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
import { createMap, Mapper } from '@automapper/core';
|
||||
import { createMap, forMember, mapFrom, Mapper } from '@automapper/core';
|
||||
import { AutomapperProfile, InjectMapper } from '@automapper/nestjs';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Ad } from '../domain/entities/ad';
|
||||
import { AdPresenter } from '../adapters/primaries/ad.presenter';
|
||||
import { CreateAdRequest } from '../domain/dtos/create-ad.request';
|
||||
import { Frequency } from '../domain/entities/frequency.enum';
|
||||
|
||||
@Injectable()
|
||||
export class AdProfile extends AutomapperProfile {
|
||||
|
@ -14,7 +15,17 @@ export class AdProfile extends AutomapperProfile {
|
|||
override get profile() {
|
||||
return (mapper) => {
|
||||
createMap(mapper, Ad, AdPresenter);
|
||||
createMap(mapper, CreateAdRequest, Ad);
|
||||
createMap(
|
||||
mapper,
|
||||
CreateAdRequest,
|
||||
Ad,
|
||||
forMember(
|
||||
(dest) => dest.frequency,
|
||||
mapFrom((source) =>
|
||||
source.frequency == Frequency.PUNCTUAL ? 'PUNCTUAL' : 'RECCURENT',
|
||||
),
|
||||
),
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ import { Address } from '../../domain/entities/address';
|
|||
import { Messager } from '../../adapters/secondaries/messager';
|
||||
import { AdsRepository } from '../../adapters/secondaries/ads.repository';
|
||||
import { CreateAdCommand } from '../../commands/create-ad.command';
|
||||
import { AddressType } from '../../domain/entities/addressEnum';
|
||||
import { AddressType } from '../../domain/entities/address.enum';
|
||||
import { AutomapperModule } from '@automapper/nestjs';
|
||||
import { classes } from '@automapper/classes';
|
||||
import { FrequencyType } from '../../domain/entities/frequencyEnum';
|
||||
import { Frequency } from '../../domain/entities/frequency.enum';
|
||||
import { Ad } from '../../domain/entities/ad';
|
||||
import { AdProfile } from '../../mappers/ad.profile';
|
||||
|
||||
|
@ -19,7 +19,7 @@ const mockAddress1: Address = {
|
|||
houseNumber: '5',
|
||||
street: 'Avenue Foch',
|
||||
locality: 'Nancy',
|
||||
postalCode: '75000',
|
||||
postalCode: '54000',
|
||||
country: 'France',
|
||||
type: AddressType.HOUSE_NUMBER,
|
||||
};
|
||||
|
@ -37,7 +37,7 @@ const newAdRequest: CreateAdRequest = {
|
|||
userUuid: '113e0000-0000-4000-a000-000000000000',
|
||||
driver: true,
|
||||
passenger: false,
|
||||
frequency: FrequencyType.RECURRENT,
|
||||
frequency: Frequency.RECURRENT,
|
||||
fromDate: new Date('01-05-2023'),
|
||||
toDate: new Date('20-08-2023'),
|
||||
tueTime: new Date(''),
|
||||
|
|
|
@ -88,6 +88,7 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
|
|||
|
||||
return res;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
if (e instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseException(
|
||||
Prisma.PrismaClientKnownRequestError.name,
|
||||
|
|
Loading…
Reference in New Issue