-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
커서 기반 페이지네이션 #596
커서 기반 페이지네이션 #596
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
굳굳👍
...d/baton/src/main/java/touch/baton/domain/runnerpost/controller/RunnerPostReadController.java
Outdated
Show resolved
Hide resolved
@RequestParam(required = false) final String tagName, | ||
@RequestParam(required = false) final Long cursor, | ||
@RequestParam final int limit, | ||
@RequestParam final ReviewStatus reviewStatus |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요거 다 같이 PageInfo 같은 객체 하나 만들어서 @ModelAttribute
로 받으면 어떤가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여쭤보고 싶은게 있습니다.
만약 댓글인 경우에는 tagName, reviewStatus가 필요하지 않을가 같은데 이런 필드도 묶어서 사용할 계획인가요? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
음 보통 그런 경우까지 생각하면 PostSearchCondition, PageInfo 두 개로 나눌거 같아요
if (isTagNameBlank(tagName) && !isFirstPage(cursor)) { | ||
return ResponseEntity.ok(runnerPostReadService.readRunnerPostByPageInfoAndReviewStatus(cursor, limit, reviewStatus)); | ||
} | ||
if (!isTagNameBlank(tagName) && isFirstPage(cursor)) { | ||
return ResponseEntity.ok(runnerPostReadService.readLatestByLimitAndTagNameAndReviewStatus(tagName, limit, reviewStatus)); | ||
} | ||
if (!isTagNameBlank(tagName) && !isFirstPage(cursor)) { | ||
return ResponseEntity.ok(runnerPostReadService.readRunnerPostByPageInfoAndTagNameAndReviewStatus(tagName, cursor, limit, reviewStatus)); | ||
} | ||
throw new ClientRequestException(INVALID_QUERY_STRING_FORMAT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tagName 같은 경우에는 QueryDSL에 BooleanExpression으로 분기 줄일 수 있을 듯. firstPage 도 될거 같은데?
https://dev.gmarket.com/33 <- 요건 참고자료
@Test
public void querydslTest2() {
QMember m = QMember.member;
String usernameCondition = null;
int ageCondition = 25;
List<Member> findMember = queryFactory
.select(m)
.from(m)
.where(usernameEq(usernameCondition), ageGoe(ageCondition))
.fetch();
assertThat(findMember.size()).isEqualTo(3);
}
private BooleanExpression usernameEq(String usernameCond) {
return usernameCond != null ? member.username.eq(usernameCond) : null;
}
private BooleanExpression ageGoe(Integer ageCond) {
return ageCond != null ? member.age.goe(ageCond) : null;
}
} | ||
|
||
private void validateElementExist(final Long readElement) { | ||
if (Objects.isNull(readElement)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (Objects.isNull(readElement)) { | |
if (readElement == null) { |
어떤가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저 이거 찬성합니다 👍
@Autowired | ||
protected EntityManager em; | ||
|
||
protected Runner persistRunner(final Member member) { | ||
em.persist(member); | ||
final Runner runner = RunnerFixture.createRunner(member); | ||
em.persist(runner); | ||
return runner; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이렇게 쓰는거 굳! 근데 ServiceTestConfig에서 안쓸거 같은데 SerivceTestConfig랑 RepositoryTestConfig 분리하는거 어떤가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
매우 찬성
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
찬성하고 갑니당
// @DisplayName("러너 게시글 식별자값 목록으로 서포터 지원자 수 카운트(count)에 성공한다.") | ||
// @Test | ||
// void readApplicantCountsByRunnerPostIds() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
문제 있는건가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
위의 테스트랑 중복이어서 헤나랑 이야기해보려했어용
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 아니다. 이거 지원자 수 메소드 검증인데 private 메소드로 바꿔서 테스트 불가능하게 된거에용
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
집가서 확인해볼게요 ㅎㅎ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
헬로우 디이투우우 D2
커서 기반 페이지네이션에 QueryDsl 까지 굿굿 고생했어요~
오늘 QueryDsl로 분기문을 해결할거라 얘기가 나왔으니 세세한 코드 리뷰는 아직 안했어요!
그래서 조금 다른 주제로 리뷰 남깁니다.
좀.. 길어요 🙇♂️🫣
현재 레포지터리는 다음과 같이 구성되어 있네요.
flowchart RL
RunnerPostRepository ---> |implements| JpaRepository
RunnerPostRepository ---> |implements| RunnerPostCustomRepository
RunnerPostCustomRepositoryImpl ---> |implements| RunnerPostCustomRepository
RunnerPostCustomRepository 인터페이스를 통해서 QueryDsl에서 사용할 메서드를 정의하고 RunnerPostCustomRepositoryImpl을 통해서 구현체를 이용하고 있습니다.
이러한 구조를 선택하신게 RunnerPostRepository를 유연하게 사용하기 위해서라고 생각했습니다. 👍
하지만 너무 많은 메서드가 RunnerPost를 통해서 사용하게 되어서 헷갈리는 문제가 있는거 같습니다. 🥲
개인적인 생각일지도 모르겠지만 생각나는 예시를 들어보겠습니다.
먼저 RunnerPostService에 있는 조회 메서드를 봐보려고 합니다.
RunnerPostRepository를 받아서 findByPageInfoAndReviewStatus()
메서드 내부 동작을 보고 이해하려고 했습니다.
@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class RunnerPostReadService {
private final RunnerPostRepository runnerPostRepository;
public RunnerPostResponses.Simple readRunnerPostByPageInfoAndReviewStatus(final Long cursor,
final int limit,
final ReviewStatus reviewStatus
) {
final List<RunnerPost> runnerPosts = runnerPostRepository.findByPageInfoAndReviewStatus(cursor, limit, reviewStatus);
final List<RunnerPostTag> runnerPostTags = runnerPostRepository.findRunnerPostTagsByRunnerPosts(runnerPosts);
final RunnerPostsApplicantCount runnerPostsApplicantCount = readRunnerPostsApplicantCount(runnerPosts);
return convertToSimpleResponses(runnerPosts, runnerPostTags, runnerPostsApplicantCount);
}
// ...
}
저는 다음과 같이 RunnerPostRepository에 들어갔습니다.
flowchart RL
RunnerPostRepository
코드가 길어서 JPQL과 매개변수를 모두 지워서 작성했습니다.
아래와 같이 8가지 메서드가 존재합니다.
현재 코드에서는 제가 보려는 findByPageInfoAndReviewStatus()
가 존재하지 않습니다.
RunnerPostCustomRepository에 들어가서 작성된 QueryDsl도 보아야 외부에서 어떤 값을 불러오는지 알 수 있습니다.
public interface RunnerPostRepository extends JpaRepository<RunnerPost, Long>, RunnerPostCustomRepository {
Optional<RunnerPost> joinMemberByRunnerPostId(/* ... */);
Page<RunnerPost> findByReviewStatus(/* ... */);
Page<RunnerPost> findByRunnerIdAndReviewStatus(/* ... */);
List<RunnerPost> findByRunnerId(/* ... */);
Page<RunnerPost> findBySupporterIdAndReviewStatus(/* ... */);
Page<RunnerPost> joinSupporterRunnerPostBySupporterIdAndReviewStatus(/* ... */);
List<RunnerPostApplicantCountDto> countApplicantsByRunnerPostIds(/* ... */);
Page<RunnerPost> findByTagReducedNameAndReviewStatus(/* ... */);
}
여기서 한 딮스를 더 들어가야 합니다.
아래와 같이 QueryDsl로 작성될 코드를 볼 수 있습니다.
public interface RunnerPostCustomRepository {
List<RunnerPost> findByPageInfoAndReviewStatus(/* ... */);
List<RunnerPost> findLatestByLimitAndReviewStatus(/* ... */);
List<RunnerPost> findByPageInfoAndReviewStatusAndTagReducedName(/* ... */);
List<RunnerPost> findLatestByLimitAndTagNameAndReviewStatus(/* ... */);
List<RunnerPostTag> findRunnerPostTagsByRunnerPosts(/* ... */);
}
하지만 현재 CustomRepository는 구현체가 아닙니다.
코드 동작을 보려면 한 딮스를 더 들어가야 합니다.
@RequiredArgsConstructor
@Repository
public class RunnerPostCustomRepositoryImpl implements RunnerPostCustomRepository {
private final JPAQueryFactory jpaQueryFactory;
@Override
public List<RunnerPost> findByPageInfoAndReviewStatus(/* ... */) {
// ...
}
@Override
public List<RunnerPost> findLatestByLimitAndReviewStatus(/* ... */) {
// ...
}
@Override
public List<RunnerPost> findByPageInfoAndReviewStatusAndTagReducedName(/* ... */) {
// ...
}
@Override
public List<RunnerPost> findLatestByLimitAndTagNameAndReviewStatus(/* ... */) {
// ..
}
@Override
public List<RunnerPostTag> findRunnerPostTagsByRunnerPosts(/* ... */) {
// ...
}
}
이런 느낌으로 실제 구현된 부분을 보기에 어렵다고 느꼈습니다.
오늘 나왔던 얘기로 QueryDsl 의 이점을 더 활용해서 구현된 메서드들이 적어져서 현재보다 더 가독성 좋은 코드가 나올거라 기대합니다. 😋
그렇지만 다른 조회 요구사항이 추가된다면 메서드가 더 늘어나도 다시 똑같은 상황이 나올거 같다고 생각됩니다. 🥲
저의 개인적인 생각으로는 Repository를 하나로 해결하지 않고 나눠서 구현하면 파악하기 좋을거 같다 생각합니다.
클래스명은 예시입니다!
flowchart RL
RunnerPostRepository ---> |implements| JpaRepository
RunnerPostQueryDslDao
아래와 같이 QueryDsl과 관련된 부분을 다른 클래스로 분리해도 좋을거 같아요.
@RequiredArgsConstructor
@Transactional(readOnly = true)
@Repository
public class RunnerPostQueryDslDao {
private final JPAQueryFactory query;
// ...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
* feat: 빈 공백 추가 * github pr 자동 할당 기능 설정 (#563) docs: github pr 자동 할당 기능 설정 * 서포터 피드백 작성 유무 반환 추가, 러너 게시글 조회수 flyway 컬럼명 수정, 서포터 지원자 수 조회시 dto 사용하도록 수정 (#555) * feat: 러너 게시글의 서포터 피드백 유무 필드(컬럼) 구현 * test: 러너 게시글에 서포터 피드백 유무 컬럼 추가 후 테스트 변경 * feat: 러너 게시글 응답에 서포터 피드백 유무 정보 추가 * chore: 러너 게시글에 서포터 피드백 유무 flyway 테이블 컬럼 추가 * chore: 러너 게시글 조회수 컬럼명 flyway 수정 추가 * style: IsReviewed get 메서드 네이밍 get으로 통일되게 수정 * fix: IsReviewed 내부 값 반환 수정 * test: 테스트 내부 entityManager 사용 후 close 하도록 수정 * refactor: 러너 게시글 식별자값 목록으로 서포터 지원자 수 조회시 매핑된 서포터 지원자 수 객체를 반환하도록 레포지터리 메서드 변경 * refactor: 매핑된 서포터 지원자 수 객체를 사용하도록 서비스, 컨트롤러 변경 * style: 공백 및 개행 스타일 수정 * style: toString 메서드 삭제 * refactor: dto 클래스를 레코드로 변경 * test: entityManager flush, close 순서 변경 * 이미 서포터 리뷰를 작성했으면 예외 반환하도록 함 (#552) * refactor: 이미 서포터 리뷰를 작성했으면 예외 반환하도록 함 * test: Repository 테스트 추가 * test: 테스트에 em.flush와 em.clear 추가 * style: 예외 메세지 이름 변경 * feat: Feedback 을 하면 isReviewed 속성이 true 가 되도록 변경 * refreshToken 과 accessToken 이 null 일 때 예외 추가 (#564) * feat: refreshToken 과 accessToken 이 null 일 때 예외 추가 * feat: deploy 에 github branch 설정 추가 * test: AssuredSupport post 에서 필요없는 Application json value 삭제 * feat: CookieValue 에 Nullable 추가 * Merbe deb/BE to feat/559 * feat: max threads 100 으로 변경 * deploy 서브 모듈 리프래쉬 토큰 만료 시간 값 변경 (#573) chore: deploy 리프래쉬 토큰 만료 시간 값 변경 * 기본 쓰레드 300 으로 변경 (#583) chore: 쓰레드 300 으로 변경 * 기본 쓰레드(200)으로 변경 및 min spare 100 으로 변경 (#584) * chore: 쓰레드 300 으로 변경 * refchore: 쓰레드 200 으로 변경 및 min spare 100 으로 변경 * min spare 1로 변경 (#586) * chore: 쓰레드 300 으로 변경 * refchore: 쓰레드 200 으로 변경 및 min spare 100 으로 변경 * refactor min spare 1로 변경 * 톰캣 쓰레드 관련 설정 롤백 (#587) * chore: 쓰레드 300 으로 변경 * refchore: 쓰레드 200 으로 변경 및 min spare 100 으로 변경 * refactor min spare 1로 변경 * chore: tomcat 관련 설정 롤백 * 깃허브 소셜 회원 가입시 계정의 닉네임이 없을 경우 기본값으로 저장 (#589) fix: 사용자 이름 null 로 생성시 기본값 '익명의 사용자'를 사용하도록 수정 * 커서 기반 페이지네이션 (#596) * refactor: 사용하지 않는 상수 제거 * chore: querydsl 추가 * chore: gitignore에 Qclass 숨기기 * chore: build 파일 형태 변경 * feat: QueryDsl config 설정 * feat: querydsl 실험을 위한 임시 컨트롤러 설정 * feat: 커서 기반 페이지네이션 레포지토리 구현 * chore: 서브모듈 업데이트 * refactor: 중복 테스트 제거 * chore: 서브 모듈 적용 * feat: 페이지네이션 쿼리 2개로 개선 * refactor: RunnerPostReadRepository 삭제 * test: 페이지 정보와 리뷰 상태로 게시글 조회 테스트 (두번째 페이지인 경우) * feat: 첫 페이지 조회 기능 구현 * refactor: 필요없는 dto 삭제 * feat: 러너 게시글 지원자 수 저장 객체 생성 * feat: 러너 게시글 페이지 조회 기능 구현 * refactor: 필요 없는 객체 삭제 * refactor: RunnerPost 목록으로 RunnerPostTag 목록 조회하는 기능 RunnerPostTagRepository 로 이동 * refactor: 필요 없는 객체 삭제 * refactor: 태그 이름으로 게시글 조회 기능 구현 * test: 태그 이름으로 조회 기능 테스트 * test: 태그 이름으로 조회 인수 테스트 * test: 태그 이름으로 조회 docs 테스트 수정 * refactor: 충돌 해결 * refactor: 동적 쿼리 적용 * test: runnerPostService 테스트 * refactor: 주석 작성 * chore: 리플랙션 의존성 제거 * chore: 빌드 파일 수정 * chore: 빌드 파일 수정 * 아키텍쳐 개선 (#608) * refactor: Member 패키지 구조 변경 * refactor: Runner 패키지 구조 변경 * refactor: Supporter 패키지 구조 변경 * refactor: Oauth 패키지 구조 변경 * refactor: RunnerPost 패키지 구조 변경 * refactor: Tag 패키지 구조 변경 * refactor: TechnicalTag 패키지 구조 변경 * refactor: Feedback 패키지 구조 변경 * refactor: 패키지 구조 변경 완료 * test: RunnerPostAssured 구조 개선 * test: Member, Feedback 구조 개선 * test: tag 구조 개선 * test: assured 구조 개선 완료 * 최종 페이지네이션 (#611) * test: 전체 조회 인수 테스트 * test: 지원자 수 조회 repo 테스트 * refactor: page model attribute 적용 * refactor: 서포터 관련 게시글 페이지네이션 * refactor: querydsl repository 추상화 해제 * test: 서포터 id 로 러너 게시글 조회 레포지토리 테스트 * feat: runner id 로 러너 게시글 조회 repository 구현 * refactor: response dto query 패키지로 이동 * refactor: PageResponse 로 응답 변경 * refactor: 필요없는 메소드 삭제 * refactor: runnerpost 테스트 패키징 변경 * test: runner로 runnerPost 조회 api 테스트 * docs: 명세서 오류 수정 * refactor: pageResponse 생성자 인자 변경 * refactor: pathParams 에서 limit + 1 되도록 수정 * refactor: querydsl config 테스트용 생성 * refactor: 테스트 자원 정리 * feat: PageInfo에 다음 커서 추가 * refactor: PageParams 패키지 위치 변경 * "/profile/runner" api 삭제 (#619) * test: 전체 조회 인수 테스트 * test: 지원자 수 조회 repo 테스트 * refactor: page model attribute 적용 * refactor: 서포터 관련 게시글 페이지네이션 * refactor: querydsl repository 추상화 해제 * test: 서포터 id 로 러너 게시글 조회 레포지토리 테스트 * feat: runner id 로 러너 게시글 조회 repository 구현 * refactor: response dto query 패키지로 이동 * refactor: PageResponse 로 응답 변경 * refactor: 필요없는 메소드 삭제 * refactor: runnerpost 테스트 패키징 변경 * test: runner로 runnerPost 조회 api 테스트 * docs: 명세서 오류 수정 * refactor: pageResponse 생성자 인자 변경 * refactor: pathParams 에서 limit + 1 되도록 수정 * refactor: querydsl config 테스트용 생성 * refactor: 테스트 자원 정리 * feat: PageInfo에 다음 커서 추가 * refactor: PageParams 패키지 위치 변경 * refactor: api 삭제 * refactor: supporter read response 삭제 * refactor: runner response 두 개 합치기 * refactor: 충돌 해결 * 무중단 배포 실험 (#623) * test: 전체 조회 인수 테스트 * test: 지원자 수 조회 repo 테스트 * refactor: page model attribute 적용 * refactor: 서포터 관련 게시글 페이지네이션 * refactor: querydsl repository 추상화 해제 * test: 서포터 id 로 러너 게시글 조회 레포지토리 테스트 * feat: runner id 로 러너 게시글 조회 repository 구현 * refactor: response dto query 패키지로 이동 * refactor: PageResponse 로 응답 변경 * refactor: 필요없는 메소드 삭제 * refactor: runnerpost 테스트 패키징 변경 * test: runner로 runnerPost 조회 api 테스트 * docs: 명세서 오류 수정 * refactor: pageResponse 생성자 인자 변경 * refactor: pathParams 에서 limit + 1 되도록 수정 * refactor: querydsl config 테스트용 생성 * refactor: 테스트 자원 정리 * feat: PageInfo에 다음 커서 추가 * refactor: PageParams 패키지 위치 변경 * refactor: api 삭제 * refactor: supporter read response 삭제 * refactor: runner response 두 개 합치기 * refactor: 충돌 해결 * refactor: dev cicd 스크립트 변경 * 무중단 배포 스크립트 작성 (#631) * test: 전체 조회 인수 테스트 * test: 지원자 수 조회 repo 테스트 * refactor: page model attribute 적용 * refactor: 서포터 관련 게시글 페이지네이션 * refactor: querydsl repository 추상화 해제 * test: 서포터 id 로 러너 게시글 조회 레포지토리 테스트 * feat: runner id 로 러너 게시글 조회 repository 구현 * refactor: response dto query 패키지로 이동 * refactor: PageResponse 로 응답 변경 * refactor: 필요없는 메소드 삭제 * refactor: runnerpost 테스트 패키징 변경 * test: runner로 runnerPost 조회 api 테스트 * docs: 명세서 오류 수정 * refactor: pageResponse 생성자 인자 변경 * refactor: pathParams 에서 limit + 1 되도록 수정 * refactor: querydsl config 테스트용 생성 * refactor: 테스트 자원 정리 * feat: PageInfo에 다음 커서 추가 * refactor: PageParams 패키지 위치 변경 * refactor: api 삭제 * refactor: supporter read response 삭제 * refactor: runner response 두 개 합치기 * refactor: 충돌 해결 * refactor: dev cicd 스크립트 변경 * feat: CICD 스크립트 수정 * refactor: dev docker compose 삭제 * restdocs 테스트 설정 변경 및 테스트 컨텍스트 로딩 개선 (#633) * test: restdocs 테스트 구성 정보 수정 * test: restdocs 각 테스트 setup 수정 * test: AuthCode 테스트용 클래스명 수정 * test: JwtConfig 테스트용 클래스명 수정 * test: GithubOauthConfig 테스트용 페이크 객체 추가 * test: RestdocsConfig beforeEach 세팅 수정 * test: FakeGithubOauthConfig 삭제 * test: Restdocs 테스트시 로그 print 삭제 * logout시 refreshtoken이 삭제되는 api 구현 (#632) * feat: 로그아웃 API 구현 * refactor: refreshtoken delete api 이름 변경 * refactor: dev에 localhost:3000 cors 추가 * refactor: 리뷰반영 deleteMapping -> patchMapping으로 변경 * test: doPring 제거 * test: 인스턴스 변수 띄어쓰기 추가 * test: repositoryTestConfig에 persistMember 추가 및 리팩토링 * test: given when then 에서 컨벤션 일관화 * zero-downtime-deploy.sh 경로 변경 (#634) * feat: 로그아웃 API 구현 * refactor: refreshtoken delete api 이름 변경 * refactor: dev에 localhost:3000 cors 추가 * refactor: 리뷰반영 deleteMapping -> patchMapping으로 변경 * test: doPring 제거 * test: 인스턴스 변수 띄어쓰기 추가 * test: repositoryTestConfig에 persistMember 추가 및 리팩토링 * test: given when then 에서 컨벤션 일관화 * refactor: zero-downtime-deploy 경로 변경 * 알림 기능 구현 (이벤트 발행 및 구독, 알림 조회, 알림 삭제, 알림 업데이트) (#625) * feat: 알람 내 값객체 구현 (제목, 내용, 연관 식별자값, 읽기 여부, 알람 타입, 알람 메시지 모음) * feat: 알람 엔티티 구현 * feat: 알람 예외 클래스 구현 * feat: 알람 목록 조회 레포지터리 기능 구현 * feat: 알람 소프트 딜리트, 읽기 여부 true 업데이트 레포지터리 기능 구현 * feat: 알람 소프트 딜리트, 읽기 여부 true 업데이트 서비스 기능 구현 * feat: 알람 목록 조회 서비스 기능 구현 * feat: 알람 읽음 여부 기록 및 삭제 API 구현 * feat: 사용자 알람 목록 조회 API 구현 * feat: 러너 게시글 식별자값으로 러너 게시글과 서포터, 사용자 조회 레포지터리 기능 구현 * feat: 알람 이벤트 (러너 게시글 리뷰 완료, 러너 게시글 서포터 할당, 러너 게시글 서포터 지원) 리스너 구현 * feat: 이벤트 (러너 게시글 리뷰 완료, 러너 게시글 서포터 할당, 러너 게시글 서포터 지원) 발행 구현 * feat: 알람 생성 시간 초단위 삭제를 위한 BaseEntity 상속 클래스 구현 * refactor: 알람 이벤트 리스너 내부 메서드 리팩터링 * test: 로그인된 사용자 알람 목록 조회에서 알람 생성시간 테스트 수정 * test: 테스트용 알람 조회 레포지터리 구현 및 테스트용 회원 조회 레포지터리 수정 * test: 알람 읽음 여부 기록 업데이트 인수 테스트 * test: 러너 게시글 지원자 생성 인수 서포트 내부 사용하지 않는 검증문 삭제 * test: 알람 삭제 인수 테스트 * test: 로그인된 사용자 알람 목록 조회 인수 테스트 * chore: flyway 알람 테이블 생성, 알람 사용자(member) 외래키 제약조건 추가 * test: 알람 삭제, 업데이트 restdocs pathVariable 추가 * docs: 로그인된 사용자 알람 목록 조회, 알람 삭제, 알람 읽음 여부 업데이트 api 문서 추가 * style: 사용하지 않는 메서드 삭제 및 정렬 * test: 테스트 로그 삭제 * style: 사용하지 않는 메서드 삭제 * test: 실험용 테스트 코드 삭제 * docs: API 문서 Index 추가 * style: 알람(Alarm)을 알림(Notification)으로 수정 * test: willDoNothing()을 doNothing()으로 수정 * test: 이벤트 발행 카운트 테스트 수정 * refactor: IsRead 를 정적 팩터리 메서드를 이용해서 생성하도록 리팩터링 * feat: 알림 읽음 여부 수정 기능 구현 * feat: 알림 읽음 여부 수정 서비스 리팩터링 * refactor: 알림 이벤트 리스너 내부 NotificationText 를 문자열로 리팩터링 * feat: 알림 목록 조회 querydsl 기능 구현 * refactor: JpaRepository 조회 레포지터리를 Querydsl 레포지터리로 리팩터링 * test: 알림 Restdocs 테스트 수정 * test: 러너 게시글에 서포터 조인 조회 기능 테스트 수정 * 프로덕션 서비스 무중단 배포 (#640) * refactor: cicd 스크립트 수정 * refactor: cicd 스크립트 수정 * flyway 알림 수정 (#644) chore: flyway 알림 테이블 생성 내 콤마 삭제 * 러너 및 서포터의 게시글 개수 조회 api 구현 (#646) * feat: 러너 식별자 값으로 러너 게시글 카운트 쿼리 작성 * refactor: secret 업데이트 * feat: Supporter 와 관련된 게시글 수 조회 repository 구현 * feat: RunnerId 와 ReviewStatus 로 러너 게시글 조회 service 구현 * feat: RunnerId 와 reviewStatus 로 로그인 된 러너의 게시글 개수 조회 api 구현 * test: 로그인한 러너와 관련된 러너 게시글 개수 조회 인수 테스트 * test: 러너와 연관된 러너 게시글 개수 조회 rest docs 테스트 * refactor: SupporterRunnerPostRepository 관련 코드 정리 * test: supporter 테스트 파일 구조 변경 * feat: 서포터 식별자 값으로 러너 게시글 개수 조회 서비스 로직 구현 * feat: 서포터 식별자 값으로 러너 게시글 개수 조회 api 구현 * test: 서포터 관련 러너 게시글 개수 조회 인수 테스트 * test: 로그인한 서포터 관련 러너 게시글 개수 조회 api 테스트 * test: 잘못된 테스트 수정 * test: 서포터가 리뷰 완료한 러너 게시글 개수 조회 api 테스트 * refactor: 서브 모듈 업데이트 * refactor: reference 타입을 primitive 타입으로 변경 * RunnerPost reviewStatus 인덱스 추가 (#650) feat: flyway에 review status enum 추가하는 기능 추가 * 태그 목록 검색 기능 리팩터링 (#637) * refactor: 입력된 문자열로 태그 목록 검색 기능 리팩터링 * refactor: TagQueryService 태그 목록 검색 기능 리팩터링 * chore: 러너 게시글 태그 패키지 이동 * refactor: TagQueryController 태그 목록 검색 기능 리팩터링 * test: 인수 테스트 검증용 TestTagQueryRepository 수정 * refactor: 태그 목록 검색 조건인 TagReducedName 이 null 이거나 공백일 경우 빈 목록을 서비스 계층에서 반환하도록 수정 * Nginx와 Spring 로그가 같은 식별자값을 가지도록 수정 (#654) feat: Nginx의 해쉬값을 받아서 spring에서도 같이 출력하도록 함 --------- Co-authored-by: Ethan <[email protected]> Co-authored-by: HyunSeo Park (Hyena) <[email protected]>
관련이슈
참고사항
같이 봐야할 것 같아용.