From f6ddb9d629a657c335ac9b7aab5aacab4b8168e2 Mon Sep 17 00:00:00 2001 From: 10 Date: Thu, 12 Dec 2024 08:52:26 +0900 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=EC=BB=A4=EB=AE=A4?= =?UTF-8?q?=EB=8B=88=ED=8B=B0=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20(#285)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :recycle: 작성자 필터 추가 & 커서 기반 페이징 적용 (#284) * :white_check_mark: 커뮤니티 게시글 테스트 코드 수정 (#284) * :recycle: 커뮤니티 게시글 command in 패키지 추가 (#284) --- .../adapter/web/in/CommunityPostController.kt | 12 +- .../web/in/CommunityPostLikeController.kt | 2 - .../web/in/dto/CreateCommunityPostDto.kt | 2 +- .../web/in/dto/DeleteCommunityPostDto.kt | 2 +- .../web/in/dto/SearchCommunityPostDto.kt | 60 ++--- .../web/in/dto/UpdateCommunityPostDto.kt | 2 +- .../port/in/CommunityPostUseCase.kt | 5 +- .../service/CommunityPostService.kt | 46 +++- .../application/service/AdminServiceTest.kt | 2 +- .../web/in/CommunityPostControllerDocsTest.kt | 75 ++++--- .../service/CommunityPostServiceTest.kt | 205 +++++++++++++++--- .../service/CommunityPostReportServiceTest.kt | 2 +- .../web/out/CommunityPostPersistence.kt | 5 +- .../web/out/CustomCommunityPostRepository.kt | 67 +++--- .../command/DeleteCommunityPostCommand.kt | 6 - .../command/GetCommunityPostCommand.kt | 6 - .../command/SearchCommunityPostCommand.kt | 15 -- .../{ => in}/CreateCommunityPostCommand.kt | 2 +- .../command/in/DeleteCommunityPostCommand.kt | 6 + .../command/in/GetCommunityPostCommand.kt | 6 + .../command/in/SearchCommunityPostCommand.kt | 18 ++ .../{ => in}/UpdateCommunityPostCommand.kt | 2 +- .../out/GetSliceCommunityPostCommand.kt | 46 ++++ .../port/out/CommunityPostReader.kt | 5 +- .../domain/entity/CommunityPostEntity.kt | 4 +- 25 files changed, 399 insertions(+), 204 deletions(-) delete mode 100644 core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/DeleteCommunityPostCommand.kt delete mode 100644 core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/GetCommunityPostCommand.kt delete mode 100644 core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/SearchCommunityPostCommand.kt rename core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/{ => in}/CreateCommunityPostCommand.kt (84%) create mode 100644 core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/DeleteCommunityPostCommand.kt create mode 100644 core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/GetCommunityPostCommand.kt create mode 100644 core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/SearchCommunityPostCommand.kt rename core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/{ => in}/UpdateCommunityPostCommand.kt (85%) create mode 100644 core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/out/GetSliceCommunityPostCommand.kt diff --git a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostController.kt b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostController.kt index fd44757b..61bf883a 100644 --- a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostController.kt +++ b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostController.kt @@ -1,11 +1,12 @@ package backend.team.ahachul_backend.api.community.adapter.web.`in` import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.* -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.* +import backend.team.ahachul_backend.api.community.application.command.`in`.DeleteCommunityPostCommand +import backend.team.ahachul_backend.api.community.application.command.`in`.GetCommunityPostCommand import backend.team.ahachul_backend.api.community.application.port.`in`.CommunityPostUseCase import backend.team.ahachul_backend.common.annotation.Authentication +import backend.team.ahachul_backend.common.dto.PageInfoDto import backend.team.ahachul_backend.common.response.CommonResponse -import org.springframework.data.domain.Pageable import org.springframework.web.bind.annotation.* @RestController @@ -16,10 +17,11 @@ class CommunityPostController( @Authentication(required = false) @GetMapping("/v1/community-posts") fun searchCommunityPosts( - pageable: Pageable, + @RequestParam(required = false) pageToken: String?, + @RequestParam pageSize: Int, request: SearchCommunityPostDto.Request - ): CommonResponse { - return CommonResponse.success(communityPostUseCase.searchCommunityPosts(request.toCommand(pageable))) + ): CommonResponse> { + return CommonResponse.success(communityPostUseCase.searchCommunityPosts(request.toCommand(pageToken, pageSize))) } @Authentication(required = false) diff --git a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostLikeController.kt b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostLikeController.kt index bbefd445..e387d2b1 100644 --- a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostLikeController.kt +++ b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostLikeController.kt @@ -1,7 +1,5 @@ package backend.team.ahachul_backend.api.community.adapter.web.`in` -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.* -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.* import backend.team.ahachul_backend.api.community.application.port.`in`.CommunityPostLikeUseCase import backend.team.ahachul_backend.common.annotation.Authentication import backend.team.ahachul_backend.common.response.CommonResponse diff --git a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/CreateCommunityPostDto.kt b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/CreateCommunityPostDto.kt index ea1ed94b..a7b18764 100644 --- a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/CreateCommunityPostDto.kt +++ b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/CreateCommunityPostDto.kt @@ -1,6 +1,6 @@ package backend.team.ahachul_backend.api.community.adapter.web.`in`.dto -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.CreateCommunityPostCommand +import backend.team.ahachul_backend.api.community.application.command.`in`.CreateCommunityPostCommand import backend.team.ahachul_backend.api.community.domain.entity.CommunityPostEntity import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType import backend.team.ahachul_backend.common.domain.model.RegionType diff --git a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/DeleteCommunityPostDto.kt b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/DeleteCommunityPostDto.kt index f96fda5a..652fc052 100644 --- a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/DeleteCommunityPostDto.kt +++ b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/DeleteCommunityPostDto.kt @@ -1,6 +1,6 @@ package backend.team.ahachul_backend.api.community.adapter.web.`in`.dto -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.DeleteCommunityPostCommand +import backend.team.ahachul_backend.api.community.application.command.`in`.DeleteCommunityPostCommand class DeleteCommunityPostDto { diff --git a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/SearchCommunityPostDto.kt b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/SearchCommunityPostDto.kt index 64314e9a..0034d58e 100644 --- a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/SearchCommunityPostDto.kt +++ b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/SearchCommunityPostDto.kt @@ -1,13 +1,11 @@ package backend.team.ahachul_backend.api.community.adapter.web.`in`.dto -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.SearchCommunityPostCommand -import backend.team.ahachul_backend.api.community.domain.SearchCommunityPost +import backend.team.ahachul_backend.api.community.application.command.`in`.SearchCommunityPostCommand import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType import backend.team.ahachul_backend.common.domain.model.RegionType import backend.team.ahachul_backend.common.domain.model.YNType import backend.team.ahachul_backend.common.dto.ImageDto -import org.springframework.data.domain.Pageable -import java.time.LocalDateTime +import org.springframework.data.domain.Sort class SearchCommunityPostDto { @@ -17,36 +15,30 @@ class SearchCommunityPostDto { val content: String?, val hashTag: String?, val hotPostYn: YNType?, + val writer: String?, + val sort: String ) { - fun toCommand(pageable: Pageable): SearchCommunityPostCommand { + fun toCommand(pageToken: String?, pageSize: Int): SearchCommunityPostCommand { return SearchCommunityPostCommand( categoryType = categoryType, subwayLineId = subwayLineId, content = content, hashTag = hashTag, hotPostYn = hotPostYn, - pageable = pageable + writer = writer, + sort = toSort(), + pageToken = pageToken, + pageSize = pageSize ) } - } - data class Response( - val hasNext: Boolean, - val nextPageNum: Int?, - val posts: List, - ) { - companion object { - fun of(hasNext: Boolean, posts: List, currentPageNum: Int): Response { - return Response( - hasNext = hasNext, - nextPageNum = if (hasNext) currentPageNum + 1 else null, - posts = posts - ) - } + private fun toSort(): Sort { + val parts = sort.split(",") + return Sort.by(Sort.Direction.fromString(parts[1]), parts[0]) } } - data class CommunityPost( + data class Response( val id: Long, val title: String, val content: String, @@ -58,31 +50,9 @@ class SearchCommunityPostDto { val hotPostYn: YNType, val regionType: RegionType, val subwayLineId: Long, - val createdAt: LocalDateTime, + val createdAt: String, val createdBy: String, val writer: String, val image: ImageDto?, - ) { - companion object { - fun of(searchCommunityPost: SearchCommunityPost, image: ImageDto?, views: Int, hashTags: List): CommunityPost { - return CommunityPost( - id = searchCommunityPost.id, - title = searchCommunityPost.title, - content = searchCommunityPost.content, - categoryType = searchCommunityPost.categoryType, - hashTags = hashTags, - commentCnt = searchCommunityPost.commentCnt, - viewCnt = views, - likeCnt = searchCommunityPost.likeCnt, - hotPostYn = searchCommunityPost.hotPostYn, - regionType = searchCommunityPost.regionType, - subwayLineId = searchCommunityPost.subwayLineId, - createdAt = searchCommunityPost.createdAt, - createdBy = searchCommunityPost.createdBy, - writer = searchCommunityPost.writer, - image = image, - ) - } - } - } + ) } diff --git a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/UpdateCommunityPostDto.kt b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/UpdateCommunityPostDto.kt index bf2380cb..e4a1387d 100644 --- a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/UpdateCommunityPostDto.kt +++ b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/dto/UpdateCommunityPostDto.kt @@ -1,6 +1,6 @@ package backend.team.ahachul_backend.api.community.adapter.web.`in`.dto -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.UpdateCommunityPostCommand +import backend.team.ahachul_backend.api.community.application.command.`in`.UpdateCommunityPostCommand import backend.team.ahachul_backend.api.community.domain.entity.CommunityPostEntity import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType import backend.team.ahachul_backend.common.dto.ImageDto diff --git a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/application/port/in/CommunityPostUseCase.kt b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/application/port/in/CommunityPostUseCase.kt index d4fa2dae..ed3a6c30 100644 --- a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/application/port/in/CommunityPostUseCase.kt +++ b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/application/port/in/CommunityPostUseCase.kt @@ -1,11 +1,12 @@ package backend.team.ahachul_backend.api.community.application.port.`in` import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.* -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.* +import backend.team.ahachul_backend.api.community.application.command.`in`.* +import backend.team.ahachul_backend.common.dto.PageInfoDto interface CommunityPostUseCase { - fun searchCommunityPosts(command: SearchCommunityPostCommand): SearchCommunityPostDto.Response + fun searchCommunityPosts(command: SearchCommunityPostCommand): PageInfoDto fun getCommunityPost(command: GetCommunityPostCommand): GetCommunityPostDto.Response diff --git a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/application/service/CommunityPostService.kt b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/application/service/CommunityPostService.kt index 03ecfb3b..e031f0ed 100644 --- a/application/src/main/kotlin/backend/team/ahachul_backend/api/community/application/service/CommunityPostService.kt +++ b/application/src/main/kotlin/backend/team/ahachul_backend/api/community/application/service/CommunityPostService.kt @@ -1,7 +1,8 @@ package backend.team.ahachul_backend.api.community.application.service import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.* -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.* +import backend.team.ahachul_backend.api.community.application.command.`in`.* +import backend.team.ahachul_backend.api.community.application.command.out.GetSliceCommunityPostCommand import backend.team.ahachul_backend.api.community.application.port.`in`.CommunityPostUseCase import backend.team.ahachul_backend.api.community.application.port.out.CommunityPostFileReader import backend.team.ahachul_backend.api.community.application.port.out.CommunityPostHashTagReader @@ -11,12 +12,14 @@ import backend.team.ahachul_backend.api.community.domain.entity.CommunityPostEnt import backend.team.ahachul_backend.api.community.domain.entity.CommunityPostFileEntity import backend.team.ahachul_backend.api.member.application.port.out.MemberReader import backend.team.ahachul_backend.common.dto.ImageDto +import backend.team.ahachul_backend.common.dto.PageInfoDto import backend.team.ahachul_backend.common.logging.NamedLogger import backend.team.ahachul_backend.common.persistence.SubwayLineReader import backend.team.ahachul_backend.common.support.ViewsSupport import backend.team.ahachul_backend.common.utils.RequestUtils import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional +import java.time.format.DateTimeFormatter @Service @Transactional(readOnly = true) @@ -37,17 +40,36 @@ class CommunityPostService( private val logger = NamedLogger("HASHTAG_LOGGER") - override fun searchCommunityPosts(command: SearchCommunityPostCommand): SearchCommunityPostDto.Response { + override fun searchCommunityPosts(command: SearchCommunityPostCommand): PageInfoDto { val userId: String? = RequestUtils.getAttribute("memberId") - val searchCommunityPosts = communityPostReader.searchCommunityPosts(command) + val subwayLine = command.subwayLineId?.let { subwayLineReader.getById(it) } + + val searchCommunityPosts = communityPostReader.searchCommunityPosts( + GetSliceCommunityPostCommand.from( + command = command, + subwayLine = subwayLine + ) + ) + val posts = searchCommunityPosts .map { val file = communityPostFileReader.findByPostId(it.id)?.file - SearchCommunityPostDto.CommunityPost.of( - searchCommunityPost = it, - image = file?.let { it1 -> ImageDto.of(it1.id, file.filePath) }, - views = viewsSupport.get(it.id), - hashTags = communityPostHashTagReader.findAllByPostId(it.id).map { it.hashTag.name } + SearchCommunityPostDto.Response( + id = it.id, + title = it.title, + content = it.content, + categoryType = it.categoryType, + hashTags = communityPostHashTagReader.findAllByPostId(it.id).map { it.hashTag.name }, + commentCnt = it.commentCnt, + viewCnt = viewsSupport.get(it.id), + likeCnt = it.likeCnt, + hotPostYn = it.hotPostYn, + regionType = it.regionType, + subwayLineId = it.subwayLineId, + createdAt = it.createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")), + createdBy = it.createdBy, + writer = it.writer, + image = file?.let { it1 -> ImageDto.of(it1.id, file.filePath) } ) }.toList() @@ -55,10 +77,10 @@ class CommunityPostService( logger.info("userId = $userId hashtag = ${command.hashTag}") } - return SearchCommunityPostDto.Response.of( - hasNext = searchCommunityPosts.hasNext(), - posts = posts, - command.pageable.pageNumber, + return PageInfoDto.of( + data=posts, + pageSize=command.pageSize, + arrayOf(SearchCommunityPostDto.Response::createdAt, SearchCommunityPostDto.Response::id) ) } diff --git a/application/src/test/kotlin/backend/team/ahachul_backend/admin/application/service/AdminServiceTest.kt b/application/src/test/kotlin/backend/team/ahachul_backend/admin/application/service/AdminServiceTest.kt index 4b75d7e2..49738756 100644 --- a/application/src/test/kotlin/backend/team/ahachul_backend/admin/application/service/AdminServiceTest.kt +++ b/application/src/test/kotlin/backend/team/ahachul_backend/admin/application/service/AdminServiceTest.kt @@ -1,6 +1,6 @@ package backend.team.ahachul_backend.admin.application.service -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.CreateCommunityPostCommand +import backend.team.ahachul_backend.api.community.application.command.`in`.CreateCommunityPostCommand import backend.team.ahachul_backend.api.community.adapter.web.out.CommunityPostRepository import backend.team.ahachul_backend.api.community.domain.entity.CommunityPostEntity import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType diff --git a/application/src/test/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostControllerDocsTest.kt b/application/src/test/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostControllerDocsTest.kt index 03e4638a..7d43d8ea 100644 --- a/application/src/test/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostControllerDocsTest.kt +++ b/application/src/test/kotlin/backend/team/ahachul_backend/api/community/adapter/web/in/CommunityPostControllerDocsTest.kt @@ -1,12 +1,12 @@ package backend.team.ahachul_backend.api.community.adapter.web.`in` import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.* -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.* import backend.team.ahachul_backend.api.community.application.port.`in`.CommunityPostUseCase import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType import backend.team.ahachul_backend.common.dto.ImageDto import backend.team.ahachul_backend.common.domain.model.RegionType import backend.team.ahachul_backend.common.domain.model.YNType +import backend.team.ahachul_backend.common.dto.PageInfoDto import backend.team.ahachul_backend.config.controller.CommonDocsTestConfig import org.junit.jupiter.api.Test import org.mockito.BDDMockito.given @@ -23,6 +23,7 @@ import org.springframework.restdocs.payload.PayloadDocumentation.* import org.springframework.restdocs.request.RequestDocumentation.* import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import java.time.LocalDateTime +import java.time.format.DateTimeFormatter @WebMvcTest(CommunityPostController::class) class CommunityPostControllerDocsTest : CommonDocsTestConfig() { @@ -33,11 +34,9 @@ class CommunityPostControllerDocsTest : CommonDocsTestConfig() { @Test fun searchCommunityPostsTest() { // given - val response = SearchCommunityPostDto.Response( - true, - 1, - listOf( - SearchCommunityPostDto.CommunityPost( + val response = PageInfoDto.of( + data=listOf( + SearchCommunityPostDto.Response( id = 1, title = "제목", content = "내용", @@ -49,12 +48,14 @@ class CommunityPostControllerDocsTest : CommonDocsTestConfig() { hotPostYn = YNType.Y, regionType = RegionType.METROPOLITAN, subwayLineId = 1L, - createdAt = LocalDateTime.now(), + createdAt = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")), createdBy = "작성자 ID", writer = "작성자 닉네임", image = ImageDto.of(1L, "url1") ) - ) + ), + pageSize=1, + arrayOf(SearchCommunityPostDto.Response::createdAt, SearchCommunityPostDto.Response::id) ) given(communityPostUseCase.searchCommunityPosts(any())) @@ -63,14 +64,15 @@ class CommunityPostControllerDocsTest : CommonDocsTestConfig() { // when val result = mockMvc.perform( get("/v1/community-posts") - .param("categoryType", "ISSUE") - .param("subwayLineId", "1") - .param("content", "내용") - .param("hashTag", "여행") - .param("hotPostYn", "Y") - .param("page", "1") - .param("size", "10") - .param("sort", "createdAt,desc") + .queryParam("categoryType", "ISSUE") + .queryParam("subwayLineId", "1") + .queryParam("content", "내용") + .queryParam("hashTag", "여행") + .queryParam("hotPostYn", "Y") + .queryParam("writer", "작성자") + .queryParam("sort", "createdAt,desc") + .queryParam("pageToken", "MTIzMTI5MTU6MTI=") + .queryParam("pageSize", "10" ) .header("Authorization", "Bearer ") .accept(MediaType.APPLICATION_JSON) ) @@ -88,31 +90,32 @@ class CommunityPostControllerDocsTest : CommonDocsTestConfig() { parameterWithName("content").description("검색하고자 하는 내용").optional(), parameterWithName("hashTag").description("검색하고자 하는 해시 태그").optional(), parameterWithName("hotPostYn").description("검색하고자 하는 핫 게시글 여부").optional(), - parameterWithName("page").description("현재 페이지"), - parameterWithName("size").description("페이지 노출 데이터 수. index 0부터 시작"), + parameterWithName("writer").description("검색하고자 하는 작성자 닉네임").optional(), parameterWithName("sort").description("정렬 조건").attributes(getFormatAttribute("(likes|createdAt|views),(asc|desc)")), + parameterWithName("pageToken").description("base64로 인코딩 된 페이지 토큰 문자열").optional(), + parameterWithName("pageSize").description("페이지 노출 데이터 수. index 0부터 시작"), ), responseFields( *commonResponseFields(), fieldWithPath("result.hasNext").type(JsonFieldType.BOOLEAN).description("다음 페이지 존재 여부"), - fieldWithPath("result.nextPageNum").type(JsonFieldType.NUMBER).description("다음 페이지 인덱스"), - fieldWithPath("result.posts[].id").type(JsonFieldType.NUMBER).description("게시글 아이디"), - fieldWithPath("result.posts[].title").type(JsonFieldType.STRING).description("게시글 제목"), - fieldWithPath("result.posts[].content").type(JsonFieldType.STRING).description("게시글 내용"), - fieldWithPath("result.posts[].categoryType").type("CategoryType").description("카테고리 타입").attributes(getFormatAttribute("FREE, INSIGHT, ISSUE, HUMOR")), - fieldWithPath("result.posts[].hashTags").type(JsonFieldType.ARRAY).description("해시 태그 목록"), - fieldWithPath("result.posts[].commentCnt").type(JsonFieldType.NUMBER).description("댓글 수"), - fieldWithPath("result.posts[].viewCnt").type(JsonFieldType.NUMBER).description("조회수"), - fieldWithPath("result.posts[].likeCnt").type(JsonFieldType.NUMBER).description("좋아요 수"), - fieldWithPath("result.posts[].hotPostYn").type("YNType").description("핫 게시글 여부").attributes(getFormatAttribute("Y, N")), - fieldWithPath("result.posts[].regionType").type("RegionType").description("지역").attributes(getFormatAttribute("METROPOLITAN")), - fieldWithPath("result.posts[].subwayLineId").type(JsonFieldType.NUMBER).description("지하철 노선 ID"), - fieldWithPath("result.posts[].createdAt").type("LocalDateTime").description("작성일자"), - fieldWithPath("result.posts[].createdBy").type(JsonFieldType.STRING).description("작성자 ID"), - fieldWithPath("result.posts[].writer").type(JsonFieldType.STRING).description("작성자 닉네임"), - fieldWithPath("result.posts[].image").type(JsonFieldType.OBJECT).description("등록된 이미지"), - fieldWithPath("result.posts[].image.imageId").type(JsonFieldType.NUMBER).description("등록된 첫 번쨰 이미지 ID"), - fieldWithPath("result.posts[].image.imageUrl").type(JsonFieldType.STRING).description("등록된 첫 번째 이미지 URI"), + fieldWithPath("result.pageToken").type(JsonFieldType.STRING).description("다음 게시글을 가져오기 위한 base64로 인코딩 된 페이지 토큰 문자열").optional(), + fieldWithPath("result.data[].id").type(JsonFieldType.NUMBER).description("게시글 아이디"), + fieldWithPath("result.data[].title").type(JsonFieldType.STRING).description("게시글 제목"), + fieldWithPath("result.data[].content").type(JsonFieldType.STRING).description("게시글 내용"), + fieldWithPath("result.data[].categoryType").type("CategoryType").description("카테고리 타입").attributes(getFormatAttribute("FREE, INSIGHT, ISSUE, HUMOR")), + fieldWithPath("result.data[].hashTags").type(JsonFieldType.ARRAY).description("해시 태그 목록"), + fieldWithPath("result.data[].commentCnt").type(JsonFieldType.NUMBER).description("댓글 수"), + fieldWithPath("result.data[].viewCnt").type(JsonFieldType.NUMBER).description("조회수"), + fieldWithPath("result.data[].likeCnt").type(JsonFieldType.NUMBER).description("좋아요 수"), + fieldWithPath("result.data[].hotPostYn").type("YNType").description("핫 게시글 여부").attributes(getFormatAttribute("Y, N")), + fieldWithPath("result.data[].regionType").type("RegionType").description("지역").attributes(getFormatAttribute("METROPOLITAN")), + fieldWithPath("result.data[].subwayLineId").type(JsonFieldType.NUMBER).description("지하철 노선 ID"), + fieldWithPath("result.data[].createdAt").type("LocalDateTime").description("작성일자"), + fieldWithPath("result.data[].createdBy").type(JsonFieldType.STRING).description("작성자 ID"), + fieldWithPath("result.data[].writer").type(JsonFieldType.STRING).description("작성자 닉네임"), + fieldWithPath("result.data[].image").type(JsonFieldType.OBJECT).description("등록된 이미지"), + fieldWithPath("result.data[].image.imageId").type(JsonFieldType.NUMBER).description("등록된 첫 번쨰 이미지 ID"), + fieldWithPath("result.data[].image.imageUrl").type(JsonFieldType.STRING).description("등록된 첫 번째 이미지 URI"), ) ) ) diff --git a/application/src/test/kotlin/backend/team/ahachul_backend/api/community/application/service/CommunityPostServiceTest.kt b/application/src/test/kotlin/backend/team/ahachul_backend/api/community/application/service/CommunityPostServiceTest.kt index eb5d581c..4addf59f 100644 --- a/application/src/test/kotlin/backend/team/ahachul_backend/api/community/application/service/CommunityPostServiceTest.kt +++ b/application/src/test/kotlin/backend/team/ahachul_backend/api/community/application/service/CommunityPostServiceTest.kt @@ -1,8 +1,8 @@ package backend.team.ahachul_backend.api.community.application.service -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.* import backend.team.ahachul_backend.api.community.adapter.web.out.CommunityPostHashTagRepository import backend.team.ahachul_backend.api.community.adapter.web.out.CommunityPostRepository +import backend.team.ahachul_backend.api.community.application.command.`in`.* import backend.team.ahachul_backend.api.community.application.port.`in`.CommunityPostUseCase import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType import backend.team.ahachul_backend.api.member.adapter.web.out.MemberRepository @@ -20,12 +20,11 @@ import backend.team.ahachul_backend.common.utils.RequestUtils import backend.team.ahachul_backend.config.controller.CommonServiceTestConfig import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy -import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired -import org.springframework.data.domain.Pageable +import org.springframework.data.domain.Sort class CommunityPostServiceTest( @Autowired val communityPostRepository: CommunityPostRepository, @@ -247,40 +246,69 @@ class CommunityPostServiceTest( val communityPost2 = communityPostUseCase.createCommunityPost(createCommand2) val verifyNameCommand = SearchCommunityPostCommand( + categoryType = null, + subwayLineId = null, content = "제", - pageable = Pageable.ofSize(2) + hashTag = null, + hotPostYn = null, + writer = null, + sort = Sort.unsorted(), + pageToken = null, + pageSize = 2 ) val verifyNameCommand2 = SearchCommunityPostCommand( + categoryType = null, + subwayLineId = null, content = "지하철", - pageable = Pageable.ofSize(1) + hashTag = null, + hotPostYn = null, + writer = null, + sort = Sort.unsorted(), + pageToken = null, + pageSize = 1 ) val verifyNameCommand3 = SearchCommunityPostCommand( + categoryType = null, + subwayLineId = null, content = "지하철", - pageable = Pageable.ofSize(2) + hashTag = null, + hotPostYn = null, + writer = null, + sort = Sort.unsorted(), + pageToken = null, + pageSize = 2 ) val verifyOrderCommand = SearchCommunityPostCommand( - pageable = Pageable.ofSize(2) + categoryType = null, + subwayLineId = null, + content = null, + hashTag = null, + hotPostYn = null, + writer = null, + sort = Sort.unsorted(), + pageToken = null, + pageSize = 2 ) // when, then var result = communityPostUseCase.searchCommunityPosts(verifyNameCommand) assertThat(result.hasNext).isFalse() - assertThat(result.posts).hasSize(1) - assertThat(result.posts.first().id).isEqualTo(communityPost.id) + assertThat(result.data).hasSize(1) + assertThat(result.data.first().id).isEqualTo(communityPost.id) result = communityPostUseCase.searchCommunityPosts(verifyNameCommand2) assertThat(result.hasNext).isTrue() - assertThat(result.posts).hasSize(1) - assertThat(result.posts.first().id).isEqualTo(communityPost2.id) + assertThat(result.data).hasSize(1) + assertThat(result.data.first().id).isEqualTo(communityPost2.id) result = communityPostUseCase.searchCommunityPosts(verifyNameCommand3) assertThat(result.hasNext).isFalse() - assertThat(result.posts).hasSize(2) + assertThat(result.data).hasSize(2) result = communityPostUseCase.searchCommunityPosts(verifyOrderCommand) - assertThat(result.posts).hasSize(2) - assertThat(result.posts.map { it.createdAt }) - .isEqualTo(result.posts.map { it.createdAt }.sortedDescending()) + assertThat(result.data).hasSize(2) + assertThat(result.data.map { it.createdAt }) + .isEqualTo(result.data.map { it.createdAt }.sortedDescending()) } @@ -306,21 +334,35 @@ class CommunityPostServiceTest( val verifyCategoryCommand = SearchCommunityPostCommand( categoryType = CommunityCategoryType.FREE, - pageable = Pageable.ofSize(2) + subwayLineId = null, + content = null, + hashTag = null, + hotPostYn = null, + writer = null, + sort = Sort.unsorted(), + pageToken = null, + pageSize = 2 ) val verifyCategoryCommand2 = SearchCommunityPostCommand( categoryType = CommunityCategoryType.ISSUE, - pageable = Pageable.ofSize(2) + subwayLineId = null, + content = null, + hashTag = null, + hotPostYn = null, + writer = null, + sort = Sort.unsorted(), + pageToken = null, + pageSize = 2 ) // when, then var result = communityPostUseCase.searchCommunityPosts(verifyCategoryCommand) - assertThat(result.posts).hasSize(1) - assertThat(result.posts.first().id).isEqualTo(communityPost.id) + assertThat(result.data).hasSize(1) + assertThat(result.data.first().id).isEqualTo(communityPost.id) result = communityPostUseCase.searchCommunityPosts(verifyCategoryCommand2) - assertThat(result.posts).hasSize(1) - assertThat(result.posts.first().id).isEqualTo(communityPost2.id) + assertThat(result.data).hasSize(1) + assertThat(result.data.first().id).isEqualTo(communityPost2.id) } @Test @@ -345,20 +387,131 @@ class CommunityPostServiceTest( communityPostUseCase.createCommunityPost(createCommand2) val verifyHashTagCommand = SearchCommunityPostCommand( + categoryType = null, + subwayLineId = null, + content = null, hashTag = "여행", - pageable = Pageable.ofSize(2) + hotPostYn = null, + writer = null, + sort = Sort.unsorted(), + pageToken = null, + pageSize = 2 ) val verifyHashTagCommand2 = SearchCommunityPostCommand( + categoryType = null, + subwayLineId = null, + content = null, hashTag = "취미", - pageable = Pageable.ofSize(2) + hotPostYn = null, + writer = null, + sort = Sort.unsorted(), + pageToken = null, + pageSize = 2 ) // when, then var result = communityPostUseCase.searchCommunityPosts(verifyHashTagCommand) - assertThat(result.posts).hasSize(1) - assertThat(result.posts.first().id).isEqualTo(communityPost.id) + assertThat(result.data).hasSize(1) + assertThat(result.data.first().id).isEqualTo(communityPost.id) result = communityPostUseCase.searchCommunityPosts(verifyHashTagCommand2) - assertThat(result.posts).hasSize(2) + assertThat(result.data).hasSize(2) + } + + @Test + @DisplayName("커뮤니티 게시글 작성자 조회") + fun 커뮤니티_게시글_작성자_조회() { + // given + val createCommand = CreateCommunityPostCommand( + title = "제목", + content = "내용", + categoryType = CommunityCategoryType.FREE, + subwayLineId = subwayLine.id + ) + val createCommand2 = CreateCommunityPostCommand( + title = "제목", + content = "내용", + categoryType = CommunityCategoryType.FREE, + subwayLineId = subwayLine.id + ) + + communityPostUseCase.createCommunityPost(createCommand) + communityPostUseCase.createCommunityPost(createCommand2) + + val verifyWriterCommand = SearchCommunityPostCommand( + categoryType = null, + subwayLineId = null, + content = null, + hashTag = null, + hotPostYn = null, + writer = "nickname", + sort = Sort.unsorted(), + pageToken = null, + pageSize = 2 + ) + + // when, then + val result = communityPostUseCase.searchCommunityPosts(verifyWriterCommand) + assertThat(result.data).hasSize(2) + } + + @Test + @DisplayName("커뮤니티_게시글_조회_페이징") + fun 커뮤니티_게시글_조회_페이징() { + // given + for(i: Int in 1.. 5) { + val createCommand = CreateCommunityPostCommand( + title = "제목$i", + content = "내용$i", + categoryType = CommunityCategoryType.FREE, + subwayLineId = subwayLine.id + ) + + communityPostUseCase.createCommunityPost(createCommand) + } + + // when + val searchCommand1 = SearchCommunityPostCommand( + categoryType = null, + subwayLineId = null, + content = null, + hashTag = null, + hotPostYn = null, + writer = null, + sort = Sort.unsorted(), + pageToken = null, + pageSize = 3 + ) + + val response1 = communityPostUseCase.searchCommunityPosts(searchCommand1) + + val searchCommand2 = SearchCommunityPostCommand( + categoryType = null, + subwayLineId = null, + content = null, + hashTag = null, + hotPostYn = null, + writer = null, + sort = Sort.unsorted(), + pageToken = response1.pageToken, + pageSize = 3 + ) + + val response2 = communityPostUseCase.searchCommunityPosts(searchCommand2) + + // then + assertThat(response1.hasNext).isEqualTo(true) + assertThat(response1.data.size).isEqualTo(3) + assertThat(response1.data) + .extracting("content") + .usingRecursiveComparison() + .isEqualTo((5 downTo 3).map { "내용$it" }) + + assertThat(response2.hasNext).isEqualTo(false) + assertThat(response2.data.size).isEqualTo(2) + assertThat(response2.data) + .extracting("content") + .usingRecursiveComparison() + .isEqualTo((2 downTo 1).map { "내용$it" }) } } diff --git a/application/src/test/kotlin/backend/team/ahachul_backend/api/report/application/service/CommunityPostReportServiceTest.kt b/application/src/test/kotlin/backend/team/ahachul_backend/api/report/application/service/CommunityPostReportServiceTest.kt index 5dc1d18e..deeb8cd8 100644 --- a/application/src/test/kotlin/backend/team/ahachul_backend/api/report/application/service/CommunityPostReportServiceTest.kt +++ b/application/src/test/kotlin/backend/team/ahachul_backend/api/report/application/service/CommunityPostReportServiceTest.kt @@ -1,6 +1,6 @@ package backend.team.ahachul_backend.api.report.application.service -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.CreateCommunityPostCommand +import backend.team.ahachul_backend.api.community.application.command.`in`.CreateCommunityPostCommand import backend.team.ahachul_backend.api.community.adapter.web.out.CommunityPostRepository import backend.team.ahachul_backend.api.community.domain.entity.CommunityPostEntity import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/out/CommunityPostPersistence.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/out/CommunityPostPersistence.kt index c308fdf0..251c4684 100644 --- a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/out/CommunityPostPersistence.kt +++ b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/out/CommunityPostPersistence.kt @@ -1,6 +1,6 @@ package backend.team.ahachul_backend.api.community.adapter.web.out -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.SearchCommunityPostCommand +import backend.team.ahachul_backend.api.community.application.command.out.GetSliceCommunityPostCommand import backend.team.ahachul_backend.api.community.application.port.out.CommunityPostReader import backend.team.ahachul_backend.api.community.application.port.out.CommunityPostWriter import backend.team.ahachul_backend.api.community.domain.GetCommunityPost @@ -8,7 +8,6 @@ import backend.team.ahachul_backend.api.community.domain.SearchCommunityPost import backend.team.ahachul_backend.api.community.domain.entity.CommunityPostEntity import backend.team.ahachul_backend.common.exception.AdapterException import backend.team.ahachul_backend.common.response.ResponseCode -import org.springframework.data.domain.Slice import org.springframework.stereotype.Component @Component @@ -30,7 +29,7 @@ class CommunityPostPersistence( return customRepository.getByCustom(postId, memberId) ?: throw AdapterException(ResponseCode.INVALID_DOMAIN) } - override fun searchCommunityPosts(command: SearchCommunityPostCommand): Slice { + override fun searchCommunityPosts(command: GetSliceCommunityPostCommand): List { return customRepository.searchCommunityPosts(command) } } \ No newline at end of file diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/out/CustomCommunityPostRepository.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/out/CustomCommunityPostRepository.kt index 1b6f0eec..3bcc46a3 100644 --- a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/out/CustomCommunityPostRepository.kt +++ b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/adapter/web/out/CustomCommunityPostRepository.kt @@ -1,9 +1,9 @@ package backend.team.ahachul_backend.api.community.adapter.web.out -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.SearchCommunityPostCommand import backend.team.ahachul_backend.api.community.domain.GetCommunityPost import backend.team.ahachul_backend.api.community.domain.SearchCommunityPost import backend.team.ahachul_backend.api.comment.domain.entity.QCommentEntity.commentEntity +import backend.team.ahachul_backend.api.community.application.command.out.GetSliceCommunityPostCommand import backend.team.ahachul_backend.api.community.domain.entity.QCommunityPostEntity.communityPostEntity import backend.team.ahachul_backend.api.community.domain.entity.QCommunityPostHashTagEntity.communityPostHashTagEntity import backend.team.ahachul_backend.api.community.domain.entity.QCommunityPostLikeEntity.communityPostLikeEntity @@ -11,6 +11,7 @@ import backend.team.ahachul_backend.api.community.domain.model.CommunityCategory import backend.team.ahachul_backend.api.member.domain.entity.QMemberEntity.memberEntity import backend.team.ahachul_backend.common.domain.entity.QHashTagEntity.hashTagEntity import backend.team.ahachul_backend.common.domain.entity.QSubwayLineEntity.subwayLineEntity +import backend.team.ahachul_backend.common.domain.entity.SubwayLineEntity import backend.team.ahachul_backend.common.domain.model.YNType import com.querydsl.core.types.ExpressionUtils import com.querydsl.core.types.ExpressionUtils.count @@ -19,9 +20,7 @@ import com.querydsl.core.types.Projections import com.querydsl.core.types.dsl.Expressions import com.querydsl.jpa.JPAExpressions import com.querydsl.jpa.impl.JPAQueryFactory -import org.springframework.data.domain.Pageable -import org.springframework.data.domain.Slice -import org.springframework.data.domain.SliceImpl +import org.springframework.data.domain.Sort import org.springframework.stereotype.Repository import java.time.LocalDateTime @@ -105,10 +104,10 @@ class CustomCommunityPostRepository( .fetchOne() } - fun searchCommunityPosts(command: SearchCommunityPostCommand): Slice { - val pageable = command.pageable + fun searchCommunityPosts(command: GetSliceCommunityPostCommand): List { + val orderSpecifier = getOrder(command.sort) - var result = queryFactory.select( + return queryFactory.select( Projections.constructor( SearchCommunityPost::class.java, communityPostEntity.id, @@ -142,27 +141,26 @@ class CustomCommunityPostRepository( .join(communityPostEntity.subwayLineEntity, subwayLineEntity) .where( categoryTypeEq(command.categoryType), - subwayLineIdEq(command.subwayLineId), + subwayLineEq(command.subwayLine), hashTagEqWithSubQuery(command.hashTag), titleOrContentContains(command.content), - hotPostYnEq(command.hotPostYn) + hotPostYnEq(command.hotPostYn), + writerEq(command.writer), + createdAtBeforeOrEqual( + command.date, + command.communityPostId + ) ) - .orderBy(getOrder(pageable)) - .offset(getOffset(pageable).toLong()) - .limit(pageable.pageSize + 1L) + .orderBy(orderSpecifier) + .limit((command.pageSize + 1).toLong()) .fetch() - - val hasNext = hasNext(result, pageable) - result = if (hasNext) result.dropLast(1) else result - - return SliceImpl(result, pageable, hasNext) } - private fun getOrder(pageable: Pageable): OrderSpecifier<*>? { - if (pageable.sort.isUnsorted) return communityPostEntity.createdAt.desc() + private fun getOrder(sort: Sort): OrderSpecifier<*>? { + if (sort.isUnsorted) return communityPostEntity.createdAt.desc() - val property = pageable.sort.toList()[0].property - val direction = pageable.sort.toList()[0].direction + val property = sort.toList()[0].property + val direction = sort.toList()[0].direction val path = when (property) { "likes" -> Expressions.numberPath(Long::class.java, "likeCnt") "createdAt" -> communityPostEntity.createdAt @@ -172,22 +170,11 @@ class CustomCommunityPostRepository( return if (direction.isAscending) path.asc() else path.desc() } - private fun getOffset(pageable: Pageable): Int { - return when { - pageable.pageNumber != 0 -> (pageable.pageNumber * pageable.pageSize) + 1 - else -> pageable.pageNumber - } - } - - private fun hasNext(result: MutableList, pageable: Pageable): Boolean { - return result.size > pageable.pageSize - } - private fun categoryTypeEq(categoryType: CommunityCategoryType?) = categoryType?.let { communityPostEntity.categoryType.eq(categoryType) } - private fun subwayLineIdEq(subwayLineId: Long?) = - subwayLineId?.let { communityPostEntity.subwayLineEntity.id.eq(subwayLineId) } + private fun subwayLineEq(subwayLine: SubwayLineEntity?) = + subwayLine?.let { communityPostEntity.subwayLineEntity.eq(subwayLine) } private fun hotPostYnEq(hotPostYn: YNType?) = hotPostYn?.let { communityPostEntity.hotPostYn.eq(hotPostYn) @@ -205,4 +192,16 @@ class CustomCommunityPostRepository( private fun titleOrContentContains(content: String?) = content?.let { communityPostEntity.title.contains(content).or(communityPostEntity.content.contains(content)) } + + private fun writerEq(writer: String?) = + writer?.let { communityPostEntity.member.nickname.eq(writer) } + + private fun createdAtBeforeOrEqual(localDateTime: LocalDateTime?, id: Long?) = + localDateTime?.let { date -> + id?.let { communityPostId -> + communityPostEntity.createdAt.lt(date).or( + communityPostEntity.createdAt.eq(date).and(communityPostEntity.id.lt(communityPostId)) + ) + } + } } diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/DeleteCommunityPostCommand.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/DeleteCommunityPostCommand.kt deleted file mode 100644 index 153d2c6a..00000000 --- a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/DeleteCommunityPostCommand.kt +++ /dev/null @@ -1,6 +0,0 @@ -package backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post - -class DeleteCommunityPostCommand( - val id: Long, -) { -} \ No newline at end of file diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/GetCommunityPostCommand.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/GetCommunityPostCommand.kt deleted file mode 100644 index fe5e50ca..00000000 --- a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/GetCommunityPostCommand.kt +++ /dev/null @@ -1,6 +0,0 @@ -package backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post - -class GetCommunityPostCommand( - val id: Long, -) { -} \ No newline at end of file diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/SearchCommunityPostCommand.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/SearchCommunityPostCommand.kt deleted file mode 100644 index 9c793da7..00000000 --- a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/SearchCommunityPostCommand.kt +++ /dev/null @@ -1,15 +0,0 @@ -package backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post - -import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType -import backend.team.ahachul_backend.common.domain.model.YNType -import org.springframework.data.domain.Pageable - -class SearchCommunityPostCommand( - val categoryType: CommunityCategoryType? = null, - val subwayLineId: Long? = null, - val content: String? = null, - val hashTag: String? = null, - val hotPostYn: YNType? = null, - val pageable: Pageable, -) { -} diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/CreateCommunityPostCommand.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/CreateCommunityPostCommand.kt similarity index 84% rename from core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/CreateCommunityPostCommand.kt rename to core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/CreateCommunityPostCommand.kt index ee36c978..727b5cee 100644 --- a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/CreateCommunityPostCommand.kt +++ b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/CreateCommunityPostCommand.kt @@ -1,4 +1,4 @@ -package backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post +package backend.team.ahachul_backend.api.community.application.command.`in` import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType import org.springframework.web.multipart.MultipartFile diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/DeleteCommunityPostCommand.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/DeleteCommunityPostCommand.kt new file mode 100644 index 00000000..00afd861 --- /dev/null +++ b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/DeleteCommunityPostCommand.kt @@ -0,0 +1,6 @@ +package backend.team.ahachul_backend.api.community.application.command.`in` + +class DeleteCommunityPostCommand( + val id: Long, +) { +} \ No newline at end of file diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/GetCommunityPostCommand.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/GetCommunityPostCommand.kt new file mode 100644 index 00000000..c75f7daa --- /dev/null +++ b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/GetCommunityPostCommand.kt @@ -0,0 +1,6 @@ +package backend.team.ahachul_backend.api.community.application.command.`in` + +class GetCommunityPostCommand( + val id: Long, +) { +} \ No newline at end of file diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/SearchCommunityPostCommand.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/SearchCommunityPostCommand.kt new file mode 100644 index 00000000..1f550634 --- /dev/null +++ b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/SearchCommunityPostCommand.kt @@ -0,0 +1,18 @@ +package backend.team.ahachul_backend.api.community.application.command.`in` + +import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType +import backend.team.ahachul_backend.common.domain.model.YNType +import org.springframework.data.domain.Sort + +class SearchCommunityPostCommand( + val categoryType: CommunityCategoryType?, + val subwayLineId: Long?, + val content: String?, + val hashTag: String?, + val hotPostYn: YNType?, + val writer: String?, + val sort: Sort, + val pageToken: String?, + val pageSize: Int +) { +} diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/UpdateCommunityPostCommand.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/UpdateCommunityPostCommand.kt similarity index 85% rename from core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/UpdateCommunityPostCommand.kt rename to core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/UpdateCommunityPostCommand.kt index 57748590..d116a868 100644 --- a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/UpdateCommunityPostCommand.kt +++ b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/in/UpdateCommunityPostCommand.kt @@ -1,4 +1,4 @@ -package backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post +package backend.team.ahachul_backend.api.community.application.command.`in` import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType import org.springframework.web.multipart.MultipartFile diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/out/GetSliceCommunityPostCommand.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/out/GetSliceCommunityPostCommand.kt new file mode 100644 index 00000000..e158b9c4 --- /dev/null +++ b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/command/out/GetSliceCommunityPostCommand.kt @@ -0,0 +1,46 @@ +package backend.team.ahachul_backend.api.community.application.command.out + +import backend.team.ahachul_backend.api.community.application.command.`in`.SearchCommunityPostCommand +import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType +import backend.team.ahachul_backend.common.domain.entity.SubwayLineEntity +import backend.team.ahachul_backend.common.domain.model.YNType +import backend.team.ahachul_backend.common.utils.PageTokenUtils +import org.springframework.data.domain.Sort +import java.time.LocalDateTime + +class GetSliceCommunityPostCommand( + val categoryType: CommunityCategoryType?, + val subwayLine: SubwayLineEntity?, + val content: String?, + val hashTag: String?, + val hotPostYn: YNType?, + val writer: String?, + val sort: Sort, + val date: LocalDateTime?, + val communityPostId: Long?, + val pageSize: Int +) { + companion object { + fun from( + command: SearchCommunityPostCommand, + subwayLine: SubwayLineEntity?, + ): GetSliceCommunityPostCommand { + val pageToken = command.pageToken?.let { + PageTokenUtils.decodePageToken(it, listOf(LocalDateTime::class.java, Long::class.java)) + } + + return GetSliceCommunityPostCommand( + categoryType = command.categoryType, + subwayLine = subwayLine, + content = command.content, + hashTag = command.hashTag, + hotPostYn = command.hotPostYn, + writer = command.writer, + sort = command.sort, + date = pageToken?.get(0) as LocalDateTime?, + communityPostId = pageToken?.get(1) as Long?, + pageSize = command.pageSize + ) + } + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/port/out/CommunityPostReader.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/port/out/CommunityPostReader.kt index 14fcc209..3a3780b0 100644 --- a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/port/out/CommunityPostReader.kt +++ b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/application/port/out/CommunityPostReader.kt @@ -1,10 +1,9 @@ package backend.team.ahachul_backend.api.community.application.port.out -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.SearchCommunityPostCommand +import backend.team.ahachul_backend.api.community.application.command.out.GetSliceCommunityPostCommand import backend.team.ahachul_backend.api.community.domain.GetCommunityPost import backend.team.ahachul_backend.api.community.domain.SearchCommunityPost import backend.team.ahachul_backend.api.community.domain.entity.CommunityPostEntity -import org.springframework.data.domain.Slice interface CommunityPostReader { @@ -12,5 +11,5 @@ interface CommunityPostReader { fun getByCustom(postId: Long, memberId: String?): GetCommunityPost - fun searchCommunityPosts(command: SearchCommunityPostCommand): Slice + fun searchCommunityPosts(command: GetSliceCommunityPostCommand): List } \ No newline at end of file diff --git a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/domain/entity/CommunityPostEntity.kt b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/domain/entity/CommunityPostEntity.kt index 282935a8..f2283e70 100644 --- a/core/src/main/kotlin/backend/team/ahachul_backend/api/community/domain/entity/CommunityPostEntity.kt +++ b/core/src/main/kotlin/backend/team/ahachul_backend/api/community/domain/entity/CommunityPostEntity.kt @@ -1,7 +1,7 @@ package backend.team.ahachul_backend.api.community.domain.entity -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.CreateCommunityPostCommand -import backend.team.ahachul_backend.api.community.adapter.web.`in`.dto.post.UpdateCommunityPostCommand +import backend.team.ahachul_backend.api.community.application.command.`in`.CreateCommunityPostCommand +import backend.team.ahachul_backend.api.community.application.command.`in`.UpdateCommunityPostCommand import backend.team.ahachul_backend.api.community.domain.model.CommunityCategoryType import backend.team.ahachul_backend.api.community.domain.model.CommunityPostType import backend.team.ahachul_backend.api.member.domain.entity.MemberEntity