find territories for a point

This commit is contained in:
sbriat 2023-02-06 16:12:40 +01:00
parent a743fefe94
commit 1da111bba9
10 changed files with 37 additions and 10 deletions

1
package-lock.json generated
View File

@ -23,6 +23,7 @@
"@nestjs/microservices": "^9.3.2", "@nestjs/microservices": "^9.3.2",
"@nestjs/platform-express": "^9.0.0", "@nestjs/platform-express": "^9.0.0",
"@prisma/client": "^4.9.0", "@prisma/client": "^4.9.0",
"cache-manager": "^5.1.5",
"cache-manager-ioredis-yet": "^1.1.0", "cache-manager-ioredis-yet": "^1.1.0",
"class-transformer": "^0.5.1", "class-transformer": "^0.5.1",
"class-validator": "^0.14.0", "class-validator": "^0.14.0",

View File

@ -41,6 +41,7 @@
"@nestjs/microservices": "^9.3.2", "@nestjs/microservices": "^9.3.2",
"@nestjs/platform-express": "^9.0.0", "@nestjs/platform-express": "^9.0.0",
"@prisma/client": "^4.9.0", "@prisma/client": "^4.9.0",
"cache-manager": "^5.1.5",
"cache-manager-ioredis-yet": "^1.1.0", "cache-manager-ioredis-yet": "^1.1.0",
"class-transformer": "^0.5.1", "class-transformer": "^0.5.1",
"class-validator": "^0.14.0", "class-validator": "^0.14.0",

View File

@ -1,5 +1,6 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { PrismaClientKnownRequestError } from '@prisma/client/runtime'; import { PrismaClientKnownRequestError } from '@prisma/client/runtime';
import { Point } from '../../domain/point.type';
import { DatabaseException } from '../../exceptions/database.exception'; import { DatabaseException } from '../../exceptions/database.exception';
import { ICollection } from '../../interfaces/collection.interface'; import { ICollection } from '../../interfaces/collection.interface';
import { IRepository } from '../../interfaces/repository.interface'; import { IRepository } from '../../interfaces/repository.interface';
@ -182,4 +183,13 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
} }
} }
} }
async findForPoint(point: Point): Promise<ICollection<T>> {
const strPoint = `SELECT uuid, name FROM ${this._model} WHERE ST_Intersects('POINT(${point.lon} ${point.lat})',shape) = true`;
const territories: Array<T> = await this._prisma.$queryRawUnsafe(strPoint);
return Promise.resolve({
data: territories,
total: territories.length,
});
}
} }

View File

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

View File

@ -32,7 +32,9 @@ export class TerritoriesController {
@GrpcMethod('TerritoriesService', 'FindForPoint') @GrpcMethod('TerritoriesService', 'FindForPoint')
@UseInterceptors(CacheInterceptor) @UseInterceptors(CacheInterceptor)
@CacheKey('TerritoriesServiceFindForPoint') @CacheKey('TerritoriesServiceFindForPoint')
async findAll(data: FindForPointRequest): Promise<ICollection<Territory>> { async findForPoint(
data: FindForPointRequest,
): Promise<ICollection<Territory>> {
const territoryCollection = await this._queryBus.execute( const territoryCollection = await this._queryBus.execute(
new FindForPointQuery(data), new FindForPointQuery(data),
); );

View File

@ -13,6 +13,7 @@ message Point {
message Territories { message Territories {
repeated Territory data = 1; repeated Territory data = 1;
int32 total = 2;
} }
message Territory { message Territory {

View File

@ -0,0 +1,9 @@
export class Point {
lon: number;
lat: number;
constructor(lon: number, lat: number) {
this.lon = lon;
this.lat = lat;
}
}

View File

@ -3,6 +3,7 @@ import { ICollection } from 'src/modules/database/src/interfaces/collection.inte
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository'; import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
import { FindForPointQuery } from '../../queries/find-for-point.query'; import { FindForPointQuery } from '../../queries/find-for-point.query';
import { Territory } from '../entities/territory'; import { Territory } from '../entities/territory';
import { Point } from '../entities/point';
@QueryHandler(FindForPointQuery) @QueryHandler(FindForPointQuery)
export class FindForPointUseCase { export class FindForPointUseCase {
@ -11,9 +12,8 @@ export class FindForPointUseCase {
async execute( async execute(
findForPointQuery: FindForPointQuery, findForPointQuery: FindForPointQuery,
): Promise<ICollection<Territory>> { ): Promise<ICollection<Territory>> {
return this._repository.findAll(1, 999999, { return this._repository.findForPoint(
lon: findForPointQuery.lon, new Point(findForPointQuery.point.lon, findForPointQuery.point.lat),
lat: findForPointQuery.lat, );
});
} }
} }

View File

@ -1,11 +1,10 @@
import { FindForPointRequest } from '../domain/dtos/find-for-point.request'; import { FindForPointRequest } from '../domain/dtos/find-for-point.request';
import { Point } from '../domain/entities/point';
export class FindForPointQuery { export class FindForPointQuery {
lon: number; point: Point;
lat: number;
constructor(findForPointRequest?: FindForPointRequest) { constructor(findForPointRequest?: FindForPointRequest) {
this.lon = findForPointRequest.lon; this.point = new Point(findForPointRequest.lon, findForPointRequest.lat);
this.lat = findForPointRequest.lat;
} }
} }

View File

@ -25,7 +25,7 @@ const mockTerritories = [
const mockTerritoriesRepository = { const mockTerritoriesRepository = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
findAll: jest.fn().mockImplementation((query?: FindForPointQuery) => { findForPoint: jest.fn().mockImplementation((query?: FindForPointQuery) => {
return Promise.resolve(mockTerritories); return Promise.resolve(mockTerritories);
}), }),
}; };