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: Create QuestionSheet #86

Merged
merged 10 commits into from
Aug 14, 2024
Merged

Conversation

toychip
Copy link
Member

@toychip toychip commented Aug 11, 2024

  • 🔀 PR 제목의 형식을 잘 작성했나요? e.g. [add] pr template
  • 🧹 불필요한 코드는 제거했나요?

작업 내용

QuestionSheet 생성 로직을 구현했습니다. 친구 관계의 질문은 친구 중에서, 비친구 관계의 질문은 비친구 중에서 완전 무작위로 후보자를 선택하는 방식이 예전에 정했던 방법 같아서 그렇게 진행했습니다.

아래와 같이 동작합니다. 혹시나 잘못되거나 틀린 점 있으면 말씀해주세요!

  1. 모든 Member를 DB에서 조회합니다.
  2. 각 Member에 대해 친구와 비친구를 구분하여 해당 후보자를 가져오는 쿼리를 실행합니다.
  3. QuestionSet의 questionIds를 List<친구 질문>과 List<비친구 질문>으로 구분합니다.
  4. 분류된 질문 목록과 각각의 후보자를 매칭하여 List를 생성합니다.
  5. 생성된 QuestionSheet들을 두 리스트를 합쳐서 반환합니다.
  6. List<QuestionSheet>List<QuestionEntity>로 변환하여 DB에 저장후 다시 List<QuestionSheet>로 변환하여 반환합니다.

쉽게 설명하려다 보니 좀 길어졌네요,, 긴 글 읽어 주셔서 감사합니다

비고 (첨부자료)

현재 친구 수가 8명 미만인 경우 오류가 발생해서, QuestionSheet를 생성하는 스케줄러를 일시적으로 주석 처리하였습니다. 추후 친구 관계가 설정된 이후에 주석을 해제할 예정입니다.

@toychip toychip self-assigned this Aug 11, 2024
Copy link
Member Author

@toychip toychip left a comment

Choose a reason for hiding this comment

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

현재 쿼리는 아래와 같습니다.
모든 회원이 동일한 QuestionSet를 할당받고, 회원마다 QuestionSet의 questionIds를 받아 친구/비친구로 구분하는데, 이를 1번의 쿼리로 해결할 수 있을 것 같은데, 고민입니다.

회원수 80 * {(회원의 친구/비친구 뽑는 회원당 2번의 쿼리) + (수정해야할 부분, 회원당 매번 QuestionSet의 Question의 타입이 친구/비친구 질문을 구분하는데 한 번으로 해결할 수 있을지, 회원당 1번 쿼리) + (회원당 QuestionSheetEntity 생성 12번 insert 쿼리, 배치 사이즈로 960개를 1번으로 해결)}

총 80 * (2 + 1 + insert 12) = select(240) + insert(1) 인데, 160 + 1 로 줄일 수 이면 좋을 것 같은데 ㅎㅎ,, 굳이일까요 여러분의 생각이 궁금합니다.

return allMemberRecords.flatMap { member ->
val candidateOfFriend = memberRelationService.findCandidateOfFriend(member.id)
val candidateOfAccompany = memberRelationService.findCandidateOfAccompany(member.id)
questionService.createQuestionSheetsForMember(
Copy link
Member Author

Choose a reason for hiding this comment

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

Question의 QuestionType이 친구인지 비친구인지 1번만 계산해서 사용하면 좋을 것 같은데 고민입니다.
QuestionOrder에 추가하자니 너무 대공사라, 어떻게 생각하시는지 궁금합니다.

Copy link
Member

Choose a reason for hiding this comment

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

우선 토요일에 말한 것처럼 배치성이니까 먼저 해보고 문제 있다면 그떄 가서 개선하는 것도 괜찮아 보입니다.

memberRelation.fromId.eq(memberId),
memberRelation.relationType.eq(RelationType.ACCOMPANY)
)
.orderBy(Expressions.numberTemplate(Double::class.java, "function('RAND')").asc())
Copy link
Member

Choose a reason for hiding this comment

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

싱기하네요 Expressions.numberTemplate()

}

companion object {
private const val DEFAULT_CANDIDATE_SIZE: Long = 8
Copy link
Member

@xonmin xonmin Aug 14, 2024

Choose a reason for hiding this comment

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

Candidate size 도 사용하는 곳에서 파편되어 사용될 수 있으니, application.yaml 로 빼고 주입해서 사용하면 좋겠네요 @Value 나 ...

Copy link
Member

@xonmin xonmin left a comment

Choose a reason for hiding this comment

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

고생하셨씁니다!

): List<QuestionSheet> {
/**
* TODO:
* TODO: 여기 있는 애들은 해결된 것일까요?
Copy link
Member

Choose a reason for hiding this comment

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

넵 해결된 것 같아요!

@@ -120,7 +122,21 @@ class DefaultQuestionUseCase(
override fun createQuestionSheet(): List<QuestionSheet> {
val currentQuestionSet = questionService.getNextOperatingQuestionSet() ?: throw DojoException.of(DojoExceptionType.QUESTION_SET_NOT_READY)
val allMemberRecords = memberService.findAllMember()
return questionService.createQuestionSheets(currentQuestionSet, allMemberRecords)
// ToDo Default 친구 수가 8명 이하일 경우 오류 발생하므로, 친구가 8명이 아니면 회원가입 불가능
Copy link
Member

Choose a reason for hiding this comment

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

어디에서 플로우를 방어하느냐도 정해야하는군요..
현재 가입자들한테는 모두 8명이 넘어서 상관없겟다만, 회원가입 절차에 팔로우 8명 추가를 하게 해야겠네요.

또 추가적으로 만약 회원가입 절차에 막지 않는다면, getQuestionSheet (투표지 조회) 에 해당 유저의 친구수가 8명이 안넘는을 때 팔로우를 추가하게끔 하는 플로우로 이어지게 하는 것도 방법이긴 하겠네요.
(물론 팔로우를 그렇게 8명 추가해도 바로 createQSheets 스케줄러가 돌지 않는다면 팔로우를 추가한 유저는 다음 투표 떄까지 기다려야겠지만요..)

Copy link
Member Author

@toychip toychip Aug 14, 2024

Choose a reason for hiding this comment

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

넵 말씀하신 것처럼 어디서 방어해야할지 정해야합니다.
개인적으로 다른 앱들 사용해봤을때처럼 최소 친구를 등록한 후 회원가입이 가능했던 것처럼 저희도 비슷하게 구현하면 단순하고 더 좋을 것 같습니다~

@toychip toychip force-pushed the junhyoung/add-create-questionsheet branch 2 times, most recently from 350507f to b5fc2ec Compare August 14, 2024 06:52
@toychip toychip merged commit 219b1a0 into master Aug 14, 2024
2 checks passed
@toychip toychip deleted the junhyoung/add-create-questionsheet branch August 14, 2024 06:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants