basic crud

This commit is contained in:
sbriat
2023-02-07 14:06:24 +01:00
parent 1da111bba9
commit 5b63d8ba1a
34 changed files with 1014 additions and 96 deletions

View File

@@ -0,0 +1,19 @@
import { AutoMap } from '@automapper/classes';
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
export class CreateTerritoryRequest {
@IsString()
@IsOptional()
@AutoMap()
uuid?: string;
@IsString()
@IsNotEmpty()
@AutoMap()
name: string;
@IsString()
@IsNotEmpty()
@AutoMap()
shape: string;
}

View File

@@ -1,6 +1,6 @@
import { IsNotEmpty, IsNumber } from 'class-validator';
export class FindForPointRequest {
export class FindAllTerritoriesForPointRequest {
@IsNumber()
@IsNotEmpty()
lon: number;

View File

@@ -0,0 +1,11 @@
import { IsInt, IsOptional } from 'class-validator';
export class FindAllTerritoriesRequest {
@IsInt()
@IsOptional()
page?: number;
@IsInt()
@IsOptional()
perPage?: number;
}

View File

@@ -0,0 +1,7 @@
import { IsNotEmpty, IsString } from 'class-validator';
export class FindTerritoryByUuidRequest {
@IsString()
@IsNotEmpty()
uuid: string;
}

View File

@@ -0,0 +1,19 @@
import { AutoMap } from '@automapper/classes';
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
export class UpdateTerritoryRequest {
@IsString()
@IsNotEmpty()
@AutoMap()
uuid: string;
@IsString()
@IsOptional()
@AutoMap()
name?: string;
@IsString()
@IsOptional()
@AutoMap()
shape?: string;
}

View File

@@ -6,4 +6,7 @@ export class Territory {
@AutoMap()
name: string;
@AutoMap()
shape: string;
}

View File

@@ -0,0 +1,50 @@
import { Mapper } from '@automapper/core';
import { InjectMapper } from '@automapper/nestjs';
import { CommandHandler } from '@nestjs/cqrs';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
import { CreateTerritoryCommand } from '../../commands/create-territory.command';
import { TerritoryMessager } from '../../adapters/secondaries/territory.messager';
import { Territory } from '../entities/territory';
import { CreateTerritoryRequest } from '../dtos/create-territory.request';
@CommandHandler(CreateTerritoryCommand)
export class CreateTerritoryUseCase {
constructor(
private readonly _repository: TerritoriesRepository,
private readonly _territoryMessager: TerritoryMessager,
private readonly _loggingMessager: LoggingMessager,
@InjectMapper() private readonly _mapper: Mapper,
) {}
async execute(command: CreateTerritoryCommand): Promise<Territory> {
const entity = this._mapper.map(
command.createTerritoryRequest,
CreateTerritoryRequest,
Territory,
);
try {
const territory = await this._repository.create(entity);
this._territoryMessager.publish('create', JSON.stringify(territory));
this._loggingMessager.publish(
'territory.create.info',
JSON.stringify(territory),
);
return territory;
} catch (error) {
let key = 'territory.create.crit';
if (error.message.includes('Already exists')) {
key = 'territory.create.warning';
}
this._loggingMessager.publish(
key,
JSON.stringify({
command,
error,
}),
);
throw error;
}
}
}

View File

@@ -0,0 +1,39 @@
import { CommandHandler } from '@nestjs/cqrs';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
import { TerritoryMessager } from '../../adapters/secondaries/territory.messager';
import { DeleteTerritoryCommand } from '../../commands/delete-territory.command';
import { Territory } from '../entities/territory';
@CommandHandler(DeleteTerritoryCommand)
export class DeleteTerritoryUseCase {
constructor(
private readonly _repository: TerritoriesRepository,
private readonly _territoryMessager: TerritoryMessager,
private readonly _loggingMessager: LoggingMessager,
) {}
async execute(command: DeleteTerritoryCommand): Promise<Territory> {
try {
const territory = await this._repository.delete(command.uuid);
this._territoryMessager.publish(
'delete',
JSON.stringify({ uuid: territory.uuid }),
);
this._loggingMessager.publish(
'territory.delete.info',
JSON.stringify({ uuid: territory.uuid }),
);
return territory;
} catch (error) {
this._loggingMessager.publish(
'territory.delete.crit',
JSON.stringify({
command,
error,
}),
);
throw error;
}
}
}

View File

@@ -1,19 +1,22 @@
import { QueryHandler } from '@nestjs/cqrs';
import { ICollection } from 'src/modules/database/src/interfaces/collection.interface';
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
import { FindForPointQuery } from '../../queries/find-for-point.query';
import { FindAllTerritoriesForPointQuery } from '../../queries/find-all-territories-for-point.query';
import { Territory } from '../entities/territory';
import { Point } from '../entities/point';
@QueryHandler(FindForPointQuery)
export class FindForPointUseCase {
@QueryHandler(FindAllTerritoriesForPointQuery)
export class FindAllTerritoriesForPointUseCase {
constructor(private readonly _repository: TerritoriesRepository) {}
async execute(
findForPointQuery: FindForPointQuery,
findAllTerritoriesForPointQuery: FindAllTerritoriesForPointQuery,
): Promise<ICollection<Territory>> {
return this._repository.findForPoint(
new Point(findForPointQuery.point.lon, findForPointQuery.point.lat),
new Point(
findAllTerritoriesForPointQuery.point.lon,
findAllTerritoriesForPointQuery.point.lat,
),
);
}
}

View File

@@ -0,0 +1,19 @@
import { QueryHandler } from '@nestjs/cqrs';
import { ICollection } from 'src/modules/database/src/interfaces/collection.interface';
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
import { FindAllTerritoriesQuery } from '../../queries/find-all-territories.query';
import { Territory } from '../entities/territory';
@QueryHandler(FindAllTerritoriesQuery)
export class FindAllTerritoriesUseCase {
constructor(private readonly _repository: TerritoriesRepository) {}
async execute(
findAllTerritoriesQuery: FindAllTerritoriesQuery,
): Promise<ICollection<Territory>> {
return this._repository.findAll(
findAllTerritoriesQuery.page,
findAllTerritoriesQuery.perPage,
);
}
}

View File

@@ -0,0 +1,35 @@
import { NotFoundException } from '@nestjs/common';
import { QueryHandler } from '@nestjs/cqrs';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
import { FindTerritoryByUuidQuery } from '../../queries/find-territory-by-uuid.query';
import { Territory } from '../entities/territory';
@QueryHandler(FindTerritoryByUuidQuery)
export class FindTerritoryByUuidUseCase {
constructor(
private readonly _repository: TerritoriesRepository,
private readonly _loggingMessager: LoggingMessager,
) {}
async execute(
findTerritoryByUuidQuery: FindTerritoryByUuidQuery,
): Promise<Territory> {
try {
const territory = await this._repository.findOneByUuid(
findTerritoryByUuidQuery.uuid,
);
if (!territory) throw new NotFoundException();
return territory;
} catch (error) {
this._loggingMessager.publish(
'territory.read.warning',
JSON.stringify({
query: findTerritoryByUuidQuery,
error,
}),
);
throw error;
}
}
}

View File

@@ -0,0 +1,52 @@
import { Mapper } from '@automapper/core';
import { InjectMapper } from '@automapper/nestjs';
import { CommandHandler } from '@nestjs/cqrs';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
import { TerritoryMessager } from '../../adapters/secondaries/territory.messager';
import { UpdateTerritoryCommand } from '../../commands/update-territory.command';
import { UpdateTerritoryRequest } from '../dtos/update-territory.request';
import { Territory } from '../entities/territory';
@CommandHandler(UpdateTerritoryCommand)
export class UpdateTerritoryUseCase {
constructor(
private readonly _repository: TerritoriesRepository,
private readonly _territoryMessager: TerritoryMessager,
private readonly _loggingMessager: LoggingMessager,
@InjectMapper() private readonly _mapper: Mapper,
) {}
async execute(command: UpdateTerritoryCommand): Promise<Territory> {
const entity = this._mapper.map(
command.updateTerritoryRequest,
UpdateTerritoryRequest,
Territory,
);
try {
const territory = await this._repository.update(
command.updateTerritoryRequest.uuid,
entity,
);
this._territoryMessager.publish(
'update',
JSON.stringify(command.updateTerritoryRequest),
);
this._loggingMessager.publish(
'territory.update.info',
JSON.stringify(command.updateTerritoryRequest),
);
return territory;
} catch (error) {
this._loggingMessager.publish(
'territory.update.crit',
JSON.stringify({
command,
error,
}),
);
throw error;
}
}
}