diff --git a/src/main/java/run/attraction/api/v1/announcement/controller/AnnouncementController.java b/src/main/java/run/attraction/api/v1/announcement/controller/AnnouncementController.java index d3da27e3..c242ce79 100644 --- a/src/main/java/run/attraction/api/v1/announcement/controller/AnnouncementController.java +++ b/src/main/java/run/attraction/api/v1/announcement/controller/AnnouncementController.java @@ -3,6 +3,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -82,12 +83,8 @@ public ApiResponse> getPosts( @GetMapping("/pinned") @Operation(summary = "고정된 모든 게시물 가져오기", description = "고정된 모든 게시물을 가져오는 로직입니다.") - public ApiResponse> getPinnedPosts( - @RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "10") int size - ) { - Pageable pageable = PageRequest.of(page, size); - final Page posts = announcementService.findPinnedPosts(pageable); + public ApiResponse> getPinnedPosts() { + final List posts = announcementService.findPinnedPosts(); return ApiResponse.from(HttpStatus.OK, "성공", posts); } diff --git a/src/main/java/run/attraction/api/v1/announcement/repository/AnnouncementRepository.java b/src/main/java/run/attraction/api/v1/announcement/repository/AnnouncementRepository.java index c6137a77..7748cde0 100644 --- a/src/main/java/run/attraction/api/v1/announcement/repository/AnnouncementRepository.java +++ b/src/main/java/run/attraction/api/v1/announcement/repository/AnnouncementRepository.java @@ -1,5 +1,6 @@ package run.attraction.api.v1.announcement.repository; +import java.util.List; import java.util.Optional; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -42,7 +43,7 @@ public interface AnnouncementRepository extends JpaRepository { WHERE p.isPinned = true ORDER BY p.createdAt DESC """) - Page findAllWithPinned(Pageable pageable); + List findAllWithPinned(); @Query(""" SELECT p @@ -57,4 +58,11 @@ public interface AnnouncementRepository extends JpaRepository { ORDER BY p.createdAt DESC """) Page findPostsBySearchQuery(Pageable pageable, String searchType, String searchQuery); + + @Query(""" + SELECT COUNT(p) + FROM Post p + WHERE p.isPinned = true + """) + int countPinnedPosts(); } diff --git a/src/main/java/run/attraction/api/v1/announcement/service/AnnouncementService.java b/src/main/java/run/attraction/api/v1/announcement/service/AnnouncementService.java index fe7d6473..7fcc8563 100644 --- a/src/main/java/run/attraction/api/v1/announcement/service/AnnouncementService.java +++ b/src/main/java/run/attraction/api/v1/announcement/service/AnnouncementService.java @@ -1,5 +1,6 @@ package run.attraction.api.v1.announcement.service; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -19,12 +20,17 @@ @RequiredArgsConstructor public class AnnouncementService { + private static final int PINNED_LIMIT = 3; + private final AnnouncementRepository announcementRepository; @Transactional public void createPost(final PostCreateRequestDTO request) { - PostCategory category = PostCategory.valueOf(request.postCategory().toUpperCase()); + if (request.isPinned()) { + checkPinnedPostCount(); + } + PostCategory category = PostCategory.valueOf(request.postCategory().toUpperCase()); Post post = Post.builder() .title(request.title()) .content(request.content()) @@ -35,6 +41,12 @@ public void createPost(final PostCreateRequestDTO request) { announcementRepository.save(post); } + private void checkPinnedPostCount() { + if (announcementRepository.countPinnedPosts() >= PINNED_LIMIT) { + throw new IllegalArgumentException("고정글은 " + PINNED_LIMIT + "개를 초과할 수 없습니다."); + } + } + @Transactional(readOnly = true) public PostDTO findPostById(final Long postId) { final Post post = announcementRepository.findById(postId) @@ -54,11 +66,16 @@ public void deletePostById(final Long postId) { } @Transactional - public void updatePostById(final Long postId, final UpdatePostRequestDTO post) { + public void updatePostById(final Long postId, final UpdatePostRequestDTO request) { final Post beforePost = announcementRepository.findById(postId) .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 게시물입니다.")); - beforePost.update(post.title(), post.content(), PostCategory.findByName(post.postCategory()), post.isPinned()); + if (request.isPinned()) { + checkPinnedPostCount(); + } + + beforePost.update(request.title(), request.content(), PostCategory.findByName(request.postCategory()), + request.isPinned()); announcementRepository.save(beforePost); } @@ -70,10 +87,10 @@ public Page findPosts(Pageable pageable) { } @Transactional(readOnly = true) - public Page findPinnedPosts(Pageable pageable) { - final Page posts = announcementRepository.findAllWithPinned(pageable); + public List findPinnedPosts() { + final List posts = announcementRepository.findAllWithPinned(); - return posts.map(PostSummaryDTO::new); + return posts.stream().map(PostSummaryDTO::new).toList(); } @Transactional(readOnly = true)