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

feat: 연애 모의고사를 작성한다 #28

Merged
merged 67 commits into from
May 21, 2024
Merged

feat: 연애 모의고사를 작성한다 #28

merged 67 commits into from
May 21, 2024

Conversation

devholic22
Copy link
Collaborator

@devholic22 devholic22 commented May 16, 2024

📄 Summary

연애 모의고사와 관련된 기능을 개발하였습니다.

  • 관리자는 연애 모의고사를 등록할 수 있습니다.
    • 기획 요구사항을 반영하여, MVP 단계에서는 생성만 가능하도록 하였습니다.
    • 연애 모의고사는 과목 : 질문 : 답변 = 1 : N : 1의 구조를 가집니다. 각 과목은 여러 질문을 생성하며, 각 질문은 여러 답변을 생성하도록 했기 때문에 생명주기가 종속된다고 생각해 OneToMany를 이용하였습니다. 또한, 답변을 구분할 때는 answerNumber (1번, 2번, 3번 등 선택지 번호)를 두도록 하였습니다.
  • 회원은 연애 모의고사를 응시할 수 있습니다.
    • 없는 연애과목을 등록하거나, 같은 질문에 중복되게 제출하거나, 없는 답변 번호를 작성할 때 예외가 발생하도록 하였습니다.
  • 회원과 같은 과목, 같은 질문, 같은 답변을 30개 이상 작성한 회원 목록을 추출 (매칭)할 수 있도록 하였습니다. 다만 이 부분은 쿼리가 최적화되지 않은 것 같습니다.

🙋🏻 More

  • OneToMany + JoinColumn으로 구조를 설계하다보니 매칭에서 조인할 때, 질문 (SurveyAnswer)이 속한 과목 (Survey)을 데이터베이스에서는 알고 있지만, 자바 코드에서는 모르게 되는 문제가 있어 Querydsl을 쓰지 않고 JdbcTemplate을 쓰도록 하였습니다. 이 부분이 적절한 해결 방법일지 의견을 나눠보고 싶습니다.

close #25

- 연애고사 과목 등록 구현
- 연애고사 과목 이름 중복 예외처리
- 일차적으로 연애고사 과목 이름과 필수 여부만 등록되도록 구현
- 연애고사 과목 질문 등록 구현
- 리포지터리를 사용하지 않도록 OneToMany 방식으로 구현
- 연애 모의고사 과목, 항목, 문항 등록 통합 개발
- SurveyAnswer NPE 문제 수정
- Survey 테스트 작성
- 관련 Fixture 클래스 작성
- SurveyService 테스트 작성
- Survey FakeRepository 작성
- SurveyJpaRepository 테스트 작성
- 잘못된 valid 어노테이션 사용 수정
- DTO 필드 이름 수정
- 생성 반환 타입 수정 (id만 반환하도록 수정)
- SurveyResponse 삭제
- id만 반환하도록 수정
- SurveyControllerWebMvc 테스트 작성
- survey.adoc 문서 작성
- 회원 설문 등록 구현
- 도메인 구분을 위해 survey와 membersurvey 패키지 분리
- 설문과 회원 설문 구분을 위해 테스트 패키지 수정
- 양방향 참조 해제되도록 수정
- SurveyQuestion 단위 테스트 작성
- 필요한 관련 Fixture 생성
- Builder, EqualsAndHashCode 추가
- SurveyAnswer 단위 테스트 작성
- getter 추가
- SurveyQuestion equals&hashcode 추가
- 관련 테스트 수정
- MemberSurvey 단위 테스트 작성
- SurveyTest 추가 테스트 작성
- Fixture id 있는 타입 추가
- Fixture import static 적용
- 답변 생성 시 문제 안에서의 상대 번호 들어가도록 수정
- SurveyService 필요없는 메서드 삭제
- questionRequests 매개변수명 통일
- 함수 위치 수정
- surveyAnswers 변환 위치 수정
- 설문 답변 생성 시 번호나 답변 문자열에 대해 모두 중복성 검사되도록 추가
- 관련 테스트 추가 작성
- validateIsValidSubmitSurveyRequest 함수명 수정
- SurveyTest 예외 클래스명 수정
- 설문 응시 질문이 유효하지 않을 경우의 예외 테스트 추가
- 설문 응시 질문 id 갯수 및 중복 예외 추가
- 답변 중복 예외 검사 추가 (번호, 내용 모두 적용되도록 수정)
- SurveyAnswer 번호 유효성 검증 추가
- Survey, SurveyQuestion에서의 테스트 추가
- MemberSurveysJpaRepository 테스트 작성
- then절 추가
- SurveyControllerAcceptanceFixture 의존성 삭제
- MemberSurveysController 구현
- 관련 통합 테스트 작성
- 관련 인수 테스트 작성
- 관련 API 문서 작성
- 연애고사 응시 제출 dto valid message 추가
- 연애고사 매칭 회원 목록 조회 기능 구현
- 관련 인수 테스트 작성
- 함수명 문법 표현 통일을 위한 수정
- MVP 단계를 고려하여 수정 기능은 아예 개발해두지 않도록 수정
- JDBC 기반을 사용하므로 리포지터리 이름 변경
- RESTful을 위해 회원 연애고사 응시 URL 변경
- 회원 응시 과목 조회 기능 개발
- 관련 테스트 및 문서 작성
- 회원 연애고사 매칭 통합 테스트 작성
- 관련 문서 작성
- 회원 연애고사 조회 서비스 테스트 작성
- 관련 fake 리포지터리 메서드 구현 변경
- 인터셉터 경로 등록
Copy link
Collaborator

