Skip to content

Commit 86010f6

Browse files
authored
Merge pull request #332 from prgrms-web-devcourse-final-project/develop
Post 도메인 리팩토링 영상 관련 테스트 추가 영상 업로드 permitAll되고있던 부분 제거 영상 다운로드시 화질을 함께 명시 하고 원본파일이 아닌 트랜스코딩된 mpd파일을 받을 수 있는 preSignedUrl반환하도록 수정
2 parents ef69103 + 6b7b0c0 commit 86010f6

File tree

21 files changed

+415
-240
lines changed

21 files changed

+415
-240
lines changed

back/src/main/java/com/back/domain/file/video/controller/VideoController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ public RsData<UploadUrlGetResponse> getUploadUrl(@RequestParam String filename)
3737

3838
@GetMapping("/videos/download")
3939
@Operation(summary = "다운로드용 URL 요청", description = "파일 다운로드를 위한 Presigned URL을 발급받습니다.")
40-
public RsData<DownLoadUrlGetResponse> getDownloadUrls(@RequestParam String objectKey) {
41-
PresignedUrlResponse downloadUrl = fileManager.getDownloadUrl(objectKey);
40+
public RsData<DownLoadUrlGetResponse> getDownloadUrls(@RequestParam String uuid, @RequestParam String resolution) {
41+
PresignedUrlResponse downloadUrl = fileManager.getDownloadUrl(uuid, resolution);
4242
DownLoadUrlGetResponse response = new DownLoadUrlGetResponse(downloadUrl.url().toString(), downloadUrl.expiresAt());
4343
return new RsData<>("200", "다운로드용 URL 요청완료", response);
4444
}

back/src/main/java/com/back/domain/file/video/repository/VideoRepository.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@
99
@Repository
1010
public interface VideoRepository extends JpaRepository<Video, Integer> {
1111
Optional<Video> findByUuid(String uuid);
12+
boolean existsByUuid(String uuid);
1213
}

back/src/main/java/com/back/domain/file/video/service/FileManager.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88

99
import java.net.URL;
1010
import java.time.LocalDateTime;
11+
import java.util.Set;
1112
import java.util.UUID;
1213

1314
@Service
1415
@RequiredArgsConstructor
1516
public class FileManager {
1617
private final VideoService videoService;
1718
private final S3Service s3Service;
19+
private final Set<String> validResolutions = Set.of("480p", "720p", "1080p");
1820

1921
public PresignedUrlResponse getUploadUrl(String filename) {
2022
String contentType = validateAndGetContentType(filename);
@@ -53,8 +55,11 @@ private String validateAndGetContentType(String filename) {
5355
}
5456
}
5557

56-
public PresignedUrlResponse getDownloadUrl(String objectKey) {
58+
public PresignedUrlResponse getDownloadUrl(String uuid, String resolution) {
5759
Integer expires = 60;
60+
validateResolution(resolution);
61+
videoService.isExistByUuid(uuid);
62+
String objectKey = "transcoded/videos/" + uuid + "/" + resolution + "/manifest.mpd";
5863
URL url = s3Service.generateDownloadUrl(objectKey, expires);
5964
LocalDateTime expiresAt = LocalDateTime.now().plusMinutes(expires);
6065
return new PresignedUrlResponse(url, expiresAt);
@@ -68,4 +73,10 @@ public void updateVideoStatus(String videoId, String status) {
6873
videoService.createVideo(videoId, status, "/", 0);
6974
}
7075
}
76+
77+
public void validateResolution(String resolution) {
78+
if (!validResolutions.contains(resolution)) {
79+
throw new ServiceException("400", "지원하지 않는 해상도입니다: " + resolution);
80+
}
81+
}
7182
}

back/src/main/java/com/back/domain/file/video/service/VideoService.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,10 @@ public Video updateStatus(String uuid, String status) {
2929
news.updateStatus(status);
3030
return videoRepository.save(news);
3131
}
32+
33+
public void isExistByUuid(String uuid) {
34+
if (!videoRepository.existsByUuid(uuid)) {
35+
throw new ServiceException("404", "Video not found");
36+
}
37+
}
3238
}

back/src/main/java/com/back/domain/post/comment/controller/PostCommentController.java

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,12 @@
55
import com.back.domain.post.comment.dto.CommentCreateRequest;
66
import com.back.domain.post.comment.dto.CommentDeleteRequest;
77
import com.back.domain.post.comment.dto.CommentModifyRequest;
8-
import com.back.domain.post.comment.entity.PostComment;
98
import com.back.domain.post.comment.service.PostCommentService;
109
import com.back.global.rq.Rq;
1110
import com.back.global.rsData.RsData;
1211
import io.swagger.v3.oas.annotations.Operation;
13-
import io.swagger.v3.oas.annotations.tags.Tag;
1412
import jakarta.validation.Valid;
15-
import jakarta.validation.constraints.Positive;
1613
import lombok.RequiredArgsConstructor;
17-
import org.springframework.beans.factory.annotation.Autowired;
18-
import org.springframework.transaction.annotation.Transactional;
1914
import org.springframework.web.bind.annotation.*;
2015

2116
import java.util.List;
@@ -30,40 +25,42 @@ public class PostCommentController {
3025

3126
@Operation(summary = "댓글 생성", description = "comment는 공백이나 Null이 될 수 없습니다. comment의 글자 수 제한은 없습니다.")
3227
@PostMapping("/{post_id}/comment")
33-
public RsData<Void> createComment(@PathVariable Long post_id,
28+
public RsData<Void> createComment(@PathVariable(name = "post_id") Long postId,
3429
@Valid @RequestBody CommentCreateRequest commentCreateRequest
3530
) {
3631
Member member = rq.getActor();
37-
postCommentService.createComment(member, post_id, commentCreateRequest);
32+
postCommentService.createComment(member, postId, commentCreateRequest);
3833

3934
return new RsData<>("200", "댓글 작성 완료", null);
4035
}
4136

4237
@Operation(summary = "댓글 다건 조회")
4338
@GetMapping("/post/{post_id}")
44-
public RsData<List<CommentAllResponse>> getAllPostComment(@PathVariable Long post_id) {
45-
List<CommentAllResponse> postAllResponse = postCommentService.getAllPostCommentResponse(post_id);
39+
public RsData<List<CommentAllResponse>> getAllPostComment(@PathVariable(name = "post_id") Long postId) {
40+
List<CommentAllResponse> postAllResponse = postCommentService.getAllPostCommentResponse(postId);
4641
return new RsData<>("200", "댓글 조회 성공", postAllResponse);
4742
}
4843

4944
@Operation(summary = "댓글 삭제", description = "commentId는 공백이나 Null이 될 수 없습니다.")
5045
@DeleteMapping("/{post_id}/comment")
51-
public RsData<Void> removePostComment(@PathVariable @Positive Long post_id
46+
public RsData<Void> removePostComment(@PathVariable(name = "post_id") Long postId
47+
5248
, @RequestBody @Valid CommentDeleteRequest commentDeleteRequest) {
5349
Member member = rq.getActor();
5450

55-
postCommentService.removePostComment(post_id, commentDeleteRequest, member);
51+
postCommentService.removePostComment(postId, commentDeleteRequest, member);
5652

5753
return new RsData<>("200", "댓글 삭제 성공", null);
5854
}
5955

6056
@Operation(summary = "댓글 수정", description = "commentId, content는 공백이나 Null이 될 수 없습니다. content의 글자 수 제한은 없습니다. ")
6157
@PutMapping("/{post_id}/comment")
62-
public RsData<Void> updatePostComment(@PathVariable Long post_id
58+
public RsData<Void> updatePostComment(@PathVariable(name = "post_id") Long postId
59+
6360
, @Valid @RequestBody CommentModifyRequest commentModifyRequest) {
6461
Member member = rq.getActor();
6562

66-
postCommentService.updatePostComment(post_id, commentModifyRequest, member);
63+
postCommentService.updatePostComment(postId, commentModifyRequest, member);
6764

6865
return new RsData<>("200", "댓글 수정 성공", null);
6966
}
@@ -77,8 +74,8 @@ public RsData<Void> adoptComment(@PathVariable Long commentId) {
7774

7875
@Operation(summary = "채택된 댓글 가져오기 ")
7976
@GetMapping("isAdopted/{post_id}")
80-
public RsData<CommentAllResponse> getAdoptComment(@PathVariable Long post_id) {
81-
CommentAllResponse commentAllResponse = postCommentService.getAdoptedComment(post_id);
77+
public RsData<CommentAllResponse> getAdoptComment(@PathVariable(name = "post_id") Long postId) {
78+
CommentAllResponse commentAllResponse = postCommentService.getAdoptedComment(postId);
8279

8380
return new RsData<>("200", "채택된 댓글 조회 성공", commentAllResponse);
8481
}

back/src/main/java/com/back/domain/post/comment/service/PostCommentService.java

Lines changed: 60 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import com.back.domain.post.comment.entity.PostComment;
99
import com.back.domain.post.comment.repository.PostCommentRepository;
1010
import com.back.domain.post.post.entity.Post;
11-
import com.back.domain.post.post.repository.PostRepository;
11+
import com.back.domain.post.post.service.PostService;
1212
import com.back.global.exception.ServiceException;
1313
import jakarta.transaction.Transactional;
1414
import lombok.RequiredArgsConstructor;
@@ -20,16 +20,13 @@
2020
@Service
2121
@RequiredArgsConstructor
2222
public class PostCommentService {
23-
private final PostRepository postRepository;
23+
private final PostService postService;
2424
private final PostCommentRepository postCommentRepository;
2525

2626
@Transactional
2727
public void createComment(Member member, Long postId, CommentCreateRequest commentCreateRequest) {
28-
Post post = postRepository.findById(postId).orElseThrow(() -> new ServiceException("400", "해당 Id의 게시글이 없습니다."));
29-
30-
if ( commentCreateRequest.comment() == null || commentCreateRequest.comment().isEmpty()) {
31-
throw new ServiceException("400", "댓글은 비어 있을 수 없습니다.");
32-
}
28+
validateComment(commentCreateRequest.comment());
29+
Post post = postService.findPostById(postId);
3330

3431
PostComment postComment = PostComment.builder()
3532
.post(post)
@@ -49,111 +46,113 @@ public List<CommentAllResponse> getAllPostCommentResponse(Long postId) {
4946
validatePostExists(postId);
5047

5148
List<PostComment> listPostComment = postCommentRepository.findCommentsWithMemberByPostId(postId);
52-
5349
return listPostComment.stream()
5450
.map(CommentAllResponse::from)
5551
.toList();
5652
}
5753

5854
@Transactional
5955
public void removePostComment(Long postId, CommentDeleteRequest commentDeleteRequest, Member member) {
60-
validatePostExists(postId);
61-
62-
PostComment postComment = getPostCommentById(commentDeleteRequest.commentId());
56+
PostComment postComment = findCommentById(commentDeleteRequest.commentId());
6357
Member author = postComment.getMember();
6458

65-
66-
if(!Objects.equals(member.getId(), author.getId())) {
67-
throw new ServiceException("400", "삭제 권한이 없습니다.");
68-
}
69-
70-
// if(postComment.getIsAdopted()) {
71-
// throw new ServiceException("400", "채택된 댓글은 삭제할 수 없습니다.");
72-
// }
59+
validateAuthorized(member,author);
60+
validatePostExists(postId);
7361

7462
postCommentRepository.delete(postComment);
75-
7663
}
7764

7865
@Transactional
7966
public void updatePostComment(Long postId, CommentModifyRequest commentModifyRequest, Member member) {
8067
validatePostExists(postId);
8168

82-
PostComment postComment = getPostCommentById(commentModifyRequest.commentId());
69+
PostComment postComment = findCommentById(commentModifyRequest.commentId());
8370
Member author = postComment.getMember();
8471

85-
86-
if(!Objects.equals(member.getId(), author.getId())) {
87-
throw new ServiceException("400", "수정 권한이 없습니다.");
88-
}
89-
90-
if ( commentModifyRequest.content() == null || commentModifyRequest.content().isEmpty()) {
91-
throw new ServiceException("400", "댓글은 비어 있을 수 없습니다.");
92-
}
72+
validateAuthorized(member, author);
73+
validateComment(commentModifyRequest.content());
9374

9475
postComment.updateContent(commentModifyRequest.content());
9576
}
9677

78+
@Transactional
79+
public void adoptComment(Long commentId, Member member) {
80+
PostComment postComment = findCommentById(commentId);
9781

82+
Post post = postComment.getPost();
9883

99-
private void validatePostExists(Long postId) {
100-
if(postId == null || postId <= 0) {
101-
throw new ServiceException("400", "유효하지 않은 게시글 Id입니다.");
102-
}
84+
validateIsPostAuthor(post, member);
85+
validatePostType(post);
86+
validateAlreadyAdoptedComment(postComment);
87+
validateAlreadyExistsAdoptedComment(post);
10388

104-
if (!postRepository.existsById(postId)) {
105-
throw new ServiceException("400", "해당 Id의 게시글이 없습니다.");
106-
}
89+
postComment.adoptComment();
90+
post.updateResolveStatus(true);
91+
}
10792

93+
@Transactional
94+
public CommentAllResponse getAdoptedComment(Long postId) {
95+
Post post = postService.findPostById(postId);
10896

109-
}
97+
validatePostType(post);
11098

111-
private PostComment getPostCommentById(Long commentId) {
112-
return postCommentRepository.findById(commentId).orElseThrow(() -> new ServiceException("400", "해당 Id의 댓글이 없습니다."));
99+
PostComment postComment = validateAdoptedComment(post);
100+
return CommentAllResponse.from(postComment);
113101
}
114102

115-
@Transactional
116-
public void adoptComment(Long commentId, Member member) {
117-
PostComment postComment = postCommentRepository.findById(commentId)
118-
.orElseThrow(() -> new ServiceException("400", "해당 Id의 댓글이 없습니다."));
119103

120-
Post post = postComment.getPost();
121104

105+
106+
107+
// ========== 헬퍼 메소드들 ========== //
108+
private void validateIsPostAuthor(Post post, Member member){
122109
if (!post.isAuthor(member)) {
123110
throw new ServiceException("400", "채택 권한이 없습니다.");
124111
}
112+
}
125113

126-
if (post.getPostType() != Post.PostType.QUESTIONPOST) {
127-
throw new ServiceException("400", "질문 게시글에만 댓글 채택이 가능합니다.");
128-
}
129-
114+
private void validateAlreadyAdoptedComment(PostComment postComment){
130115
if (postComment.getIsAdopted()) {
131116
throw new ServiceException("400", "이미 채택된 댓글입니다.");
132117
}
118+
}
133119

134-
// 이미 채택된 댓글이 있는지 확인
135-
boolean alreadyAdopted = postCommentRepository.existsByPostAndIsAdoptedTrue(post);
136-
if (alreadyAdopted) {
120+
private void validateAlreadyExistsAdoptedComment(Post post) {
121+
if (postCommentRepository.existsByPostAndIsAdoptedTrue(post)) {
137122
throw new ServiceException("400", "이미 채택된 댓글이 있습니다.");
138123
}
124+
}
139125

140-
postComment.adoptComment();
141-
142-
post.updateResolveStatus(true);
126+
private void validateAuthorized(Member member, Member author) {
127+
if(!Objects.equals(member.getId(), author.getId())) {
128+
throw new ServiceException("400", "변경 권한이 없습니다.");
129+
}
143130
}
144131

145-
@Transactional
146-
public CommentAllResponse getAdoptedComment(Long postId) {
147-
Post post = postRepository.findById(postId)
148-
.orElseThrow(() -> new ServiceException("400", "해당 Id의 게시글이 없습니다."));
132+
private PostComment validateAdoptedComment(Post post) {
133+
return postCommentRepository.findByPostAndIsAdoptedTrue(post)
134+
.orElseThrow(() -> new ServiceException("400", "채택된 댓글이 없습니다."));
135+
}
149136

137+
private void validatePostType(Post post) {
150138
if (post.getPostType() != Post.PostType.QUESTIONPOST) {
151139
throw new ServiceException("400", "질문 게시글만 채택된 댓글을 가질 수 있습니다.");
152140
}
141+
}
153142

154-
PostComment postComment = postCommentRepository.findByPostAndIsAdoptedTrue(post)
155-
.orElseThrow(() -> new ServiceException("400", "채택된 댓글이 없습니다."));
143+
private void validateComment(String comment) {
144+
if (comment == null || comment.isEmpty()) {
145+
throw new ServiceException("400", "댓글은 비어 있을 수 없습니다.");
146+
}
147+
}
156148

157-
return CommentAllResponse.from(postComment);
149+
private void validatePostExists(Long postId) {
150+
if (!postService.existsById(postId)) {
151+
throw new ServiceException("400", "유효하지 않은 게시글 Id입니다.");
152+
}
153+
}
154+
155+
private PostComment findCommentById(Long commentId) {
156+
return postCommentRepository.findById(commentId).orElseThrow(() -> new ServiceException("400", "해당 Id의 댓글이 없습니다."));
158157
}
159158
}

0 commit comments

Comments
 (0)