mirror of
https://gitlab.com/mobicoop/v3/service/matcher.git
synced 2026-01-01 14:02:39 +00:00
create ad WIP, extract geography methods to dedicated module
This commit is contained in:
@@ -2,9 +2,16 @@ import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq';
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import { AdMessagerController } from './adapters/primaries/ad-messager.controller';
|
||||
import { AdProfile } from './mappers/ad.profile';
|
||||
import { CreateAdUseCase } from './domain/usecases/create-ad.usecase';
|
||||
import { AdRepository } from './adapters/secondaries/ad.repository';
|
||||
import { DatabaseModule } from '../database/database.module';
|
||||
import { CqrsModule } from '@nestjs/cqrs';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
DatabaseModule,
|
||||
CqrsModule,
|
||||
RabbitMQModule.forRootAsync(RabbitMQModule, {
|
||||
imports: [ConfigModule],
|
||||
useFactory: async (configService: ConfigService) => ({
|
||||
@@ -18,9 +25,7 @@ import { AdMessagerController } from './adapters/primaries/ad-messager.controlle
|
||||
adCreated: {
|
||||
exchange: configService.get<string>('RMQ_EXCHANGE'),
|
||||
routingKey: 'ad.created',
|
||||
queue: `${configService.get<string>(
|
||||
'RMQ_EXCHANGE',
|
||||
)}-matcher-ad-created`,
|
||||
queue: 'matcher-ad-created',
|
||||
},
|
||||
},
|
||||
uri: configService.get<string>('RMQ_URI'),
|
||||
@@ -31,7 +36,7 @@ import { AdMessagerController } from './adapters/primaries/ad-messager.controlle
|
||||
}),
|
||||
],
|
||||
controllers: [AdMessagerController],
|
||||
providers: [],
|
||||
providers: [AdProfile, AdRepository, CreateAdUseCase],
|
||||
exports: [],
|
||||
})
|
||||
export class AdModule {}
|
||||
|
||||
@@ -1,19 +1,32 @@
|
||||
import { RabbitSubscribe } from '@golevelup/nestjs-rabbitmq';
|
||||
import { Controller } from '@nestjs/common';
|
||||
// import { Ad } from '../../domain/entities/ad';
|
||||
import { Ad } from '../../domain/entities/ad';
|
||||
import { InjectMapper } from '@automapper/nestjs';
|
||||
import { Mapper } from '@automapper/core';
|
||||
import { CommandBus } from '@nestjs/cqrs';
|
||||
import { CreateAdCommand } from '../../commands/create-ad.command';
|
||||
import { AdPresenter } from './ad.presenter';
|
||||
import { CreateAdRequest } from '../../domain/dtos/create-ad.request';
|
||||
|
||||
@Controller()
|
||||
export class AdMessagerController {
|
||||
constructor(
|
||||
private readonly _commandBus: CommandBus,
|
||||
@InjectMapper() private readonly _mapper: Mapper,
|
||||
) {}
|
||||
|
||||
@RabbitSubscribe({
|
||||
name: 'adCreated',
|
||||
})
|
||||
public adCreatedHandler(message: string) {
|
||||
console.log(JSON.parse(message));
|
||||
// try {
|
||||
// const createdAd: Ad = JSON.parse(message);
|
||||
// console.log(createdAd);
|
||||
// } catch (e) {
|
||||
// console.log('error', e);
|
||||
// }
|
||||
async adCreatedHandler(message: string): Promise<AdPresenter> {
|
||||
try {
|
||||
const createAdRequest: CreateAdRequest = JSON.parse(message);
|
||||
const ad: Ad = await this._commandBus.execute(
|
||||
new CreateAdCommand(createAdRequest),
|
||||
);
|
||||
return this._mapper.map(ad, Ad, AdPresenter);
|
||||
} catch (e) {
|
||||
console.log('error', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
src/modules/ad/adapters/primaries/ad.presenter.ts
Normal file
6
src/modules/ad/adapters/primaries/ad.presenter.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { AutoMap } from '@automapper/classes';
|
||||
|
||||
export class AdPresenter {
|
||||
@AutoMap()
|
||||
uuid: string;
|
||||
}
|
||||
79
src/modules/ad/adapters/secondaries/ad.repository.ts
Normal file
79
src/modules/ad/adapters/secondaries/ad.repository.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { MatcherRepository } from '../../../database/src/domain/matcher-repository';
|
||||
import { Ad } from '../../domain/entities/ad';
|
||||
import { DatabaseException } from '../../../database/src/exceptions/database.exception';
|
||||
|
||||
@Injectable()
|
||||
export class AdRepository extends MatcherRepository<Ad> {
|
||||
protected _model = 'ad';
|
||||
|
||||
async createAd(ad: Partial<Ad>): Promise<Ad> {
|
||||
try {
|
||||
const affectedRowNumber = await this.createWithFields(
|
||||
this.createFields(ad),
|
||||
);
|
||||
if (affectedRowNumber == 1) {
|
||||
return this.findOneByUuid(ad.uuid);
|
||||
}
|
||||
throw new DatabaseException();
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private createFields(ad: Partial<Ad>): Partial<AdFields> {
|
||||
return {
|
||||
uuid: `'${ad.uuid}'`,
|
||||
driver: ad.driver ? 'true' : 'false',
|
||||
passenger: ad.passenger ? 'true' : 'false',
|
||||
frequency: ad.frequency,
|
||||
fromDate: `'${ad.fromDate}'`,
|
||||
toDate: `'${ad.toDate}'`,
|
||||
monTime: `'${ad.monTime}'`,
|
||||
tueTime: `'${ad.tueTime}'`,
|
||||
wedTime: `'${ad.wedTime}'`,
|
||||
thuTime: `'${ad.thuTime}'`,
|
||||
friTime: `'${ad.friTime}'`,
|
||||
satTime: `'${ad.satTime}'`,
|
||||
sunTime: `'${ad.sunTime}'`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
type AdFields = {
|
||||
uuid: string;
|
||||
driver: string;
|
||||
passenger: string;
|
||||
frequency: number;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
monTime: string;
|
||||
tueTime: string;
|
||||
wedTime: string;
|
||||
thuTime: string;
|
||||
friTime: string;
|
||||
satTime: string;
|
||||
sunTime: string;
|
||||
monMargin: number;
|
||||
tueMargin: number;
|
||||
wedMargin: number;
|
||||
thuMargin: number;
|
||||
friMargin: number;
|
||||
satMargin: number;
|
||||
sunMargin: number;
|
||||
driverDuration: number;
|
||||
driverDistance: number;
|
||||
passengerDuration: number;
|
||||
passengerDistance: number;
|
||||
originType: number;
|
||||
destinationType: number;
|
||||
waypoints: string;
|
||||
direction: string;
|
||||
fwdAzimuth: number;
|
||||
backAzimuth: number;
|
||||
seatsDriver: number;
|
||||
seatsPassenger: number;
|
||||
seatsUsed: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
9
src/modules/ad/commands/create-ad.command.ts
Normal file
9
src/modules/ad/commands/create-ad.command.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { CreateAdRequest } from '../domain/dtos/create-ad.request';
|
||||
|
||||
export class CreateAdCommand {
|
||||
readonly createAdRequest: CreateAdRequest;
|
||||
|
||||
constructor(request: CreateAdRequest) {
|
||||
this.createAdRequest = request;
|
||||
}
|
||||
}
|
||||
116
src/modules/ad/domain/dtos/create-ad.request.ts
Normal file
116
src/modules/ad/domain/dtos/create-ad.request.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import { AutoMap } from '@automapper/classes';
|
||||
import { IsBoolean, IsNotEmpty, IsNumber, IsString } from 'class-validator';
|
||||
|
||||
export class CreateAdRequest {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@AutoMap()
|
||||
uuid: string;
|
||||
|
||||
@IsBoolean()
|
||||
@AutoMap()
|
||||
driver: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
@AutoMap()
|
||||
passenger: boolean;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
frequency: number;
|
||||
|
||||
@IsString()
|
||||
@AutoMap()
|
||||
fromDate: string;
|
||||
|
||||
@IsString()
|
||||
@AutoMap()
|
||||
toDate: string;
|
||||
|
||||
@IsString()
|
||||
@AutoMap()
|
||||
monTime: string;
|
||||
|
||||
@IsString()
|
||||
@AutoMap()
|
||||
tueTime: string;
|
||||
|
||||
@IsString()
|
||||
@AutoMap()
|
||||
wedTime: string;
|
||||
|
||||
@IsString()
|
||||
@AutoMap()
|
||||
thuTime: string;
|
||||
|
||||
@IsString()
|
||||
@AutoMap()
|
||||
friTime: string;
|
||||
|
||||
@IsString()
|
||||
@AutoMap()
|
||||
satTime: string;
|
||||
|
||||
@IsString()
|
||||
@AutoMap()
|
||||
sunTime: string;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
monMargin: number;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
tueMargin: number;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
wedMargin: number;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
thuMargin: number;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
friMargin: number;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
satMargin: number;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
sunMargin: number;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
originType: number;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
destinationType: number;
|
||||
|
||||
@AutoMap()
|
||||
waypoints: [];
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
seatsDriver: number;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
seatsPassenger: number;
|
||||
|
||||
@IsNumber()
|
||||
@AutoMap()
|
||||
seatsUsed: number;
|
||||
|
||||
@IsString()
|
||||
@AutoMap()
|
||||
createdAt: string;
|
||||
|
||||
@IsString()
|
||||
@AutoMap()
|
||||
updatedAt: string;
|
||||
}
|
||||
@@ -4,38 +4,105 @@ export class Ad {
|
||||
@AutoMap()
|
||||
uuid: string;
|
||||
|
||||
@AutoMap()
|
||||
driver: boolean;
|
||||
|
||||
@AutoMap()
|
||||
passenger: boolean;
|
||||
|
||||
@AutoMap()
|
||||
frequency: number;
|
||||
|
||||
@AutoMap()
|
||||
fromDate: string;
|
||||
|
||||
@AutoMap()
|
||||
toDate: string;
|
||||
|
||||
@AutoMap()
|
||||
monTime: string;
|
||||
|
||||
@AutoMap()
|
||||
tueTime: string;
|
||||
|
||||
@AutoMap()
|
||||
wedTime: string;
|
||||
|
||||
@AutoMap()
|
||||
thuTime: string;
|
||||
|
||||
@AutoMap()
|
||||
friTime: string;
|
||||
|
||||
@AutoMap()
|
||||
satTime: string;
|
||||
|
||||
@AutoMap()
|
||||
sunTime: string;
|
||||
|
||||
@AutoMap()
|
||||
monMargin: number;
|
||||
|
||||
@AutoMap()
|
||||
tueMargin: number;
|
||||
|
||||
@AutoMap()
|
||||
wedMargin: number;
|
||||
|
||||
@AutoMap()
|
||||
thuMargin: number;
|
||||
|
||||
@AutoMap()
|
||||
friMargin: number;
|
||||
|
||||
@AutoMap()
|
||||
satMargin: number;
|
||||
|
||||
@AutoMap()
|
||||
sunMargin: number;
|
||||
|
||||
@AutoMap()
|
||||
driverDuration: number;
|
||||
|
||||
@AutoMap()
|
||||
driverDistance: number;
|
||||
|
||||
@AutoMap()
|
||||
passengerDuration: number;
|
||||
|
||||
@AutoMap()
|
||||
passengerDistance: number;
|
||||
|
||||
@AutoMap()
|
||||
originType: number;
|
||||
|
||||
@AutoMap()
|
||||
destinationType: number;
|
||||
|
||||
@AutoMap()
|
||||
waypoints: [];
|
||||
|
||||
@AutoMap()
|
||||
direction: string;
|
||||
|
||||
@AutoMap()
|
||||
fwdAzimuth: number;
|
||||
|
||||
@AutoMap()
|
||||
backAzimuth: number;
|
||||
|
||||
@AutoMap()
|
||||
seatsDriver: number;
|
||||
|
||||
@AutoMap()
|
||||
seatsPassenger: number;
|
||||
|
||||
@AutoMap()
|
||||
seatsUsed: number;
|
||||
|
||||
@AutoMap()
|
||||
createdAt: string;
|
||||
|
||||
@AutoMap()
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
17
src/modules/ad/domain/usecases/create-ad.usecase.ts
Normal file
17
src/modules/ad/domain/usecases/create-ad.usecase.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { CommandHandler } from '@nestjs/cqrs';
|
||||
import { CreateAdCommand } from '../../commands/create-ad.command';
|
||||
import { Ad } from '../entities/ad';
|
||||
import { AdRepository } from '../../adapters/secondaries/ad.repository';
|
||||
|
||||
@CommandHandler(CreateAdCommand)
|
||||
export class CreateAdUseCase {
|
||||
constructor(private readonly adRepository: AdRepository) {}
|
||||
|
||||
async execute(command: CreateAdCommand): Promise<Ad> {
|
||||
try {
|
||||
return await this.adRepository.createAd(command.createAdRequest);
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/modules/ad/mappers/ad.profile.ts
Normal file
18
src/modules/ad/mappers/ad.profile.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { createMap, 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';
|
||||
|
||||
@Injectable()
|
||||
export class AdProfile extends AutomapperProfile {
|
||||
constructor(@InjectMapper() mapper: Mapper) {
|
||||
super(mapper);
|
||||
}
|
||||
|
||||
override get profile() {
|
||||
return (mapper: any) => {
|
||||
createMap(mapper, Ad, AdPresenter);
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user