Skip to content

Commit cb247e0

Browse files
authored
Merge pull request #448 from boostcampwm-2024/feat/add-feed-comment-count
✨ feat: Feed 조회 시 댓글 수 데이터 제공
2 parents 0ad4b9d + f026b8f commit cb247e0

File tree

13 files changed

+122
-25
lines changed

13 files changed

+122
-25
lines changed

server/src/comment/service/comment.service.ts

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,27 @@ import { Payload } from '../../common/guard/jwt.guard';
1111
import { DeleteCommentRequestDto } from '../dto/request/delete-comment.dto';
1212
import { UpdateCommentRequestDto } from '../dto/request/update-comment.dto';
1313
import { GetCommentRequestDto } from '../dto/request/get-comment.dto';
14+
import { DataSource } from 'typeorm';
15+
import { Comment } from '../entity/comment.entity';
1416

1517
@Injectable()
1618
export class CommentService {
1719
constructor(
1820
private readonly commentRepository: CommentRepository,
1921
private readonly feedRepository: FeedRepository,
2022
private readonly userRepository: UserRepository,
23+
private readonly dataSource: DataSource,
2124
) {}
2225

23-
private async commentCheck(userInformation: Payload, commentId: number) {
26+
private async getValidatedComment(
27+
userInformation: Payload,
28+
commentId: number,
29+
) {
2430
const commentObj = await this.commentRepository.findOne({
2531
where: {
2632
id: commentId,
2733
},
28-
relations: ['user'],
34+
relations: ['user', 'feed'],
2935
});
3036

3137
if (!commentObj) {
@@ -35,6 +41,8 @@ export class CommentService {
3541
if (userInformation.id !== commentObj.user.id) {
3642
throw new UnauthorizedException('본인이 작성한 댓글이 아닙니다.');
3743
}
44+
45+
return commentObj;
3846
}
3947

4048
async get(commentDto: GetCommentRequestDto) {
@@ -62,37 +70,73 @@ export class CommentService {
6270
}
6371

6472
async create(userInformation: Payload, commentDto: CreateCommentRequestDto) {
65-
const feed = await this.feedRepository.findOneBy({ id: commentDto.feedId });
66-
if (!feed) {
67-
throw new NotFoundException('존재하지 않는 게시글입니다.');
68-
}
73+
const queryRunner = this.dataSource.createQueryRunner();
74+
await queryRunner.connect();
75+
await queryRunner.startTransaction();
6976

70-
const user = await this.userRepository.findOneBy({
71-
id: userInformation.id,
72-
});
73-
if (!user) {
74-
throw new NotFoundException('존재하지 않는 유저입니다.');
75-
}
77+
try {
78+
const feed = await this.feedRepository.findOneBy({
79+
id: commentDto.feedId,
80+
});
81+
if (!feed) {
82+
throw new NotFoundException('존재하지 않는 게시글입니다.');
83+
}
7684

77-
await this.commentRepository.save({
78-
comment: commentDto.comment,
79-
feed,
80-
user,
81-
});
85+
const user = await this.userRepository.findOneBy({
86+
id: userInformation.id,
87+
});
88+
89+
if (!user) {
90+
throw new NotFoundException('존재하지 않는 유저입니다.');
91+
}
92+
93+
feed.commentCount++;
94+
await queryRunner.manager.save(feed);
95+
await queryRunner.manager.save(Comment, {
96+
comment: commentDto.comment,
97+
feed: { id: commentDto.feedId },
98+
user: { id: userInformation.id },
99+
});
100+
101+
await queryRunner.commitTransaction();
102+
} catch (error) {
103+
await queryRunner.rollbackTransaction();
104+
throw error;
105+
} finally {
106+
await queryRunner.release();
107+
}
82108
}
83109

84110
async delete(userInformation: Payload, commentDto: DeleteCommentRequestDto) {
85-
await this.commentCheck(userInformation, commentDto.commentId);
86-
await this.feedRepository.delete({
87-
id: commentDto.commentId,
88-
});
111+
const comment = await this.getValidatedComment(
112+
userInformation,
113+
commentDto.commentId,
114+
);
115+
116+
const queryRunner = this.dataSource.createQueryRunner();
117+
await queryRunner.connect();
118+
await queryRunner.startTransaction();
119+
120+
try {
121+
const feed = comment.feed;
122+
feed.commentCount--;
123+
await queryRunner.manager.save(feed);
124+
await queryRunner.manager.remove(comment);
125+
126+
await queryRunner.commitTransaction();
127+
} catch (error) {
128+
await queryRunner.rollbackTransaction();
129+
throw error;
130+
} finally {
131+
await queryRunner.release();
132+
}
89133
}
90134

91135
async update(userInformation: Payload, commentDto: UpdateCommentRequestDto) {
92-
await this.commentCheck(userInformation, commentDto.commentId);
93-
const commentObj = await this.commentRepository.findOneBy({
94-
id: commentDto.commentId,
95-
});
136+
const commentObj = await this.getValidatedComment(
137+
userInformation,
138+
commentDto.commentId,
139+
);
96140

97141
commentObj.comment = commentDto.newComment;
98142
await this.commentRepository.save(commentObj);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { MigrationInterface, QueryRunner } from 'typeorm';
2+
3+
export class AlterFeedCommentCountColumn1754027996037
4+
implements MigrationInterface
5+
{
6+
public async up(queryRunner: QueryRunner): Promise<void> {
7+
await queryRunner.query(`ALTER TABLE \`feed\`
8+
ADD \`comment_count\` int NOT NULL DEFAULT '0'`);
9+
}
10+
11+
public async down(queryRunner: QueryRunner): Promise<void> {
12+
await queryRunner.query(
13+
`ALTER TABLE \`feed\` DROP COLUMN \`comment_count\``,
14+
);
15+
}
16+
}

server/src/feed/api-docs/readFeedDetail.api-docs.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export function ApiReadFeedDetail() {
3838
},
3939
},
4040
likes: { type: 'number' },
41+
comments: { type: 'number' },
4142
},
4243
},
4344
},
@@ -56,6 +57,7 @@ export function ApiReadFeedDetail() {
5657
summary: '#example/n ### exexample',
5758
tag: ['tag1', 'tag2'],
5859
likes: 0,
60+
comments: 0,
5961
},
6062
},
6163
}),

