Skip to content

Commit dd08f3e

Browse files
authored
Merge pull request #385 from boostcampwm-2024/feat/comment
✨ feat: 댓글 등록, 수정, 삭제 기능 API 및 테스트 코드 작성
2 parents 43c2c5e + 05e77b4 commit dd08f3e

27 files changed

+1037
-9
lines changed

server/src/admin/module/admin.module.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ import { AdminRepository } from '../repository/admin.repository';
77
imports: [],
88
controllers: [AdminController],
99
providers: [AdminService, AdminRepository],
10+
exports: [AdminRepository],
1011
})
1112
export class AdminModule {}

server/src/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { TestModule } from './common/test/test.module';
1313
import { UserModule } from './user/module/user.module';
1414
import { ActivityModule } from './activity/module/activity.module';
1515
import { EmailModule } from './common/email/email.module';
16+
import { CommentModule } from './comment/module/comment.module';
1617

1718
@Module({
1819
imports: [
@@ -42,6 +43,7 @@ import { EmailModule } from './common/email/email.module';
4243
TestModule,
4344
StatisticModule,
4445
EmailModule,
46+
CommentModule,
4547
],
4648
controllers: [],
4749
providers: [],
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { applyDecorators } from '@nestjs/common';
2+
import {
3+
ApiBadRequestResponse,
4+
ApiCreatedResponse,
5+
ApiOperation,
6+
ApiUnauthorizedResponse,
7+
} from '@nestjs/swagger';
8+
9+
export function ApiCreateComment() {
10+
return applyDecorators(
11+
ApiOperation({
12+
summary: '댓글 등록 API',
13+
}),
14+
ApiCreatedResponse({
15+
description: 'Created',
16+
schema: {
17+
properties: {
18+
message: {
19+
type: 'string',
20+
},
21+
},
22+
},
23+
example: {
24+
message: '댓글 등록을 성공했습니다.',
25+
},
26+
}),
27+
ApiBadRequestResponse({
28+
description: 'Bad Request',
29+
example: {
30+
message: '오류 메세지',
31+
},
32+
}),
33+
ApiUnauthorizedResponse({
34+
description: 'Unauthorized',
35+
example: {
36+
message: '인증되지 않은 요청입니다.',
37+
},
38+
}),
39+
);
40+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { applyDecorators } from '@nestjs/common';
2+
import {
3+
ApiBadRequestResponse,
4+
ApiOkResponse,
5+
ApiOperation,
6+
ApiUnauthorizedResponse,
7+
} from '@nestjs/swagger';
8+
9+
export function ApiDeleteComment() {
10+
return applyDecorators(
11+
ApiOperation({
12+
summary: '댓글 삭제 API',
13+
}),
14+
ApiOkResponse({
15+
description: 'Ok',
16+
schema: {
17+
properties: {
18+
message: {
19+
type: 'string',
20+
},
21+
},
22+
},
23+
example: {
24+
message: '댓글 삭제를 성공했습니다.',
25+
},
26+
}),
27+
ApiBadRequestResponse({
28+
description: 'Bad Request',
29+
example: {
30+
message: '오류 메세지',
31+
},
32+
}),
33+
ApiUnauthorizedResponse({
34+
description: 'Unauthorized',
35+
example: {
36+
message: '인증되지 않은 요청입니다.',
37+
},
38+
}),
39+
);
40+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { applyDecorators } from '@nestjs/common';
2+
import {
3+
ApiBadRequestResponse,
4+
ApiOkResponse,
5+
ApiOperation,
6+
ApiUnauthorizedResponse,
7+
} from '@nestjs/swagger';
8+
9+
export function ApiUpdateComment() {
10+
return applyDecorators(
11+
ApiOperation({
12+
summary: '댓글 수정 API',
13+
}),
14+
ApiOkResponse({
15+
description: 'Ok',
16+
schema: {
17+
properties: {
18+
message: {
19+
type: 'string',
20+
},
21+
},
22+
},
23+
example: {
24+
message: '댓글을 수정을 성공했습니다.',
25+
},
26+
}),
27+
ApiBadRequestResponse({
28+
description: 'Bad Request',
29+
example: {
30+
message: '오류 메세지',
31+
},
32+
}),
33+
ApiUnauthorizedResponse({
34+
description: 'Unauthorized',
35+
example: {
36+
message: '인증되지 않은 요청입니다.',
37+
},
38+
}),
39+
);
40+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import {
2+
Body,
3+
Controller,
4+
Delete,
5+
HttpCode,
6+
HttpStatus,
7+
Patch,
8+
Post,
9+
Req,
10+
UseGuards,
11+
} from '@nestjs/common';
12+
import { ApiTags } from '@nestjs/swagger';
13+
import { CommentService } from '../service/comment.service';
14+
import { ApiCreateComment } from '../api-docs/createComment.api-docs';
15+
import { ApiDeleteComment } from '../api-docs/deleteComment.api-docs';
16+
import { ApiUpdateComment } from '../api-docs/updateComment.api-docs';
17+
import { JwtGuard } from '../../common/guard/jwt.guard';
18+
import { ApiResponse } from '../../common/response/common.response';
19+
import { CreateCommentRequestDto } from '../dto/request/create-comment.dto';
20+
import { DeleteCommentRequestDto } from '../dto/request/delete-comment.dto';
21+
import { UpdateCommentRequestDto } from '../dto/request/update-comment.dto';
22+
23+
@ApiTags('Comment')
24+
@Controller('comment')
25+
@UseGuards(JwtGuard)
26+
export class CommentController {
27+
constructor(private readonly commentService: CommentService) {}
28+
29+
@ApiCreateComment()
30+
@Post()
31+
@HttpCode(HttpStatus.CREATED)
32+
async createComment(@Req() req, @Body() commentDto: CreateCommentRequestDto) {
33+
await this.commentService.create(req.user, commentDto);
34+
return ApiResponse.responseWithNoContent('댓글 등록을 성공했습니다.');
35+
}
36+
37+
@ApiDeleteComment()
38+
@Delete()
39+
@HttpCode(HttpStatus.OK)
40+
async deleteComment(@Req() req, @Body() commentDto: DeleteCommentRequestDto) {
41+
await this.commentService.delete(req.user, commentDto);
42+
return ApiResponse.responseWithNoContent('댓글 삭제를 성공했습니다.');
43+
}
44+
45+
@ApiUpdateComment()
46+
@Patch()
47+
@HttpCode(HttpStatus.OK)
48+
async updateComment(@Req() req, @Body() commentDto: UpdateCommentRequestDto) {
49+
await this.commentService.update(req.user, commentDto);
50+
return ApiResponse.responseWithNoContent('댓글 수정을 성공했습니다.');
51+
}
52+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { IsInt, IsNotEmpty, IsString } from 'class-validator';
3+
4+
export class CreateCommentRequestDto {
5+
@ApiProperty({
6+
example: '댓글 내용',
7+
description: '댓글 내용을 입력해주세요.',
8+
})
9+
@IsString({
10+
message: '문자열을 입력해주세요',
11+
})
12+
@IsNotEmpty({ message: '댓글 내용을 입력하세요.' })
13+
comment: string;
14+
15+
@ApiProperty({
16+
example: '1',
17+
description: '게시글 번호를 입력해주세요.',
18+
})
19+
@IsInt({
20+
message: '숫자로 입력해주세요.',
21+
})
22+
@IsNotEmpty({ message: '피드 아이디를 입력하세요.' })
23+
feedId: number;
24+
25+
constructor(partial: Partial<CreateCommentRequestDto>) {
26+
Object.assign(this, partial);
27+
}
28+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { IsInt, IsNotEmpty } from 'class-validator';
3+
4+
export class DeleteCommentRequestDto {
5+
@ApiProperty({
6+
example: '1',
7+
description: '댓글 번호를 입력해주세요.',
8+
})
9+
@IsInt({
10+
message: '숫자로 입력해주세요.',
11+
})
12+
@IsNotEmpty({ message: '댓글 아이디를 입력하세요.' })
13+
commentId: number;
14+
15+
constructor(partial: Partial<DeleteCommentRequestDto>) {
16+
Object.assign(this, partial);
17+
}
18+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { IsInt, IsNotEmpty, IsString } from 'class-validator';
3+
4+
export class UpdateCommentRequestDto {
5+
@ApiProperty({
6+
example: '댓글 번호',
7+
description: '댓글 번호를 입력해주세요.',
8+
})
9+
@IsInt({
10+
message: '정수로 입력하세요.',
11+
})
12+
@IsNotEmpty({ message: '댓글 아이디를 입력하세요.' })
13+
commentId: number;
14+
15+
@ApiProperty({
16+
example: '수정할 내용',
17+
description: '수정할 내용을 입력해주세요.',
18+
})
19+
@IsString({
20+
message: '문자열을 입력하세요.',
21+
})
22+
@IsNotEmpty({ message: '댓글 내용을 입력하세요.' })
23+
newComment: string;
24+
25+
constructor(partial: Partial<UpdateCommentRequestDto>) {
26+
Object.assign(this, partial);
27+
}
28+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {
2+
BaseEntity,
3+
Column,
4+
CreateDateColumn,
5+
Entity,
6+
JoinColumn,
7+
ManyToOne,
8+
PrimaryGeneratedColumn,
9+
} from 'typeorm';
10+
import { Feed } from '../../feed/entity/feed.entity';
11+
import { User } from '../../user/entity/user.entity';
12+
13+
@Entity({ name: 'comment' })
14+
export class Comment extends BaseEntity {
15+
@PrimaryGeneratedColumn()
16+
id: number;
17+
18+
@Column({
19+
name: 'comment',
20+
nullable: false,
21+
type: 'text',
22+
})
23+
comment: string;
24+
25+
@CreateDateColumn({
26+
name: 'date',
27+
nullable: false,
28+
})
29+
date: Date;
30+
31+
@ManyToOne(() => Feed, (feed) => feed.id, {
32+
nullable: false,
33+
onUpdate: 'CASCADE',
34+
onDelete: 'CASCADE',
35+
})
36+
@JoinColumn({
37+
name: 'feed_id',
38+
})
39+
feed: Feed;
40+
41+
@ManyToOne(() => User, (user) => user.id, {
42+
nullable: false,
43+
onUpdate: 'CASCADE',
44+
onDelete: 'CASCADE',
45+
})
46+
@JoinColumn({
47+
name: 'user_id',
48+
})
49+
user: User;
50+
}

0 commit comments

Comments
 (0)