Skip to content
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

dev -> main #47

Merged
merged 25 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
91e68b5
feat #43: 풀었던 문제 세트 체크를 위한 solveCount 필드 추가
GiHoo Apr 26, 2024
0f56387
feat #43: SolveHistory 필드 추가
GiHoo Apr 26, 2024
803ac34
feat #43: SolveHistoryDetail 엔티티 구성
GiHoo Apr 26, 2024
ebdc6f2
feat #43: SolveHistoryDetailRepository 구현
GiHoo Apr 26, 2024
bc90a43
feat #43: SolveHistoryRepository 구현
GiHoo Apr 26, 2024
4db91e0
feat #43: SolveHistoryController 구현(문서화x)
GiHoo Apr 26, 2024
ffd0bc8
feat #43: SolveHistoryService 구현
GiHoo Apr 26, 2024
3d485dc
feat #43: 풀이 기록 요청 정보 dto 구현 - list, detail
GiHoo Apr 26, 2024
1c99490
feat #43: 풀이 기록 응답 정보 dto 구현 - list, detail
GiHoo Apr 26, 2024
2675009
docs #45: 요청 응답 정보 문서화
GiHoo Apr 26, 2024
6113858
docs #45: SolveHistoryController 문서화
GiHoo Apr 26, 2024
425170c
refactor #45: 사용하지 않는 import 제거
GiHoo Apr 26, 2024
0341352
refactor #45: updateSolveCount 메서드 반환값 변경
GiHoo Apr 28, 2024
1c2ba05
feat #45: findByMemberId 메서드 추가
GiHoo Apr 28, 2024
7699b47
feat #45: findByMemberId 메서드 추가
GiHoo Apr 28, 2024
47ce566
refactor #45: 편의 메서드 제거 및 필드 명 변경
GiHoo Apr 28, 2024
75ef960
refactor #45: pathVariable 변수 명 변경 (solveHistoryId -> solveCount)
GiHoo Apr 28, 2024
2f37e3c
feat #45: requestDto에 toEntity 메서드 추가
GiHoo Apr 28, 2024
2641352
feat #45: SolveHistoryExistsException 추가
GiHoo Apr 28, 2024
7203a72
feat #45: SolveHistoryErrorCode 추가
GiHoo Apr 28, 2024
5a7dcd4
feat #45: SolveHistoryExceptionHandler 추가
GiHoo Apr 28, 2024
ac61815
refactor #45: 메서드명 명확하게 변경
GiHoo Apr 28, 2024
92bfeba
refactor #45: Builder 메서드 위치 변경 (클래스 -> 메서드)
GiHoo Apr 28, 2024
dc8790b
refactor #45: 주석 제거 / 코드 리팩토링 / 예외 처리
GiHoo Apr 28, 2024
57c6913
feat #45: 생성자 추가
GiHoo Apr 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/main/java/com/syu/capsbe/domain/member/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,15 @@ public class Member extends BaseEntity implements UserDetails {
@ElementCollection(fetch = FetchType.LAZY)
private List<String> roles;

@Column(nullable = false)
private Long solveCount;

@Builder
public Member(String email) {
this.email = new EmailVo(email);
this.uuid = UUID.randomUUID().toString();
this.roles = List.of("ROLE_USER");
this.solveCount = 0L;
}

@Override
Expand Down Expand Up @@ -84,4 +88,9 @@ public boolean isCredentialsNonExpired() {
public boolean isEnabled() {
return true;
}

public Long updateSolveCount() {
this.solveCount++;
return this.solveCount;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public interface MemberService {

void checkMemberIsExist(String email);

Member findByMemberId(Long memberId);

Member findByUuid(String uuid);

Member findByEmail(String email);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ public void checkMemberIsExist(String email) {
}
}

@Override
public Member findByMemberId(Long memberId) {
return memberRepository.findById(memberId)
.orElseThrow(() -> MemberExistsException.of(MemberErrorCode.MEMBER_IS_NOT_EXIST));
}

@Override
public Member findByUuid(String uuid) {
return memberRepository.findByUuid(uuid)
Expand Down
28 changes: 22 additions & 6 deletions src/main/java/com/syu/capsbe/domain/solveHistory/SolveHistory.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package com.syu.capsbe.domain.solveHistory;

import com.syu.capsbe.domain.member.Member;
import com.syu.capsbe.domain.problem.Problem;
import com.syu.capsbe.domain.problem.ProblemType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

Expand All @@ -29,9 +33,21 @@ public class SolveHistory {
@JoinColumn(name = "member_id", nullable = false)
private Member member;

@OneToOne
@JoinColumn(name = "problem_id", nullable = false)
private Problem problem;
private Long solveCount;

private boolean isCorrect;
@OneToMany(mappedBy = "solveHistory")
private List<SolveHistoryDetail> solveHistoryDetails = new ArrayList<>();

private ProblemType problemType;

private LocalDateTime solveDate;

@Builder
public SolveHistory(Member member, Long solveCount, ProblemType problemType,
LocalDateTime solveDate) {
this.member = member;
this.solveCount = solveCount;
this.problemType = problemType;
this.solveDate = solveDate;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.syu.capsbe.domain.solveHistory;

import com.syu.capsbe.domain.solveHistory.dto.request.SolveHistoryDetailRequestDto;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "solve_history_details")
public class SolveHistoryDetail {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "solve_history_id", nullable = false)
private SolveHistory solveHistory;

private String question;

private String answer;

private String userAnswer;

private boolean isCorrect;

public SolveHistoryDetail toEntity(SolveHistoryDetailRequestDto solveHistoryDetailRequestDto, SolveHistory solveHistory) {
return SolveHistoryDetail.builder()
.solveHistory(solveHistory)
.question(solveHistoryDetailRequestDto.getQuestion())
.answer(solveHistoryDetailRequestDto.getAnswer())
.userAnswer(solveHistoryDetailRequestDto.getUserAnswer())
.isCorrect(solveHistoryDetailRequestDto.isCorrect())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.syu.capsbe.domain.solveHistory;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface SolveHistoryDetailRepository extends JpaRepository<SolveHistoryDetail, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.syu.capsbe.domain.solveHistory;

import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

@Repository
public interface SolveHistoryRepository extends JpaRepository<SolveHistory, Long> {

@Query("SELECT sh FROM SolveHistory sh WHERE sh.member.id = :memberId")
List<SolveHistory> findByMemberId(Long memberId);

@Query("SELECT sh FROM SolveHistory sh WHERE sh.member.id = :memberId AND sh.solveCount = :solveCount")
Optional<SolveHistory> findByMemberIdAndSolveHistoryId(Long memberId, Long solveCount);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.syu.capsbe.domain.solveHistory.application;

import com.syu.capsbe.domain.solveHistory.dto.request.SolveHistoryRequestDto;
import com.syu.capsbe.domain.solveHistory.dto.response.SolveHistoryDetailResponse;
import com.syu.capsbe.domain.solveHistory.dto.response.SolveHistoryResponseDto;
import java.util.List;

public interface SolveHistoryService {

void submitSolveHistory(SolveHistoryRequestDto request, Long memberId);

List<SolveHistoryResponseDto> getHistoryList(Long memberId);

List<SolveHistoryDetailResponse> getHistoryDetails(Long memberId, Long solveCount);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package com.syu.capsbe.domain.solveHistory.application;

import com.syu.capsbe.domain.member.Member;
import com.syu.capsbe.domain.member.application.MemberService;
import com.syu.capsbe.domain.problem.ProblemType;
import com.syu.capsbe.domain.solveHistory.SolveHistory;
import com.syu.capsbe.domain.solveHistory.SolveHistoryDetail;
import com.syu.capsbe.domain.solveHistory.SolveHistoryDetailRepository;
import com.syu.capsbe.domain.solveHistory.SolveHistoryRepository;
import com.syu.capsbe.domain.solveHistory.dto.request.SolveHistoryDetailRequestDto;
import com.syu.capsbe.domain.solveHistory.dto.request.SolveHistoryRequestDto;
import com.syu.capsbe.domain.solveHistory.dto.response.SolveHistoryDetailResponse;
import com.syu.capsbe.domain.solveHistory.dto.response.SolveHistoryResponseDto;
import com.syu.capsbe.domain.solveHistory.exception.SolveHistoryExistsException;
import com.syu.capsbe.domain.solveHistory.exception.common.SolveHistoryErrorCode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class SolveHistoryServiceImpl implements SolveHistoryService {

private final MemberService memberService;
private final SolveHistoryRepository solveHistoryRepository;
private final SolveHistoryDetailRepository solveHistoryDetailRepository;

@Override
@Transactional
public void submitSolveHistory(SolveHistoryRequestDto request, Long memberId) {
Member member = memberService.findByMemberId(memberId);

Long solveCount = member.updateSolveCount();

SolveHistory solveHistory = new SolveHistory(member, solveCount,
ProblemType.valueOf(request.getProblemType()), LocalDateTime.now());

solveHistoryRepository.save(solveHistory);

List<SolveHistoryDetailRequestDto> submittedSolveHistory = request.getSolveHistoryDetail();

for (SolveHistoryDetailRequestDto dto : submittedSolveHistory) {
solveHistoryDetailRepository.save(dto.toEntity(solveHistory));
}
}

@Override
public List<SolveHistoryResponseDto> getHistoryList(Long memberId) {
List<SolveHistory> solveHistoryList = solveHistoryRepository.findByMemberId(memberId);

return convertSolveHistoryEntityToDto(solveHistoryList);
}

@Override
public List<SolveHistoryDetailResponse> getHistoryDetails(Long memberId, Long solveCount) {
SolveHistory solveHistory = solveHistoryRepository.findByMemberIdAndSolveHistoryId(memberId, solveCount)
.orElseThrow(() -> SolveHistoryExistsException.of(SolveHistoryErrorCode.SOLVE_HISTORY_IS_NOT_EXISTS));

return convertSolveHistoryDetailsEntityToDto(solveHistory);
}

private List<SolveHistoryResponseDto> convertSolveHistoryEntityToDto(
List<SolveHistory> solveHistoryList) {
List<SolveHistoryResponseDto> solveHistoryResponseDtoList = new ArrayList<>();

for (SolveHistory solveHistory : solveHistoryList) {
List<SolveHistoryDetailResponse> solveHistoryDetailResponseList = convertSolveHistoryDetailsEntityToDto(
solveHistory);

SolveHistoryResponseDto solveHistoryResponseDto = SolveHistoryResponseDto.builder()
.solveHistoryCount(solveHistory.getSolveCount())
.solveHistoryDetail(solveHistoryDetailResponseList)
.build();

solveHistoryResponseDtoList.add(solveHistoryResponseDto);
}

return solveHistoryResponseDtoList;
}

private List<SolveHistoryDetailResponse> convertSolveHistoryDetailsEntityToDto(
SolveHistory solveHistory) {
List<SolveHistoryDetail> solveHistoryDetails = solveHistory.getSolveHistoryDetails();

List<SolveHistoryDetailResponse> solveHistoryDetailResponseList = new ArrayList<>();

for (SolveHistoryDetail detail : solveHistoryDetails) {
SolveHistoryDetailResponse solveHistoryDetailResponse = SolveHistoryDetailResponse.builder()
.question(detail.getQuestion())
.answer(detail.getAnswer())
.userAnswer(detail.getUserAnswer())
.isCorrect(detail.isCorrect())
.build();

solveHistoryDetailResponseList.add(solveHistoryDetailResponse);
}

return solveHistoryDetailResponseList;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.syu.capsbe.domain.solveHistory.dto.request;

import com.syu.capsbe.domain.solveHistory.SolveHistory;
import com.syu.capsbe.domain.solveHistory.SolveHistoryDetail;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@Schema(description = "풀이 세부 기록 요청 정보")
@AllArgsConstructor
public class SolveHistoryDetailRequestDto {

@Schema(description = "문제", example = "Fill in the blank: 'Due to unforeseen circumstances, the meeting has been _______.' Choices: a) canceled, b) advanced, c) delayed, d) extended")
private String question;

@Schema(description = "정답", example = "c")
private String answer;

@Schema(description = "유저 제출 정답", example = "c")
private String userAnswer;

@Schema(description = "정답 여부", example = "true")
private boolean isCorrect;

public SolveHistoryDetail toEntity(SolveHistory solveHistory) {
return SolveHistoryDetail.builder()
.solveHistory(solveHistory)
.question(question)
.answer(answer)
.userAnswer(userAnswer)
.isCorrect(isCorrect)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.syu.capsbe.domain.solveHistory.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@Schema(description = "풀이 기록 요청 정보")
@AllArgsConstructor
public class SolveHistoryRequestDto {

@Schema(description = "문제 유형", example = "GRAMMAR | CONVERSATION | WORD")
private String problemType;

@Schema(description = "풀이 세부 기록 리스트", example = "[\n"
+ " {\n"
+ " \"question\": \"What is the best synonym for 'enduring' in the context of business relationships? Choices: a) lasting, b) brief, c) fragile, d) sporadic\",\n"
+ " \"answer\": \"a\",\n"
+ " \"userAnswer\": \"b\",\n"
+ " \"correct\": false\n"
+ " },\n"
+ " {\n"
+ " \"question\": \"Identify the error in the sentence: 'She has less clients than she did last year.' Choices: a) She has, b) less, c) than she, d) last year\",\n"
+ " \"answer\": \"b\",\n"
+ " \"userAnswer\": \"b\",\n"
+ " \"correct\": true\n"
+ " },\n"
+ " {\n"
+ " \"question\": \"What does the phrase 'touch base' mean in a business context? Choices: a) To negotiate, b) To update, c) To argue, d) To finalize\",\n"
+ " \"answer\": \"b\",\n"
+ " \"userAnswer\": \"b\",\n"
+ " \"correct\": true\n"
+ " }\n"
+ " ]\n"
+ " },\n"
+ " {\n"
+ " \"solveHistoryCount\": 2,\n"
+ " \"solveHistoryDetail\": [\n"
+ " {\n"
+ " \"question\": \"What is the best synonym for 'enduring' in the context of business relationships? Choices: a) lasting, b) brief, c) fragile, d) sporadic\",\n"
+ " \"answer\": \"a\",\n"
+ " \"userAnswer\": \"a\",\n"
+ " \"correct\": true\n"
+ " },\n"
+ " {\n"
+ " \"question\": \"Identify the error in the sentence: 'She has less clients than she did last year.' Choices: a) She has, b) less, c) than she, d) last year\",\n"
+ " \"answer\": \"b\",\n"
+ " \"userAnswer\": \"b\",\n"
+ " \"correct\": true\n"
+ " },\n"
+ " {\n"
+ " \"question\": \"What does the phrase 'touch base' mean in a business context? Choices: a) To negotiate, b) To update, c) To argue, d) To finalize\",\n"
+ " \"answer\": \"b\",\n"
+ " \"userAnswer\": \"b\",\n"
+ " \"correct\": true\n"
+ " }\n"
+ " ]")
private List<SolveHistoryDetailRequestDto> solveHistoryDetail;
}
Loading
Loading