Skip to content

Commit eadbfac

Browse files
authored
Merge pull request #234 from boostcampwm-2022/223-docs-조회-버그-수정-및-rest-server-db-관련-리팩토링
rest, socket 서버 버그 수정 및 rest server db 관련 리팩토링
2 parents 3884c07 + 816912d commit eadbfac

File tree

17 files changed

+142
-116
lines changed

17 files changed

+142
-116
lines changed

backend/rest/src/auth/service/auth.service.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,15 @@ export class AuthService {
4848
* user info를 얻은 후, 가입이 되어있지 않다면 회원 가입을 합니다.
4949
* @param type 해당 social oauth 이름
5050
* @param authorizationCode 해당 social oauth의 인증으로 얻은 authorizationCode
51-
* @returns 가입 된 user의 id
51+
* @returns 가입 된 user info
5252
*/
53-
async socialStart({ type, authorizationCode }: { type: string; authorizationCode: string }) {
53+
async socialStart({
54+
type,
55+
authorizationCode,
56+
}: {
57+
type: string;
58+
authorizationCode: string;
59+
}): Promise<UserInfo> {
5460
this.setOauthInstanceByType(type);
5561

5662
const accessToken = await this.oauthInstance.getAccessTokenByAuthorizationCode(

backend/rest/src/common/typeorm-base.entity.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { IsBoolean, IsDate } from 'class-validator';
22
import { Column } from 'typeorm';
33

44
export class TypeormBaseEntity {
5-
@Column({ name: 'created_at', type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
5+
@Column({ name: 'created_at', type: 'timestamp', default: 'CURRENT_TIMESTAMP' })
66
@IsDate()
77
createdAt: Date;
88

9-
@Column({ name: 'updated_at', type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
9+
@Column({ name: 'updated_at', type: 'timestamp', default: 'CURRENT_TIMESTAMP' })
1010
@IsDate()
1111
updatedAt: Date;
1212

backend/rest/src/config/typeorm.config.ts

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,18 @@ import { ConfigService } from '@nestjs/config';
22
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
33
import { SnakeNamingStrategy } from 'typeorm-naming-strategies';
44

5-
export const typeormConfig =
6-
process.env.NODE_ENV === 'dev'
7-
? {
8-
useFactory: async (
9-
configService: ConfigService
10-
): Promise<TypeOrmModuleOptions> => ({
11-
type: 'mysql',
12-
host: 'localhost',
13-
port: 3306,
14-
username: configService.get('DB_USER'),
15-
password: configService.get('DB_PASSWORD'),
16-
database: configService.get('DB_NAME'),
17-
entities: [__dirname + '/../**/*.entity.{ts,js}'],
18-
logging: ['query', 'error'],
19-
synchronize: true,
20-
namingStrategy: new SnakeNamingStrategy(),
21-
}),
22-
inject: [ConfigService],
23-
}
24-
: {
25-
useFactory: async (
26-
configService: ConfigService
27-
): Promise<TypeOrmModuleOptions> => ({
28-
type: 'mysql',
29-
host: 'localhost',
30-
port: 3306,
31-
username: process.env.DB_USER,
32-
password: process.env.DB_PASSWORD,
33-
database: process.env.DB_NAME,
34-
entities: [__dirname + '/../**/*.entity.{ts,js}'],
35-
logging: [],
36-
synchronize: true,
37-
}),
38-
inject: [ConfigService],
39-
};
5+
export const typeormConfig = {
6+
useFactory: async (configService: ConfigService): Promise<TypeOrmModuleOptions> => ({
7+
type: 'mysql',
8+
host: 'localhost',
9+
port: 3306,
10+
username: configService.get('DB_USER'),
11+
password: configService.get('DB_PASSWORD'),
12+
database: configService.get('DB_NAME'),
13+
entities: [__dirname + '/../**/*.entity.{ts,js}'],
14+
logging: ['query', 'error'],
15+
synchronize: true,
16+
namingStrategy: new SnakeNamingStrategy(),
17+
}),
18+
inject: [ConfigService],
19+
};

backend/rest/src/constant/swagger.constant.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { HttpStatus } from '@nestjs/common';
22
import { RedirectUrlResponseDto } from 'src/auth/dto/redirect-url.dto';
33
import { UserIdResponseDto } from 'src/auth/dto/user-id.dto';
44
import { DocsListResponseDto } from 'src/interview/dto/docs-list.dto';
5-
import { DocsGetResponseDto } from 'src/interview/dto/docs.dto';
5+
import { DocsResponseDto } from 'src/interview/dto/docs.dto';
66
import { DocsRequestDto } from 'src/interview/dto/request-docs.dto';
7-
import { FeedbackRequestDto } from 'src/interview/dto/request-feedback.dto';
7+
import { FeedbackRequestDto } from 'src/interview/dto/feedback.dto';
88

99
export const REDIRECT_URL_SWAGGER = {
1010
SUMMARY: { summary: 'type별 oauth URL 가져오기' },
@@ -87,7 +87,7 @@ export const GET_INTERVIEW_DOCS_SWAGGER = {
8787
SUCCESS: {
8888
status: HttpStatus.OK,
8989
description: '성공',
90-
type: DocsGetResponseDto,
90+
type: DocsResponseDto,
9191
},
9292
FAIL: {
9393
status: HttpStatus.UNAUTHORIZED,

backend/rest/src/filter/http-exception.filter.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
Logger,
88
} from '@nestjs/common';
99
import { Request, Response } from 'express';
10+
import { QueryFailedError } from 'typeorm';
1011

1112
@Catch()
1213
export class HttpExceptionFilter implements ExceptionFilter {
@@ -17,7 +18,7 @@ export class HttpExceptionFilter implements ExceptionFilter {
1718
const res = ctx.getResponse<Response>();
1819
const req = ctx.getRequest<Request>();
1920

20-
if (!(exception instanceof HttpException)) {
21+
if (!(exception instanceof HttpException || exception instanceof QueryFailedError)) {
2122
console.error(exception);
2223
exception = new InternalServerErrorException();
2324
}
@@ -30,6 +31,9 @@ export class HttpExceptionFilter implements ExceptionFilter {
3031
logger.error(`[Exception Name] ${name}`);
3132
logger.error(`[Exception Message] ${statusCode} - ${message}`);
3233
logger.error(`[Exception Stack] ${stack}`);
34+
if (exception instanceof QueryFailedError) {
35+
Logger.error(`[SQL MESSAGE] ${exception.message}`);
36+
}
3337

3438
const response = {
3539
name,

backend/rest/src/interceptor/http.interceptor.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ export class RestInterceptor implements NestInterceptor {
99
const ctx = context.switchToHttp();
1010
const req = ctx.getRequest<Request>();
1111

12+
logger.log(`[Request URL] ${req.method} ${req.url}`);
13+
1214
const start = new Date().getTime();
1315
return next
1416
.handle()
1517
.pipe(
1618
tap(() => {
1719
const end = new Date();
18-
logger.log(`[Request URL] ${req.url}`);
1920
logger.log(`[Process Time] ${end.getTime() - start}ms`);
2021
})
2122
)

backend/rest/src/interview/controller/interview.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { JwtAuthGuard } from 'src/auth/guard/jwt.guard';
1616
import { DocsRequestDto } from '../dto/request-docs.dto';
1717
import { InterviewService } from '../service/interview.service';
1818
import { Request } from 'express';
19-
import { FeedbackRequestDto } from '../dto/request-feedback.dto';
19+
import { FeedbackRequestDto } from '../dto/feedback.dto';
2020
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
2121
import {
2222
CREATE_FEEDBACK_DOCS_SWAGGER,

backend/rest/src/interview/dto/docs.dto.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { ApiProperty } from '@nestjs/swagger';
22
import { IsDate, IsNotEmpty, IsNumber, IsString } from 'class-validator';
3-
import { feedbackBoxDto } from './request-feedback.dto';
3+
import { FeedbackBoxDto } from './feedback.dto';
44

5-
export class DocsGetResponseDto {
5+
export class DocsResponseDto {
66
@IsString()
77
@IsNotEmpty()
88
@ApiProperty({
@@ -52,5 +52,5 @@ export class UserFeedback {
5252
@IsNotEmpty()
5353
nickname: string;
5454

55-
feedbackList: feedbackBoxDto[];
55+
feedbackList: FeedbackBoxDto[];
5656
}

backend/rest/src/interview/dto/request-feedback.dto.ts renamed to backend/rest/src/interview/dto/feedback.dto.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ApiProperty } from '@nestjs/swagger';
2-
import { IsNotEmpty, IsNumber, IsString } from 'class-validator';
2+
import { Type } from 'class-transformer';
3+
import { IsNotEmpty, IsNumber, IsString, ValidateNested } from 'class-validator';
34

45
export class FeedbackRequestDto {
56
@IsString()
@@ -11,6 +12,8 @@ export class FeedbackRequestDto {
1112
docsUUID: string;
1213

1314
@IsNotEmpty()
15+
@ValidateNested({ each: true })
16+
@Type(() => FeedbackBoxDto)
1417
@ApiProperty({
1518
example: '{ startTime: 0, innerIndex: 0, content: "목소리에서 울림이 느껴지네요." }',
1619
description: 'feedbackbox (startTime, innerIndex, content)',
@@ -19,10 +22,10 @@ export class FeedbackRequestDto {
1922
type: 'feedbackBoxDto',
2023
},
2124
})
22-
feedbackList: feedbackBoxDto[];
25+
feedbackList: FeedbackBoxDto[];
2326
}
2427

25-
export class feedbackBoxDto {
28+
export class FeedbackBoxDto {
2629
@IsNumber()
2730
@IsNotEmpty()
2831
startTime: number;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { BaseBuilder } from '@common';
2+
import { DocsResponseDto, UserFeedback } from './docs.dto';
3+
4+
export class DocsResponseDtoBuilder extends BaseBuilder<DocsResponseDto> {
5+
constructor() {
6+
super(DocsResponseDto);
7+
}
8+
9+
setCreatedAt(createdAt: Date) {
10+
this.instance.createdAt = createdAt;
11+
return this;
12+
}
13+
14+
setDocsUUID(docsUUID: string) {
15+
this.instance.docsUUID = docsUUID;
16+
return this;
17+
}
18+
19+
setVideoPlayTime(videoPlayTime: number) {
20+
this.instance.videoPlayTime = videoPlayTime;
21+
return this;
22+
}
23+
24+
setVideoUrl(videoUrl: string) {
25+
this.instance.videoUrl = videoUrl;
26+
return this;
27+
}
28+
29+
setFeedback(feedbacks: UserFeedback[]) {
30+
this.instance.feedbacks = feedbacks;
31+
return this;
32+
}
33+
}

0 commit comments

Comments
 (0)