diff --git a/package-lock.json b/package-lock.json index b8660fb..7febf97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "@nestjs/microservices": "^9.3.2", "@nestjs/platform-express": "^9.0.0", "@prisma/client": "^4.9.0", + "cache-manager": "^5.1.5", "cache-manager-ioredis-yet": "^1.1.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", diff --git a/package.json b/package.json index c149ac0..a112e7d 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@nestjs/microservices": "^9.3.2", "@nestjs/platform-express": "^9.0.0", "@prisma/client": "^4.9.0", + "cache-manager": "^5.1.5", "cache-manager-ioredis-yet": "^1.1.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", diff --git a/src/modules/database/src/adapters/secondaries/prisma-repository.abstract.ts b/src/modules/database/src/adapters/secondaries/prisma-repository.abstract.ts index b48caf8..bf121d2 100644 --- a/src/modules/database/src/adapters/secondaries/prisma-repository.abstract.ts +++ b/src/modules/database/src/adapters/secondaries/prisma-repository.abstract.ts @@ -1,5 +1,6 @@ import { Injectable } from '@nestjs/common'; import { PrismaClientKnownRequestError } from '@prisma/client/runtime'; +import { Point } from '../../domain/point.type'; import { DatabaseException } from '../../exceptions/database.exception'; import { ICollection } from '../../interfaces/collection.interface'; import { IRepository } from '../../interfaces/repository.interface'; @@ -182,4 +183,13 @@ export abstract class PrismaRepository implements IRepository { } } } + + async findForPoint(point: Point): Promise> { + const strPoint = `SELECT uuid, name FROM ${this._model} WHERE ST_Intersects('POINT(${point.lon} ${point.lat})',shape) = true`; + const territories: Array = await this._prisma.$queryRawUnsafe(strPoint); + return Promise.resolve({ + data: territories, + total: territories.length, + }); + } } diff --git a/src/modules/database/src/domain/point.type.ts b/src/modules/database/src/domain/point.type.ts new file mode 100644 index 0000000..9bb160e --- /dev/null +++ b/src/modules/database/src/domain/point.type.ts @@ -0,0 +1,4 @@ +export type Point = { + lon: number; + lat: number; +}; diff --git a/src/modules/territories/adapters/primaries/territories.controller.ts b/src/modules/territories/adapters/primaries/territories.controller.ts index 05bb75b..9fe7d43 100644 --- a/src/modules/territories/adapters/primaries/territories.controller.ts +++ b/src/modules/territories/adapters/primaries/territories.controller.ts @@ -32,7 +32,9 @@ export class TerritoriesController { @GrpcMethod('TerritoriesService', 'FindForPoint') @UseInterceptors(CacheInterceptor) @CacheKey('TerritoriesServiceFindForPoint') - async findAll(data: FindForPointRequest): Promise> { + async findForPoint( + data: FindForPointRequest, + ): Promise> { const territoryCollection = await this._queryBus.execute( new FindForPointQuery(data), ); diff --git a/src/modules/territories/adapters/primaries/territory.proto b/src/modules/territories/adapters/primaries/territory.proto index 0989af1..7582188 100644 --- a/src/modules/territories/adapters/primaries/territory.proto +++ b/src/modules/territories/adapters/primaries/territory.proto @@ -13,6 +13,7 @@ message Point { message Territories { repeated Territory data = 1; + int32 total = 2; } message Territory { diff --git a/src/modules/territories/domain/entities/point.ts b/src/modules/territories/domain/entities/point.ts new file mode 100644 index 0000000..893dab4 --- /dev/null +++ b/src/modules/territories/domain/entities/point.ts @@ -0,0 +1,9 @@ +export class Point { + lon: number; + lat: number; + + constructor(lon: number, lat: number) { + this.lon = lon; + this.lat = lat; + } +} diff --git a/src/modules/territories/domain/usecases/find-for-point.usecase.ts b/src/modules/territories/domain/usecases/find-for-point.usecase.ts index 8f3d945..a385e39 100644 --- a/src/modules/territories/domain/usecases/find-for-point.usecase.ts +++ b/src/modules/territories/domain/usecases/find-for-point.usecase.ts @@ -3,6 +3,7 @@ import { ICollection } from 'src/modules/database/src/interfaces/collection.inte import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository'; import { FindForPointQuery } from '../../queries/find-for-point.query'; import { Territory } from '../entities/territory'; +import { Point } from '../entities/point'; @QueryHandler(FindForPointQuery) export class FindForPointUseCase { @@ -11,9 +12,8 @@ export class FindForPointUseCase { async execute( findForPointQuery: FindForPointQuery, ): Promise> { - return this._repository.findAll(1, 999999, { - lon: findForPointQuery.lon, - lat: findForPointQuery.lat, - }); + return this._repository.findForPoint( + new Point(findForPointQuery.point.lon, findForPointQuery.point.lat), + ); } } diff --git a/src/modules/territories/queries/find-for-point.query.ts b/src/modules/territories/queries/find-for-point.query.ts index 561ff34..343bc6e 100644 --- a/src/modules/territories/queries/find-for-point.query.ts +++ b/src/modules/territories/queries/find-for-point.query.ts @@ -1,11 +1,10 @@ import { FindForPointRequest } from '../domain/dtos/find-for-point.request'; +import { Point } from '../domain/entities/point'; export class FindForPointQuery { - lon: number; - lat: number; + point: Point; constructor(findForPointRequest?: FindForPointRequest) { - this.lon = findForPointRequest.lon; - this.lat = findForPointRequest.lat; + this.point = new Point(findForPointRequest.lon, findForPointRequest.lat); } } diff --git a/src/modules/territories/tests/unit/find-for-point.usecase.spec.ts b/src/modules/territories/tests/unit/find-for-point.usecase.spec.ts index ea7777f..6f6bc2a 100644 --- a/src/modules/territories/tests/unit/find-for-point.usecase.spec.ts +++ b/src/modules/territories/tests/unit/find-for-point.usecase.spec.ts @@ -25,7 +25,7 @@ const mockTerritories = [ const mockTerritoriesRepository = { // 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); }), };