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
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ class Scheduler(
@Async("questionSheetSchedulerExecutor")
fun createQuestionSheet() {
log.info { "=== Start Create questionSheet at ${LocalDateTime.now()}. ===" }
questionUseCase.createQuestionSheet()

// ToDo ์นœ๊ตฌ ๊ด€๊ณ„ ์ƒ์„ฑ ํ›„ ์ฃผ์„ ํ•ด์ œํ•  ๊ฒƒ
// questionUseCase.createQuestionSheet()
log.info { "=== Done Create questionSheet at ${LocalDateTime.now()}. ===" }
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.mashup.dojo

import com.mashup.dojo.base.BaseTimeEntity
import com.querydsl.core.types.dsl.Expressions
import com.querydsl.jpa.impl.JPAQueryFactory
import jakarta.persistence.Column
import jakarta.persistence.Entity
Expand Down Expand Up @@ -48,6 +49,16 @@ interface MemberRelationQueryRepository {
fromId: String,
toId: String,
): Boolean

fun findRandomOfFriend(
memberId: String,
limit: Long,
): List<String>

fun findRandomOfAccompany(
memberId: String,
limit: Long,
): List<String>
}

class MemberRelationQueryRepositoryImpl(
Expand Down Expand Up @@ -92,6 +103,42 @@ class MemberRelationQueryRepositoryImpl(
return findMemberRelation != null
}

override fun findRandomOfFriend(
memberId: String,
limit: Long,
): List<String> {
val memberRelation = QMemberRelationEntity.memberRelationEntity

return jpaQueryFactory
.select(memberRelation.toId)
.from(memberRelation)
.where(
memberRelation.fromId.eq(memberId),
memberRelation.relationType.eq(RelationType.FRIEND)
)
.orderBy(Expressions.numberTemplate(Double::class.java, "function('RAND')").asc())
.limit(limit)
.fetch()
}

override fun findRandomOfAccompany(
memberId: String,
limit: Long,
): List<String> {
val memberRelation = QMemberRelationEntity.memberRelationEntity

return jpaQueryFactory
.select(memberRelation.toId)
.from(memberRelation)
.where(
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()

.limit(8)
.fetch()
}

private fun findByFromIdAndRelationType(
fromId: String,
relationType: RelationType,
Expand Down
37 changes: 36 additions & 1 deletion entity/src/main/kotlin/com/mashup/dojo/QuestionRepository.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.mashup.dojo

import com.mashup.dojo.base.BaseEntity
import com.querydsl.jpa.impl.JPAQueryFactory
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.EnumType
Expand All @@ -12,7 +13,7 @@ import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param

interface QuestionRepository : JpaRepository<QuestionEntity, String> {
interface QuestionRepository : JpaRepository<QuestionEntity, String>, QuestionRepositoryCustom {
@Query("SELECT q FROM QuestionEntity q WHERE q.type = :type AND q.id NOT IN :excludeIds ORDER BY function('RAND')")
fun findRandomQuestions(
@Param("type") type: QuestionType,
Expand Down Expand Up @@ -54,3 +55,37 @@ enum class QuestionCategory {
HUMOR,
OTHER,
}

interface QuestionRepositoryCustom {
fun findFriendQuestionsByIds(questionIds: List<String>): List<String>

fun findAccompanyQuestionsByIds(questionIds: List<String>): List<String>
}

class QuestionRepositoryImpl(
private val queryFactory: JPAQueryFactory,
) : QuestionRepositoryCustom {
override fun findFriendQuestionsByIds(questionIds: List<String>): List<String> {
val question = QQuestionEntity.questionEntity

return queryFactory.select(question.id)
.from(question)
.where(
question.type.eq(QuestionType.FRIEND),
question.id.`in`(questionIds)
)
.fetch()
}

override fun findAccompanyQuestionsByIds(questionIds: List<String>): List<String> {
val question = QQuestionEntity.questionEntity

return queryFactory.select(question.id)
.from(question)
.where(
question.type.eq(QuestionType.ACCOMPANY),
question.id.`in`(questionIds)
)
.fetch()
}
}
19 changes: 18 additions & 1 deletion service/src/main/kotlin/com/mashup/dojo/domain/Question.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,21 @@ data class QuestionSheet(
val questionId: QuestionId,
val resolverId: MemberId,
val candidates: List<MemberId>,
)
) {
companion object {
fun create(
questionSetId: QuestionSetId,
questionId: QuestionId,
resolverId: MemberId,
candidates: List<MemberId>,
): QuestionSheet {
return QuestionSheet(
questionSheetId = QuestionSheetId(UUIDGenerator.generate()),
questionSetId = questionSetId,
questionId = questionId,
resolverId = resolverId,
candidates = candidates
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ interface MemberRelationService {
fromId: MemberId,
toId: MemberId,
): Boolean

fun findCandidateOfFriend(memberId: MemberId): List<MemberId>

fun findCandidateOfAccompany(memberId: MemberId): List<MemberId>
}

@Service
Expand Down Expand Up @@ -79,6 +83,28 @@ class DefaultMemberRelationService(
): Boolean {
return memberRelationRepository.isFriend(fromId = fromId.value, toId = toId.value)
}

override fun findCandidateOfFriend(memberId: MemberId): List<MemberId> {
return memberRelationRepository.findRandomOfFriend(
memberId = memberId.value,
limit = DEFAULT_CANDIDATE_SIZE
).map {
MemberId(it)
}
}

override fun findCandidateOfAccompany(memberId: MemberId): List<MemberId> {
return memberRelationRepository.findRandomOfAccompany(
memberId = memberId.value,
limit = DEFAULT_CANDIDATE_SIZE
).map {
MemberId(it)
}
}

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 ๋‚˜ ...

}
}

private fun MemberRelation.toEntity(): MemberRelationEntity {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import com.mashup.dojo.QuestionSheetEntity
import com.mashup.dojo.QuestionSheetRepository
import com.mashup.dojo.Status
import com.mashup.dojo.domain.ImageId
import com.mashup.dojo.domain.Member
import com.mashup.dojo.domain.MemberId
import com.mashup.dojo.domain.PublishStatus
import com.mashup.dojo.domain.PublishedTime
Expand Down Expand Up @@ -71,9 +70,11 @@ interface QuestionService {
endAt: LocalDateTime,
): QuestionSet

fun createQuestionSheets(
fun createQuestionSheetsForMember(
questionSet: QuestionSet,
members: List<Member>,
candidatesOfFriend: List<MemberId>,
candidatesOfAccompany: List<MemberId>,
resolver: MemberId,
): List<QuestionSheet>
}

Expand Down Expand Up @@ -224,21 +225,51 @@ class DefaultQuestionService(
}

@Transactional
override fun createQuestionSheets(
override fun createQuestionSheetsForMember(
questionSet: QuestionSet,
members: List<Member>,
candidatesOfFriend: List<MemberId>,
candidatesOfAccompany: List<MemberId>,
resolver: MemberId,
): 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.

๋„ต ํ•ด๊ฒฐ๋œ ๊ฒƒ ๊ฐ™์•„์š”!

* target : members
* question : QuestionSet
* candidate : member.candidate()
*
* - make friend logic, get Candidate logic
*
* ToDo ์•„๋ž˜๋Š” ์ถ”ํ›„ ์บ์‹œ์— ๋„ฃ๋Š” ์ž‘์—…์„ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
* - cache put -> QuestionSet and return
* - Temporarily set to create for all members, discuss details later
*/
return LIST_SAMPLE_QUESTION_SHEET

val questionIds = questionSet.questionIds.map { questionOrder -> questionOrder.questionId.value }
val friendQuestionIds = questionRepository.findFriendQuestionsByIds(questionIds)
val accompanyQuestionIds = questionRepository.findAccompanyQuestionsByIds(questionIds)

val friendQuestionSheetEntities =
friendQuestionIds.map { friendQuestionId ->
QuestionSheet.create(
questionSetId = questionSet.id,
questionId = QuestionId(friendQuestionId),
resolverId = resolver,
candidates = candidatesOfFriend
).toEntity()
}

val accompanyQuestionSheetEntities =
accompanyQuestionIds.map { friendQuestionId ->
QuestionSheet.create(
questionSetId = questionSet.id,
questionId = QuestionId(friendQuestionId),
resolverId = resolver,
candidates = candidatesOfAccompany
).toEntity()
}

val questionSheetEntities = friendQuestionSheetEntities + accompanyQuestionSheetEntities
return questionSheetRepository.saveAll(questionSheetEntities).map { it.toQuestionSheetWithCandidatesId() }
}

override fun getQuestionById(id: QuestionId): Question? {
Expand Down Expand Up @@ -379,6 +410,16 @@ private fun QuestionSetEntity.toQuestionSet(): QuestionSet {
)
}

private fun QuestionSheet.toEntity(): QuestionSheetEntity {
return QuestionSheetEntity(
id = questionSheetId.value,
questionSetId = questionSetId.value,
questionId = questionId.value,
resolverId = resolverId.value,
candidates = candidates.map { it.value }.toList()
)
}

private fun QuestionSheetEntity.toQuestionSheetWithCandidatesId(): QuestionSheet {
return QuestionSheet(
questionSheetId = QuestionSheetId(id),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.mashup.dojo.domain.QuestionSheet
import com.mashup.dojo.domain.QuestionSheetId
import com.mashup.dojo.domain.QuestionType
import com.mashup.dojo.service.ImageService
import com.mashup.dojo.service.MemberRelationService
import com.mashup.dojo.service.MemberService
import com.mashup.dojo.service.PickService
import com.mashup.dojo.service.QuestionService
Expand Down Expand Up @@ -85,6 +86,7 @@ class DefaultQuestionUseCase(
private val memberService: MemberService,
private val pickService: PickService,
private val imageService: ImageService,
private val memberRelationService: MemberRelationService,
) : QuestionUseCase {
@Transactional
override fun create(command: QuestionUseCase.CreateCommand): QuestionId {
Expand Down Expand Up @@ -120,7 +122,18 @@ 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.

๋„ต ๋ง์”€ํ•˜์‹  ๊ฒƒ์ฒ˜๋Ÿผ ์–ด๋””์„œ ๋ฐฉ์–ดํ•ด์•ผํ• ์ง€ ์ •ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
๊ฐœ์ธ์ ์œผ๋กœ ๋‹ค๋ฅธ ์•ฑ๋“ค ์‚ฌ์šฉํ•ด๋ดค์„๋•Œ์ฒ˜๋Ÿผ ์ตœ์†Œ ์นœ๊ตฌ๋ฅผ ๋“ฑ๋กํ•œ ํ›„ ํšŒ์›๊ฐ€์ž…์ด ๊ฐ€๋Šฅํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์ €ํฌ๋„ ๋น„์Šทํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜๋ฉด ๋‹จ์ˆœํ•˜๊ณ  ๋” ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค~


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.

์šฐ์„  ํ† ์š”์ผ์— ๋งํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ฐฐ์น˜์„ฑ์ด๋‹ˆ๊นŒ ๋จผ์ € ํ•ด๋ณด๊ณ  ๋ฌธ์ œ ์žˆ๋‹ค๋ฉด ๊ทธ๋–„ ๊ฐ€์„œ ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ๋„ ๊ดœ์ฐฎ์•„ ๋ณด์ž…๋‹ˆ๋‹ค.

questionSet = currentQuestionSet,
candidatesOfFriend = candidateOfFriend,
candidatesOfAccompany = candidateOfAccompany,
resolver = member.id
)
}
}

override fun getQuestionSheetList(memberId: MemberId): QuestionUseCase.GetQuestionSheetsResult {
Expand Down
Loading