-
Notifications
You must be signed in to change notification settings - Fork 0
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
DailyDefense 컨트롤러 작성 및 시험 타이머 기능 개발 #36
Merged
Changes from all commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
53768b2
feat: solved problemnumber set 반환
miiiinju1 fdd6973
feat: 사용자 로그인 여부에 따라 오늘의 문제 정보를 반환하는 service 및 테스트 개발
miiiinju1 bf2a2f4
feat: 오늘의 문제 시험 정보, 랭킹 정보 페이지로 반환하는 서비스
miiiinju1 ca91cc9
fix: RankUseCaseImpl 패키지 이동 및 AtomicLong long 캐스팅
miiiinju1 f90fe32
test: DailyDefenseInfoResponse Test 추가
miiiinju1 ae6ef73
refactor: DTO 생성 로직 Mapper로 분리
miiiinju1 8656861
feat: 오늘의 문제 정보 반환, 오늘의 문제 랭킹 Controller 및 테스트 작성
miiiinju1 0a57c33
:art: Mapper 기본 생성자 private 변경
miiiinju1 fcc7d74
:art: 필요없는 중괄호 삭제
miiiinju1 5ff52c0
:fire: Remove unused import 'StartDailyDefenseResponse'
miiiinju1 014182d
:art: Dailydefense mapper 생성
miiiinju1 ff0ea61
fix: @JsonInclude 어노테이션 필드로 이동
miiiinju1 4e6175c
fix: dailydefense 조회 시 problem fecth join
miiiinju1 2d9f64e
:sparkles: DailyDefense 시작 시 문제 content 포함 dto 변경
miiiinju1 3e3e868
:sparkles: 시험 시작 시 문제 본문 가져오게 구현, 테스트코드 작성
miiiinju1 cf4c7a0
fix: 응용서비스에서 Port 이용하게 변경
miiiinju1 45bb1f1
:bug: WebClient 정상적으로 mocking되도록 변경
miiiinju1 c21af05
:fire: Remove unused import
miiiinju1 c36ee7d
:fire: 사용하지 않는 throws 제거
miiiinju1 cccc8e5
:sparkles: Webclient retryWhen을 통해 재처리 로직 추가
miiiinju1 a7ba850
:recycle: Problem Content 책임에 따라 problem_information하위로 이동
miiiinju1 f31c451
:zap: TempCode hashmap enummap으로 변경
miiiinju1 42886fe
:fire: Remove unused import
miiiinju1 ddb9199
:art: 기본생성자 private으로 변경
miiiinju1 32cd24a
Google OAuth 적용 및 커스텀 예외 코드 추가 (#37)
aj4941 4965450
:sparkles: 시험 시작 시 문제 본문 가져오게 구현, 테스트코드 작성
miiiinju1 391bc83
:white_check_mark: Spring Security & WebMvcTest 충돌 해결
miiiinju1 57736cd
Merge branch 'dev' into feat/#30
miiiinju1 81758af
:fire: 충돌 해결
miiiinju1 d775630
:fire: Remove unused import
miiiinju1 1091e77
:sparkles: HandlerMethodArgumentResolver 추가 및 controller 반영
miiiinju1 2202b2b
:sparkles: SetAuthentication 로직 변경
miiiinju1 515a758
:art: GetDailydefenseInfo 로직 변경
miiiinju1 4e6852b
:art: 로그인 여부 관계없는 API로직 filter 반영
miiiinju1 bea3db7
:sparkles: 제한 시간 후 시험 자동 종료 로직 추가
miiiinju1 db548fc
:art: 도메인 서비스 구조 변경
miiiinju1 0a9891b
:art: ConcurrentHashMap 대신 구조적으로 타이머 등록 1회 보장
miiiinju1 d286429
:art: 롤백시 타이머 정상 제거를 위해 Timer Event 발행 방식 선택
miiiinju1 52a52e1
:white_check_mark: 롤백 테스트 추가
miiiinju1 340b587
:sparkles: RestDocs 추가 및 docstest 작성
miiiinju1 be50f0e
:memo: 오늘의 문제 랭킹 restdocs 추가
miiiinju1 fa1e930
:fire: Remove unused import
miiiinju1 8263edf
:fire: Remove unused import
miiiinju1 a6436aa
:white_check_mark: 테스트 환경 통합
miiiinju1 fb738f4
:art: DailyDefenseProblemStrategy로 이름 변경
miiiinju1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
[[Daily-Defense]] | ||
== 오늘의 문제 정보 조회 | ||
|
||
=== Request | ||
include::{snippets}/daily-defense-info/http-request.adoc[] | ||
|
||
=== Response | ||
include::{snippets}/daily-defense-info/http-response.adoc[] | ||
include::{snippets}/daily-defense-info/response-fields.adoc[] | ||
|
||
== 오늘의 문제 기록 조회 | ||
|
||
=== Request | ||
include::{snippets}/daily-defense-ranking/http-request.adoc[] | ||
|
||
=== Response | ||
include::{snippets}/daily-defense-ranking/http-response.adoc[] | ||
include::{snippets}/daily-defense-ranking/response-fields.adoc[] | ||
|
||
|
||
== 오늘의 문제 시작 | ||
|
||
=== Request | ||
include::{snippets}/daily-defense-start/http-request.adoc[] | ||
|
||
=== Response | ||
include::{snippets}/daily-defense-start/http-response.adoc[] | ||
include::{snippets}/daily-defense-start/response-fields.adoc[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
ifndef::snippets[] | ||
:snippets: ../../build/generated-snippets | ||
endif::[] | ||
= 모두의 랜덤 디펜스 REST API | ||
:doctype: book | ||
:icons: font | ||
:source-highlighter: highlightjs | ||
:toc: left | ||
:toclevels: 1 | ||
:sectlinks: | ||
|
||
include::api/dailydefense/dailydefense.adoc[] | ||
|
||
|
||
|
||
[[Daily-Defense-List]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
src/main/java/kr/co/morandi/backend/common/config/WebMvcConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package kr.co.morandi.backend.common.config; | ||
|
||
import kr.co.morandi.backend.common.web.resolver.MemberHandlerMethodArgumentResolver; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
|
||
import java.util.List; | ||
|
||
@Configuration | ||
public class WebMvcConfig implements WebMvcConfigurer { | ||
|
||
@Bean | ||
MemberHandlerMethodArgumentResolver memberHandlerMethodArgumentResolver() { | ||
return new MemberHandlerMethodArgumentResolver(); | ||
} | ||
|
||
@Override | ||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { | ||
resolvers.add(memberHandlerMethodArgumentResolver()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
src/main/java/kr/co/morandi/backend/common/web/MemberId.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package kr.co.morandi.backend.common.web; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Target(ElementType.PARAMETER) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface MemberId { | ||
} |
22 changes: 22 additions & 0 deletions
22
...n/java/kr/co/morandi/backend/common/web/resolver/MemberHandlerMethodArgumentResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package kr.co.morandi.backend.common.web.resolver; | ||
|
||
import kr.co.morandi.backend.common.web.MemberId; | ||
import kr.co.morandi.backend.member_management.infrastructure.config.security.utils.SecurityUtils; | ||
import org.springframework.core.MethodParameter; | ||
import org.springframework.web.bind.support.WebDataBinderFactory; | ||
import org.springframework.web.context.request.NativeWebRequest; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
import org.springframework.web.method.support.ModelAndViewContainer; | ||
|
||
public class MemberHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { | ||
@Override | ||
public boolean supportsParameter(MethodParameter parameter) { | ||
return parameter.getParameterAnnotation(MemberId.class) != null | ||
&& parameter.getParameterType().equals(Long.class); | ||
} | ||
|
||
@Override | ||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { | ||
return SecurityUtils.getCurrentMemberId(); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
...orandi/backend/defense_information/application/dto/response/DailyDefenseInfoResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package kr.co.morandi.backend.defense_information.application.dto.response; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
import java.util.List; | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class DailyDefenseInfoResponse { | ||
|
||
private String defenseName; | ||
private Integer problemCount; | ||
private Long attemptCount; | ||
private List<DailyDefenseProblemInfoResponse> problems; | ||
|
||
|
||
@Builder | ||
private DailyDefenseInfoResponse(String defenseName, Integer problemCount, Long attemptCount, List<DailyDefenseProblemInfoResponse> problems) { | ||
this.defenseName = defenseName; | ||
this.problemCount = problemCount; | ||
this.attemptCount = attemptCount; | ||
this.problems = problems; | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
...backend/defense_information/application/dto/response/DailyDefenseProblemInfoResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package kr.co.morandi.backend.defense_information.application.dto.response; | ||
|
||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import kr.co.morandi.backend.defense_information.domain.model.defense.ProblemTier; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
public class DailyDefenseProblemInfoResponse { | ||
|
||
private Long problemNumber; | ||
private Long problemId; | ||
private Long baekjoonProblemId; | ||
private ProblemTier difficulty; | ||
private Long solvedCount; | ||
private Long submitCount; | ||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
private Boolean isSolved; | ||
|
||
@Builder | ||
private DailyDefenseProblemInfoResponse(Long problemNumber, Long problemId, Long baekjoonProblemId, ProblemTier difficulty, Long solvedCount, Long submitCount, Boolean isSolved) { | ||
this.problemNumber = problemNumber; | ||
this.problemId = problemId; | ||
this.baekjoonProblemId = baekjoonProblemId; | ||
this.difficulty = difficulty; | ||
this.solvedCount = solvedCount; | ||
this.submitCount = submitCount; | ||
this.isSolved = isSolved; | ||
} | ||
} | ||
|
||
|
32 changes: 32 additions & 0 deletions
32
...i/backend/defense_information/application/mapper/dailydefense/DailyDefenseInfoMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package kr.co.morandi.backend.defense_information.application.mapper.dailydefense; | ||
|
||
import kr.co.morandi.backend.defense_information.application.dto.response.DailyDefenseInfoResponse; | ||
import kr.co.morandi.backend.defense_information.domain.model.dailydefense.DailyDefense; | ||
import kr.co.morandi.backend.defense_record.domain.model.dailydefense_record.DailyRecord; | ||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class DailyDefenseInfoMapper { | ||
|
||
public static DailyDefenseInfoResponse fromNonAttempted(DailyDefense dailyDefense) { | ||
return DailyDefenseInfoResponse.builder() | ||
.defenseName(dailyDefense.getContentName()) | ||
.problemCount(dailyDefense.getProblemCount()) | ||
.attemptCount(dailyDefense.getAttemptCount()) | ||
.problems(DailyDefenseProblemInfoMapper.ofNonAttempted(dailyDefense.getDailyDefenseProblems())) | ||
.build(); | ||
} | ||
|
||
public static DailyDefenseInfoResponse ofAttempted(DailyDefense dailyDefense, DailyRecord dailyRecord) { | ||
return DailyDefenseInfoResponse.builder() | ||
.defenseName(dailyDefense.getContentName()) | ||
.problemCount(dailyDefense.getProblemCount()) | ||
.attemptCount(dailyDefense.getAttemptCount()) | ||
.problems(DailyDefenseProblemInfoMapper.ofAttempted( | ||
dailyDefense.getDailyDefenseProblems(), | ||
dailyRecord.getSolvedProblemNumbers()) | ||
) | ||
.build(); | ||
} | ||
} | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Mapper 클래스를 따로 분리하는 것보다 DailyDefenseInfoResponse 객체 안에 두 개의 메서드를 만들어서 관리하는 것은 어떻게 생각하실까요?
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.
SRP 원칙에 따라 하나의 클래스가 하나의 역할을 하도록 Mapper로 구성하는 것도 좋아보여요!
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.
말씀하신 부분도 제가 정말 많이 고민해봤던 부분 중 하나인데
"시험 시작 시 응답" dto의 경우에는 변환 로직이 복잡했던 관계로 mapper를 도입했었지만
"오늘의 문제 정보 응답" dto는 비교적 간단하여 정적 팩토리 메소드로 구현할까 생각도 했었습니다. 하지만 비즈니스 로직에 따라 응답 로직이 달라지는 점이 존재하여 응답 dto에 여러 변환 로직이 들어가는 것이 적절하지 않을 것으로 생각하여 mapper도입을 결정했습니다.
p.s. 변환 메소드에서 단순히 필드를 get만 하는 비즈니스 로직일 경우 mapper를 도입하더라도 큰 효과를 보지 못할 것으로 생각합니다!