diff --git a/src/common/dtos/pagination-query.dto.ts b/src/common/dtos/pagination-query.dto.ts new file mode 100644 index 0000000..758f628 --- /dev/null +++ b/src/common/dtos/pagination-query.dto.ts @@ -0,0 +1,24 @@ +import { Type } from 'class-transformer'; +import { IsInt, IsOptional, IsString, Min } from 'class-validator'; + +export class PaginationQueryDTO { + @IsOptional() + @Type(() => Number) + @IsInt() + @Min(1) + page?: number = 1; + + @IsOptional() + @Type(() => Number) + @IsInt() + @Min(1) + limit?: number = 20; + + @IsOptional() + @IsString() + sortBy?: string; + + @IsOptional() + @IsString() + order?: 'ASC' | 'DESC' = 'DESC'; +} diff --git a/src/common/exceptions/app-timeout.exception.ts b/src/common/exceptions/app-timeout.exception.ts new file mode 100644 index 0000000..65bcfb4 --- /dev/null +++ b/src/common/exceptions/app-timeout.exception.ts @@ -0,0 +1,10 @@ +import { RequestTimeoutException } from '@nestjs/common'; + +export class AppTimeoutException extends RequestTimeoutException { + constructor(cause?: unknown, description?: string) { + super('common.errors.requestTimeout', { + cause, + description: description ?? 'Error connecting to the database', + }); + } +} diff --git a/src/common/utils/index.ts b/src/common/utils/index.ts index fc63d25..60424e2 100644 --- a/src/common/utils/index.ts +++ b/src/common/utils/index.ts @@ -1,7 +1,9 @@ import * as StringUtils from './string-utils'; +import * as PaginationUtils from './pagination-utils'; const Utils = { StringUtils, + PaginationUtils, }; export default Utils; diff --git a/src/common/utils/pagination-utils.ts b/src/common/utils/pagination-utils.ts new file mode 100644 index 0000000..642c4aa --- /dev/null +++ b/src/common/utils/pagination-utils.ts @@ -0,0 +1,13 @@ +import { PaginationQueryDTO } from '../dtos/pagination-query.dto'; + +export const getPaginationOptions = (query: PaginationQueryDTO) => { + const page = query.page ?? 1; + const limit = query.limit ?? 20; + + return { + skip: (page - 1) * limit, + take: limit, + page, + limit, + }; +}; diff --git a/src/modules/admin/auth/admin-auth.controller.ts b/src/modules/admin/auth/admin-auth.controller.ts index 1660610..b2ec5aa 100644 --- a/src/modules/admin/auth/admin-auth.controller.ts +++ b/src/modules/admin/auth/admin-auth.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, HttpCode, Post } from '@nestjs/common'; +import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common'; import { AdminAuthService } from './providers/admin-auth.service'; import { AdminLoginDTO } from './dtos/admin-login.dto'; import { Public } from '@/modules/auth/decorators/public.decorator'; @@ -14,7 +14,7 @@ export class AdminAuthController { @Public() @Post('login') - @HttpCode(200) + @HttpCode(HttpStatus.OK) public async login(@Body() adminLoginDto: AdminLoginDTO) { return await this.adminAuthService.login(adminLoginDto); } diff --git a/src/modules/admin/tests/admin-tests.controller.ts b/src/modules/admin/tests/admin-tests.controller.ts index 31a72e7..a8958d3 100644 --- a/src/modules/admin/tests/admin-tests.controller.ts +++ b/src/modules/admin/tests/admin-tests.controller.ts @@ -1,16 +1,21 @@ import { Role } from '@/common/enums/roles.enum'; import { Roles } from '@/modules/auth/decorators/roles.decorator'; import { CreateTestDTO } from '@/modules/tests/dtos/create-test.dto'; +import { FindTestsDTO } from '@/modules/tests/dtos/find-tests.dto'; import { UpdateTestDTO } from '@/modules/tests/dtos/update-test.dto'; import { TestsService } from '@/modules/tests/providers/tests.service'; import { Body, Controller, + Delete, Get, + HttpCode, + HttpStatus, Param, ParseIntPipe, Patch, Post, + Query, } from '@nestjs/common'; @Controller('admin/tests') @@ -29,8 +34,8 @@ export class AdminTestsController { } @Get() - public async getAllTests() { - return await this.testsService.adminGetAll(); + public async getAllTests(@Query() query: FindTestsDTO) { + return await this.testsService.adminGetAll(query); } @Get(':id') @@ -45,4 +50,10 @@ export class AdminTestsController { ) { return await this.testsService.updateOne(id, updateTestDto); } + + @Delete(':id') + @HttpCode(HttpStatus.NO_CONTENT) + public async deleteTestById(@Param('id', ParseIntPipe) id: number) { + return await this.testsService.deleteOne(id); + } } diff --git a/src/modules/admin/tests/http/admin-tests.delete.endpoints.http b/src/modules/admin/tests/http/admin-tests.delete.endpoints.http new file mode 100644 index 0000000..1c7aaa8 --- /dev/null +++ b/src/modules/admin/tests/http/admin-tests.delete.endpoints.http @@ -0,0 +1,2 @@ +DELETE http://localhost:3000/admin/tests/1 +Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJwaG9uZSI6IjA5MzMzMDI2MzYzIiwiaWF0IjoxNzgwNzQ5MTcwLCJleHAiOjE3ODA3NTI3NzAsImF1ZCI6ImxvY2FsaG9zdCIsImlzcyI6ImxvY2FsaG9zdCJ9.apRhtVZgFMFcyutZGO7uzckscch9Jw42s0RCSZZv4K0 diff --git a/src/modules/admin/tests/http/admin-tests.get.endpoints.http b/src/modules/admin/tests/http/admin-tests.get.endpoints.http index c3129d2..e90bfdd 100644 --- a/src/modules/admin/tests/http/admin-tests.get.endpoints.http +++ b/src/modules/admin/tests/http/admin-tests.get.endpoints.http @@ -1,5 +1,5 @@ -GET http://localhost:3000/admin/tests -Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJwaG9uZSI6IjA5MzMzMDI2MzYzIiwiaWF0IjoxNzgwMzk4MzI0LCJleHAiOjE3ODA0MDE5MjQsImF1ZCI6ImxvY2FsaG9zdCIsImlzcyI6ImxvY2FsaG9zdCJ9.s3NAErSAjMTz2s27obas3TEi5Og2HPeLgWCoIyzmzII +GET http://localhost:3000/admin/tests?title=test&isActive=true&accessType=paid&sortBy=title&order=DSC&page=2&limit=1 +Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJwaG9uZSI6IjA5MzMzMDI2MzYzIiwiaWF0IjoxNzgwNzQ5MTcwLCJleHAiOjE3ODA3NTI3NzAsImF1ZCI6ImxvY2FsaG9zdCIsImlzcyI6ImxvY2FsaG9zdCJ9.apRhtVZgFMFcyutZGO7uzckscch9Jw42s0RCSZZv4K0 GET http://localhost:3000/admin/tests/4 -Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJwaG9uZSI6IjA5MzMzMDI2MzYzIiwiaWF0IjoxNzgwMzk4MzI0LCJleHAiOjE3ODA0MDE5MjQsImF1ZCI6ImxvY2FsaG9zdCIsImlzcyI6ImxvY2FsaG9zdCJ9.s3NAErSAjMTz2s27obas3TEi5Og2HPeLgWCoIyzmzII +Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJwaG9uZSI6IjA5MzMzMDI2MzYzIiwiaWF0IjoxNzgwNzQ5MTcwLCJleHAiOjE3ODA3NTI3NzAsImF1ZCI6ImxvY2FsaG9zdCIsImlzcyI6ImxvY2FsaG9zdCJ9.apRhtVZgFMFcyutZGO7uzckscch9Jw42s0RCSZZv4K0 diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index 8e08488..2f4b52d 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, HttpCode, Post } from '@nestjs/common'; +import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common'; import { LoginDTO } from './dtos/login.dto'; import { AuthService } from './providers/auth.service'; import { VerifyOtpDTO } from './dtos/verify-otp.dto'; @@ -16,21 +16,21 @@ export class AuthController { @Public() @Post('login') - @HttpCode(200) + @HttpCode(HttpStatus.OK) public async logIn(@Body() loginDto: LoginDTO) { return await this.authService.logIn(loginDto); } @Public() @Post('verify-otp') - @HttpCode(200) + @HttpCode(HttpStatus.OK) public async verifyOTP(@Body() verifyOtpDto: VerifyOtpDTO) { return await this.authService.verifyOTP(verifyOtpDto); } @Public() @Post('refresh') - @HttpCode(200) + @HttpCode(HttpStatus.OK) public async refreshToken(@Body() refreshTokenDto: RefreshTokenDTO) { return await this.authService.refreshToken(refreshTokenDto); } diff --git a/src/modules/otp/providers/otp.service.ts b/src/modules/otp/providers/otp.service.ts index 2773550..12eaedb 100644 --- a/src/modules/otp/providers/otp.service.ts +++ b/src/modules/otp/providers/otp.service.ts @@ -1,15 +1,11 @@ -import { - HttpStatus, - Injectable, - RequestTimeoutException, - UnauthorizedException, -} from '@nestjs/common'; +import { HttpStatus, Injectable, UnauthorizedException } from '@nestjs/common'; import { LessThan, MoreThanOrEqual, Repository } from 'typeorm'; import { OTP } from '../entities/otp.entity'; import { InjectRepository } from '@nestjs/typeorm'; import { Cron } from '@nestjs/schedule'; import { HashingProvider } from '@/common/modules/hashing/providers/hashing.provider'; import { AppException } from '@/common/exceptions/app.exception'; +import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception'; @Injectable() export class OtpService { @@ -73,10 +69,7 @@ export class OtpService { order: { createdAt: 'DESC' }, }); } catch (err) { - throw new RequestTimeoutException('common.errors.requestTimeout', { - cause: err, - description: 'Error connecting to the database', - }); + throw new AppTimeoutException(err); } if (!otp) throw new UnauthorizedException('auth.errors.invalidOTP'); diff --git a/src/modules/tests/dtos/find-tests.dto.ts b/src/modules/tests/dtos/find-tests.dto.ts new file mode 100644 index 0000000..6af132c --- /dev/null +++ b/src/modules/tests/dtos/find-tests.dto.ts @@ -0,0 +1,41 @@ +import { PaginationQueryDTO } from '@/common/dtos/pagination-query.dto'; +import { + IsBoolean, + IsEnum, + IsNumber, + IsOptional, + IsString, +} from 'class-validator'; +import { AccessType } from '../enums/access-types.enum'; +import { PartialType } from '@nestjs/swagger'; +import { TestSortField } from '../enums/test-sort-field.enum'; + +export class FindTestsDTO extends PartialType(PaginationQueryDTO) { + @IsNumber() + @IsOptional() + id?: number; + + @IsString() + @IsOptional() + title?: string; + + @IsString() + @IsOptional() + description?: string; + + @IsString() + @IsOptional() + price?: string; + + @IsEnum(AccessType) + @IsOptional() + accessType?: AccessType; + + @IsBoolean() + @IsOptional() + isActive?: boolean; + + @IsEnum(TestSortField) + @IsOptional() + sortBy?: TestSortField; +} diff --git a/src/modules/tests/enums/test-sort-field.enum.ts b/src/modules/tests/enums/test-sort-field.enum.ts new file mode 100644 index 0000000..ef19f01 --- /dev/null +++ b/src/modules/tests/enums/test-sort-field.enum.ts @@ -0,0 +1,9 @@ +export enum TestSortField { + ID = 'id', + TITLE = 'title', + DESCRIPTION = 'description', + ACCESS_TYPE = 'accessType', + PRICE = 'price', + IS_ACTIVE = 'isActive', + CREATED_AT = 'createdAt', +} diff --git a/src/modules/tests/helpers/filter-tests.helper.ts b/src/modules/tests/helpers/filter-tests.helper.ts new file mode 100644 index 0000000..4a29b83 --- /dev/null +++ b/src/modules/tests/helpers/filter-tests.helper.ts @@ -0,0 +1,32 @@ +import { FindOptionsWhere, ILike } from 'typeorm'; +import { FindTestsDTO } from '../dtos/find-tests.dto'; + +export const filterTests = (query: FindTestsDTO) => { + const where: FindOptionsWhere = {}; + + if (query.id) { + where.id = query.id; + } + + if (query.title) { + where.title = ILike(`%${query.title}%`); + } + + if (query.description) { + where.description = ILike(`%${query.description}%`); + } + + if (query.accessType !== undefined) { + where.accessType = query.accessType; + } + + if (query.price !== undefined) { + where.price = query.price; + } + + if (query.isActive !== undefined) { + where.isActive = query.isActive; + } + + return where; +}; diff --git a/src/modules/tests/providers/tests-command.provider.ts b/src/modules/tests/providers/tests-command.provider.ts new file mode 100644 index 0000000..009ed14 --- /dev/null +++ b/src/modules/tests/providers/tests-command.provider.ts @@ -0,0 +1,104 @@ +import { + BadRequestException, + HttpStatus, + Injectable, + NotFoundException, +} from '@nestjs/common'; +import { CreateTestDTO } from '../dtos/create-test.dto'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Test } from '../entities/test.entity'; +import { Repository } from 'typeorm'; +import { I18nService } from 'nestjs-i18n'; +import { AppException } from '@/common/exceptions/app.exception'; +import { AppResponse } from '@/common/responses'; +import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception'; +import { UpdateTestDTO } from '../dtos/update-test.dto'; +import { AccessType } from '../enums/access-types.enum'; + +@Injectable() +export class TestsCommandProvider { + constructor( + /** + * Inject Tests Repository + */ + @InjectRepository(Test) + private readonly testRepository: Repository, + + /** + * Inject I18n Service + */ + private readonly i18nService: I18nService, + ) {} + + public async createOne(createTestDto: CreateTestDTO) { + const titleExists = await this.testRepository.findOne({ + where: { + title: createTestDto.title, + }, + }); + + if (titleExists) { + throw new AppException('validation.duplicateField', HttpStatus.CONFLICT, { + field: '$t(tests.fields.title)', + }); + } + + const newTest = this.testRepository.create(createTestDto); + + try { + await this.testRepository.save(newTest); + return new AppResponse( + newTest, + this.i18nService.translate('tests.messages.createSuccess'), + ); + } catch (err) { + throw new AppTimeoutException(err); + } + } + + public async updateOne(id: number, updateTestDto: UpdateTestDTO) { + const test = await this.testRepository.findOneBy({ id }); + + if (!test) { + throw new NotFoundException('tests.errors.testNotFound'); + } + + const accessType = updateTestDto.accessType ?? test.accessType; + const price = updateTestDto.price ?? test.price; + + if ( + (accessType === AccessType.PAID && !price) || + (accessType !== AccessType.PAID && price) + ) { + throw new BadRequestException( + this.i18nService.translate('tests.errors.priceAccessConstraint'), + ); + } + + Object.assign(test, updateTestDto); + + try { + return await this.testRepository.save(test); + } catch (err) { + throw new AppTimeoutException(err); + } + } + + public async deleteOne(id: number) { + let test: Test | null = null; + + try { + test = await this.testRepository.findOneBy({ id }); + } catch (err) { + throw new AppTimeoutException(err); + } + + if (!test) throw new NotFoundException('tests.errors.testNotFound'); + + try { + await this.testRepository.delete(test.id); + } catch (err) { + throw new AppTimeoutException(err); + } + } +} diff --git a/src/modules/tests/providers/tests-query.provider.ts b/src/modules/tests/providers/tests-query.provider.ts new file mode 100644 index 0000000..9961a32 --- /dev/null +++ b/src/modules/tests/providers/tests-query.provider.ts @@ -0,0 +1,98 @@ +import { Injectable, NotFoundException } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { PaginatedResponse } from '@/common/responses'; +import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception'; +import { FindTestsDTO } from '../dtos/find-tests.dto'; +import { filterTests } from '../helpers/filter-tests.helper'; +import Utils from '@/common/utils'; +import { Test } from '../entities/test.entity'; + +@Injectable() +export class TestsQueryProvider { + constructor( + /** + * Inject Tests Repository + */ + @InjectRepository(Test) + private readonly testRepository: Repository, + ) {} + + public async findAllForAdmin(query: FindTestsDTO) { + const filterOptions = filterTests(query); + const { page, take, limit, skip } = + Utils.PaginationUtils.getPaginationOptions(query); + + try { + const [tests, total] = await this.testRepository.findAndCount({ + where: filterOptions, + skip, + take, + order: query.sortBy + ? { + [query.sortBy]: query.order ?? 'ASC', + } + : { createdAt: 'DESC' }, + }); + + return new PaginatedResponse(tests, { + page, + limit, + total, + }); + } catch (err) { + throw new AppTimeoutException(err); + } + } + + public async findAllForUser() { + try { + return await this.testRepository.find({ + where: { isActive: true }, + select: { + id: true, + accessType: true, + description: true, + price: true, + title: true, + }, + order: { createdAt: 'DESC' }, + }); + } catch (err) { + throw new AppTimeoutException(err); + } + } + + public async findOneForAdmin(id: number) { + try { + return await this.testRepository.findOneBy({ id }); + } catch (err) { + throw new AppTimeoutException(err); + } + } + + public async findOneForUser(id: number) { + let test: Test | null; + + try { + test = await this.testRepository.findOne({ + where: { id, isActive: true }, + select: { + id: true, + accessType: true, + description: true, + price: true, + title: true, + }, + }); + } catch (err) { + throw new AppTimeoutException(err); + } + + if (!test) { + throw new NotFoundException('tests.errors.testNotFound'); + } + + return test; + } +} diff --git a/src/modules/tests/providers/tests.service.ts b/src/modules/tests/providers/tests.service.ts index 7da84eb..df94218 100644 --- a/src/modules/tests/providers/tests.service.ts +++ b/src/modules/tests/providers/tests.service.ts @@ -1,163 +1,49 @@ -import { - BadRequestException, - HttpStatus, - Injectable, - NotFoundException, - RequestTimeoutException, -} from '@nestjs/common'; -import { Repository } from 'typeorm'; -import { Test } from '../entities/test.entity'; -import { InjectRepository } from '@nestjs/typeorm'; +import { Injectable } from '@nestjs/common'; import { CreateTestDTO } from '../dtos/create-test.dto'; -import { AppException } from '@/common/exceptions/app.exception'; -import { AppResponse } from '@/common/responses'; -import { I18nService } from 'nestjs-i18n'; import { UpdateTestDTO } from '../dtos/update-test.dto'; -import { AccessType } from '../enums/access-types.enum'; +import { FindTestsDTO } from '../dtos/find-tests.dto'; +import { TestsQueryProvider } from './tests-query.provider'; +import { TestsCommandProvider } from './tests-command.provider'; @Injectable() export class TestsService { constructor( /** - * Inject Tests Repository + * Inject Tests Query Provider */ - @InjectRepository(Test) - private readonly testRepository: Repository, + private readonly testsQueryProvider: TestsQueryProvider, /** - * Inject I18n Service + * Inject Tests Command Provider */ - private readonly i18nService: I18nService, + private readonly testsCommandProvider: TestsCommandProvider, ) {} public async createOne(createTestDto: CreateTestDTO) { - const titleExists = await this.testRepository.findOne({ - where: { - title: createTestDto.title, - }, - }); - - if (titleExists) { - throw new AppException('validation.duplicateField', HttpStatus.CONFLICT, { - field: '$t(tests.fields.title)', - }); - } - - const newTest = this.testRepository.create(createTestDto); - - try { - await this.testRepository.save(newTest); - return new AppResponse( - newTest, - this.i18nService.translate('tests.messages.createSuccess'), - ); - } catch (err) { - throw new RequestTimeoutException('common.errors.requestTimeout', { - cause: err, - description: 'Error connecting to the database', - }); - } + return await this.testsCommandProvider.createOne(createTestDto); } - public async adminGetAll() { - try { - return await this.testRepository.find({ order: { createdAt: 'DESC' } }); - } catch (err) { - throw new RequestTimeoutException('common.errors.requestTimeout', { - cause: err, - description: 'Error connecting to the database', - }); - } + public async adminGetAll(query: FindTestsDTO) { + return await this.testsQueryProvider.findAllForAdmin(query); } public async userGetAll() { - try { - return await this.testRepository.find({ - where: { isActive: true }, - select: { - id: true, - accessType: true, - description: true, - price: true, - title: true, - }, - order: { createdAt: 'DESC' }, - }); - } catch (err) { - throw new RequestTimeoutException('common.errors.requestTimeout', { - cause: err, - description: 'Error connecting to the database', - }); - } + return await this.testsQueryProvider.findAllForUser(); } public async adminGetOne(id: number) { - try { - return await this.testRepository.findOneBy({ id }); - } catch (err) { - throw new RequestTimeoutException('common.errors.requestTimeout', { - cause: err, - description: 'Error connecting to the database', - }); - } + return await this.testsQueryProvider.findOneForAdmin(id); } public async userGetOne(id: number) { - let test: Test | null; - - try { - test = await this.testRepository.findOne({ - where: { id, isActive: true }, - select: { - id: true, - accessType: true, - description: true, - price: true, - title: true, - }, - }); - } catch (err) { - throw new RequestTimeoutException('common.errors.requestTimeout', { - cause: err, - description: 'Error connecting to the database', - }); - } - - if (!test) { - throw new NotFoundException('tests.errors.testNotFound'); - } - - return test; + return await this.testsQueryProvider.findOneForUser(id); } public async updateOne(id: number, updateTestDto: UpdateTestDTO) { - const test = await this.testRepository.findOneBy({ id }); + return await this.testsCommandProvider.updateOne(id, updateTestDto); + } - if (!test) { - throw new NotFoundException('tests.errors.testNotFound'); - } - - const accessType = updateTestDto.accessType ?? test.accessType; - const price = updateTestDto.price ?? test.price; - - if ( - (accessType === AccessType.PAID && !price) || - (accessType !== AccessType.PAID && price) - ) { - throw new BadRequestException( - this.i18nService.translate('tests.errors.priceAccessConstraint'), - ); - } - - Object.assign(test, updateTestDto); - - try { - return await this.testRepository.save(test); - } catch (err) { - throw new RequestTimeoutException('common.errors.requestTimeout', { - cause: err, - description: 'Error connecting to the database', - }); - } + public async deleteOne(id: number) { + return await this.testsCommandProvider.deleteOne(id); } } diff --git a/src/modules/tests/tests.module.ts b/src/modules/tests/tests.module.ts index af066df..b65a377 100644 --- a/src/modules/tests/tests.module.ts +++ b/src/modules/tests/tests.module.ts @@ -3,11 +3,13 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { Test } from './entities/test.entity'; import { TestsService } from './providers/tests.service'; import { TestsController } from './tests.controller'; +import { TestsQueryProvider } from './providers/tests-query.provider'; +import { TestsCommandProvider } from './providers/tests-command.provider'; @Module({ imports: [TypeOrmModule.forFeature([Test])], controllers: [TestsController], - providers: [TestsService], + providers: [TestsService, TestsQueryProvider, TestsCommandProvider], exports: [TestsService], }) export class TestsModule {} diff --git a/src/modules/users/providers/user-profile.provider.ts b/src/modules/users/providers/user-profile.provider.ts index 8683bf0..f9074de 100644 --- a/src/modules/users/providers/user-profile.provider.ts +++ b/src/modules/users/providers/user-profile.provider.ts @@ -1,11 +1,12 @@ import { HashingProvider } from '@/common/modules/hashing/providers/hashing.provider'; -import { Injectable, RequestTimeoutException } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { I18nService } from 'nestjs-i18n'; import { User } from '../entities/user.entity'; import { UpdateProfileDTO } from '../dto/update-profile.dto'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { AppResponse } from '@/common/responses'; +import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception'; @Injectable() export class UserProfileProvider { @@ -59,10 +60,7 @@ export class UserProfileProvider { try { await this.userRepository.update(user.id, updateData); } catch (err) { - throw new RequestTimeoutException('common.errors.requestTimeout', { - cause: err, - description: 'Error connecting to the database', - }); + throw new AppTimeoutException(err); } return { diff --git a/src/modules/users/providers/users.service.ts b/src/modules/users/providers/users.service.ts index b00e2fb..5094cf7 100644 --- a/src/modules/users/providers/users.service.ts +++ b/src/modules/users/providers/users.service.ts @@ -1,13 +1,10 @@ -import { - BadRequestException, - Injectable, - RequestTimeoutException, -} from '@nestjs/common'; +import { BadRequestException, Injectable } from '@nestjs/common'; import { Repository } from 'typeorm'; import { User } from '../entities/user.entity'; import { InjectRepository } from '@nestjs/typeorm'; import { UpdateProfileDTO } from '../dto/update-profile.dto'; import { UserProfileProvider } from './user-profile.provider'; +import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception'; @Injectable() export class UsersService { @@ -29,10 +26,7 @@ export class UsersService { try { user = await this.userRepository.findOneById(id); } catch (err) { - throw new RequestTimeoutException('common.errors.requestTimeout', { - cause: err, - description: 'Error connecting to the database', - }); + throw new AppTimeoutException(err); } if (!user) { @@ -46,10 +40,7 @@ export class UsersService { try { return await this.userRepository.findOneBy({ phone }); } catch (err) { - throw new RequestTimeoutException('common.errors.requestTimeout', { - cause: err, - description: 'Error connecting to the database', - }); + throw new AppTimeoutException(err); } } @@ -59,10 +50,7 @@ export class UsersService { try { await this.userRepository.save(newUser); } catch (err) { - throw new RequestTimeoutException('common.errors.requestTimeout', { - cause: err, - description: 'Error connecting to the database', - }); + throw new AppTimeoutException(err); } return newUser;