diff --git a/build.gradle b/build.gradle index 607aefb..4e2f107 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ buildscript { ext { // Spring - springBootVersion = "3.3.0" + springBootVersion = "3.3.1" springDependencyManagementVersion = "1.1.5" // Swagger diff --git a/threedollar-application/http/post.http b/threedollar-application/http/post.http index c640fb8..8c8ee4b 100644 --- a/threedollar-application/http/post.http +++ b/threedollar-application/http/post.http @@ -1,20 +1,29 @@ -### Post -POST {{host_api}}/community/v1/post +### Post 추가 +POST {{host_api}}/community/v1/post?accountId=USER222 X-Community-Api-Key: {{api_key}} Content-Type: application/json { - "postGroup": "BOSS_NEWS", + "postGroup": "NEWS_POST", "title": "오늘은 휴일입니다", "content": "정기적인 휴일입니다.", - "accountId": "USER222", - "postSectionRequests": [ + "targetId": "3", + "workspaceId": "threedollar-dev", + "sections": [ { - "postType": "IMAGE", + "sectionType": "IMAGE", "priority": "2", - "url": "image.jpg", - "width": "300", - "height": "400" + "ratio": 23.333, + "url": "www.naver.com" } ] } + + + +### Post 조회 +GET {{host_api}}/community/v1/posts?cursor=8&size=3&workspaceId=threedollar-dev&targetId=3&postGroup=NEWS_POST +X-Community-Api-Key: {{api_key}} +Content-Type: application/json + + diff --git a/threedollar-application/src/main/java/com/threedollar/config/advice/ExceptionControllerAdvice.java b/threedollar-application/src/main/java/com/threedollar/config/advice/ExceptionControllerAdvice.java new file mode 100644 index 0000000..92bfa63 --- /dev/null +++ b/threedollar-application/src/main/java/com/threedollar/config/advice/ExceptionControllerAdvice.java @@ -0,0 +1,24 @@ +package com.threedollar.config.advice; + +import com.threedollar.common.dto.response.ApiResponse; +import com.threedollar.common.exception.NotFoundException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +@RestControllerAdvice +public class ExceptionControllerAdvice { + + @ExceptionHandler(NotFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public ApiResponse handleNotFoundException(NotFoundException e) { + log.error(e.getErrorCode().getMessage(), e); + return ApiResponse.error(e.getErrorCode(), e.getMessage()); + } + + + +} diff --git a/threedollar-application/src/main/java/com/threedollar/controller/post/PostController.java b/threedollar-application/src/main/java/com/threedollar/controller/post/PostController.java index 3dafdd7..525f26f 100644 --- a/threedollar-application/src/main/java/com/threedollar/controller/post/PostController.java +++ b/threedollar-application/src/main/java/com/threedollar/controller/post/PostController.java @@ -3,11 +3,17 @@ import com.threedollar.common.dto.response.ApiResponse; import com.threedollar.config.interceptor.ApiKeyContext; import com.threedollar.config.resolver.RequestApiKey; +import com.threedollar.domain.post.PostGroup; import com.threedollar.service.post.PostFacadeService; +import com.threedollar.service.post.request.GetPostRequest; import com.threedollar.service.post.request.PostAddRequest; +import com.threedollar.service.post.request.PostAndCursorRequest; +import com.threedollar.service.post.response.PostAndCursorResponse; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; @@ -20,23 +26,25 @@ public class PostController { private final PostFacadeService postFacadeService; @PostMapping("/v1/post") - public ApiResponse addPost(@RequestApiKey ApiKeyContext workspaceId, - @RequestParam String accountId, - @Valid @RequestBody PostAddRequest request) { + public ApiResponse addPost(@RequestApiKey ApiKeyContext workspaceId, + @RequestParam String accountId, + @Valid @RequestBody PostAddRequest request) { - postFacadeService.addPost(request, workspaceId.getWorkspaceId(), accountId); - return ApiResponse.OK; + return ApiResponse.success(postFacadeService.addPost(request, workspaceId.getWorkspaceId(), accountId)); } - @DeleteMapping("/v1/post") - public ApiResponse deletePost(Long postId, - String accountId, - String workspaceId) { - - postFacadeService.deletePost(workspaceId, accountId, postId); + @DeleteMapping("/v1/post/{postId}") + public ApiResponse deletePost(@PathVariable Long postId, + GetPostRequest request) { + postFacadeService.deletePost(request.getWorkspaceId(), request.getAccountId(), postId, request.getPostGroup(), request.getTargetId()); return ApiResponse.OK; + } + @GetMapping("/v1/post-group/{postGroup}") + public ApiResponse getPosts(@Valid PostAndCursorRequest request, + @PathVariable PostGroup postGroup) { + return ApiResponse.success(postFacadeService.getPostAndCursor(request, postGroup)); } } diff --git a/threedollar-application/src/main/java/com/threedollar/service/poll/dto/response/CursorResponse.java b/threedollar-application/src/main/java/com/threedollar/service/poll/dto/response/CursorResponse.java index b5c37f6..50cc6a2 100644 --- a/threedollar-application/src/main/java/com/threedollar/service/poll/dto/response/CursorResponse.java +++ b/threedollar-application/src/main/java/com/threedollar/service/poll/dto/response/CursorResponse.java @@ -10,12 +10,12 @@ public class CursorResponse { private boolean hasNext; - private Long next; + private Long nextCursor; @Builder - public CursorResponse(boolean hasNext, Long next) { + public CursorResponse(boolean hasNext, Long nextCursor) { this.hasNext = hasNext; - this.next = next; + this.nextCursor = nextCursor; } } diff --git a/threedollar-application/src/main/java/com/threedollar/service/post/PostFacadeService.java b/threedollar-application/src/main/java/com/threedollar/service/post/PostFacadeService.java index 156dde9..66a9677 100644 --- a/threedollar-application/src/main/java/com/threedollar/service/post/PostFacadeService.java +++ b/threedollar-application/src/main/java/com/threedollar/service/post/PostFacadeService.java @@ -1,6 +1,10 @@ package com.threedollar.service.post; +import com.threedollar.domain.post.PostGroup; import com.threedollar.service.post.request.PostAddRequest; +import com.threedollar.service.post.request.PostAndCursorRequest; +import com.threedollar.service.post.response.PostAndCursorResponse; +import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; @@ -12,20 +16,32 @@ public class PostFacadeService { private final PostService postService; - public void addPost(PostAddRequest request, + public Long addPost(PostAddRequest request, @NotBlank String workspaceId, @NotBlank String accountId) { - postService.addPost(request, workspaceId, accountId); + return postService.addPost(request, workspaceId, accountId); } public void deletePost(@NotBlank String workspaceId, @NotBlank String accountId, - @NotNull Long postId) { + @NotNull Long postId, + @NotNull PostGroup postGroup, + @NotBlank String targetId) { - postService.deletePost(workspaceId, accountId, postId); + postService.deletePost(workspaceId, accountId, postId, postGroup, targetId); } + public PostAndCursorResponse getPostAndCursor(@Valid PostAndCursorRequest request, + PostGroup postGroup) { + return postService.getPostsAndCursor( + postGroup, + request.getWorkspaceId(), + request.getTargetId(), + request.getCursor(), + request.getSize()); + } + } diff --git a/threedollar-application/src/main/java/com/threedollar/service/post/PostService.java b/threedollar-application/src/main/java/com/threedollar/service/post/PostService.java index 452d21b..387730c 100644 --- a/threedollar-application/src/main/java/com/threedollar/service/post/PostService.java +++ b/threedollar-application/src/main/java/com/threedollar/service/post/PostService.java @@ -2,13 +2,17 @@ import com.threedollar.common.exception.NotFoundException; import com.threedollar.domain.post.Post; +import com.threedollar.domain.post.PostGroup; import com.threedollar.domain.post.repository.PostRepository; import com.threedollar.service.post.request.PostAddRequest; +import com.threedollar.service.post.response.PostAndCursorResponse; import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; + @Service @RequiredArgsConstructor public class PostService { @@ -17,20 +21,23 @@ public class PostService { @Transactional - public void addPost(PostAddRequest request, + public Long addPost(PostAddRequest request, @NotBlank String workspaceId, String accountId) { - postRepository.save(request.toEntity(workspaceId, accountId)); + Post post = postRepository.save(request.toEntity(workspaceId, accountId)); + return post.getId(); } @Transactional public void deletePost(String workspaceId, String accountId, - Long postId) { + Long postId, + PostGroup postGroup, + String targetId) { - Post post = postRepository.findByIdAndWorkspaceIdAndAccountId(postId, accountId, workspaceId); + Post post = postRepository.findByIdAndWorkspaceIdAndAccountIdAndGroupAndTargetId(postId, accountId, workspaceId, postGroup, targetId); if (post == null) { throw new NotFoundException(String.format("(%s)에 해당하는 postId 는 존재하지 않거나 잘못된 접근입니다", postId)); } @@ -39,4 +46,19 @@ public void deletePost(String workspaceId, } + @Transactional(readOnly = true) + public PostAndCursorResponse getPostsAndCursor(PostGroup postGroup, + String workspaceId, + String targetId, + Long cursor, + int size) { + List posts = postRepository.findByPostGroupAndWorkspaceIdAndTargetIdAndCursorAndSize(postGroup, workspaceId, targetId, cursor, size + 1); + + if (posts.isEmpty() || posts.size() <= size) { + return PostAndCursorResponse.noMore(posts); + } + return PostAndCursorResponse.hasNext(posts); + + } + } diff --git a/threedollar-application/src/main/java/com/threedollar/service/post/request/CursorRequest.java b/threedollar-application/src/main/java/com/threedollar/service/post/request/CursorRequest.java new file mode 100644 index 0000000..2507c16 --- /dev/null +++ b/threedollar-application/src/main/java/com/threedollar/service/post/request/CursorRequest.java @@ -0,0 +1,26 @@ +package com.threedollar.service.post.request; + + +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class CursorRequest { + + @Nullable + private Long cursor; + + @Min(0) + @Max(30) + private int size; + + public CursorRequest(Long cursor, int size) { + this.cursor = cursor; + this.size = size; + } + +} diff --git a/threedollar-application/src/main/java/com/threedollar/service/post/request/GetPostRequest.java b/threedollar-application/src/main/java/com/threedollar/service/post/request/GetPostRequest.java new file mode 100644 index 0000000..02b4f90 --- /dev/null +++ b/threedollar-application/src/main/java/com/threedollar/service/post/request/GetPostRequest.java @@ -0,0 +1,28 @@ +package com.threedollar.service.post.request; + +import com.threedollar.domain.post.PostGroup; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class GetPostRequest { + + @NotBlank + private String accountId; + + @NotBlank + private String workspaceId; + + private PostGroup postGroup; + + private String targetId; + + public GetPostRequest(String accountId, String workspaceId, PostGroup postGroup, String targetId) { + this.accountId = accountId; + this.workspaceId = workspaceId; + this.postGroup = postGroup; + this.targetId = targetId; + } +} diff --git a/threedollar-application/src/main/java/com/threedollar/service/post/request/PostAddRequest.java b/threedollar-application/src/main/java/com/threedollar/service/post/request/PostAddRequest.java index 3dd85bf..9549fad 100644 --- a/threedollar-application/src/main/java/com/threedollar/service/post/request/PostAddRequest.java +++ b/threedollar-application/src/main/java/com/threedollar/service/post/request/PostAddRequest.java @@ -22,6 +22,8 @@ public class PostAddRequest { private String title; + private String workspaceId; + private String targetId; @NotBlank @@ -31,12 +33,13 @@ public class PostAddRequest { private List sections; @Builder - public PostAddRequest(PostGroup postGroup, Long parentId, String title, String content, String targetId, List sections) { + public PostAddRequest(PostGroup postGroup, Long parentId, String title, String targetId, String content, String workspaceId, List sections) { this.postGroup = postGroup; this.parentId = parentId; this.title = title; - this.targetId = + this.workspaceId = workspaceId; this.content = content; + this.targetId = targetId; this.sections = sections; } diff --git a/threedollar-application/src/main/java/com/threedollar/service/post/request/PostAndCursorRequest.java b/threedollar-application/src/main/java/com/threedollar/service/post/request/PostAndCursorRequest.java new file mode 100644 index 0000000..41ee1d5 --- /dev/null +++ b/threedollar-application/src/main/java/com/threedollar/service/post/request/PostAndCursorRequest.java @@ -0,0 +1,33 @@ +package com.threedollar.service.post.request; + +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class PostAndCursorRequest { + + @Nullable + private Long cursor; + + @Min(0) + @Max(30) + private int size; + + @NotBlank + private String workspaceId; + + @NotBlank + private String targetId; + + public PostAndCursorRequest(Long cursor, int size, String workspaceId, String targetId) { + this.cursor = cursor; + this.size = size; + this.workspaceId = workspaceId; + this.targetId = targetId; + } +} diff --git a/threedollar-application/src/main/java/com/threedollar/service/post/request/PostSectionRequest.java b/threedollar-application/src/main/java/com/threedollar/service/post/request/PostSectionRequest.java index a00e54b..d17a743 100644 --- a/threedollar-application/src/main/java/com/threedollar/service/post/request/PostSectionRequest.java +++ b/threedollar-application/src/main/java/com/threedollar/service/post/request/PostSectionRequest.java @@ -19,22 +19,20 @@ public class PostSectionRequest { private String url; - private int width; - - private int height; + private double ratio; @Builder - public PostSectionRequest(SectionType sectionType, int priority, String url, int width, int height) { + public PostSectionRequest(SectionType sectionType, int priority, String url, double ratio) { this.sectionType = sectionType; this.priority = priority; this.url = url; - this.width = width; - this.height = height; + this.ratio = ratio; + } public PostSection toEntity(Post post) { - return PostSection.of(sectionType, post, priority, url, width, height); + return PostSection.of(sectionType, post, priority, url, ratio); } diff --git a/threedollar-application/src/main/java/com/threedollar/service/post/response/PostAndCursorResponse.java b/threedollar-application/src/main/java/com/threedollar/service/post/response/PostAndCursorResponse.java new file mode 100644 index 0000000..5da354c --- /dev/null +++ b/threedollar-application/src/main/java/com/threedollar/service/post/response/PostAndCursorResponse.java @@ -0,0 +1,51 @@ +package com.threedollar.service.post.response; + +import com.threedollar.domain.post.Post; +import com.threedollar.service.poll.dto.response.CursorResponse; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; + +@NoArgsConstructor +@Getter +public class PostAndCursorResponse { + + private CursorResponse cursor; + + private List posts; + + @Builder + public PostAndCursorResponse(CursorResponse cursor, List posts) { + this.cursor = cursor; + this.posts = posts; + } + + public static PostAndCursorResponse hasNext(List posts) { + return PostAndCursorResponse.builder() + .cursor(CursorResponse.builder() + .hasNext(true) + .nextCursor(posts.get(posts.size() - 2).getId()) + .build()) + .posts(getPostResponse(posts.subList(0, posts.size() - 1))) + .build(); + } + + public static PostAndCursorResponse noMore(List posts) { + return PostAndCursorResponse.builder() + .cursor(CursorResponse.builder() + .hasNext(false) + .nextCursor(null) + .build()) + .posts(getPostResponse(posts)) + .build(); + } + + public static List getPostResponse(List posts) { + return posts.stream() + .map(PostResponse::of) + .collect(Collectors.toList()); + } +} diff --git a/threedollar-application/src/main/java/com/threedollar/service/post/response/PostResponse.java b/threedollar-application/src/main/java/com/threedollar/service/post/response/PostResponse.java new file mode 100644 index 0000000..9f36bd8 --- /dev/null +++ b/threedollar-application/src/main/java/com/threedollar/service/post/response/PostResponse.java @@ -0,0 +1,64 @@ +package com.threedollar.service.post.response; + +import com.threedollar.domain.post.Post; +import com.threedollar.domain.post.PostGroup; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; + +@NoArgsConstructor +@Getter +public class PostResponse { + + private Long postId; + + private PostGroup postGroup; + + private Long parentId; + + private String title; + + private String content; + + private String accountId; + + private String targetId; + + private List postSections; + + @Builder + public PostResponse(Long postId, PostGroup postGroup, Long parentId, String title, String content, String accountId, String targetId, List postSections) { + this.postId = postId; + this.postGroup = postGroup; + this.parentId = parentId; + this.title = title; + this.content = content; + this.accountId = accountId; + this.targetId = targetId; + this.postSections = postSections; + } + + public static PostResponse of(Post post) { + return PostResponse.builder() + .postId(post.getId()) + .postGroup(post.getPostGroup()) + .parentId(post.getParentId()) + .title(post.getTitle()) + .content(post.getContent()) + .accountId(post.getAccountId()) + .targetId(post.getTargetId()) + .postSections(getPostSectionResponses(post)) + .build(); + + } + + public static List getPostSectionResponses(Post post) { + return post.getPostSection().stream() + .map(PostSectionResponse::of) + .collect(Collectors.toList()); + } + +} diff --git a/threedollar-application/src/main/java/com/threedollar/service/post/response/PostSectionResponse.java b/threedollar-application/src/main/java/com/threedollar/service/post/response/PostSectionResponse.java new file mode 100644 index 0000000..af30b33 --- /dev/null +++ b/threedollar-application/src/main/java/com/threedollar/service/post/response/PostSectionResponse.java @@ -0,0 +1,39 @@ +package com.threedollar.service.post.response; + +import com.threedollar.domain.post.SectionType; +import com.threedollar.domain.post.postsection.PostSection; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class PostSectionResponse { + + private SectionType sectionType; + + private int priority; + + private String url; + + private double ratio; + + @Builder + public PostSectionResponse(SectionType sectionType, int priority, String url, double ratio) { + this.sectionType = sectionType; + this.priority = priority; + this.url = url; + this.ratio = ratio; + } + + public static PostSectionResponse of(PostSection section) { + + return PostSectionResponse.builder() + .sectionType(section.getSectionType()) + .priority(section.getPriority()) + .url(section.getUrl()) + .ratio(section.getRatio()) + .build(); + + } +} diff --git a/threedollar-application/src/test/java/com/threedollar/service/post/PostServiceTest.java b/threedollar-application/src/test/java/com/threedollar/service/post/PostServiceTest.java index 1de151a..5706aad 100644 --- a/threedollar-application/src/test/java/com/threedollar/service/post/PostServiceTest.java +++ b/threedollar-application/src/test/java/com/threedollar/service/post/PostServiceTest.java @@ -33,7 +33,6 @@ void clean_up() { @Test void 사장님이_소식을_작성한다() { - // given PostAddRequest request = newRequest(); String workspaceId = "three-user"; @@ -45,59 +44,60 @@ void clean_up() { // then Post post = postRepository.findAll().get(0); assertThat(postRepository.findAll()).hasSize(1); - assertThat(workspaceId).isEqualTo(post.getWorkspaceId()); - assertPost(post, request.getPostGroup(), request.getTitle(), request.getContent(), accountId, request.getTargetId()); + assertPost(post, request.getPostGroup(), request.getTitle(), request.getContent(), accountId, workspaceId, request.getTargetId()); } @Test void 사장님이_소식을_지운다() { // given String workspaceId = "three-dollar-dev"; - String accountId = "user222"; + String accountId = "user"; Post post = postRepository.save(newRequest().toEntity(workspaceId, accountId)); // when - postService.deletePost(workspaceId, accountId, post.getId()); + postService.deletePost(workspaceId, accountId, post.getId(), post.getPostGroup(), post.getTargetId()); // then List posts = postRepository.findAll(); + assertThat(posts).hasSize(1); assertThat(posts.get(0).getStatus()).isEqualTo(PostStatus.DELETED); } - private void assertPost(Post post, PostGroup postGroup, String title, String content, String accountId, String targetId) { + private void assertPost(Post post, PostGroup postGroup, String title, String content, String accountId, String workspaceId, String targetId) { assertThat(post.getPostGroup()).isEqualTo(postGroup); assertThat(post.getTitle()).isEqualTo(title); assertThat(post.getContent()).isEqualTo(content); assertThat(post.getAccountId()).isEqualTo(accountId); + assertThat(post.getWorkspaceId()).isEqualTo(workspaceId); assertThat(post.getTargetId()).isEqualTo(targetId); } private PostAddRequest newRequest() { - PostGroup postGroup = PostGroup.BOSS_NEWS; + PostGroup postGroup = PostGroup.NEWS_POST; + String targetId = "33"; + String workspaceId = "threedollar-dev"; String title = "은평구 핫도그 아저씨"; String content = "콘텐트"; SectionType sectionType = SectionType.IMAGE; - int height = 400; - int width = 200; + double ratio = 23.333; String url = "image.jpg"; - String targetId = "111"; PostSectionRequest postSectionRequest = PostSectionRequest.builder() .sectionType(sectionType) - .height(height) - .width(width) + .ratio(ratio) .url(url) .build(); return PostAddRequest.builder() .postGroup(postGroup) .title(title) - .targetId(targetId) .content(content) + .targetId(targetId) + .workspaceId(workspaceId) .sections(List.of(postSectionRequest)) .build(); } diff --git a/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/Post.java b/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/Post.java index b0454ec..ba6f44d 100644 --- a/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/Post.java +++ b/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/Post.java @@ -37,6 +37,7 @@ public class Post extends BaseEntity { @Column(length = 4000) private String content; + @Column(nullable = false, length = 200) private String targetId; @Column(nullable = false, length = 200) diff --git a/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/PostGroup.java b/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/PostGroup.java index 46ad004..de43ca7 100644 --- a/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/PostGroup.java +++ b/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/PostGroup.java @@ -5,7 +5,7 @@ @Getter public enum PostGroup { - BOSS_NEWS("사장님 소식") + NEWS_POST("소식") ; private final String description; diff --git a/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/postsection/PostSection.java b/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/postsection/PostSection.java index 1a586e4..8fddb92 100644 --- a/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/postsection/PostSection.java +++ b/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/postsection/PostSection.java @@ -35,29 +35,24 @@ public class PostSection extends BaseEntity { private String url; @Column(length = 100) - private int width; - - @Column(length = 100) - private int height; + private double ratio; @Builder - public PostSection(SectionType sectionType, Post post, int priority, String url, int width, int height) { + public PostSection(SectionType sectionType, Post post, double ratio, String url, int priority) { this.sectionType = sectionType; this.post = post; this.priority = priority; this.url = url; - this.width = width; - this.height = height; + this.ratio = ratio; } - public static PostSection of(SectionType sectionType, Post post, int priority, String url, int width, int height) { + public static PostSection of(SectionType sectionType, Post post, int priority, String url, double ratio) { return PostSection.builder() .post(post) .sectionType(sectionType) .priority(priority) .url(url) - .width(width) - .height(height) + .ratio(ratio) .build(); } diff --git a/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/repository/PostRepositoryCustom.java b/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/repository/PostRepositoryCustom.java index f5d2c98..30729d6 100644 --- a/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/repository/PostRepositoryCustom.java +++ b/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/repository/PostRepositoryCustom.java @@ -1,10 +1,22 @@ package com.threedollar.domain.post.repository; import com.threedollar.domain.post.Post; +import com.threedollar.domain.post.PostGroup; +import jakarta.annotation.Nullable; + +import java.util.List; public interface PostRepositoryCustom { - Post findByIdAndWorkspaceIdAndAccountId(Long postId, - String accountId, - String workspaceId); + Post findByIdAndWorkspaceIdAndAccountIdAndGroupAndTargetId(Long postId, + String accountId, + String workspaceId, + PostGroup group, + String targetId); + + List findByPostGroupAndWorkspaceIdAndTargetIdAndCursorAndSize(PostGroup postGroup, + String workspaceId, + String targetId, + @Nullable Long cursor, + int size); } diff --git a/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/repository/PostRepositoryCustomImpl.java b/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/repository/PostRepositoryCustomImpl.java index 7ba7b60..dcb94c6 100644 --- a/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/repository/PostRepositoryCustomImpl.java +++ b/threedollar-core/threedollar-domain/src/main/java/com/threedollar/domain/post/repository/PostRepositoryCustomImpl.java @@ -1,11 +1,16 @@ package com.threedollar.domain.post.repository; +import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import com.threedollar.domain.post.Post; +import com.threedollar.domain.post.PostGroup; import com.threedollar.domain.post.PostStatus; import lombok.RequiredArgsConstructor; +import java.util.List; + import static com.threedollar.domain.post.QPost.post; +import static com.threedollar.domain.post.postsection.QPostSection.postSection; @RequiredArgsConstructor public class PostRepositoryCustomImpl implements PostRepositoryCustom { @@ -13,14 +18,44 @@ public class PostRepositoryCustomImpl implements PostRepositoryCustom { private final JPAQueryFactory jpaQueryFactory; @Override - public Post findByIdAndWorkspaceIdAndAccountId(Long postId, String accountId, String workspaceId) { + public Post findByIdAndWorkspaceIdAndAccountIdAndGroupAndTargetId(Long postId, String accountId, String workspaceId, PostGroup postGroup, String targetId) { return jpaQueryFactory.selectFrom(post) .where( post.workspaceId.eq(workspaceId), post.accountId.eq(accountId), post.id.eq(postId), + post.postGroup.eq(postGroup), + post.targetId.eq(targetId), post.status.eq(PostStatus.ACTIVE) ) .fetchOne(); } + + @Override + public List findByPostGroupAndWorkspaceIdAndTargetIdAndCursorAndSize(PostGroup postGroup, String workspaceId, String targetId, Long cursor, int size) { + List postIds = jpaQueryFactory.select(post.id) + .from(post) + .where(existsCursor(cursor), + post.workspaceId.eq(workspaceId), + post.postGroup.eq(postGroup), + post.targetId.eq(targetId), + post.status.eq(PostStatus.ACTIVE)) + .orderBy(post.id.desc()) + .limit(size) + .fetch(); + + return jpaQueryFactory.selectFrom(post) + .leftJoin(post.postSection, postSection).fetchJoin() + .where(post.id.in(postIds)) + .orderBy(post.id.desc()) + .fetch(); + } + + private BooleanExpression existsCursor(Long cursor) { + if (cursor == null) { + return null; + } + return post.id.lt(cursor); + } + }