fix: eliminate untyped repository returns and standardize DomainException usage across all handlers
- Create typed DTOs (ListingDetailData, ListingSearchItem, ListingSellerItem) for repository read methods - Replace all Promise<any> and PaginatedResult<any> with concrete types in repository interface and implementation - Remove `as any` casts in search params by using Prisma enum types (TransactionType, PropertyType) - Migrate all 16 handlers from NestJS built-in exceptions to domain exceptions (NotFoundException, ValidationException, etc.) - Add CONTRIBUTING.md documenting error handling convention - All 230 tests pass, typecheck clean Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { CommandHandler, type ICommandHandler } from '@nestjs/cqrs';
|
||||
import { UnauthorizedException, Inject } from '@nestjs/common';
|
||||
import { Inject } from '@nestjs/common';
|
||||
import { UnauthorizedException } from '@modules/shared/domain/domain-exception';
|
||||
import { RefreshTokenCommand } from './refresh-token.command';
|
||||
import { TokenService, type TokenPair } from '../../../infrastructure/services/token.service';
|
||||
import { USER_REPOSITORY, type IUserRepository } from '../../../domain/repositories/user.repository';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CommandHandler, EventBus, type ICommandHandler } from '@nestjs/cqrs';
|
||||
import { ConflictException, BadRequestException } from '@nestjs/common';
|
||||
import { Inject } from '@nestjs/common';
|
||||
import { ConflictException, ValidationException } from '@modules/shared/domain/domain-exception';
|
||||
import { createId } from '@paralleldrive/cuid2';
|
||||
import { RegisterUserCommand } from './register-user.command';
|
||||
import { USER_REPOSITORY, type IUserRepository } from '../../../domain/repositories/user.repository';
|
||||
@@ -22,7 +22,7 @@ export class RegisterUserHandler implements ICommandHandler<RegisterUserCommand>
|
||||
// Validate phone
|
||||
const phoneResult = Phone.create(command.phone);
|
||||
if (phoneResult.isErr) {
|
||||
throw new BadRequestException(phoneResult.unwrapErr());
|
||||
throw new ValidationException(phoneResult.unwrapErr());
|
||||
}
|
||||
const phone = phoneResult.unwrap();
|
||||
|
||||
@@ -37,7 +37,7 @@ export class RegisterUserHandler implements ICommandHandler<RegisterUserCommand>
|
||||
if (command.email) {
|
||||
const emailResult = Email.create(command.email);
|
||||
if (emailResult.isErr) {
|
||||
throw new BadRequestException(emailResult.unwrapErr());
|
||||
throw new ValidationException(emailResult.unwrapErr());
|
||||
}
|
||||
email = emailResult.unwrap();
|
||||
|
||||
@@ -50,7 +50,7 @@ export class RegisterUserHandler implements ICommandHandler<RegisterUserCommand>
|
||||
// Hash password
|
||||
const passwordResult = await HashedPassword.fromPlain(command.password);
|
||||
if (passwordResult.isErr) {
|
||||
throw new BadRequestException(passwordResult.unwrapErr());
|
||||
throw new ValidationException(passwordResult.unwrapErr());
|
||||
}
|
||||
const passwordHash = passwordResult.unwrap();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { CommandHandler, type ICommandHandler } from '@nestjs/cqrs';
|
||||
import { Inject, NotFoundException } from '@nestjs/common';
|
||||
import { Inject } from '@nestjs/common';
|
||||
import { NotFoundException } from '@modules/shared/domain/domain-exception';
|
||||
import { CacheService, CachePrefix } from '@modules/shared/infrastructure/cache.service';
|
||||
import { VerifyKycCommand } from './verify-kyc.command';
|
||||
import { USER_REPOSITORY, type IUserRepository } from '../../../domain/repositories/user.repository';
|
||||
@@ -14,7 +15,7 @@ export class VerifyKycHandler implements ICommandHandler<VerifyKycCommand> {
|
||||
async execute(command: VerifyKycCommand): Promise<void> {
|
||||
const user = await this.userRepo.findById(command.userId);
|
||||
if (!user) {
|
||||
throw new NotFoundException('Người dùng không tồn tại');
|
||||
throw new NotFoundException('Người dùng', command.userId);
|
||||
}
|
||||
|
||||
user.updateKycStatus(command.kycStatus, command.kycData);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type IQueryHandler, QueryHandler } from '@nestjs/cqrs';
|
||||
import { Inject, NotFoundException } from '@nestjs/common';
|
||||
import { Inject } from '@nestjs/common';
|
||||
import { NotFoundException } from '@modules/shared/domain/domain-exception';
|
||||
import { CacheService, CachePrefix, CacheTTL } from '@modules/shared/infrastructure/cache.service';
|
||||
import { GetProfileQuery } from './get-profile.query';
|
||||
import { USER_REPOSITORY, type IUserRepository } from '../../../domain/repositories/user.repository';
|
||||
@@ -31,7 +32,7 @@ export class GetProfileHandler implements IQueryHandler<GetProfileQuery> {
|
||||
async () => {
|
||||
const user = await this.userRepo.findById(query.userId);
|
||||
if (!user) {
|
||||
throw new NotFoundException('Người dùng không tồn tại');
|
||||
throw new NotFoundException('Người dùng', query.userId);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user