diff --git a/api/src/modules/eudr-alerts/alerts-query-builder/big-query-alerts-query.builder.ts b/api/src/modules/eudr-alerts/alerts-query-builder/big-query-alerts-query.builder.ts index 0c622c9d6..b708a09c9 100644 --- a/api/src/modules/eudr-alerts/alerts-query-builder/big-query-alerts-query.builder.ts +++ b/api/src/modules/eudr-alerts/alerts-query-builder/big-query-alerts-query.builder.ts @@ -1,7 +1,7 @@ import { SelectQueryBuilder } from 'typeorm'; import { AlertsOutput } from 'modules/eudr-alerts/dto/alerts-output.dto'; -import { GetEUDRAlertsDto } from 'modules/eudr-alerts/dto/get-alerts.dto'; import { Query } from '@google-cloud/bigquery'; +import { GetEUDRAlertsDto } from 'modules/eudr-alerts/dto/get-alerts.dto'; export class BigQueryAlertsQueryBuilder { queryBuilder: SelectQueryBuilder; @@ -51,6 +51,8 @@ export class BigQueryAlertsQueryBuilder { this.queryBuilder.limit(this.dto?.limit); const [query, params] = this.queryBuilder.getQueryAndParameters(); + console.log('query', query); + console.log('params', params); return this.parseToBigQuery(query, params); } @@ -76,7 +78,7 @@ export class BigQueryAlertsQueryBuilder { addAlertDateRange(): void { this.queryBuilder.andWhere( - 'DATE(alertdate) BETWEEN :startAlertDate AND :endAlertDate', + 'DATE(alertdate) BETWEEN DATE(:startAlertDate) AND DATE(:endAlertDate)', { startAlertDate: this.dto?.startAlertDate, endAlertDate: this.dto?.endAlertDate, diff --git a/api/src/modules/eudr-alerts/alerts.repository.ts b/api/src/modules/eudr-alerts/alerts.repository.ts index ca611ebab..7d6ada2c6 100644 --- a/api/src/modules/eudr-alerts/alerts.repository.ts +++ b/api/src/modules/eudr-alerts/alerts.repository.ts @@ -13,7 +13,6 @@ import { DataSource, SelectQueryBuilder } from 'typeorm'; import { AlertsOutput } from 'modules/eudr-alerts/dto/alerts-output.dto'; import { EUDRAlertDates, - GetEUDRAlertDatesDto, IEUDRAlertsRepository, } from 'modules/eudr-alerts/eudr.repositoty.interface'; import { GetEUDRAlertsDto } from 'modules/eudr-alerts/dto/get-alerts.dto'; @@ -52,6 +51,23 @@ export class AlertsRepository implements IEUDRAlertsRepository { queryBuilder.addSelect('alertconfidence', 'alertConfidence'); queryBuilder.addSelect('year', 'alertYear'); queryBuilder.addSelect('alertcount', 'alertCount'); + return this.query(queryBuilder, dto); + } + + async getDates(dto: GetEUDRAlertsDto): Promise { + const queryBuilder: SelectQueryBuilder = + this.dataSource.createQueryBuilder(); + queryBuilder.from(this.baseDataset, 'alerts'); + queryBuilder.select('alertdate', 'alertDate'); + queryBuilder.orderBy('alertdate', 'ASC'); + queryBuilder.groupBy('alertdate'); + return this.query(queryBuilder, dto); + } + + private async query( + queryBuilder: SelectQueryBuilder, + dto?: GetEUDRAlertsDto, + ): Promise { try { const response: SimpleQueryRowsResponse = await this.bigQueryClient.query( this.buildQuery(queryBuilder, dto), @@ -69,10 +85,6 @@ export class AlertsRepository implements IEUDRAlertsRepository { } } - getDates(dto: GetEUDRAlertDatesDto): Promise { - return [] as any; - } - private buildQuery( queryBuilder: SelectQueryBuilder, dto?: GetEUDRAlertsDto, diff --git a/api/src/modules/eudr-alerts/dto/alerts-output.dto.ts b/api/src/modules/eudr-alerts/dto/alerts-output.dto.ts index 824e5785a..a66b22516 100644 --- a/api/src/modules/eudr-alerts/dto/alerts-output.dto.ts +++ b/api/src/modules/eudr-alerts/dto/alerts-output.dto.ts @@ -1,8 +1,8 @@ -import { GeoJSON } from 'geojson'; - export type AlertsOutput = { alertCount: boolean; - date: Date; + alertDate: { + value: Date | string; + }; year: number; alertConfidence: 'low' | 'medium' | 'high' | 'very high'; }; diff --git a/api/src/modules/eudr-alerts/dto/get-alerts.dto.ts b/api/src/modules/eudr-alerts/dto/get-alerts.dto.ts index 77f3e295e..5b6699caa 100644 --- a/api/src/modules/eudr-alerts/dto/get-alerts.dto.ts +++ b/api/src/modules/eudr-alerts/dto/get-alerts.dto.ts @@ -1,8 +1,8 @@ +import { ApiPropertyOptional } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { IsArray, IsDate, - IsEnum, IsInt, IsNumber, IsOptional, @@ -10,21 +10,25 @@ import { } from 'class-validator'; export class GetEUDRAlertsDto { + @ApiPropertyOptional() @IsOptional() @IsArray() @IsUUID('4', { each: true }) supplierIds: string[]; + @ApiPropertyOptional() @IsOptional() @IsArray() @IsUUID('4', { each: true }) geoRegionIds: string[]; + @ApiPropertyOptional() @IsOptional() @IsNumber() @Type(() => Number) startYear: number; + @ApiPropertyOptional() @IsOptional() @IsNumber() @Type(() => Number) @@ -32,16 +36,19 @@ export class GetEUDRAlertsDto { alertConfidence: 'high' | 'medium' | 'low'; + @ApiPropertyOptional() @IsOptional() @IsDate() @Type(() => Date) startAlertDate: Date; + @ApiPropertyOptional() @IsOptional() @IsDate() @Type(() => Date) endAlertDate: Date; + @ApiPropertyOptional() @IsOptional() @IsInt() limit: number = 1000; diff --git a/api/src/modules/eudr-alerts/eudr.controller.ts b/api/src/modules/eudr-alerts/eudr.controller.ts index d45b8eeaa..01d8e7ec5 100644 --- a/api/src/modules/eudr-alerts/eudr.controller.ts +++ b/api/src/modules/eudr-alerts/eudr.controller.ts @@ -2,7 +2,6 @@ import { Controller, Get, Query, - Res, UseInterceptors, ValidationPipe, } from '@nestjs/common'; @@ -10,6 +9,7 @@ import { ApiForbiddenResponse, ApiOkResponse, ApiOperation, + ApiTags, ApiUnauthorizedResponse, } from '@nestjs/swagger'; import { Response } from 'express'; @@ -34,7 +34,9 @@ import { JSONAPIQueryParams } from 'decorators/json-api-parameters.decorator'; import { GetEUDRGeoRegions } from 'modules/geo-regions/dto/get-geo-region.dto'; import { EudrService } from 'modules/eudr-alerts/eudr.service'; import { GetEUDRAlertsDto } from 'modules/eudr-alerts/dto/get-alerts.dto'; +import { EUDRAlertDates } from 'modules/eudr-alerts/eudr.repositoty.interface'; +@ApiTags('EUDR') @Controller('/api/v1/eudr') export class EudrController { constructor( @@ -140,6 +142,22 @@ export class EudrController { return this.geoRegionsService.serialize(results); } + @ApiOperation({ + description: 'Get EUDR alerts dates', + }) + @ApiOkResponse({ + type: EUDRAlertDates, + isArray: true, + }) + @ApiUnauthorizedResponse() + @ApiForbiddenResponse() + @Get('/dates') + async getAlertDates( + @Query(ValidationPipe) dto: GetEUDRAlertsDto, + ): Promise { + return this.eudrAlertsService.getDates(dto); + } + @Get('/alerts') async getAlerts(@Query(ValidationPipe) dto: GetEUDRAlertsDto): Promise { return this.eudrAlertsService.getAlerts(dto); diff --git a/api/src/modules/eudr-alerts/eudr.repositoty.interface.ts b/api/src/modules/eudr-alerts/eudr.repositoty.interface.ts index dfd1c9662..eda3a10c6 100644 --- a/api/src/modules/eudr-alerts/eudr.repositoty.interface.ts +++ b/api/src/modules/eudr-alerts/eudr.repositoty.interface.ts @@ -1,19 +1,19 @@ import { GetEUDRAlertsDto } from 'modules/eudr-alerts/dto/get-alerts.dto'; import { AlertsOutput } from 'modules/eudr-alerts/dto/alerts-output.dto'; +import { ApiProperty } from '@nestjs/swagger'; -export class GetEUDRAlertDatesDto { - startDate: string; - endDate: string; +class DateValue { + @ApiProperty() + value: Date | string; } -export type EUDRAlertDates = { - alertDate: { - value: Date | string; - }; -}; +export class EUDRAlertDates { + @ApiProperty() + alertDate: DateValue; +} export interface IEUDRAlertsRepository { getAlerts(dto?: GetEUDRAlertsDto): Promise; - getDates(dto: GetEUDRAlertDatesDto): Promise; + getDates(dto: GetEUDRAlertsDto): Promise; } diff --git a/api/src/modules/eudr-alerts/eudr.service.ts b/api/src/modules/eudr-alerts/eudr.service.ts index 3d0a232f7..06e909bf1 100644 --- a/api/src/modules/eudr-alerts/eudr.service.ts +++ b/api/src/modules/eudr-alerts/eudr.service.ts @@ -1,7 +1,10 @@ import { Inject, Injectable } from '@nestjs/common'; import { GetEUDRAlertsDto } from 'modules/eudr-alerts/dto/get-alerts.dto'; import { AlertsOutput } from 'modules/eudr-alerts/dto/alerts-output.dto'; -import { IEUDRAlertsRepository } from 'modules/eudr-alerts/eudr.repositoty.interface'; +import { + EUDRAlertDates, + IEUDRAlertsRepository, +} from 'modules/eudr-alerts/eudr.repositoty.interface'; @Injectable() export class EudrService { @@ -13,4 +16,8 @@ export class EudrService { async getAlerts(dto: GetEUDRAlertsDto): Promise { return this.alertsRepository.getAlerts(dto); } + + async getDates(dto: GetEUDRAlertsDto): Promise { + return this.alertsRepository.getDates(dto); + } } diff --git a/api/test/utils/application-manager.ts b/api/test/utils/application-manager.ts index 964c52b54..61dd9fb57 100644 --- a/api/test/utils/application-manager.ts +++ b/api/test/utils/application-manager.ts @@ -10,7 +10,6 @@ import { Type } from '@nestjs/common/interfaces'; import { TestingModule } from '@nestjs/testing/testing-module'; import { isUndefined } from 'lodash'; import { MockAlertRepository, MockEmailService } from './service-mocks'; -import { IEUDRAlertsRepositoryToken } from '../../src/modules/eudr-alerts/eudr.module'; import { IEmailServiceToken } from '../../src/modules/notifications/notifications.module'; import { AlertsRepository } from 'modules/eudr-alerts/alerts.repository'; @@ -48,7 +47,7 @@ export default class ApplicationManager { }) .overrideProvider(IEmailServiceToken) .useClass(MockEmailService) - .overrideProvider(AlertsRepository) + .overrideProvider('IEUDRAlertsRepository') .useClass(MockAlertRepository); ApplicationManager.testApplication.moduleFixture = diff --git a/api/test/utils/service-mocks.ts b/api/test/utils/service-mocks.ts index 1b393ae9b..45cc6dc31 100644 --- a/api/test/utils/service-mocks.ts +++ b/api/test/utils/service-mocks.ts @@ -5,7 +5,6 @@ import { import { Logger } from '@nestjs/common'; import { EUDRAlertDates, - GetEUDRAlertDatesDto, IEUDRAlertsRepository, } from 'modules/eudr-alerts/eudr.repositoty.interface'; @@ -28,7 +27,7 @@ export class MockAlertRepository implements IEUDRAlertsRepository { }); } - getDates(dto: GetEUDRAlertDatesDto): Promise { + getDates(): Promise { return new Promise((resolve) => { resolve([]); });