-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* chore: configure linter (#7) chore: configure linter * fix: resolve eslint configuration error (#11) * feat: make register * feat: error exception handling * feat: add api prefix * feat: duplication check api * fix: resolve conflict error --------- Co-authored-by: shl0501 <[email protected]>
- Loading branch information
Showing
20 changed files
with
900 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
generator client { | ||
provider = "prisma-client-js" | ||
} | ||
|
||
datasource db { | ||
provider = "postgresql" | ||
url = env("DATABASE_URL") | ||
} | ||
|
||
model User { | ||
user_id Int @id @default(autoincrement()) | ||
email String @unique | ||
password String | ||
nickname String @unique | ||
created_at DateTime @default(now()) | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
import { Module } from '@nestjs/common'; | ||
|
||
import { AppController } from './app.controller'; | ||
import { AppService } from './app.service'; | ||
import { PrismaModule } from './prisma/prisma.module'; | ||
import { UsersModule } from './users/users.module'; | ||
|
||
@Module({ | ||
imports: [], | ||
controllers: [AppController], | ||
providers: [AppService], | ||
imports: [UsersModule, PrismaModule], | ||
controllers: [], | ||
providers: [], | ||
}) | ||
export class AppModule {} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { ArgumentsHost, Catch, ExceptionFilter, HttpStatus } from '@nestjs/common'; | ||
import { | ||
PrismaClientInitializationError, | ||
PrismaClientKnownRequestError, | ||
PrismaClientRustPanicError, | ||
PrismaClientUnknownRequestError, | ||
PrismaClientValidationError, | ||
} from '@prisma/client/runtime/library'; | ||
import { Response } from 'express'; | ||
|
||
@Catch( | ||
PrismaClientKnownRequestError, | ||
PrismaClientUnknownRequestError, | ||
PrismaClientRustPanicError, | ||
PrismaClientInitializationError, | ||
PrismaClientValidationError, | ||
) | ||
export class PrismaExceptionFilter implements ExceptionFilter { | ||
catch(exception: any, host: ArgumentsHost) { | ||
const ctx = host.switchToHttp(); | ||
const response = ctx.getResponse<Response>(); | ||
const status = HttpStatus.BAD_REQUEST; | ||
|
||
const errorResponse = { | ||
type: 'fail', | ||
error: { | ||
message: '알 수 없는 오류가 발생했습니다.', | ||
}, | ||
}; | ||
|
||
if (exception instanceof PrismaClientKnownRequestError) { | ||
if (exception.code === 'P2002') errorResponse.error.message = '이미 존재하는 값입니다. 다른 값을 사용하세요.'; | ||
else errorResponse.error.message = `Prisma 오류 발생: ${exception.message}`; | ||
} else if (exception instanceof PrismaClientUnknownRequestError) { | ||
errorResponse.error.message = `알 수 없는 Prisma 오류 발생: ${exception.message}`; | ||
} else if (exception instanceof PrismaClientRustPanicError) { | ||
errorResponse.error.message = 'Prisma 엔진에서 패닉이 발생했습니다. 관리자에게 문의하세요.'; | ||
} else if (exception instanceof PrismaClientInitializationError) { | ||
errorResponse.error.message = 'Prisma 초기화 오류가 발생했습니다. 설정을 확인하세요.'; | ||
} else if (exception instanceof PrismaClientValidationError) { | ||
errorResponse.error.message = `유효성 검사 오류: ${exception.message}`; | ||
} | ||
|
||
response.status(status).json(errorResponse); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { ArgumentsHost, BadRequestException, Catch, ExceptionFilter } from '@nestjs/common'; | ||
import { Request, Response } from 'express'; | ||
|
||
@Catch(BadRequestException) | ||
export class ValidationExceptionFilter implements ExceptionFilter { | ||
catch(exception: BadRequestException, host: ArgumentsHost) { | ||
const ctx = host.switchToHttp(); | ||
const response = ctx.getResponse<Response>(); | ||
const request = ctx.getRequest<Request>(); | ||
const status = exception.getStatus(); | ||
const exceptionResponse = exception.getResponse(); | ||
|
||
const errorMessage = typeof exceptionResponse === 'string' ? exceptionResponse : (exceptionResponse as any).message; | ||
|
||
response.status(status).json({ | ||
type: 'fail', | ||
error: { | ||
statusCode: status, | ||
timestamp: new Date().toISOString(), | ||
path: request.url, | ||
messages: Array.isArray(errorMessage) ? errorMessage : [errorMessage], | ||
}, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,20 @@ | ||
import { ValidationPipe } from '@nestjs/common'; | ||
import { NestFactory } from '@nestjs/core'; | ||
|
||
import { AppModule } from './app.module'; | ||
|
||
import { PrismaExceptionFilter } from './filters/prisma-exception.filter'; | ||
import { ValidationExceptionFilter } from './filters/validation-exception.filter'; | ||
async function bootstrap() { | ||
const app = await NestFactory.create(AppModule); | ||
|
||
app.setGlobalPrefix('api'); | ||
|
||
app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true })); | ||
|
||
app.useGlobalFilters(new ValidationExceptionFilter()); | ||
|
||
app.useGlobalFilters(new PrismaExceptionFilter()); | ||
|
||
await app.listen(process.env.PORT ?? 3000); | ||
} | ||
bootstrap(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { Module } from '@nestjs/common'; | ||
|
||
import { PrismaService } from './prisma.service'; | ||
|
||
@Module({ | ||
providers: [PrismaService], | ||
exports: [PrismaService], | ||
}) | ||
export class PrismaModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common'; | ||
import { PrismaClient } from '@prisma/client'; | ||
|
||
@Injectable() | ||
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy { | ||
async onModuleInit() { | ||
await this.$connect(); | ||
} | ||
|
||
async onModuleDestroy() { | ||
await this.$disconnect(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { IsEmail, IsNotEmpty, IsString, MaxLength, MinLength, NotContains } from 'class-validator'; | ||
|
||
export class CreateUserDto { | ||
@IsEmail() | ||
@IsNotEmpty() | ||
@NotContains(' ') | ||
email: string; | ||
|
||
@IsString() | ||
@IsNotEmpty() | ||
@MinLength(3) | ||
@MaxLength(20) | ||
@NotContains(' ') | ||
nickname: string; | ||
|
||
@IsString() | ||
@MinLength(8) | ||
@MaxLength(20) | ||
@NotContains(' ') | ||
password: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { IsEmail, IsOptional, IsString, MaxLength, MinLength, NotContains } from 'class-validator'; | ||
|
||
export class ValidateUserDto { | ||
@IsOptional() | ||
@IsEmail() | ||
@NotContains(' ') | ||
email: string; | ||
|
||
@IsOptional() | ||
@IsString() | ||
@MinLength(3) | ||
@MaxLength(20) | ||
@NotContains(' ') | ||
nickname: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { Test, TestingModule } from '@nestjs/testing'; | ||
|
||
import { UsersController } from './users.controller'; | ||
import { UsersService } from './users.service'; | ||
|
||
describe('UsersController', () => { | ||
let controller: UsersController; | ||
|
||
beforeEach(async () => { | ||
const module: TestingModule = await Test.createTestingModule({ | ||
controllers: [UsersController], | ||
providers: [UsersService], | ||
}).compile(); | ||
|
||
controller = module.get<UsersController>(UsersController); | ||
}); | ||
|
||
it('should be defined', () => { | ||
expect(controller).toBeDefined(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { BadRequestException, Body, Controller, Get, Post, Query } from '@nestjs/common'; | ||
|
||
import { CreateUserDto } from './dto/create-user.dto'; | ||
import { ValidateUserDto } from './dto/validate-user.dto'; | ||
import { UsersService } from './users.service'; | ||
|
||
@Controller('users') | ||
export class UsersController { | ||
constructor(private readonly usersService: UsersService) {} | ||
|
||
@Post() | ||
async create(@Body() createUserDto: CreateUserDto) { | ||
await this.usersService.create(createUserDto); | ||
return { | ||
type: 'success', | ||
data: {}, | ||
}; | ||
} | ||
|
||
@Get() | ||
async checkDuplication(@Query() validateUserDto: ValidateUserDto) { | ||
if (!validateUserDto.email && !validateUserDto.nickname) throw new BadRequestException('중복확인을 위한 email 또는 nickname을 제공해주세요.'); | ||
|
||
if (validateUserDto.email && validateUserDto.nickname) throw new BadRequestException('이메일 또는 닉네임 하나만 요청해 주세요.'); | ||
return { | ||
type: 'success', | ||
data: { | ||
exists: await this.usersService.exist(validateUserDto), | ||
}, | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Module } from '@nestjs/common'; | ||
|
||
import { UsersController } from './users.controller'; | ||
import { UserRepository } from './users.repository'; | ||
import { UsersService } from './users.service'; | ||
import { PrismaModule } from '../prisma/prisma.module'; | ||
|
||
@Module({ | ||
imports: [PrismaModule], | ||
controllers: [UsersController], | ||
providers: [UsersService, UserRepository], | ||
}) | ||
export class UsersModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
|
||
import { PrismaService } from '../prisma/prisma.service'; | ||
import { CreateUserDto } from './dto/create-user.dto'; | ||
|
||
@Injectable() | ||
export class UserRepository { | ||
constructor(private readonly prisma: PrismaService) {} | ||
|
||
async create(data: CreateUserDto) { | ||
await this.prisma.user.create({ data }); | ||
} | ||
|
||
async findByEmail(email: string) { | ||
return this.prisma.user.findUnique({ | ||
where: { email }, | ||
}); | ||
} | ||
|
||
async findByNickname(nickname: string) { | ||
return this.prisma.user.findUnique({ | ||
where: { nickname }, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Test, TestingModule } from '@nestjs/testing'; | ||
|
||
import { UsersService } from './users.service'; | ||
|
||
describe('UsersService', () => { | ||
let service: UsersService; | ||
|
||
beforeEach(async () => { | ||
const module: TestingModule = await Test.createTestingModule({ | ||
providers: [UsersService], | ||
}).compile(); | ||
|
||
service = module.get<UsersService>(UsersService); | ||
}); | ||
|
||
it('should be defined', () => { | ||
expect(service).toBeDefined(); | ||
}); | ||
}); |
Oops, something went wrong.