From 82cddae001618d58e4def196ac443ee5da6cc780 Mon Sep 17 00:00:00 2001 From: Ignas-rgb <61393113+Ignas-rgb@users.noreply.github.com> Date: Fri, 2 Feb 2024 16:33:17 +0200 Subject: [PATCH 01/10] Update endpoints to allow forest data posting and fetching Endpoints, DTOs updated with 'type' parameter, to specify what kind of reports is being created/fetched --- src/admin/admin.controller.ts | 3 ++- src/admin/admin.service.ts | 4 ++-- src/report/dto/create-report.dto.ts | 3 +++ src/report/report.controller.ts | 11 +++++++---- src/report/report.service.ts | 8 ++++---- src/repositories/reports/report.repository.ts | 13 +++++++------ 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/admin/admin.controller.ts b/src/admin/admin.controller.ts index e8f0777..39c6da4 100644 --- a/src/admin/admin.controller.ts +++ b/src/admin/admin.controller.ts @@ -47,10 +47,11 @@ export class AdminController { @Get('/reports') async getAllReports( @Query('isDeleted', ParseBoolPipe) isDeleted: boolean, + @Query('type') type: string, ): Promise { return isDeleted ? await this.adminService.getAllDeletedReports() - : await this.adminService.getAllReports(); + : await this.adminService.getAllReports(type); } @ApiOkResponse({ diff --git a/src/admin/admin.service.ts b/src/admin/admin.service.ts index 20d41a7..4c0dd80 100644 --- a/src/admin/admin.service.ts +++ b/src/admin/admin.service.ts @@ -22,8 +22,8 @@ export class AdminService { private readonly reportRepository: ReportRepository, ) {} - async getAllReports(): Promise { - const reports = await this.reportRepository.getAllReports(); + async getAllReports(type: string): Promise { + const reports = await this.reportRepository.getAllReports(type); return reports.map(AdminService.docToFullReport); } diff --git a/src/report/dto/create-report.dto.ts b/src/report/dto/create-report.dto.ts index 9f91684..9b59269 100644 --- a/src/report/dto/create-report.dto.ts +++ b/src/report/dto/create-report.dto.ts @@ -11,6 +11,9 @@ export class CreateReportDto { @IsLatitude() latitude: number; + @IsNotEmpty() + type: string; + @IsEmail() email: string; diff --git a/src/report/report.controller.ts b/src/report/report.controller.ts index 9d20c2d..e72561c 100644 --- a/src/report/report.controller.ts +++ b/src/report/report.controller.ts @@ -6,6 +6,7 @@ import { Param, ParseIntPipe, Post, + Query, UploadedFiles, UseInterceptors, } from '@nestjs/common'; @@ -46,8 +47,8 @@ export class ReportController { type: [PublicReportDto], }) @Get() - getAllPublicReports(): Promise { - return this.reportService.getAllVisibleReports(); + getAllPublicReports(@Query('type') type: string): Promise { + return this.reportService.getAllVisibleReports(type); } @ApiOkResponse({ @@ -55,8 +56,10 @@ export class ReportController { type: ReportStatisticsDto, }) @Get('/statistics') - getReportStatistics(): Promise { - return this.reportService.getReportStatistics(); + getReportStatistics( + @Query('type') type: string, + ): Promise { + return this.reportService.getReportStatistics(type); } @Get('/:refId') diff --git a/src/report/report.service.ts b/src/report/report.service.ts index 77ab2a7..4c8de87 100644 --- a/src/report/report.service.ts +++ b/src/report/report.service.ts @@ -8,8 +8,8 @@ import { ReportStatisticsDto } from './dto/report-statistics.dto'; export class ReportService { constructor(private readonly reportRepository: ReportRepository) {} - async getAllVisibleReports(): Promise { - const reports = await this.reportRepository.getVisibleReports(); + async getAllVisibleReports(type: string): Promise { + const reports = await this.reportRepository.getVisibleReports(type); return reports.map(ReportService.docToPublicReport); } @@ -30,8 +30,8 @@ export class ReportService { return ReportService.docToPublicReport(report); } - async getReportStatistics(): Promise { - const stats = await this.reportRepository.getVisibleStatusCounts(); + async getReportStatistics(type: string): Promise { + const stats = await this.reportRepository.getVisibleStatusCounts(type); return ReportService.docToReportStatistics(stats); } diff --git a/src/repositories/reports/report.repository.ts b/src/repositories/reports/report.repository.ts index 3cdfcb6..6abf560 100644 --- a/src/repositories/reports/report.repository.ts +++ b/src/repositories/reports/report.repository.ts @@ -14,16 +14,16 @@ export class ReportRepository { private cloudinary: CloudinaryService, ) {} - async getVisibleReports(): Promise { + async getVisibleReports(type: string): Promise { return await this.reportModel - .find({ isVisible: true, isDeleted: false }) + .find({ isVisible: true, isDeleted: false, type: type }) .sort({ reportDate: -1 }) .exec(); } - async getAllReports(): Promise { + async getAllReports(type: string): Promise { return await this.reportModel - .find({ isDeleted: false }) + .find({ isDeleted: false, type: type }) .sort({ reportDate: -1 }) .exec(); } @@ -39,13 +39,14 @@ export class ReportRepository { return await this.reportModel.findOne({ refId: refId }).exec(); } - async getVisibleStatusCounts(): Promise { + async getVisibleStatusCounts(type: string): Promise { return await this.reportModel .aggregate([ { $match: { isDeleted: false, isVisible: true, + type: type, }, }, { @@ -72,7 +73,7 @@ export class ReportRepository { const reportCount = reports.length; const newReport = new this.reportModel({ name: createReport.name, - type: 'trash', + type: createReport.type, refId: reportCount + 1, comment: ' ', reportLong: createReport.longitude, From 68514062f09960d631c72757100398830d359fca Mon Sep 17 00:00:00 2001 From: Ignas-rgb <61393113+Ignas-rgb@users.noreply.github.com> Date: Thu, 8 Feb 2024 11:14:56 +0200 Subject: [PATCH 02/10] Update category fields with enums, fix database queries with user-controlled sources --- src/admin/admin.controller.ts | 9 +- src/admin/admin.service.ts | 11 +- src/admin/dto/full-dump.dto.ts | 6 +- src/admin/dto/full-report.dto.ts | 7 +- src/common/constants/enums.ts | 4 + src/dumps/dto/dump.dto.ts | 9 +- src/report/dto/create-report.dto.ts | 3 +- src/report/dto/public-report.dto.ts | 7 +- src/report/report.controller.ts | 15 ++- src/report/report.service.ts | 13 +- src/repositories/dumps/dump.repository.ts | 2 +- src/repositories/reports/report.repository.ts | 111 ++++++++++++------ 12 files changed, 128 insertions(+), 69 deletions(-) create mode 100644 src/common/constants/enums.ts diff --git a/src/admin/admin.controller.ts b/src/admin/admin.controller.ts index 39c6da4..007aa5c 100644 --- a/src/admin/admin.controller.ts +++ b/src/admin/admin.controller.ts @@ -20,6 +20,7 @@ import { ApiConsumes, ApiNotFoundResponse, ApiOkResponse, + ApiQuery, ApiTags, } from '@nestjs/swagger'; import { @@ -32,6 +33,7 @@ import { import { FilesInterceptor } from '@nestjs/platform-express'; import { JwtAuthGuard } from '../auth/jwt-auth.guard'; import { Request } from 'express'; +import { Category } from '../common/constants/enums'; @Controller('admin') @ApiTags('admin') @@ -44,14 +46,15 @@ export class AdminController { description: 'All reports have been successfully found', type: [FullReportDto], }) + @ApiQuery({ name: 'category', enum: Category, required: false }) @Get('/reports') async getAllReports( @Query('isDeleted', ParseBoolPipe) isDeleted: boolean, - @Query('type') type: string, + @Query('category') category: Category, ): Promise { return isDeleted - ? await this.adminService.getAllDeletedReports() - : await this.adminService.getAllReports(type); + ? await this.adminService.getAllDeletedReports(category) + : await this.adminService.getAllReports(category); } @ApiOkResponse({ diff --git a/src/admin/admin.service.ts b/src/admin/admin.service.ts index 4c0dd80..8edb2ba 100644 --- a/src/admin/admin.service.ts +++ b/src/admin/admin.service.ts @@ -14,6 +14,7 @@ import { HistoryEditsDto } from './dto/history-edits.dto'; import { StatusRecordsDto } from '../report/dto'; import { UpdateReportDto } from './dto'; import { Dump } from '../repositories/dumps/schemas'; +import { Category } from '../common/constants/enums'; @Injectable() export class AdminService { @@ -22,8 +23,8 @@ export class AdminService { private readonly reportRepository: ReportRepository, ) {} - async getAllReports(type: string): Promise { - const reports = await this.reportRepository.getAllReports(type); + async getAllReports(category: Category): Promise { + const reports = await this.reportRepository.getAllReports(category); return reports.map(AdminService.docToFullReport); } @@ -39,8 +40,8 @@ export class AdminService { return AdminService.docToFullDump(dump); } - async getAllDeletedReports(): Promise { - const reports = await this.reportRepository.getDeletedReports(); + async getAllDeletedReports(category?: Category): Promise { + const reports = await this.reportRepository.getDeletedReports(category); return reports.map(AdminService.docToFullReport); } @@ -93,7 +94,7 @@ export class AdminService { return new FullReportDto( report.refId, report.name, - report.type, + report.type as Category, report.refId, report.reportLong, report.reportLat, diff --git a/src/admin/dto/full-dump.dto.ts b/src/admin/dto/full-dump.dto.ts index 8cb712d..b8096fa 100644 --- a/src/admin/dto/full-dump.dto.ts +++ b/src/admin/dto/full-dump.dto.ts @@ -9,7 +9,7 @@ export class FullDumpDto { name: string; @ApiProperty() - type: string; + category: string; @ApiProperty({ format: 'double' }) longitude: number; @@ -36,7 +36,7 @@ export class FullDumpDto { constructor( refId: string, name: string, - type: string, + category: string, longitude: number, latitude: number, isVisible: boolean, @@ -47,7 +47,7 @@ export class FullDumpDto { ) { this.refId = refId; this.name = name; - this.type = type; + this.category = category; this.longitude = longitude; this.latitude = latitude; this.isVisible = isVisible; diff --git a/src/admin/dto/full-report.dto.ts b/src/admin/dto/full-report.dto.ts index 8938d2c..18bae22 100644 --- a/src/admin/dto/full-report.dto.ts +++ b/src/admin/dto/full-report.dto.ts @@ -2,6 +2,7 @@ import { ApiProperty } from '@nestjs/swagger'; import { HistoryDataDto } from './history-data.dto'; import { StatusRecordsDto } from './status-records.dto'; import { ToBoolean } from '../../common/transform/boolean.transform'; +import { Category } from '../../common/constants/enums'; export class FullReportDto { @ApiProperty() @@ -11,7 +12,7 @@ export class FullReportDto { name: string; @ApiProperty() - type: string; + category: Category; @ApiProperty() refId: string; @@ -57,7 +58,7 @@ export class FullReportDto { constructor( _id: string, name: string, - type: string, + category: Category, refId: string, longitude: number, latitude: number, @@ -74,7 +75,7 @@ export class FullReportDto { ) { this._id = _id; this.name = name; - this.type = type; + this.category = category; this.refId = refId; this.longitude = longitude; this.latitude = latitude; diff --git a/src/common/constants/enums.ts b/src/common/constants/enums.ts new file mode 100644 index 0000000..66bb547 --- /dev/null +++ b/src/common/constants/enums.ts @@ -0,0 +1,4 @@ +export enum Category { + trash = 'trash', + forest = 'forest', +} diff --git a/src/dumps/dto/dump.dto.ts b/src/dumps/dto/dump.dto.ts index a562f6a..4b9405c 100644 --- a/src/dumps/dto/dump.dto.ts +++ b/src/dumps/dto/dump.dto.ts @@ -1,11 +1,14 @@ import { ApiProperty } from '@nestjs/swagger'; +import { IsEnum } from 'class-validator'; +import { Category } from '../../common/constants/enums'; export class DumpDto { @ApiProperty() name: string; @ApiProperty() - type: string; + @IsEnum(Category) + category: string; @ApiProperty({ format: 'double' }) reportLong: number; @@ -27,7 +30,7 @@ export class DumpDto { constructor( name: string, - type: string, + category: string, reportLong: number, reportLat: number, address: string, @@ -36,7 +39,7 @@ export class DumpDto { moreInformation: string, ) { this.name = name; - this.type = type; + this.category = category; this.reportLong = reportLong; this.reportLat = reportLat; this.address = address; diff --git a/src/report/dto/create-report.dto.ts b/src/report/dto/create-report.dto.ts index 9b59269..54301c7 100644 --- a/src/report/dto/create-report.dto.ts +++ b/src/report/dto/create-report.dto.ts @@ -1,5 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsEmail, IsLatitude, IsLongitude, IsNotEmpty } from 'class-validator'; +import { Category } from '../../common/constants/enums'; export class CreateReportDto { @IsNotEmpty() @@ -12,7 +13,7 @@ export class CreateReportDto { latitude: number; @IsNotEmpty() - type: string; + category: Category; @IsEmail() email: string; diff --git a/src/report/dto/public-report.dto.ts b/src/report/dto/public-report.dto.ts index 1065f4b..e8d1d04 100644 --- a/src/report/dto/public-report.dto.ts +++ b/src/report/dto/public-report.dto.ts @@ -1,12 +1,13 @@ import { ApiProperty } from '@nestjs/swagger'; import { StatusRecordsDto } from './status-records.dto'; +import { Category } from '../../common/constants/enums'; export class PublicReportDto { @ApiProperty() name: string; @ApiProperty() - type: string; + category: Category; @ApiProperty() refId: string; @@ -37,7 +38,7 @@ export class PublicReportDto { constructor( name: string, - type: string, + category: Category, refId: string, longitude: number, latitude: number, @@ -49,7 +50,7 @@ export class PublicReportDto { statusRecords: StatusRecordsDto[], ) { this.name = name; - this.type = type; + this.category = category; this.refId = refId; this.longitude = longitude; this.latitude = latitude; diff --git a/src/report/report.controller.ts b/src/report/report.controller.ts index e72561c..4fb8c00 100644 --- a/src/report/report.controller.ts +++ b/src/report/report.controller.ts @@ -16,12 +16,14 @@ import { ApiCreatedResponse, ApiNotFoundResponse, ApiOkResponse, + ApiQuery, ApiTags, } from '@nestjs/swagger'; import { PublicReportDto } from './dto'; import { CreateReportDto } from './dto'; import { FilesInterceptor } from '@nestjs/platform-express'; import { ReportStatisticsDto } from './dto/report-statistics.dto'; +import { Category } from '../common/constants/enums'; @Controller('reports') @ApiTags('reports') @@ -46,20 +48,25 @@ export class ReportController { description: 'All visible reports have been successfully found', type: [PublicReportDto], }) + @ApiQuery({ name: 'category', enum: Category, required: false }) @Get() - getAllPublicReports(@Query('type') type: string): Promise { - return this.reportService.getAllVisibleReports(type); + getAllPublicReports( + @Query('category') + category?: Category | undefined, + ): Promise { + return this.reportService.getAllVisibleReports(category); } @ApiOkResponse({ description: 'Report statistics have been successfully fetched', type: ReportStatisticsDto, }) + @ApiQuery({ name: 'category', enum: Category, required: false }) @Get('/statistics') getReportStatistics( - @Query('type') type: string, + @Query('category') category?: Category, ): Promise { - return this.reportService.getReportStatistics(type); + return this.reportService.getReportStatistics(category); } @Get('/:refId') diff --git a/src/report/report.service.ts b/src/report/report.service.ts index 4c8de87..7a7563d 100644 --- a/src/report/report.service.ts +++ b/src/report/report.service.ts @@ -3,13 +3,16 @@ import { CreateReportDto, PublicReportDto, StatusRecordsDto } from './dto'; import { ReportRepository } from '../repositories/reports/report.repository'; import { Report, StatusRecords } from '../repositories/reports/schemas'; import { ReportStatisticsDto } from './dto/report-statistics.dto'; +import { Category } from '../common/constants/enums'; @Injectable() export class ReportService { constructor(private readonly reportRepository: ReportRepository) {} - async getAllVisibleReports(type: string): Promise { - const reports = await this.reportRepository.getVisibleReports(type); + async getAllVisibleReports( + category: Category | undefined, + ): Promise { + const reports = await this.reportRepository.getVisibleReports(category); return reports.map(ReportService.docToPublicReport); } @@ -30,8 +33,8 @@ export class ReportService { return ReportService.docToPublicReport(report); } - async getReportStatistics(type: string): Promise { - const stats = await this.reportRepository.getVisibleStatusCounts(type); + async getReportStatistics(category?: Category): Promise { + const stats = await this.reportRepository.getVisibleStatusCounts(category); return ReportService.docToReportStatistics(stats); } @@ -50,7 +53,7 @@ export class ReportService { private static docToPublicReport(e: Report): PublicReportDto { return new PublicReportDto( e.name, - e.type, + e.type as Category, e.refId, e.reportLong, e.reportLat, diff --git a/src/repositories/dumps/dump.repository.ts b/src/repositories/dumps/dump.repository.ts index e378df5..205f577 100644 --- a/src/repositories/dumps/dump.repository.ts +++ b/src/repositories/dumps/dump.repository.ts @@ -34,7 +34,7 @@ export class DumpRepository { return await newDump.save(); } getDumpById(id: string) { - return this.dumpModel.findOne({ _id: id }).exec(); + return this.dumpModel.findOne({ _id: { eq: id } }).exec(); } async updateDump(updateDump: UpdateDumpDto): Promise { const dump = await this.getDumpById(updateDump._id); diff --git a/src/repositories/reports/report.repository.ts b/src/repositories/reports/report.repository.ts index 6abf560..a48760b 100644 --- a/src/repositories/reports/report.repository.ts +++ b/src/repositories/reports/report.repository.ts @@ -7,6 +7,7 @@ import { CloudinaryService } from '../../cloudinary/cloudinary.service'; import { BadRequestException } from '@nestjs/common'; import { HistoryDataDto } from '../../admin/dto/history-data.dto'; import { HistoryEditsDto } from '../../admin/dto/history-edits.dto'; +import { Category } from '../../common/constants/enums'; export class ReportRepository { constructor( @@ -14,51 +15,85 @@ export class ReportRepository { private cloudinary: CloudinaryService, ) {} - async getVisibleReports(type: string): Promise { - return await this.reportModel - .find({ isVisible: true, isDeleted: false, type: type }) - .sort({ reportDate: -1 }) - .exec(); + async getVisibleReports(category: Category | undefined): Promise { + return category === undefined + ? await this.reportModel + .find({ isVisible: true, isDeleted: false }) + .sort({ reportDate: -1 }) + .exec() + : await this.reportModel + .find({ isVisible: true, isDeleted: false, type: { $eq: category } }) + .sort({ reportDate: -1 }) + .exec(); } - async getAllReports(type: string): Promise { - return await this.reportModel - .find({ isDeleted: false, type: type }) - .sort({ reportDate: -1 }) - .exec(); + async getAllReports(category: Category): Promise { + return category === undefined + ? await this.reportModel + .find({ isDeleted: false }) + .sort({ reportDate: -1 }) + .exec() + : await this.reportModel + .find({ isDeleted: false, type: { $eq: category } }) + .sort({ reportDate: -1 }) + .exec(); } - async getDeletedReports(): Promise { - return await this.reportModel - .find({ isDeleted: true }) - .sort({ reportDate: -1 }) - .exec(); + async getDeletedReports(category?: Category): Promise { + return category === undefined + ? await this.reportModel + .find({ isDeleted: true }) + .sort({ reportDate: -1 }) + .exec() + : await this.reportModel + .find({ isDeleted: true, type: { $eq: category } }) + .sort({ reportDate: -1 }) + .exec(); } async getReportById(refId: number): Promise { - return await this.reportModel.findOne({ refId: refId }).exec(); + return await this.reportModel.findOne({ refId: { $eq: refId } }).exec(); } - async getVisibleStatusCounts(type: string): Promise { - return await this.reportModel - .aggregate([ - { - $match: { - isDeleted: false, - isVisible: true, - type: type, - }, - }, - { - $group: { - _id: '$status', - count: { - $sum: 1, + async getVisibleStatusCounts(category?: Category): Promise { + return category === undefined + ? await this.reportModel + .aggregate([ + { + $match: { + isDeleted: false, + isVisible: true, + type: { $eq: category }, + }, }, - }, - }, - ]) - .exec(); + { + $group: { + _id: '$status', + count: { + $sum: 1, + }, + }, + }, + ]) + .exec() + : await this.reportModel + .aggregate([ + { + $match: { + isDeleted: false, + isVisible: true, + }, + }, + { + $group: { + _id: '$status', + count: { + $sum: 1, + }, + }, + }, + ]) + .exec(); } async createReport( @@ -73,7 +108,7 @@ export class ReportRepository { const reportCount = reports.length; const newReport = new this.reportModel({ name: createReport.name, - type: createReport.type, + type: createReport.category, refId: reportCount + 1, comment: ' ', reportLong: createReport.longitude, @@ -119,7 +154,7 @@ export class ReportRepository { } const report = await this.reportModel - .findOne({ refId: updateReport.refId }) + .findOne({ refId: { $eq: updateReport.refId } }) .exec(); if (report != null) { @@ -213,7 +248,7 @@ export class ReportRepository { updatedReport = await this.reportModel .findOneAndUpdate( { - refId: updateReport.refId, + refId: { eq: updateReport.refId }, }, { $set: { From ac8d861af2bc9b2968702ffbdf7b9b5839ef91bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karolis=20Vy=C4=8Dius?= Date: Thu, 8 Feb 2024 12:40:29 +0200 Subject: [PATCH 03/10] Validations for ReportCategory --- src/admin/admin.controller.ts | 8 +++++--- src/admin/admin.service.ts | 10 ++++++---- src/admin/dto/full-report.dto.ts | 6 +++--- src/common/constants/enums.ts | 2 +- src/dumps/dto/dump.dto.ts | 7 ------- src/report/dto/create-report.dto.ts | 8 ++++---- src/report/dto/public-report.dto.ts | 6 +++--- src/report/report.controller.ts | 14 ++++++++------ src/report/report.service.ts | 10 ++++++---- src/repositories/reports/report.repository.ts | 10 +++++----- 10 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/admin/admin.controller.ts b/src/admin/admin.controller.ts index 007aa5c..5a0548a 100644 --- a/src/admin/admin.controller.ts +++ b/src/admin/admin.controller.ts @@ -5,6 +5,7 @@ import { NotFoundException, Param, ParseBoolPipe, + ParseEnumPipe, ParseIntPipe, Post, Put, @@ -33,7 +34,7 @@ import { import { FilesInterceptor } from '@nestjs/platform-express'; import { JwtAuthGuard } from '../auth/jwt-auth.guard'; import { Request } from 'express'; -import { Category } from '../common/constants/enums'; +import { ReportCategory } from '../common/constants/enums'; @Controller('admin') @ApiTags('admin') @@ -46,11 +47,12 @@ export class AdminController { description: 'All reports have been successfully found', type: [FullReportDto], }) - @ApiQuery({ name: 'category', enum: Category, required: false }) + @ApiQuery({ name: 'category', enum: ReportCategory, required: false }) @Get('/reports') async getAllReports( @Query('isDeleted', ParseBoolPipe) isDeleted: boolean, - @Query('category') category: Category, + @Query('category', new ParseEnumPipe(ReportCategory, { optional: true })) + category?: ReportCategory, ): Promise { return isDeleted ? await this.adminService.getAllDeletedReports(category) diff --git a/src/admin/admin.service.ts b/src/admin/admin.service.ts index 8edb2ba..1f9c393 100644 --- a/src/admin/admin.service.ts +++ b/src/admin/admin.service.ts @@ -14,7 +14,7 @@ import { HistoryEditsDto } from './dto/history-edits.dto'; import { StatusRecordsDto } from '../report/dto'; import { UpdateReportDto } from './dto'; import { Dump } from '../repositories/dumps/schemas'; -import { Category } from '../common/constants/enums'; +import { ReportCategory } from '../common/constants/enums'; @Injectable() export class AdminService { @@ -23,7 +23,7 @@ export class AdminService { private readonly reportRepository: ReportRepository, ) {} - async getAllReports(category: Category): Promise { + async getAllReports(category?: ReportCategory): Promise { const reports = await this.reportRepository.getAllReports(category); return reports.map(AdminService.docToFullReport); } @@ -40,7 +40,9 @@ export class AdminService { return AdminService.docToFullDump(dump); } - async getAllDeletedReports(category?: Category): Promise { + async getAllDeletedReports( + category?: ReportCategory, + ): Promise { const reports = await this.reportRepository.getDeletedReports(category); return reports.map(AdminService.docToFullReport); } @@ -94,7 +96,7 @@ export class AdminService { return new FullReportDto( report.refId, report.name, - report.type as Category, + report.type as ReportCategory, report.refId, report.reportLong, report.reportLat, diff --git a/src/admin/dto/full-report.dto.ts b/src/admin/dto/full-report.dto.ts index 18bae22..d9e8b74 100644 --- a/src/admin/dto/full-report.dto.ts +++ b/src/admin/dto/full-report.dto.ts @@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger'; import { HistoryDataDto } from './history-data.dto'; import { StatusRecordsDto } from './status-records.dto'; import { ToBoolean } from '../../common/transform/boolean.transform'; -import { Category } from '../../common/constants/enums'; +import { ReportCategory } from '../../common/constants/enums'; export class FullReportDto { @ApiProperty() @@ -12,7 +12,7 @@ export class FullReportDto { name: string; @ApiProperty() - category: Category; + category: ReportCategory; @ApiProperty() refId: string; @@ -58,7 +58,7 @@ export class FullReportDto { constructor( _id: string, name: string, - category: Category, + category: ReportCategory, refId: string, longitude: number, latitude: number, diff --git a/src/common/constants/enums.ts b/src/common/constants/enums.ts index 66bb547..a4084ea 100644 --- a/src/common/constants/enums.ts +++ b/src/common/constants/enums.ts @@ -1,4 +1,4 @@ -export enum Category { +export enum ReportCategory { trash = 'trash', forest = 'forest', } diff --git a/src/dumps/dto/dump.dto.ts b/src/dumps/dto/dump.dto.ts index 4b9405c..6781967 100644 --- a/src/dumps/dto/dump.dto.ts +++ b/src/dumps/dto/dump.dto.ts @@ -1,15 +1,9 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsEnum } from 'class-validator'; -import { Category } from '../../common/constants/enums'; export class DumpDto { @ApiProperty() name: string; - @ApiProperty() - @IsEnum(Category) - category: string; - @ApiProperty({ format: 'double' }) reportLong: number; @@ -39,7 +33,6 @@ export class DumpDto { moreInformation: string, ) { this.name = name; - this.category = category; this.reportLong = reportLong; this.reportLat = reportLat; this.address = address; diff --git a/src/report/dto/create-report.dto.ts b/src/report/dto/create-report.dto.ts index 54301c7..f63bbaa 100644 --- a/src/report/dto/create-report.dto.ts +++ b/src/report/dto/create-report.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsEmail, IsLatitude, IsLongitude, IsNotEmpty } from 'class-validator'; -import { Category } from '../../common/constants/enums'; +import { IsEmail, IsEnum, IsLatitude, IsLongitude, IsNotEmpty } from 'class-validator'; +import { ReportCategory } from '../../common/constants/enums'; export class CreateReportDto { @IsNotEmpty() @@ -12,8 +12,8 @@ export class CreateReportDto { @IsLatitude() latitude: number; - @IsNotEmpty() - category: Category; + @IsEnum(ReportCategory) + category: ReportCategory; @IsEmail() email: string; diff --git a/src/report/dto/public-report.dto.ts b/src/report/dto/public-report.dto.ts index e8d1d04..ba5208c 100644 --- a/src/report/dto/public-report.dto.ts +++ b/src/report/dto/public-report.dto.ts @@ -1,13 +1,13 @@ import { ApiProperty } from '@nestjs/swagger'; import { StatusRecordsDto } from './status-records.dto'; -import { Category } from '../../common/constants/enums'; +import { ReportCategory } from '../../common/constants/enums'; export class PublicReportDto { @ApiProperty() name: string; @ApiProperty() - category: Category; + category: ReportCategory; @ApiProperty() refId: string; @@ -38,7 +38,7 @@ export class PublicReportDto { constructor( name: string, - category: Category, + category: ReportCategory, refId: string, longitude: number, latitude: number, diff --git a/src/report/report.controller.ts b/src/report/report.controller.ts index 4fb8c00..8141af1 100644 --- a/src/report/report.controller.ts +++ b/src/report/report.controller.ts @@ -4,6 +4,7 @@ import { Get, NotFoundException, Param, + ParseEnumPipe, ParseIntPipe, Post, Query, @@ -23,7 +24,7 @@ import { PublicReportDto } from './dto'; import { CreateReportDto } from './dto'; import { FilesInterceptor } from '@nestjs/platform-express'; import { ReportStatisticsDto } from './dto/report-statistics.dto'; -import { Category } from '../common/constants/enums'; +import { ReportCategory } from '../common/constants/enums'; @Controller('reports') @ApiTags('reports') @@ -48,11 +49,11 @@ export class ReportController { description: 'All visible reports have been successfully found', type: [PublicReportDto], }) - @ApiQuery({ name: 'category', enum: Category, required: false }) + @ApiQuery({ name: 'category', enum: ReportCategory, required: false }) @Get() getAllPublicReports( - @Query('category') - category?: Category | undefined, + @Query('category', new ParseEnumPipe(ReportCategory, { optional: true })) + category?: ReportCategory, ): Promise { return this.reportService.getAllVisibleReports(category); } @@ -61,10 +62,11 @@ export class ReportController { description: 'Report statistics have been successfully fetched', type: ReportStatisticsDto, }) - @ApiQuery({ name: 'category', enum: Category, required: false }) + @ApiQuery({ name: 'category', enum: ReportCategory, required: false }) @Get('/statistics') getReportStatistics( - @Query('category') category?: Category, + @Query('category', new ParseEnumPipe(ReportCategory, { optional: true })) + category?: ReportCategory, ): Promise { return this.reportService.getReportStatistics(category); } diff --git a/src/report/report.service.ts b/src/report/report.service.ts index 7a7563d..0cbfdb2 100644 --- a/src/report/report.service.ts +++ b/src/report/report.service.ts @@ -3,14 +3,14 @@ import { CreateReportDto, PublicReportDto, StatusRecordsDto } from './dto'; import { ReportRepository } from '../repositories/reports/report.repository'; import { Report, StatusRecords } from '../repositories/reports/schemas'; import { ReportStatisticsDto } from './dto/report-statistics.dto'; -import { Category } from '../common/constants/enums'; +import { ReportCategory } from '../common/constants/enums'; @Injectable() export class ReportService { constructor(private readonly reportRepository: ReportRepository) {} async getAllVisibleReports( - category: Category | undefined, + category?: ReportCategory, ): Promise { const reports = await this.reportRepository.getVisibleReports(category); return reports.map(ReportService.docToPublicReport); @@ -33,7 +33,9 @@ export class ReportService { return ReportService.docToPublicReport(report); } - async getReportStatistics(category?: Category): Promise { + async getReportStatistics( + category?: ReportCategory, + ): Promise { const stats = await this.reportRepository.getVisibleStatusCounts(category); return ReportService.docToReportStatistics(stats); } @@ -53,7 +55,7 @@ export class ReportService { private static docToPublicReport(e: Report): PublicReportDto { return new PublicReportDto( e.name, - e.type as Category, + e.type as ReportCategory, e.refId, e.reportLong, e.reportLat, diff --git a/src/repositories/reports/report.repository.ts b/src/repositories/reports/report.repository.ts index a48760b..33fdde1 100644 --- a/src/repositories/reports/report.repository.ts +++ b/src/repositories/reports/report.repository.ts @@ -7,7 +7,7 @@ import { CloudinaryService } from '../../cloudinary/cloudinary.service'; import { BadRequestException } from '@nestjs/common'; import { HistoryDataDto } from '../../admin/dto/history-data.dto'; import { HistoryEditsDto } from '../../admin/dto/history-edits.dto'; -import { Category } from '../../common/constants/enums'; +import { ReportCategory } from '../../common/constants/enums'; export class ReportRepository { constructor( @@ -15,7 +15,7 @@ export class ReportRepository { private cloudinary: CloudinaryService, ) {} - async getVisibleReports(category: Category | undefined): Promise { + async getVisibleReports(category?: ReportCategory): Promise { return category === undefined ? await this.reportModel .find({ isVisible: true, isDeleted: false }) @@ -27,7 +27,7 @@ export class ReportRepository { .exec(); } - async getAllReports(category: Category): Promise { + async getAllReports(category?: ReportCategory): Promise { return category === undefined ? await this.reportModel .find({ isDeleted: false }) @@ -39,7 +39,7 @@ export class ReportRepository { .exec(); } - async getDeletedReports(category?: Category): Promise { + async getDeletedReports(category?: ReportCategory): Promise { return category === undefined ? await this.reportModel .find({ isDeleted: true }) @@ -55,7 +55,7 @@ export class ReportRepository { return await this.reportModel.findOne({ refId: { $eq: refId } }).exec(); } - async getVisibleStatusCounts(category?: Category): Promise { + async getVisibleStatusCounts(category?: ReportCategory): Promise { return category === undefined ? await this.reportModel .aggregate([ From ae64baef04f1ff818b9f9c78968592218e1199f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karolis=20Vy=C4=8Dius?= Date: Thu, 8 Feb 2024 12:45:07 +0200 Subject: [PATCH 04/10] Safely parse ReportCategory --- src/admin/admin.service.ts | 10 +++++++++- src/report/report.service.ts | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/admin/admin.service.ts b/src/admin/admin.service.ts index 1f9c393..ab990a7 100644 --- a/src/admin/admin.service.ts +++ b/src/admin/admin.service.ts @@ -96,7 +96,7 @@ export class AdminService { return new FullReportDto( report.refId, report.name, - report.type as ReportCategory, + AdminService.parseReportCategory(report.type), report.refId, report.reportLong, report.reportLat, @@ -130,4 +130,12 @@ export class AdminService { private static docToStatusRecords(records: StatusRecords): StatusRecordsDto { return new StatusRecordsDto(records.status, new Date(records.date)); } + + private static parseReportCategory(value: string): ReportCategory { + if (Object.values(ReportCategory).includes(value as ReportCategory)) { + return value as ReportCategory; + } else { + throw new Error(`Invalid report category: ${value}`); + } + } } diff --git a/src/report/report.service.ts b/src/report/report.service.ts index 0cbfdb2..30462a8 100644 --- a/src/report/report.service.ts +++ b/src/report/report.service.ts @@ -55,7 +55,7 @@ export class ReportService { private static docToPublicReport(e: Report): PublicReportDto { return new PublicReportDto( e.name, - e.type as ReportCategory, + ReportService.parseReportCategory(e.type), e.refId, e.reportLong, e.reportLat, @@ -73,4 +73,12 @@ export class ReportService { ): StatusRecordsDto { return new StatusRecordsDto(e.status, new Date(e.date)); } + + private static parseReportCategory(value: string): ReportCategory { + if (Object.values(ReportCategory).includes(value as ReportCategory)) { + return value as ReportCategory; + } else { + throw new Error(`Invalid report category: ${value}`); + } + } } From f16376bd4e997a033c807ccb804ee2a32a6e7460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karolis=20Vy=C4=8Dius?= Date: Thu, 8 Feb 2024 13:00:42 +0200 Subject: [PATCH 05/10] Keep it dry --- src/admin/admin.controller.ts | 4 +- src/admin/admin.service.ts | 17 ++- src/repositories/reports/report.repository.ts | 111 +++++++----------- 3 files changed, 51 insertions(+), 81 deletions(-) diff --git a/src/admin/admin.controller.ts b/src/admin/admin.controller.ts index 5a0548a..a6aab7e 100644 --- a/src/admin/admin.controller.ts +++ b/src/admin/admin.controller.ts @@ -54,9 +54,7 @@ export class AdminController { @Query('category', new ParseEnumPipe(ReportCategory, { optional: true })) category?: ReportCategory, ): Promise { - return isDeleted - ? await this.adminService.getAllDeletedReports(category) - : await this.adminService.getAllReports(category); + return this.adminService.getAllReports(isDeleted, category); } @ApiOkResponse({ diff --git a/src/admin/admin.service.ts b/src/admin/admin.service.ts index ab990a7..b58718d 100644 --- a/src/admin/admin.service.ts +++ b/src/admin/admin.service.ts @@ -23,8 +23,14 @@ export class AdminService { private readonly reportRepository: ReportRepository, ) {} - async getAllReports(category?: ReportCategory): Promise { - const reports = await this.reportRepository.getAllReports(category); + async getAllReports( + isDeleted: boolean, + category?: ReportCategory, + ): Promise { + const reports = await this.reportRepository.getAllReports( + isDeleted, + category, + ); return reports.map(AdminService.docToFullReport); } @@ -40,13 +46,6 @@ export class AdminService { return AdminService.docToFullDump(dump); } - async getAllDeletedReports( - category?: ReportCategory, - ): Promise { - const reports = await this.reportRepository.getDeletedReports(category); - return reports.map(AdminService.docToFullReport); - } - async updateReport( updateReport: UpdateReportDto, images: Array, diff --git a/src/repositories/reports/report.repository.ts b/src/repositories/reports/report.repository.ts index 33fdde1..7bebc9c 100644 --- a/src/repositories/reports/report.repository.ts +++ b/src/repositories/reports/report.repository.ts @@ -15,85 +15,58 @@ export class ReportRepository { private cloudinary: CloudinaryService, ) {} - async getVisibleReports(category?: ReportCategory): Promise { - return category === undefined - ? await this.reportModel - .find({ isVisible: true, isDeleted: false }) - .sort({ reportDate: -1 }) - .exec() - : await this.reportModel - .find({ isVisible: true, isDeleted: false, type: { $eq: category } }) - .sort({ reportDate: -1 }) - .exec(); - } + getVisibleReports(category?: ReportCategory): Promise { + const query: any = { isVisible: true, isDeleted: false }; + + if (category) { + query.type = { $eq: category }; + } - async getAllReports(category?: ReportCategory): Promise { - return category === undefined - ? await this.reportModel - .find({ isDeleted: false }) - .sort({ reportDate: -1 }) - .exec() - : await this.reportModel - .find({ isDeleted: false, type: { $eq: category } }) - .sort({ reportDate: -1 }) - .exec(); + return this.reportModel.find(query).sort({ reportDate: -1 }).exec(); } - async getDeletedReports(category?: ReportCategory): Promise { - return category === undefined - ? await this.reportModel - .find({ isDeleted: true }) - .sort({ reportDate: -1 }) - .exec() - : await this.reportModel - .find({ isDeleted: true, type: { $eq: category } }) - .sort({ reportDate: -1 }) - .exec(); + getAllReports( + isDeleted: boolean, + category?: ReportCategory, + ): Promise { + const query: any = { isDeleted: isDeleted }; + + if (category) { + query.type = { $eq: category }; + } + + return this.reportModel.find(query).sort({ reportDate: -1 }).exec(); } async getReportById(refId: number): Promise { return await this.reportModel.findOne({ refId: { $eq: refId } }).exec(); } - async getVisibleStatusCounts(category?: ReportCategory): Promise { - return category === undefined - ? await this.reportModel - .aggregate([ - { - $match: { - isDeleted: false, - isVisible: true, - type: { $eq: category }, - }, - }, - { - $group: { - _id: '$status', - count: { - $sum: 1, - }, - }, - }, - ]) - .exec() - : await this.reportModel - .aggregate([ - { - $match: { - isDeleted: false, - isVisible: true, - }, - }, - { - $group: { - _id: '$status', - count: { - $sum: 1, - }, - }, + getVisibleStatusCounts(category?: ReportCategory): Promise { + const query: any = { + isDeleted: false, + isVisible: true, + }; + + if (category) { + query.type = { $eq: category }; + } + + return this.reportModel + .aggregate([ + { + $match: query, + }, + { + $group: { + _id: '$status', + count: { + $sum: 1, }, - ]) - .exec(); + }, + }, + ]) + .exec(); } async createReport( From db429ba23b3895331832b805623e5c984ce9d9be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karolis=20Vy=C4=8Dius?= Date: Thu, 8 Feb 2024 13:02:04 +0200 Subject: [PATCH 06/10] Remove category from dump --- src/admin/admin.service.ts | 1 - src/admin/dto/full-dump.dto.ts | 5 ----- src/dumps/dto/dump.dto.ts | 1 - src/dumps/dump.service.ts | 2 +- 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/admin/admin.service.ts b/src/admin/admin.service.ts index b58718d..cbd33a9 100644 --- a/src/admin/admin.service.ts +++ b/src/admin/admin.service.ts @@ -80,7 +80,6 @@ export class AdminService { return new FullDumpDto( dump._id.toString(), dump.name, - dump.type, dump.reportLong, dump.reportLat, dump.isVisible, diff --git a/src/admin/dto/full-dump.dto.ts b/src/admin/dto/full-dump.dto.ts index b8096fa..b3d5ad7 100644 --- a/src/admin/dto/full-dump.dto.ts +++ b/src/admin/dto/full-dump.dto.ts @@ -8,9 +8,6 @@ export class FullDumpDto { @ApiProperty() name: string; - @ApiProperty() - category: string; - @ApiProperty({ format: 'double' }) longitude: number; @@ -36,7 +33,6 @@ export class FullDumpDto { constructor( refId: string, name: string, - category: string, longitude: number, latitude: number, isVisible: boolean, @@ -47,7 +43,6 @@ export class FullDumpDto { ) { this.refId = refId; this.name = name; - this.category = category; this.longitude = longitude; this.latitude = latitude; this.isVisible = isVisible; diff --git a/src/dumps/dto/dump.dto.ts b/src/dumps/dto/dump.dto.ts index 6781967..9a8a39e 100644 --- a/src/dumps/dto/dump.dto.ts +++ b/src/dumps/dto/dump.dto.ts @@ -24,7 +24,6 @@ export class DumpDto { constructor( name: string, - category: string, reportLong: number, reportLat: number, address: string, diff --git a/src/dumps/dump.service.ts b/src/dumps/dump.service.ts index 23ea7d3..e5524dd 100644 --- a/src/dumps/dump.service.ts +++ b/src/dumps/dump.service.ts @@ -11,10 +11,10 @@ export class DumpService { const dumps = await this.dumpRepository.getVisibleDumps(); return dumps.map(this.docToPublicDump); } + private docToPublicDump(e: Dump): DumpDto { return new DumpDto( e.name, - e.type, e.reportLong, e.reportLat, e.address, From be8a91839731bcccd7849b3f0012ec8b60a19861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karolis=20Vy=C4=8Dius?= Date: Thu, 8 Feb 2024 13:06:31 +0200 Subject: [PATCH 07/10] Move out ReportCategory from constants --- src/admin/admin.controller.ts | 2 +- src/admin/admin.service.ts | 2 +- src/admin/dto/full-report.dto.ts | 2 +- src/common/{constants/enums.ts => dto/report-category.ts} | 0 src/report/dto/create-report.dto.ts | 2 +- src/report/dto/public-report.dto.ts | 2 +- src/report/report.controller.ts | 2 +- src/report/report.service.ts | 2 +- src/repositories/reports/report.repository.ts | 2 +- 9 files changed, 8 insertions(+), 8 deletions(-) rename src/common/{constants/enums.ts => dto/report-category.ts} (100%) diff --git a/src/admin/admin.controller.ts b/src/admin/admin.controller.ts index a6aab7e..a777273 100644 --- a/src/admin/admin.controller.ts +++ b/src/admin/admin.controller.ts @@ -34,7 +34,7 @@ import { import { FilesInterceptor } from '@nestjs/platform-express'; import { JwtAuthGuard } from '../auth/jwt-auth.guard'; import { Request } from 'express'; -import { ReportCategory } from '../common/constants/enums'; +import { ReportCategory } from '../common/dto/report-category'; @Controller('admin') @ApiTags('admin') diff --git a/src/admin/admin.service.ts b/src/admin/admin.service.ts index cbd33a9..5a4c262 100644 --- a/src/admin/admin.service.ts +++ b/src/admin/admin.service.ts @@ -14,7 +14,7 @@ import { HistoryEditsDto } from './dto/history-edits.dto'; import { StatusRecordsDto } from '../report/dto'; import { UpdateReportDto } from './dto'; import { Dump } from '../repositories/dumps/schemas'; -import { ReportCategory } from '../common/constants/enums'; +import { ReportCategory } from '../common/dto/report-category'; @Injectable() export class AdminService { diff --git a/src/admin/dto/full-report.dto.ts b/src/admin/dto/full-report.dto.ts index d9e8b74..320240a 100644 --- a/src/admin/dto/full-report.dto.ts +++ b/src/admin/dto/full-report.dto.ts @@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger'; import { HistoryDataDto } from './history-data.dto'; import { StatusRecordsDto } from './status-records.dto'; import { ToBoolean } from '../../common/transform/boolean.transform'; -import { ReportCategory } from '../../common/constants/enums'; +import { ReportCategory } from '../../common/dto/report-category'; export class FullReportDto { @ApiProperty() diff --git a/src/common/constants/enums.ts b/src/common/dto/report-category.ts similarity index 100% rename from src/common/constants/enums.ts rename to src/common/dto/report-category.ts diff --git a/src/report/dto/create-report.dto.ts b/src/report/dto/create-report.dto.ts index f63bbaa..c77fd1e 100644 --- a/src/report/dto/create-report.dto.ts +++ b/src/report/dto/create-report.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsEmail, IsEnum, IsLatitude, IsLongitude, IsNotEmpty } from 'class-validator'; -import { ReportCategory } from '../../common/constants/enums'; +import { ReportCategory } from '../../common/dto/report-category'; export class CreateReportDto { @IsNotEmpty() diff --git a/src/report/dto/public-report.dto.ts b/src/report/dto/public-report.dto.ts index ba5208c..d1dc5e6 100644 --- a/src/report/dto/public-report.dto.ts +++ b/src/report/dto/public-report.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { StatusRecordsDto } from './status-records.dto'; -import { ReportCategory } from '../../common/constants/enums'; +import { ReportCategory } from '../../common/dto/report-category'; export class PublicReportDto { @ApiProperty() diff --git a/src/report/report.controller.ts b/src/report/report.controller.ts index 8141af1..aa94cca 100644 --- a/src/report/report.controller.ts +++ b/src/report/report.controller.ts @@ -24,7 +24,7 @@ import { PublicReportDto } from './dto'; import { CreateReportDto } from './dto'; import { FilesInterceptor } from '@nestjs/platform-express'; import { ReportStatisticsDto } from './dto/report-statistics.dto'; -import { ReportCategory } from '../common/constants/enums'; +import { ReportCategory } from '../common/dto/report-category'; @Controller('reports') @ApiTags('reports') diff --git a/src/report/report.service.ts b/src/report/report.service.ts index 30462a8..f684058 100644 --- a/src/report/report.service.ts +++ b/src/report/report.service.ts @@ -3,7 +3,7 @@ import { CreateReportDto, PublicReportDto, StatusRecordsDto } from './dto'; import { ReportRepository } from '../repositories/reports/report.repository'; import { Report, StatusRecords } from '../repositories/reports/schemas'; import { ReportStatisticsDto } from './dto/report-statistics.dto'; -import { ReportCategory } from '../common/constants/enums'; +import { ReportCategory } from '../common/dto/report-category'; @Injectable() export class ReportService { diff --git a/src/repositories/reports/report.repository.ts b/src/repositories/reports/report.repository.ts index 7bebc9c..f1d3bc0 100644 --- a/src/repositories/reports/report.repository.ts +++ b/src/repositories/reports/report.repository.ts @@ -7,7 +7,7 @@ import { CloudinaryService } from '../../cloudinary/cloudinary.service'; import { BadRequestException } from '@nestjs/common'; import { HistoryDataDto } from '../../admin/dto/history-data.dto'; import { HistoryEditsDto } from '../../admin/dto/history-edits.dto'; -import { ReportCategory } from '../../common/constants/enums'; +import { ReportCategory } from '../../common/dto/report-category'; export class ReportRepository { constructor( From 2009b75d824580d4f1461a20559d5a495a39fde3 Mon Sep 17 00:00:00 2001 From: Ignas-rgb <61393113+Ignas-rgb@users.noreply.github.com> Date: Tue, 13 Feb 2024 03:40:58 +0200 Subject: [PATCH 08/10] Add check for undefined fields --- src/report/report.service.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/report/report.service.ts b/src/report/report.service.ts index f684058..efb683f 100644 --- a/src/report/report.service.ts +++ b/src/report/report.service.ts @@ -42,16 +42,20 @@ export class ReportService { private static docToReportStatistics(e: any): ReportStatisticsDto { return new ReportStatisticsDto( - e.filter((stat: { _id: string }) => stat._id == 'gautas')[0].count ?? 0, - e.filter((stat: { _id: string }) => stat._id == 'tiriamas')[0].count ?? 0, - e.filter((stat: { _id: string }) => stat._id == 'ištirtas')[0].count ?? 0, - e.filter((stat: { _id: string }) => stat._id == 'sutvarkyta')[0].count ?? - 0, - e.filter((stat: { _id: string }) => stat._id == 'nepasitvirtino')[0] - .count ?? 0, + ReportService.filterStatistics(e, 'gautas'), + ReportService.filterStatistics(e, 'tiriamas'), + ReportService.filterStatistics(e, 'ištirtas'), + ReportService.filterStatistics(e, 'sutvarkyta'), + ReportService.filterStatistics(e, 'nepasitvirtino'), ); } + private static filterStatistics(e: any, status: string): number { + return e.filter((stat: { _id: string }) => stat._id == status).length > 0 + ? e.filter((stat: { _id: string }) => stat._id == status)[0].count ?? 0 + : 0; + } + private static docToPublicReport(e: Report): PublicReportDto { return new PublicReportDto( e.name, From 33dff6afe25b4a5bd688618264fda0a32ff977b0 Mon Sep 17 00:00:00 2001 From: Ignas-rgb <61393113+Ignas-rgb@users.noreply.github.com> Date: Tue, 13 Feb 2024 13:55:55 +0200 Subject: [PATCH 09/10] Equal operator bug fix --- src/repositories/dumps/dump.repository.ts | 2 +- src/repositories/reports/report.repository.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/repositories/dumps/dump.repository.ts b/src/repositories/dumps/dump.repository.ts index 205f577..ba6d65e 100644 --- a/src/repositories/dumps/dump.repository.ts +++ b/src/repositories/dumps/dump.repository.ts @@ -1,7 +1,7 @@ import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { Dump } from './schemas'; -import { UpdateDumpDto } from '../../admin/dto/update-dump.dto'; +import { UpdateDumpDto } from '../../admin/dto'; import { CreateDumpDto } from '../../admin/dto'; export class DumpRepository { diff --git a/src/repositories/reports/report.repository.ts b/src/repositories/reports/report.repository.ts index f1d3bc0..954de09 100644 --- a/src/repositories/reports/report.repository.ts +++ b/src/repositories/reports/report.repository.ts @@ -221,7 +221,7 @@ export class ReportRepository { updatedReport = await this.reportModel .findOneAndUpdate( { - refId: { eq: updateReport.refId }, + refId: { $eq: updateReport.refId }, }, { $set: { From 9b117f9c06e1d536656068800f7dd80955dc2f48 Mon Sep 17 00:00:00 2001 From: Ignas-rgb <61393113+Ignas-rgb@users.noreply.github.com> Date: Tue, 13 Feb 2024 14:29:50 +0200 Subject: [PATCH 10/10] Update status statistics logic --- src/report/dto/report-statistics.dto.ts | 4 ---- src/report/report.service.ts | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/report/dto/report-statistics.dto.ts b/src/report/dto/report-statistics.dto.ts index ea7a864..ede17c4 100644 --- a/src/report/dto/report-statistics.dto.ts +++ b/src/report/dto/report-statistics.dto.ts @@ -8,21 +8,17 @@ export class ReportStatisticsDto { @ApiProperty({ type: 'integer' }) totalInvestigatedReports: number; @ApiProperty({ type: 'integer' }) - totalCleanedReports: number; - @ApiProperty({ type: 'integer' }) totalFalseReports: number; constructor( totalSentReports: number, totalInInvestigationReports: number, totalInvestigatedReports: number, - totalCleanedReports: number, totalFalseReports: number, ) { this.totalSentReports = totalSentReports; this.totalInInvestigationReports = totalInInvestigationReports; this.totalInvestigatedReports = totalInvestigatedReports; - this.totalCleanedReports = totalCleanedReports; this.totalFalseReports = totalFalseReports; } } diff --git a/src/report/report.service.ts b/src/report/report.service.ts index efb683f..8e932dd 100644 --- a/src/report/report.service.ts +++ b/src/report/report.service.ts @@ -44,8 +44,7 @@ export class ReportService { return new ReportStatisticsDto( ReportService.filterStatistics(e, 'gautas'), ReportService.filterStatistics(e, 'tiriamas'), - ReportService.filterStatistics(e, 'ištirtas'), - ReportService.filterStatistics(e, 'sutvarkyta'), + ReportService.filterStatistics(e, 'išspręsta'), ReportService.filterStatistics(e, 'nepasitvirtino'), ); }