server/src/feed/api-docs/readFeedPagination.api-docs.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export function ApiReadFeedPagination() {
6464
},
6565
},
6666
likes: { type: 'number' },
67+
comments: { type: 'number' },
6768
},
6869
},
6970
},
@@ -89,6 +90,7 @@ export function ApiReadFeedPagination() {
8990
isNew: false,
9091
tag: ['tag1', 'tag2'],
9192
likes: 0,
93+
comments: 0,
9294
},
9395
],
9496
lastId: 3,

server/src/feed/api-docs/readRecentFeedList.api-docs.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export function ApiReadRecentFeedList() {
3737
},
3838
},
3939
likes: { type: 'number' },
40+
comments: { type: 'number' },
4041
},
4142
},
4243
},
@@ -57,6 +58,7 @@ export function ApiReadRecentFeedList() {
5758
isNew: true,
5859
tag: ['tag1', 'tag2'],
5960
likes: 0,
61+
comments: 0,
6062
},
6163
],
6264
},

server/src/feed/api-docs/readTrendFeedList.api-docs.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export function ApiReadTrendFeedList() {
3636
},
3737
},
3838
likes: { type: 'number' },
39+
comments: { type: 'number' },
3940
},
4041
},
4142
},
@@ -58,6 +59,7 @@ export function ApiReadTrendFeedList() {
5859
viewCount: 0,
5960
tag: ['tag1', 'tag2'],
6061
likes: 0,
62+
comments: 0,
6163
},
6264
{
6365
id: 2,
@@ -70,6 +72,7 @@ export function ApiReadTrendFeedList() {
7072
viewCount: 0,
7173
tag: ['tag1', 'tag2'],
7274
likes: 0,
75+
comments: 0,
7376
},
7477
],
7578
},
@@ -90,6 +93,7 @@ export function ApiReadTrendFeedList() {
9093
viewCount: 0,
9194
tag: ['tag1', 'tag2'],
9295
likes: 0,
96+
comments: 0,
9397
},
9498
{
9599
id: 4,
@@ -102,6 +106,7 @@ export function ApiReadTrendFeedList() {
102106
viewCount: 0,
103107
tag: ['tag1', 'tag2'],
104108
likes: 0,
109+
comments: 0,
105110
},
106111
],
107112
},

server/src/feed/api-docs/searchFeedList.api-docs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ export function ApiSearchFeedList() {
103103
path: 'https://test.com/1',
104104
createdAt: '2024-10-27T02:08:55.000Z',
105105
likes: 0,
106+
comments: 0,
106107
},
107108
],
108109
totalPages: 3,

server/src/feed/dto/response/feed-detail.dto.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export class FeedDetailResponseDto {
1212
private viewCount: number,
1313
private summary: string,
1414
private likes: number,
15+
private comments: number,
1516
private tag: string[],
1617
) {}
1718

@@ -27,6 +28,7 @@ export class FeedDetailResponseDto {
2728
feed.viewCount,
2829
feed.summary,
2930
feed.likeCount,
31+
feed.commentCount,
3032
feed.tag ? feed.tag : [],
3133
);
3234
}

server/src/feed/dto/response/feed-pagination.dto.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export class FeedResult {
1313
private isNew: boolean,
1414
private tag: string[],
1515
private likes: number,
16+
private comments: number,
1617
) {}
1718

1819
private static toResultDto(feed: FeedPaginationResult) {
@@ -28,6 +29,7 @@ export class FeedResult {
2829
feed.isNew,
2930
feed.tag ? feed.tag : [],
3031
feed.likeCount,
32+
feed.commentCount,
3133
);
3234
}
3335

@@ -65,6 +67,7 @@ export class FeedTrendResponseDto {
6567
private thumbnail: string,
6668
private viewCount: number,
6769
private likes: number,
70+
private comments: number,
6871
private tag: string[],
6972
) {}
7073

@@ -79,6 +82,7 @@ export class FeedTrendResponseDto {
7982
feed.thumbnail,
8083
feed.viewCount,
8184
feed.likeCount,
85+
feed.commentCount,
8286
feed.tag ? feed.tag : [],
8387
);
8488
}

server/src/feed/dto/response/recent.dto.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export class FeedRecentResponseDto {
1010
private viewCount: number,
1111
private isNew: boolean,
1212
private likes: number,
13+
private comments: number,
1314
private tag: string[] | string,
1415
) {}
1516

@@ -25,6 +26,7 @@ export class FeedRecentResponseDto {
2526
feed.viewCount,
2627
feed.isNew,
2728
feed.likes,
29+
feed.comments,
2830
feed.tagList,
2931
);
3032
}
@@ -46,4 +48,5 @@ export type FeedRecentRedis = {
4648
isNew?: boolean;
4749
tagList: string[] | string;
4850
likes: number;
51+
comments: number;
4952
};

0 commit comments

Comments
 (0)