@eom-tae-in eom-tae-in left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다~ 몇가지 수정해주세요

Querydsl을 사용했을 때 어떤 문제가 있었나요?? 제가 볼 땐 쿼리 작성하는게 가능해보이는데 이 부분은 추가적으로 이야기 해보면 좋을거 같아요 :)

return survey;
}

private static void validateIsQuestionsNotDuplicated(final List<SurveyQuestionCreateRequest> questionRequests) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. validate도 동사고 is도 동사인데 둘을 같이 사용하신 이유가 있나요?
  2. 해당 메서드를 타입 변환을 담당하는 메서드와 검증을 하는 메서드로 분리해서 사용하는 건 어떨까요?

Copy link
Collaborator Author

@devholic22 devholic22 May 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

검증 메서드를 작성할 때 간혹 의문사로 작성하는 습관이 아직 있는 것 같네요..! 다른 메서드들도 반영하였습니다.
메서드 분리는 본 함수의 의도 (중복 검증)를 위해서 스트림 메서드를 이용해 타입 변환을 하는 것이 필수적이라 생각해서, 메서드를 더 분리하는 것 보다는 해당 메서드 안에서 작성해도 괜찮다는 생각이 들어서 작성했었습니다.

this.required = required;
}

public static Survey from(final SurveyCreateRequest request) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SurveyCreateRequest는 ui계층에서 사용하는 dto인 것으로 파악되는데 entity에서 dto로 받지 않고 필드 값으로 받는건 어떨까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

도메인 단에 dto 패키지를 두고 그 dto에서 서비스 -> 도메인으로 변환되는 방식으로 수정하였습니다. 처음 의도는 dto 안에 세부 dto가 있어 복잡할 것 같아 서비스 dto를 받도록 했는데 의존을 최대한 덜어내야 하는 것을 잊고 있었네요. 감사합니다!

Comment on lines 46 to 57
private Set<Long> extractSubmittedSurveyIds(final List<SurveySubmitRequest> requests) {
List<Long> submittedSurveyIds = requests.stream()
.map(SurveySubmitRequest::surveyId)
.toList();
HashSet<Long> surveyIds = new HashSet<>(submittedSurveyIds);

if (surveyIds.size() != submittedSurveyIds.size()) {
throw new SurveySubmitDuplicateException();
}

return surveyIds;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 메서드 로직을 분리하는게 좋아보입니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정 완료하였습니다!

Comment on lines 61 to 62
memberSurveysRepository.save(memberSurveys);
return memberSurveys;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return memberSurveysRepository.save(memberSurveys); 로 바꾸면 좋을거 같아요 :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인라인 변수로 수정 완료하였습니다 :)

.orElseThrow(SurveyQuestionNotSubmittedException::new);
}

private boolean isContainsSameAnswer(final Integer answerNumber) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is, contains 모두 동사인데 hasSameAnswer로 바꾸는 건 어떨까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정 완료하였습니다!

.build();
}

public void submitSurveys(final List<SurveySubmitRequest> requests) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SurveySubmitRequest는 ui 계층에서 요청을 받는 dto로 사용되고 있는데 entity에서 파라미터로 받는 게 괜찮을까요? 이렇게 사용하신 이유가 있나요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

도메인 단에 dto를 두는 것으로 수정하였습니다!

- 리턴 변수 인라인화 적용
- 함수명 문법에 맞게 수정
- survey에 ui적 DTO 의존 제거하고 도메인 DTO를 의존하도록 수정
- memberSurveys에 ui적 DTO 의존 제거하고 도메인 DTO를 의존하도록 수정
- 문법에 맞게 동사 중복 사용되지 않도록 수정
- 문법에 맞게 동사 중복 사용되지 않도록 수정
- surveyId 중복 예외 메서드 분할 처리
@devholic22 devholic22 merged commit e2c9e12 into develop May 21, 2024
1 check passed
@devholic22 devholic22 self-assigned this May 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

연애 모의고사를 작성한다
2 participants