Skip to content

Commit

Permalink
데벨업 v2.0.4 Release (#748)
Browse files Browse the repository at this point in the history
* refactor: 미션이 없을 때 보여지는 NoContent 화면 추가 및 NoContentWithoutButton 타입 추가 (#672)

* feat: PageResponse 응답 추가 (#678)

* 솔루션, 디스커션 목록 조회 할 때 해시태그 필터링 시 조회 결과에 해당 해시태그만 표시되는 버그 수정(issue #674) (#676)

* fix: 솔루션 목록 조회 시 미션과 해시태그 필터링이 모두 걸린 경우 해시태그가 하나만 조회되는 현상 수정

* fix: 디스커션 목록 조회 시 미션과 해시태그 필터링이 모두 걸린 경우 해시태그가 하나만 조회되는 현상 수정

* test: 해시태그 검증 테스트 추가

* test: 해시태그 검증 테스트 추가

* chore: submodule 업데이트

* feat: lombok.config 설정

* refactor: allArgs 제거

* style: discussion comment 생성자 개행 추가

* feat: 사용자가 작성한 디스커션 댓글 목록 api 페이지네이션 적용

* feat: 사용자가 작성한 디스커션 댓글 조회 페이지네이션 쿼리 구현

* feat: 페이지네이션 적용 버전 getMyComments 구현

* refactor: 파라미터 wrapper 사용하도록 변경

* refactor: 메서드 이름 변경

* feat: 솔루션 목록 조회에 페이지네이션 추가

* test: 솔루션 목록 조회 페이지네이션 테스트 추가

* fix: 최대 페이지 잘못 지정하는 오류 수정

* fix: 반환 타입 수정

* fix: 페이지네이션 0 베이스로 변경

* feat: 제출한 솔루션 댓글 pagination 적용 (issue #686)(#689)

Co-authored-by: 임수빈 <[email protected]>

* refactor: discussion 목록 조회 api 쿼리 파라미터 추가

* feat: 사용자 디스커션 조회 페이징 기능 구현

* feat: 사용자 작성 디스커션 목록 api 페이지네이션 적용

* refactor: pagePageableExecutionUtils을 사용하도록 변경

* refactor: repository에서 page를 반환하도록 변경

* chore: 미사용 필드 제거

* refactor: 메서드 이름 변경

* refactor: wrapper 타입 사용하도록 변경

* 디스커션 목록 페이지네이션 (issue #679) (#691)

* feat: 디스커션 페이지네이션 작성

* 테스트: 디스커션 페이지네이션 테스트

* 대시보드 제출한 풀이 페이지네이션 (issue #692) (#693)

* feat: 대시보드 제출한 풀이 페이지네이션 기능 구현

* feat: 대시보드 제출한 미션 페이지네이션을 사용하는 서비스 구현

* feat: 대시보드 제출한 미션 페이지네이션을 사용할 수 있도록 API 구현

* 풀이/디스커션 제출 페이지 마크다운 에디터 적용 (issue #683) (#694)

* feat: 태그 선택 시 게시글 리스트만 리렌더되도록 수정

* feat: 디스커션 제출 페이지 마크다운 에디터 적용

* feat: 풀이 제출 마크다운 에디터 적용

* chore: 임시 주석 삭제

* refactor: solutionListPage SpinnerSuspense 적용

* 웹 페이지 접근성 헤더 적용 및 mediaQueries 추가 (issue #675) (#696)

* feat: 본문으로 바로가기 추가

* design: mediaQueries 추가 및 전체 디자인 레이아웃 조정
- mediaQueries 추가
- Header 및 Footer min-width, width 기본 조정
- AboutPage 이미지 대체 및 Rocket Image 추가

* design: skip button 포커스 시 화면에 보이도록 수정

---------

Co-authored-by: JEON TAEHEON <[email protected]>

* 페이지네이션 구현 (issue #684) (#698)

* refactor: 커스텀 뮤테이션 인자 변경

* Merge branch 'dev' of https://github.com/woowacourse-teams/2024-devel-up into dev

* remove: 파일 삭제

* feat: 페이지네이션 커스텀 훅구현

* feat: 페이지네이션 구현

* fix: 빌드 에러 수정

* refactor: 변경사항 반영

* refactor: 미션페이지 페이지네이션 제거

* 상세 및 제출 페이지 웹 접근성 대응 (#700)

* feat: 미션 상세 페이지 시맨틱 태그 적용

* feat: 풀이 상세 페이지 시맨틱 태그 적용

* feat: 디스커션 상세 페이지 시맨틱 태그 적용

* feat: 솔루션 제출 페이지 시맨틱 태그 적용

* feat: 디스커션 제출 페이지 시맨틱 태그 적용

* feat: 미션 상세 페이지 aria 속성 적용

* feat: 디스커션 상세 페이지 aria 속성 적용

* feat: 풀이 제출 페이지 aria 속성 적용

* feat: 디스커션 제출 페이지 aria 속성 적용

* feat: 풀이 상세 페이지 aria 속성 적용

---------

Co-authored-by: JEON TAEHEON <[email protected]>

* 웹 접근성 적용 (issue #699) (#704)

* refactor: 커스텀 뮤테이션 인자 변경

* Merge branch 'dev' of https://github.com/woowacourse-teams/2024-devel-up into dev

* remove: 파일 삭제

* feat: 미션 리스트 페이지 접근성 개선

* 랜딩 페이지 이미지 대체 및 헤더, 랜딩 웹 접근성 추가 (issue #697) (#706)

* feat: Rocket 영역 분리 및 LevelMission 영역 추가

* feat: DiscussionSpace 영역 추가

* feat: LevelMission 영역 수정 및 이미지 대체

* refactor: mediaQueries에 landingMedium 사이즈 추가

* feat: Solution 영역 구현 및 로켓 애니메이션 추가

* feat: DownArrow 추가 및 디자인 수정

* feat: useScrollComponent 구현
- 스크롤 시 컴포넌트가 화면에 보이도록 구현

* refactor: AboutPage 공통 디자인 속성 정리
- levelMission 이미지 수정

* fix: rocket 이미지 크기 에러 해결

* refactor: AboutPage semantic tag 개선 및 소개 텍스트 스타일 코드 수정

* feat: DownArrow 엔터 시 컴포넌트 이동 기능 추가

* feat: 헤더 웹 접근성 추가 (로그인)

* fix: 스타일 컴포넌트 isVisible props prefix $ 추가

* fix: DownArrow 반복 클릭 시 발생하는 인덱스 오류 해결

* design: 로켓이미지 breakpoint 수정

* QA 개선 사항 반영 (issue #707) (#709)

* design: TagButton hover transition 조정

* design: 렌더 시 부드럽게 렌더링 되도록 추가

* feat: 풀이 상세 페이지의 미션태그 navigate 기능 추가

* refactor: scrollToTopButton에 debounce 적용 및 최상단에서 보여지지 않도록 구현

* design: 메인 페이지 뷰포트 및 margin 조정

* 반응형 대응 (issue #703) (#710)

* feat: 미션 디테일 페이지 반응형 추가

* feat: 반응형 완성

* 대시보드 페이지 반응형 구현 (issue #705) (#708)

* refactor: 커스텀 뮤테이션 인자 변경

* Merge branch 'dev' of https://github.com/woowacourse-teams/2024-devel-up into dev

* remove: 파일 삭제

* design: 대시보드 반응형 적용

* refactor: 미디어쿼리 적용

* refactor: msw 환경 해제

* 헤더 반응형 구현 (issue #701) (#711)

* feat: mediaQueries medium 추가

* feat: 반응형 헤더 추가
- medium 사이즈에서 dropdown 형태
- hamburger Toggle Image 추가
- Mobile, DeskTop 컴포넌트 분리

* fix: 머지 에러 해결

* design: 화면 너비에 맞춰 대시보드 메뉴 위치를 토글로 변경

* style: 사용하지 않는 코드 제거

* fix: 스크린 리더가 사용하지 않는 컴포넌트를 읽는 문제 해결

* QA 사항 반영 및 페이지네이션 버그 수정 (issue #712) (#713)

* refactor: 커스텀 뮤테이션 인자 변경

* Merge branch 'dev' of https://github.com/woowacourse-teams/2024-devel-up into dev

* remove: 파일 삭제

* refactor:  솔루션 상세에 SpinnerSuspense 적용

* fix: 페이지네이션 초기화 로직 적용

* 리스트 반응형 적용 (issue #717) (#718)

* design: 미션 리스트 스타일 조정

* design: min-width 지정

* design: 풀이 리스트 스타일 조정

* design: 디스커션 리스트 스타일 조정

* design: 메인페이지 미션리스트 스타일 조정

* fix: 본문으로 바로가기 버튼 안보이도록 수정 (#721)

* 솔루션 목록 조회 개선 (issue #714) (#720)

* fix: 시간 측정 코드 추가

* fix: 목록 조회시 정렬 빠진 오류 수정

* fix: 목록 조회시 카운트 쿼리 distinct 삭제

* fix: 솔루션 목록 조회시 카운트 쿼리 오류 수정

* fix: 솔루션 목록 조회 출력문 제거

* fix: 시크릿 최신화

* fix: 인덱스 추가

* 디스커션 목록 조회 쿼리 개선 (issue #715) (#716)

* refactor: 디스커션 목록 조회 쿼리 개선

* feat: mission id 인덱스 추가

* 푸터 반응형 수정 및 about 간격 조정 (#725)

* feat: 푸터 반응형 깨지는 현상 수정

* fix: 본문으로 바로가기 포커스 시에만 보이도록 수정

* fix: about 페이지 간격 조정

* chore: 불필요한 주석 삭제

* 페이지네이션 로직 버그 수정 (issue #723) (#726)

* refactor: 커스텀 뮤테이션 인자 변경

* Merge branch 'dev' of https://github.com/woowacourse-teams/2024-devel-up into dev

* remove: 파일 삭제

* refactor: 태그 변경시 데이터 다시 받아오도록 수정

* fix: useMissions인자로 미션 태그 주입

* refactor: 페이지네이션 기능 개선

* refactor: 에러사항 바로 적용

* 미션 카드 크기 반응형 조정 (issue #724) (#727)

* design: 미션, 풀이 리스트 반응형 조정

* design: 줄 수 조정

* 디스커션 및 솔루션 제출시 에러 수정 (issue #728) (#729)

* refactor: 커스텀 뮤테이션 인자 변경

* Merge branch 'dev' of https://github.com/woowacourse-teams/2024-devel-up into dev

* remove: 파일 삭제

* refactor: 변경사항 반영

* 반응형 디자인 수정 (issue #730) (#733)

* design: 랜딩 페이지 리스트 조정

* design: card min-height 조정

* design: 디스커션 리스트 레이아웃 조정

* 깃허브에서 이메일 수집하지 않도록 변경합니다. (issue #735) (#736)

* feat: 깃허브에서 이메일 수집하지 않도록 변경합니다.

* feat: 이메일 넘기지 않도록 수정

* 디스커션 페이지네이션 적용 문제 해결  (issue #731) (#734)

* refactor: 커스텀 뮤테이션 인자 변경

* Merge branch 'dev' of https://github.com/woowacourse-teams/2024-devel-up into dev

* remove: 파일 삭제

* refactor: 수정사항 반영

* design: css 수정사항 반영

* refactor: 미션리스트 디테일 로직 개선

* 각종 QA 반영 (#737)

* feat: QA 사항 반영

* fix: 로컬 환경 테스트를 위해 임의로 수정한 isLoggedIn 수정

* chore: msw 해제

* 대시보드 카드 줄바꿈 수정 (issue  #739) (#740)

* refactor: 커스텀 뮤테이션 인자 변경

* Merge branch 'dev' of https://github.com/woowacourse-teams/2024-devel-up into dev

* remove: 파일 삭제

* refactor: 수정사항 반영

* 대시보드 카드 공통 컴포넌트로 추출 (issue #741) (#743)

* refactor: 커스텀 뮤테이션 인자 변경

* Merge branch 'dev' of https://github.com/woowacourse-teams/2024-devel-up into dev

* remove: 파일 삭제

* chore : refactor

* refactor: 수정사항 반영

* 카드 컴포넌트 줄바꿈 수정 (issue #738) (#742)

* design: Card 컴포넌트 줄바꿈 수정

* design: 풀이 상세 타이틀 줄바꿈 조정

* fix: import 타입에러 해결

* fix: import 타입에러 해결

* design: 풀이 상세 헤더 디자인 반응형 수정

---------

Co-authored-by: JEON TAEHEON <[email protected]>

* 빌드 에러 수정 (issue #744) (#745)

* refactor: 커스텀 뮤테이션 인자 변경

* Merge branch 'dev' of https://github.com/woowacourse-teams/2024-devel-up into dev

* remove: 파일 삭제

* refactor: 수정사항 반영

* 수정사항 반영 (issue #746) (#747)

* refactor: 커스텀 뮤테이션 인자 변경

* Merge branch 'dev' of https://github.com/woowacourse-teams/2024-devel-up into dev

* remove: 파일 삭제

* refactor: 수정사항 반영

* refactor: privateRotue

* refacotr: a링크로 대체

* fix: 링크 삭제

* design: 수정사항 반영

* design: 수정사항 반영

---------

Co-authored-by: Minji <[email protected]>
Co-authored-by: Minsu Kim <[email protected]>
Co-authored-by: 임수빈 <[email protected]>
Co-authored-by: le2sky <[email protected]>
Co-authored-by: yoonseo choi <[email protected]>
Co-authored-by: Kim Minjoo(김민주/리브) <[email protected]>
Co-authored-by: JEON TAEHEON <[email protected]>
  • Loading branch information
8 people authored Oct 24, 2024
1 parent 1796cee commit 2916a85
Show file tree
Hide file tree
Showing 187 changed files with 3,935 additions and 713 deletions.
7 changes: 7 additions & 0 deletions backend/lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
lombok.Setter.flagUsage = error
lombok.toString.flagUsage = error
lombok.builder.flagUsage = error
lombok.value.flagUsage = error
lombok.builder.flagUsage = error
lombok.data.flagUsage = error
lombok.allArgsConstructor.flagUsage = error
2 changes: 1 addition & 1 deletion backend/secrets
55 changes: 48 additions & 7 deletions backend/src/main/java/develup/api/DiscussionApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import java.util.List;
import develup.api.auth.Auth;
import develup.api.common.ApiResponse;
import develup.api.common.PageResponse;
import develup.api.exception.DevelupException;
import develup.api.exception.ExceptionType;
import develup.application.auth.Accessor;
import develup.application.discussion.CreateDiscussionRequest;
import develup.application.discussion.DiscussionReadService;
Expand All @@ -15,6 +18,7 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
Expand All @@ -34,13 +38,24 @@ public class DiscussionApi {

@GetMapping("/discussions")
@Operation(summary = "디스커션 목록 조회 API", description = "디스커션 목록을 조회합니다.")
public ResponseEntity<ApiResponse<List<SummarizedDiscussionResponse>>> getDiscussions(
public ResponseEntity<?> getDiscussions(
@RequestParam(defaultValue = "all") String mission,
@RequestParam(defaultValue = "all") String hashTag
@RequestParam(defaultValue = "all") String hashTag,
@RequestParam(required = false) Integer size,
@RequestParam(required = false) Integer page
) {
List<SummarizedDiscussionResponse> responses = discussionReadService.getSummaries(mission, hashTag);
if (size == null && page == null) {
List<SummarizedDiscussionResponse> response = discussionReadService.getSummaries(mission, hashTag);
return ResponseEntity.ok(new ApiResponse<>(response));
}

return ResponseEntity.ok(new ApiResponse<>(responses));
if (size == null || page == null) {
throw new DevelupException(ExceptionType.INVALID_PAGE_REQUEST);
}

PageResponse<List<SummarizedDiscussionResponse>> response = discussionReadService
.getSummaries(mission, hashTag, size, page);
return ResponseEntity.ok(response);
}

@GetMapping("/discussions/{id}")
Expand Down Expand Up @@ -86,9 +101,35 @@ public ResponseEntity<ApiResponse<Void>> deleteSolution(

@GetMapping("/discussions/mine")
@Operation(summary = "나의 디스커션 목록 조회 API", description = "내가 작성한 디스커션 목록을 조회합니다.")
public ResponseEntity<ApiResponse<List<SummarizedDiscussionResponse>>> getMyDiscussions(@Auth Accessor accessor) {
List<SummarizedDiscussionResponse> response = discussionReadService.getDiscussionsByMemberId(accessor.id());
public ResponseEntity<?> getMyDiscussions(
@RequestParam(required = false) Integer page,
@RequestParam(required = false) Integer size,
@Auth Accessor accessor
) throws MissingServletRequestParameterException {
// TODO : 하위호환
if (isBothNull(page, size)) {
List<SummarizedDiscussionResponse> response = discussionReadService.getDiscussionsByMemberId(accessor.id());
return ResponseEntity.ok(new ApiResponse<>(response));
}

return ResponseEntity.ok(new ApiResponse<>(response));
requireNonNull(page, size);

PageResponse<List<SummarizedDiscussionResponse>> response =
discussionReadService.getDiscussionsByMemberId(accessor.id(), page, size);
return ResponseEntity.ok(response);
}

private boolean isBothNull(Integer page, Integer size) {
return page == null && size == null;
}

private void requireNonNull(Integer page, Integer size) throws MissingServletRequestParameterException {
if (page == null) {
throw new MissingServletRequestParameterException("page", "number");
}

if (size == null) {
throw new MissingServletRequestParameterException("size", "number");
}
}
}
36 changes: 33 additions & 3 deletions backend/src/main/java/develup/api/DiscussionCommentApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.List;
import develup.api.auth.Auth;
import develup.api.common.ApiResponse;
import develup.api.common.PageResponse;
import develup.application.auth.Accessor;
import develup.application.discussion.comment.CreateDiscussionCommentResponse;
import develup.application.discussion.comment.DiscussionCommentReadService;
Expand All @@ -18,12 +19,14 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
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;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
Expand All @@ -46,9 +49,36 @@ public ResponseEntity<ApiResponse<List<DiscussionCommentRepliesResponse>>> getCo

@GetMapping("/discussions/comments/mine")
@Operation(summary = "사용자가 디스커션에 단 댓글 조회 API", description = "사용자가 디스커션에 단 댓글 목록을 조회합니다. 댓글 정보와 댓글이 달린 디스커션의 일부 정보를 조회합니다.")
public ResponseEntity<ApiResponse<List<MyDiscussionCommentResponse>>> getMyComments(@Auth Accessor accessor) {
List<MyDiscussionCommentResponse> responses = discussionCommentReadService.getMyComments(accessor.id());
return ResponseEntity.ok(new ApiResponse<>(responses));
public ResponseEntity<?> getMyComments(
@RequestParam(required = false) Integer page,
@RequestParam(required = false) Integer size,
@Auth Accessor accessor
) throws MissingServletRequestParameterException {
// TODO : 하위호환
if (isBothNull(page, size)) {
List<MyDiscussionCommentResponse> responses = discussionCommentReadService.getMyComments(accessor.id());
return ResponseEntity.ok(new ApiResponse<>(responses));
}

requireNonNull(page, size);

PageResponse<List<MyDiscussionCommentResponse>> response =
discussionCommentReadService.getMyComments(accessor.id(), page, size);
return ResponseEntity.ok(response);
}

private boolean isBothNull(Integer page, Integer size) {
return page == null && size == null;
}

private void requireNonNull(Integer page, Integer size) throws MissingServletRequestParameterException {
if (page == null) {
throw new MissingServletRequestParameterException("page", "number");
}

if (size == null) {
throw new MissingServletRequestParameterException("size", "number");
}
}

@PostMapping("/discussions/{discussionId}/comments")
Expand Down
37 changes: 32 additions & 5 deletions backend/src/main/java/develup/api/SolutionApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import java.util.List;
import develup.api.auth.Auth;
import develup.api.common.ApiResponse;
import develup.api.common.PageResponse;
import develup.api.exception.DevelupException;
import develup.api.exception.ExceptionType;
import develup.application.auth.Accessor;
import develup.application.solution.MySolutionResponse;
import develup.application.solution.SolutionReadService;
Expand All @@ -17,6 +20,7 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
Expand Down Expand Up @@ -80,13 +84,26 @@ public ResponseEntity<ApiResponse<SolutionResponse>> deleteSolution(

@GetMapping("/solutions")
@Operation(summary = "솔루션 목록 조회 API", description = "솔루션 목록을 조회합니다.")
public ResponseEntity<ApiResponse<List<SummarizedSolutionResponse>>> getSolutions(
public ResponseEntity<?> getSolutions(
@RequestParam(defaultValue = "all") String mission,
@RequestParam(defaultValue = "all") String hashTag
@RequestParam(defaultValue = "all") String hashTag,
@RequestParam(required = false) Integer page,
@RequestParam(required = false) Integer size
) {
List<SummarizedSolutionResponse> responses = solutionReadService.getCompletedSummaries(mission, hashTag);

return ResponseEntity.ok(new ApiResponse<>(responses));
if (page == null && size == null) {
List<SummarizedSolutionResponse> responses = solutionReadService.getCompletedSummaries(mission, hashTag);
return ResponseEntity.ok(new ApiResponse<>(responses));
}
if (page == null || size == null) {
throw new DevelupException(ExceptionType.INVALID_PAGE_REQUEST);
}
PageResponse<List<SummarizedSolutionResponse>> responses = solutionReadService.getCompletedSummaries(
mission,
hashTag,
page,
size
);
return ResponseEntity.ok(responses);
}

@GetMapping("/solutions/{id}")
Expand All @@ -104,4 +121,14 @@ public ResponseEntity<ApiResponse<List<MySolutionResponse>>> getMySolutions(@Aut

return ResponseEntity.ok(new ApiResponse<>(response));
}

private void requiredNotNull(Integer page, Integer size) throws MissingServletRequestParameterException {
if (page == null) {
throw new MissingServletRequestParameterException("page", "number");
}

if (size == null) {
throw new MissingServletRequestParameterException("size", "number");
}
}
}
33 changes: 30 additions & 3 deletions backend/src/main/java/develup/api/SolutionCommentApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.List;
import develup.api.auth.Auth;
import develup.api.common.ApiResponse;
import develup.api.common.PageResponse;
import develup.application.auth.Accessor;
import develup.application.solution.comment.CreateSolutionCommentResponse;
import develup.application.solution.comment.MySolutionCommentResponse;
Expand All @@ -17,14 +18,17 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
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;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

@RequiredArgsConstructor
@RestController
Expand All @@ -46,9 +50,32 @@ public ResponseEntity<ApiResponse<List<SolutionCommentRepliesResponse>>> getComm

@GetMapping("/solutions/comments/mine")
@Operation(summary = "사용자가 솔루션에 단 댓글 조회 API", description = "사용자가 솔루션에 단 댓글 목록을 조회합니다. 댓글 정보와 댓글이 달린 솔루션의 일부 정보를 조회합니다.")
public ResponseEntity<ApiResponse<List<MySolutionCommentResponse>>> getMyComments(@Auth Accessor accessor) {
List<MySolutionCommentResponse> responses = solutionCommentReadService.getMyComments(accessor.id());
return ResponseEntity.ok(new ApiResponse<>(responses));
public ResponseEntity<?> getMyComments(
@Auth Accessor accessor,
@RequestParam(required = false) Integer page,
@RequestParam(required = false) Integer size
) {
if (isPaginationNotProvided(page, size)) {
List<MySolutionCommentResponse> responses = solutionCommentReadService.getMyComments(accessor.id());
return ResponseEntity.ok(new ApiResponse<>(responses));
}
if (isPaginationPartiallyProvided(page, size)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST);
}
PageResponse<List<MySolutionCommentResponse>> responses = solutionCommentReadService.getMyComments(
accessor.id(),
page,
size
);
return ResponseEntity.ok(responses);
}

private boolean isPaginationNotProvided(Integer page, Integer size) {
return page == null && size == null;
}

private boolean isPaginationPartiallyProvided(Integer page, Integer size) {
return page == null || size == null;
}

@PostMapping("/solutions/{solutionId}/comments")
Expand Down
4 changes: 4 additions & 0 deletions backend/src/main/java/develup/api/common/PageResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package develup.api.common;

public record PageResponse<T>(T data, int currentPage, int totalPage) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public enum ExceptionType {
HASHTAG_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 해시태그입니다."),
DISCUSSION_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 디스커션입니다."),
DISCUSSION_NOT_WRITTEN_BY_MEMBER(HttpStatus.FORBIDDEN, "디스커션 작성자가 아닙니다."),

INVALID_PAGE_REQUEST(HttpStatus.BAD_REQUEST, "페이지 요청이 잘못되었습니다."),
;

private final HttpStatus status;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package develup.application.discussion;

import java.util.List;
import develup.api.common.PageResponse;
import develup.api.exception.DevelupException;
import develup.api.exception.ExceptionType;
import develup.domain.discussion.Discussion;
import develup.domain.discussion.DiscussionRepositoryCustom;
import develup.domain.discussion.comment.DiscussionCommentCounts;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -18,7 +21,7 @@ public class DiscussionReadService {
private final DiscussionRepositoryCustom discussionRepositoryCustom;

public List<SummarizedDiscussionResponse> getSummaries(String mission, String hashTagName) {
List<Discussion> discussions = discussionRepositoryCustom.findAllByMissionAndHashTagName(mission, hashTagName);
List<Discussion> discussions = discussionRepositoryCustom.findAllByMissionAndHashTagNameOrderByDesc(mission, hashTagName);
DiscussionCommentCounts discussionCommentCounts = new DiscussionCommentCounts(
discussionRepositoryCustom.findAllDiscussionCommentCounts()
);
Expand All @@ -31,6 +34,30 @@ public List<SummarizedDiscussionResponse> getSummaries(String mission, String ha
.toList();
}

public PageResponse<List<SummarizedDiscussionResponse>> getSummaries(
String mission,
String hashTagName,
Integer size,
Integer page
) {
PageRequest pageRequest = PageRequest.of(page, size);
Page<Discussion> discussions = discussionRepositoryCustom
.findAllByMissionAndHashTagNameOrderByDesc(mission, hashTagName, pageRequest);

DiscussionCommentCounts discussionCommentCounts = new DiscussionCommentCounts(
discussionRepositoryCustom.findAllDiscussionCommentCounts()
);

List<SummarizedDiscussionResponse> responseWithCommentCounts = discussions.stream()
.map(discussion -> SummarizedDiscussionResponse.of(
discussion,
discussionCommentCounts.getCount(discussion))
)
.toList();

return new PageResponse<>(responseWithCommentCounts, pageRequest.getPageNumber(), discussions.getTotalPages());
}

public List<SummarizedDiscussionResponse> getDiscussionsByMemberId(Long memberId) {
List<Discussion> myDiscussions = discussionRepositoryCustom.findAllByMemberIdOrderByDesc(memberId);
DiscussionCommentCounts discussionCommentCounts = new DiscussionCommentCounts(
Expand All @@ -45,6 +72,27 @@ public List<SummarizedDiscussionResponse> getDiscussionsByMemberId(Long memberId
.toList();
}

public PageResponse<List<SummarizedDiscussionResponse>> getDiscussionsByMemberId(
Long memberId,
Integer page,
Integer size
) {
PageRequest pageRequest = PageRequest.of(page, size);
Page<Discussion> myDiscussions = discussionRepositoryCustom.findPageByMemberIdOrderByDesc(memberId, pageRequest);
DiscussionCommentCounts discussionCommentCounts = new DiscussionCommentCounts(
discussionRepositoryCustom.findAllDiscussionCommentCounts()
);

List<SummarizedDiscussionResponse> countIncludeData = myDiscussions.getContent().stream()
.map(discussion -> SummarizedDiscussionResponse.of(
discussion,
discussionCommentCounts.getCount(discussion))
)
.toList();

return new PageResponse<>(countIncludeData, pageRequest.getPageNumber(), myDiscussions.getTotalPages());
}

public DiscussionResponse getById(Long id) {
Discussion discussion = getDiscussion(id);

Expand Down
Loading

0 comments on commit 2916a85

Please sign in to comment.