Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,29 @@
import com.brainpix.post.dto.PostCollaborationResponse;
import com.brainpix.post.dto.PostIdeaMarketResponse;
import com.brainpix.post.dto.PostRequestTaskResponse;
import com.brainpix.post.dto.SavePostResponseDto;
import com.brainpix.post.service.SavedPostService;
import com.brainpix.security.authorization.AllUser;
import com.brainpix.security.authorization.UserId;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/saved-posts")
@RequiredArgsConstructor
@Tag(name = "게시글 저장 관련 API", description = "게시글을 저장 및 해제 하고, 저장된 게시글을 조회하는 API입니다.")
public class SavedPostController {

private final SavedPostService savedPostService;

@Operation(summary = "게시글 저장", description = "현재 로그인한 사용자가 특정 게시글을 저장합니다.")
@Operation(summary = "게시글 저장 및 해제", description = "토글 형식으로 현재 로그인한 사용자가 특정 게시글을 저장 또는 해제 합니다.<br>이미 저장된 게시글은 해제되고, 그렇지 않다면 저장합니다.")
@AllUser
@PostMapping
public ResponseEntity<ApiResponse<Void>> savePost(@UserId Long userId, @RequestParam long postId) {
savedPostService.savePost(userId, postId);
return ResponseEntity.ok(ApiResponse.successWithNoData());
public ResponseEntity<ApiResponse<SavePostResponseDto>> savePost(@UserId Long userId, @RequestParam long postId) {
SavePostResponseDto result = savedPostService.savePost(userId, postId);
return ResponseEntity.ok(ApiResponse.success(result));
}

@Operation(summary = "저장된 요청 과제 조회", description = "현재 로그인한 사용자가 저장한 요청 과제를 조회합니다.")
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/com/brainpix/post/dto/SavePostResponseDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.brainpix.post.dto;

public record SavePostResponseDto(
Boolean isSaved
) {
public static SavePostResponseDto from(Boolean isSaved) {
return new SavePostResponseDto(isSaved);
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package com.brainpix.post.repository;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;

import com.brainpix.post.entity.Post;
import com.brainpix.post.entity.SavedPost;
import com.brainpix.user.entity.User;

public interface SavedPostRepository extends JpaRepository<SavedPost, Long>, SavedPostRepositoryCustom {

boolean existsByUserAndPost(User user, Post post);


Long countByPostId(Long postId);

Optional<SavedPost> findByUserAndPost(User user, Post post);
}
38 changes: 23 additions & 15 deletions src/main/java/com/brainpix/post/service/SavedPostService.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package com.brainpix.post.service;

import java.util.Optional;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.brainpix.api.code.error.SavedPostErrorCode;
import com.brainpix.api.code.error.CommonErrorCode;
import com.brainpix.api.code.error.PostErrorCode;
import com.brainpix.api.exception.BrainPixException;
import com.brainpix.post.dto.PostCollaborationResponse;
import com.brainpix.post.dto.PostIdeaMarketResponse;
import com.brainpix.post.dto.PostRequestTaskResponse;
import com.brainpix.post.dto.SavePostResponseDto;
import com.brainpix.post.entity.Post;
import com.brainpix.post.entity.SavedPost;
import com.brainpix.post.entity.collaboration_hub.CollaborationHub;
Expand All @@ -31,21 +36,30 @@ public class SavedPostService {
private final PostRepository postRepository;

@Transactional
public void savePost(long userId, long postId) {
public SavePostResponseDto savePost(long userId, long postId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new IllegalArgumentException(SavedPostErrorCode.USER_NOT_FOUND.getMessage()));
.orElseThrow(() -> new BrainPixException(CommonErrorCode.USER_NOT_FOUND));

Post post = postRepository.findById(postId)
.orElseThrow(() -> new IllegalArgumentException(SavedPostErrorCode.POST_NOT_FOUND.getMessage()));
.orElseThrow(() -> new BrainPixException(PostErrorCode.POST_NOT_FOUND));

Optional<SavedPost> savedPost = savedPostRepository.findByUserAndPost(user, post);

validateNotDuplicate(user, post);
boolean isSaved;
if (savedPost.isEmpty()) {
savedPostRepository.save(new SavedPost(user, post)); // 즐겨찾기 등록
isSaved = true;
} else {
savedPostRepository.delete(savedPost.get()); // 즐겨찾기 해제
isSaved = false;
}

savedPostRepository.save(new SavedPost(user, post));
return SavePostResponseDto.from(isSaved);
}

public Page<PostRequestTaskResponse> findSavedRequestTasks(long userId, Pageable pageable) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new IllegalArgumentException(SavedPostErrorCode.USER_NOT_FOUND.getMessage()));
.orElseThrow(() -> new BrainPixException(CommonErrorCode.USER_NOT_FOUND));

return savedPostRepository.findSavedRequestTasksByUser(user, pageable)
.map(savedPost -> {
Expand All @@ -57,7 +71,7 @@ public Page<PostRequestTaskResponse> findSavedRequestTasks(long userId, Pageable

public Page<PostIdeaMarketResponse> findSavedIdeaMarkets(long userId, Pageable pageable) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new IllegalArgumentException(SavedPostErrorCode.USER_NOT_FOUND.getMessage()));
.orElseThrow(() -> new BrainPixException(CommonErrorCode.USER_NOT_FOUND));

return savedPostRepository.findSavedIdeaMarketsByUser(user, pageable)
.map(savedPost -> {
Expand All @@ -69,7 +83,7 @@ public Page<PostIdeaMarketResponse> findSavedIdeaMarkets(long userId, Pageable p

public Page<PostCollaborationResponse> findSavedCollaborationHubs(long userId, Pageable pageable) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new IllegalArgumentException(SavedPostErrorCode.USER_NOT_FOUND.getMessage()));
.orElseThrow(() -> new BrainPixException(CommonErrorCode.USER_NOT_FOUND));

return savedPostRepository.findSavedCollaborationHubsByUser(user, pageable)
.map(savedPost -> {
Expand All @@ -84,10 +98,4 @@ public Page<PostCollaborationResponse> findSavedCollaborationHubs(long userId, P
occupiedQuantity);
});
}

private void validateNotDuplicate(User user, Post post) {
if (savedPostRepository.existsByUserAndPost(user, post)) {
throw new IllegalStateException(SavedPostErrorCode.DUPLICATE_SAVED_POST.getMessage());
}
}
}