diff --git a/README.md b/README.md index bf1b144..3de973f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Potato Backend -![Generic badge](https://img.shields.io/badge/version-1.0.1-orange.svg) +![Generic badge](https://img.shields.io/badge/version-1.0.2-orange.svg) [![codecov](https://codecov.io/gh/steamed-potatoes/potato-backend/branch/develop/graph/badge.svg?token=ACoWRzqGBl)](https://codecov.io/gh/steamed-potatoes/potato-backend) --- @@ -85,3 +85,8 @@ docker-compose up --build ## Contacts - will.seungho@gmail.com + +--- + +License +Potato Backend is MIT licensed. diff --git a/potato-api/src/main/java/com/potato/api/controller/board/organization/OrganizationBoardRetrieveController.java b/potato-api/src/main/java/com/potato/api/controller/board/organization/OrganizationBoardRetrieveController.java index 59d102c..be7f5fb 100644 --- a/potato-api/src/main/java/com/potato/api/controller/board/organization/OrganizationBoardRetrieveController.java +++ b/potato-api/src/main/java/com/potato/api/controller/board/organization/OrganizationBoardRetrieveController.java @@ -3,7 +3,7 @@ import com.potato.api.config.argumentResolver.MemberId; import com.potato.api.config.interceptor.auth.Auth; import com.potato.api.controller.ApiResponse; -import com.potato.domain.domain.board.organization.repository.dto.BoardWithOrganizationDto; +import com.potato.api.service.board.organization.dto.response.OrganizationBoardWithOrganizationResponse; import com.potato.api.service.board.organization.OrganizationBoardRetrieveService; import com.potato.api.service.board.organization.dto.request.*; import com.potato.api.service.board.organization.dto.response.OrganizationBoardInfoResponse; @@ -34,7 +34,7 @@ public ApiResponse retrieveBoardWithOr @Operation(summary = "전체 그룹 게시물을 스크롤 페이지네이션 기반으로 조회하는 API") @GetMapping("/api/v2/organization/board/list") - public ApiResponse> retrieveLatestOrganizationBoardList(@Valid RetrieveLatestBoardsRequest request) { + public ApiResponse> retrieveLatestOrganizationBoardList(@Valid RetrieveLatestBoardsRequest request) { return ApiResponse.success(organizationBoardRetrieveService.retrieveBoardsWithPagination(request.getType(), request.getLastOrganizationBoardId(), request.getSize())); } @@ -52,7 +52,7 @@ public ApiResponse> retrievePopularBoard(@Va @Operation(summary = "특정 그룹의 게시물을 스크롤 페이지네이션 기반으로 조회하는 API") @GetMapping("/api/v2/organization/board/list/in/{subDomain}") - public ApiResponse> getBoardsInOrganization(@PathVariable String subDomain, @Valid RetrieveLatestBoardsRequest request) { + public ApiResponse> getBoardsInOrganization(@PathVariable String subDomain, @Valid RetrieveLatestBoardsRequest request) { return ApiResponse.success(organizationBoardRetrieveService.getBoardsInOrganization(subDomain, request.getType(), request.getLastOrganizationBoardId(), request.getSize())); } diff --git a/potato-api/src/main/java/com/potato/api/service/board/organization/OrganizationBoardRetrieveService.java b/potato-api/src/main/java/com/potato/api/service/board/organization/OrganizationBoardRetrieveService.java index d6b0930..ac9f75f 100644 --- a/potato-api/src/main/java/com/potato/api/service/board/organization/OrganizationBoardRetrieveService.java +++ b/potato-api/src/main/java/com/potato/api/service/board/organization/OrganizationBoardRetrieveService.java @@ -1,6 +1,6 @@ package com.potato.api.service.board.organization; -import com.potato.domain.domain.board.organization.repository.dto.BoardWithOrganizationDto; +import com.potato.api.service.board.organization.dto.response.OrganizationBoardWithOrganizationResponse; import com.potato.domain.domain.image.BoardImageRepository; import com.potato.domain.domain.board.BoardType; import com.potato.domain.domain.board.organization.OrganizationBoard; @@ -53,9 +53,9 @@ private List getBoardHashTags(Long boardId) { } @Transactional(readOnly = true) - public List retrieveBoardsWithPagination(OrganizationBoardCategory type, long lastOrganizationBoardId, int size) { + public List retrieveBoardsWithPagination(OrganizationBoardCategory type, long lastOrganizationBoardId, int size) { return organizationBoardRepository.findAllWithOrganizationByTypeLessThanOrderByIdDescLimit(null, type, lastOrganizationBoardId, size).stream() - .map(boardWithOrganizationDto -> boardWithOrganizationDto.setImageUrls(OrganizationBoardServiceUtils.findOrganizationBoardImage(boardImageRepository, boardWithOrganizationDto.getBoardId()))) + .map(boardWithOrganizationDto -> OrganizationBoardWithOrganizationResponse.of(boardWithOrganizationDto, OrganizationBoardServiceUtils.findOrganizationBoardImage(boardImageRepository, boardWithOrganizationDto.getBoardId()))) .collect(Collectors.toList()); } @@ -75,9 +75,9 @@ public List retrievePopularBoard(int size) { } @Transactional(readOnly = true) - public List getBoardsInOrganization(String subDomain, OrganizationBoardCategory type, long lastOrganizationBoardId, int size) { + public List getBoardsInOrganization(String subDomain, OrganizationBoardCategory type, long lastOrganizationBoardId, int size) { return organizationBoardRepository.findAllWithOrganizationByTypeLessThanOrderByIdDescLimit(subDomain, type, lastOrganizationBoardId, size).stream() - .map(boardWithOrganizationDto -> boardWithOrganizationDto.setImageUrls(OrganizationBoardServiceUtils.findOrganizationBoardImage(boardImageRepository, boardWithOrganizationDto.getBoardId()))) + .map(boardWithOrganizationDto -> OrganizationBoardWithOrganizationResponse.of(boardWithOrganizationDto, OrganizationBoardServiceUtils.findOrganizationBoardImage(boardImageRepository, boardWithOrganizationDto.getBoardId()))) .collect(Collectors.toList()); } diff --git a/potato-api/src/main/java/com/potato/api/service/board/organization/dto/response/OrganizationBoardWithOrganizationResponse.java b/potato-api/src/main/java/com/potato/api/service/board/organization/dto/response/OrganizationBoardWithOrganizationResponse.java new file mode 100644 index 0000000..814edc1 --- /dev/null +++ b/potato-api/src/main/java/com/potato/api/service/board/organization/dto/response/OrganizationBoardWithOrganizationResponse.java @@ -0,0 +1,78 @@ +package com.potato.api.service.board.organization.dto.response; + +import com.potato.api.service.common.dto.response.BaseTimeResponse; +import com.potato.domain.domain.board.organization.OrganizationBoardCategory; +import com.potato.domain.domain.board.organization.repository.dto.BoardWithOrganizationDto; +import com.potato.domain.domain.organization.OrganizationCategory; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@ToString +@Getter +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class OrganizationBoardWithOrganizationResponse extends BaseTimeResponse { + + private String orgSubDomain; + private String orgName; + private OrganizationCategory orgCategory; + private String orgProfileUrl; + private String orgDescription; + private int orgMembersCount; + private int orgFollowersCount; + + private Long boardId; + private String boardTitle; + private String boardContent; + private OrganizationBoardCategory boardCategory; + private LocalDateTime boardStartDateTime; + private LocalDateTime boardEndDateTime; + private final List imageUrls = new ArrayList<>(); + + @Builder + public OrganizationBoardWithOrganizationResponse(String orgSubDomain, String orgName, OrganizationCategory orgCategory, + String orgProfileUrl, String orgDescription, int orgMembersCount, int orgFollowersCount, + Long boardId, String boardTitle, String boardContent, OrganizationBoardCategory boardCategory, + LocalDateTime boardStartDateTime, LocalDateTime boardEndDateTime) { + this.orgSubDomain = orgSubDomain; + this.orgName = orgName; + this.orgCategory = orgCategory; + this.orgProfileUrl = orgProfileUrl; + this.orgDescription = orgDescription; + this.orgMembersCount = orgMembersCount; + this.orgFollowersCount = orgFollowersCount; + this.boardId = boardId; + this.boardTitle = boardTitle; + this.boardContent = boardContent; + this.boardCategory = boardCategory; + this.boardStartDateTime = boardStartDateTime; + this.boardEndDateTime = boardEndDateTime; + } + + public static OrganizationBoardWithOrganizationResponse of(BoardWithOrganizationDto dto, List imageUrls) { + OrganizationBoardWithOrganizationResponse response = OrganizationBoardWithOrganizationResponse.builder() + .orgSubDomain(dto.getOrgSubDomain()) + .orgName(dto.getOrgName()) + .orgCategory(dto.getOrgCategory()) + .orgProfileUrl(dto.getOrgProfileUrl()) + .orgDescription(dto.getOrgDescription()) + .orgMembersCount(dto.getOrgMembersCount()) + .orgFollowersCount(dto.getOrgFollowersCount()) + .boardId(dto.getBoardId()) + .boardTitle(dto.getBoardTitle()) + .boardContent(dto.getBoardContent()) + .boardCategory(dto.getBoardCategory()) + .boardStartDateTime(dto.getBoardStartDateTime()) + .boardEndDateTime(dto.getBoardEndDateTime()) + .build(); + response.setBaseTime(dto.getCreatedDateTime(), dto.getLastModifiedDateTime()); + return response; + } + +} diff --git a/potato-api/src/main/java/com/potato/api/service/common/dto/response/BaseTimeResponse.java b/potato-api/src/main/java/com/potato/api/service/common/dto/response/BaseTimeResponse.java index 2d563e7..ebbf7ba 100644 --- a/potato-api/src/main/java/com/potato/api/service/common/dto/response/BaseTimeResponse.java +++ b/potato-api/src/main/java/com/potato/api/service/common/dto/response/BaseTimeResponse.java @@ -19,4 +19,9 @@ protected void setBaseTime(BaseTimeEntity entity) { this.lastModifiedDateTime = entity.getLastModifiedDateTime(); } + protected void setBaseTime(LocalDateTime createdDateTime, LocalDateTime lastModifiedDateTime) { + this.createdDateTime = createdDateTime; + this.lastModifiedDateTime = lastModifiedDateTime; + } + } diff --git a/potato-api/src/test/java/com/potato/api/service/board/OrganizationBoardRetrieveServiceTest.java b/potato-api/src/test/java/com/potato/api/service/board/OrganizationBoardRetrieveServiceTest.java index 2016ed5..f51294f 100644 --- a/potato-api/src/test/java/com/potato/api/service/board/OrganizationBoardRetrieveServiceTest.java +++ b/potato-api/src/test/java/com/potato/api/service/board/OrganizationBoardRetrieveServiceTest.java @@ -1,10 +1,10 @@ package com.potato.api.service.board; +import com.potato.api.service.board.organization.dto.response.OrganizationBoardWithOrganizationResponse; import com.potato.domain.domain.board.organization.OrganizationBoard; import com.potato.domain.domain.board.organization.OrganizationBoardCategory; import com.potato.domain.domain.board.organization.OrganizationBoardCreator; import com.potato.domain.domain.board.organization.OrganizationBoardRepository; -import com.potato.domain.domain.board.organization.repository.dto.BoardWithOrganizationDto; import com.potato.api.service.OrganizationMemberSetUpTest; import com.potato.api.service.board.organization.OrganizationBoardRetrieveService; import com.potato.api.service.board.organization.dto.response.OrganizationBoardInfoResponse; @@ -45,13 +45,13 @@ void cleanUp() { organizationBoardRepository.saveAll(Arrays.asList(organizationBoard1, organizationBoard2, organizationBoard3)); //when - List responses = organizationBoardService.retrieveBoardsWithPagination(null, 0, 3); + List responses = organizationBoardService.retrieveBoardsWithPagination(null, 0, 3); //then assertThat(responses).hasSize(3); - assertOrganizationBoardWithCreatorInfo(responses.get(0), organizationBoard3); - assertOrganizationBoardWithCreatorInfo(responses.get(1), organizationBoard2); - assertOrganizationBoardWithCreatorInfo(responses.get(2), organizationBoard1); + assertOrganizationBoardWithOrganizationResponse(responses.get(0), organizationBoard3); + assertOrganizationBoardWithOrganizationResponse(responses.get(1), organizationBoard2); + assertOrganizationBoardWithOrganizationResponse(responses.get(2), organizationBoard1); } @DisplayName("게시물 조회시 마지막 게시물의 id가 따로 지정되지 않으면, 가장 최신의 게시물 N개가 조회된다.") @@ -64,17 +64,17 @@ void cleanUp() { organizationBoardRepository.saveAll(Arrays.asList(organizationBoard1, organizationBoard2)); //when - List responses = organizationBoardService.retrieveBoardsWithPagination(null, 0, 1); + List responses = organizationBoardService.retrieveBoardsWithPagination(null, 0, 1); //then assertThat(responses).hasSize(1); - assertOrganizationBoardWithCreatorInfo(responses.get(0), organizationBoard2); + assertOrganizationBoardWithOrganizationResponse(responses.get(0), organizationBoard2); } @Test void 게시물_조회시_없을_경우_NULL이_아닌_빈리스트를_반환() { //given - List responses = organizationBoardService.retrieveBoardsWithPagination(null, 0, 3); + List responses = organizationBoardService.retrieveBoardsWithPagination(null, 0, 3); //then assertThat(responses).isEmpty(); @@ -91,11 +91,11 @@ void cleanUp() { organizationBoardRepository.saveAll(Arrays.asList(organizationBoard1, organizationBoard2, organizationBoard3)); //when - List responses = organizationBoardService.retrieveBoardsWithPagination(null, organizationBoard3.getId(), 1); + List responses = organizationBoardService.retrieveBoardsWithPagination(null, organizationBoard3.getId(), 1); //then assertThat(responses).hasSize(1); - assertOrganizationBoardWithCreatorInfo(responses.get(0), organizationBoard2); + assertOrganizationBoardWithOrganizationResponse(responses.get(0), organizationBoard2); } @Test @@ -108,11 +108,11 @@ void cleanUp() { organizationBoardRepository.saveAll(Arrays.asList(organizationBoard1, organizationBoard2, organizationBoard3)); //when - List responses = organizationBoardService.retrieveBoardsWithPagination(OrganizationBoardCategory.RECRUIT, organizationBoard3.getId(), 1); + List responses = organizationBoardService.retrieveBoardsWithPagination(OrganizationBoardCategory.RECRUIT, organizationBoard3.getId(), 1); //then assertThat(responses).hasSize(1); - assertOrganizationBoardWithCreatorInfo(responses.get(0), organizationBoard1); + assertOrganizationBoardWithOrganizationResponse(responses.get(0), organizationBoard1); } @Test @@ -122,7 +122,7 @@ void cleanUp() { organizationBoardRepository.save(organizationBoard1); //when - List responses = organizationBoardService.retrieveBoardsWithPagination(null, organizationBoard1.getId(), 3); + List responses = organizationBoardService.retrieveBoardsWithPagination(null, organizationBoard1.getId(), 3); //then assertThat(responses).isEmpty(); @@ -181,7 +181,7 @@ void cleanUp() { assertOrganizationBoardInfo(responses.get(1), organizationBoard2); } - private void assertOrganizationBoardWithCreatorInfo(BoardWithOrganizationDto boardWithOrganizationDto, OrganizationBoard organizationBoard) { + private void assertOrganizationBoardWithOrganizationResponse(OrganizationBoardWithOrganizationResponse boardWithOrganizationDto, OrganizationBoard organizationBoard) { assertThat(boardWithOrganizationDto.getBoardId()).isEqualTo(organizationBoard.getId()); assertThat(boardWithOrganizationDto.getOrgSubDomain()).isEqualTo(organizationBoard.getSubDomain()); assertThat(boardWithOrganizationDto.getBoardTitle()).isEqualTo(organizationBoard.getTitle()); diff --git a/potato-domain/src/main/java/com/potato/domain/domain/board/organization/repository/OrganizationBoardRepositoryCustomImpl.java b/potato-domain/src/main/java/com/potato/domain/domain/board/organization/repository/OrganizationBoardRepositoryCustomImpl.java index 1f4d46d..ee3d68c 100644 --- a/potato-domain/src/main/java/com/potato/domain/domain/board/organization/repository/OrganizationBoardRepositoryCustomImpl.java +++ b/potato-domain/src/main/java/com/potato/domain/domain/board/organization/repository/OrganizationBoardRepositoryCustomImpl.java @@ -3,7 +3,7 @@ import com.potato.domain.domain.board.organization.OrganizationBoard; import com.potato.domain.domain.board.organization.OrganizationBoardCategory; import com.potato.domain.domain.board.organization.repository.dto.BoardWithOrganizationDto; -import com.querydsl.core.types.Projections; +import com.potato.domain.domain.board.organization.repository.dto.QBoardWithOrganizationDto; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; @@ -41,22 +41,22 @@ public OrganizationBoard findOrganizationBoardByIdAndSubDomain(Long organization @Override public List findAllWithOrganizationByTypeLessThanOrderByIdDescLimit(String subDomain, OrganizationBoardCategory category, long lastOrganizationBoardId, int size) { - return queryFactory.select(Projections.fields(BoardWithOrganizationDto.class, - organizationBoard.subDomain.as("orgSubDomain"), - organization.name.as("orgName"), - organization.category.as("orgCategory"), - organization.profileUrl.as("orgProfileUrl"), - organization.description.as("orgDescription"), - organization.membersCount.as("orgMembersCount"), - organization.followersCount.as("orgFollowersCount"), - organizationBoard.id.as("boardId"), - organizationBoard.boardInfo.title.as("boardTitle"), - organizationBoard.boardInfo.content.as("boardContent"), - organizationBoard.category.as("boardCategory"), - organizationBoard.dateTimeInterval.startDateTime.as("boardStartDateTime"), - organizationBoard.dateTimeInterval.endDateTime.as("boardEndDateTime"), - organizationBoard.createdDateTime, - organizationBoard.lastModifiedDateTime + return queryFactory.select(new QBoardWithOrganizationDto( + organization.subDomain, + organization.name, + organization.category, + organization.profileUrl, + organization.description, + organization.membersCount, + organization.followersCount, + organizationBoard.id, + organizationBoard.boardInfo.title, + organizationBoard.boardInfo.content, + organizationBoard.category, + organizationBoard.dateTimeInterval.startDateTime, + organizationBoard.dateTimeInterval.endDateTime, + organization.createdDateTime, + organization.lastModifiedDateTime )) .from(organizationBoard) .innerJoin(organization).on(organizationBoard.subDomain.eq(organization.subDomain)) diff --git a/potato-domain/src/main/java/com/potato/domain/domain/board/organization/repository/dto/BoardWithOrganizationDto.java b/potato-domain/src/main/java/com/potato/domain/domain/board/organization/repository/dto/BoardWithOrganizationDto.java index e053424..1d79a8d 100644 --- a/potato-domain/src/main/java/com/potato/domain/domain/board/organization/repository/dto/BoardWithOrganizationDto.java +++ b/potato-domain/src/main/java/com/potato/domain/domain/board/organization/repository/dto/BoardWithOrganizationDto.java @@ -2,42 +2,52 @@ import com.potato.domain.domain.board.organization.OrganizationBoardCategory; import com.potato.domain.domain.organization.OrganizationCategory; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; +import com.querydsl.core.annotations.QueryProjection; import lombok.Getter; -import lombok.NoArgsConstructor; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; @Getter -@NoArgsConstructor -@AllArgsConstructor(access = AccessLevel.PRIVATE) public class BoardWithOrganizationDto { - private String orgSubDomain; - private String orgName; - private OrganizationCategory orgCategory; - private String orgProfileUrl; - private String orgDescription; - private int orgMembersCount; - private int orgFollowersCount; - - private Long boardId; - private String boardTitle; - private String boardContent; - private OrganizationBoardCategory boardCategory; - private LocalDateTime boardStartDateTime; - private LocalDateTime boardEndDateTime; - private LocalDateTime createdDateTime; - private LocalDateTime lastModifiedDateTime; - - private final List imageUrls = new ArrayList<>(); - - public BoardWithOrganizationDto setImageUrls(List imageUrls) { - this.imageUrls.addAll(imageUrls); - return this; + private final String orgSubDomain; + private final String orgName; + private final OrganizationCategory orgCategory; + private final String orgProfileUrl; + private final String orgDescription; + private final int orgMembersCount; + private final int orgFollowersCount; + + private final Long boardId; + private final String boardTitle; + private final String boardContent; + private final OrganizationBoardCategory boardCategory; + private final LocalDateTime boardStartDateTime; + private final LocalDateTime boardEndDateTime; + private final LocalDateTime createdDateTime; + private final LocalDateTime lastModifiedDateTime; + + @QueryProjection + public BoardWithOrganizationDto(String orgSubDomain, String orgName, OrganizationCategory orgCategory, String orgProfileUrl, + String orgDescription, int orgMembersCount, int orgFollowersCount, + Long boardId, String boardTitle, String boardContent, OrganizationBoardCategory boardCategory, + LocalDateTime boardStartDateTime, LocalDateTime boardEndDateTime, + LocalDateTime createdDateTime, LocalDateTime lastModifiedDateTime) { + this.orgSubDomain = orgSubDomain; + this.orgName = orgName; + this.orgCategory = orgCategory; + this.orgProfileUrl = orgProfileUrl; + this.orgDescription = orgDescription; + this.orgMembersCount = orgMembersCount; + this.orgFollowersCount = orgFollowersCount; + this.boardId = boardId; + this.boardTitle = boardTitle; + this.boardContent = boardContent; + this.boardCategory = boardCategory; + this.boardStartDateTime = boardStartDateTime; + this.boardEndDateTime = boardEndDateTime; + this.createdDateTime = createdDateTime; + this.lastModifiedDateTime = lastModifiedDateTime; } } diff --git a/version.txt b/version.txt index b18d465..570c796 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v1.0.1 +v1.0.2