Skip to content

Commit

Permalink
[๐ŸŒŽ Refactor] Goal ์ด๋ชจ์ง€ ๋ฐ˜์‘ํ•˜๊ธฐ API ์ •์ • (#193)
Browse files Browse the repository at this point in the history
* refactor : reactedEmojis๋ฅผ json ๋ฐฐ์—ด์˜ ํ˜•ํƒœ๋กœ ์‘๋‹ต (#192)

* refactor : ReactedEmojisResponse ๋ณ€์ˆ˜๋ช… ์ •๋ฆฌ (#192)

* refactor : ReactUser ์‘๋‹ต์— id๊ฐ€ ์•„๋‹Œ username์„ ์‘๋‹ตํ•ด ์ฃผ๋„๋ก ๋ณ€๊ฒฝ  (#192)

* refactor : ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„์„ ์ปจ๋ฒค์…˜์— ๋งž๊ฒŒ of๋กœ ๋ณ€๊ฒฝ (#192)

* refactor : ReactUser๋ฅผ ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋งŒ๋“ค๋„๋ก ๋ณ€๊ฒฝ (#192)

* feat : Reaction์ด ์š”์ฒญ์„ ๋ณด๋‚ธ ๋ณธ์ธ ๊ฒƒ์ธ์ง€ ํ™•์ธํ•˜๋Š” ํ•„๋“œ isMyReaction ์ถ”๊ฐ€ (#192)

* feat : ๊ฐ€์žฅ ์ตœ๊ทผ์— ๋ฐ˜์‘ํ•œ ์œ ์ €์˜ nickname์„ ์‘๋‹ต์— ํฌํ•จ (#192)

* refactor : ReactedEmojis ์กฐํšŒ์‹œ "๋‚ด๊ฐ€ ๋ˆ„๋ฅธ ์ด๋ชจ์ง€" ํ™•์ธ์„ ์œ„ํ•œ ๋กœ๊ทธ์ธํ•œ user์˜ username ์ „๋‹ฌ (#192)

* ktlint formatting (#192)

* test : ์ฝ”๋“œ ๋ณ€๊ฒฝ์— ๋”ฐ๋ผ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ๋ณ€๊ฒฝ (#192)

* refactor : ๋ถˆํ•„์š”ํ•œ ์ฝ”ํ‹€๋ฆฐ ์ŠคํŠธ๋ฆผ ์ œ๊ฑฐ (#192)

* refactor : ReactUser๋ฅผ Set์ด ์•„๋‹Œ List๋กœ ๊ด€๋ฆฌ (#192)

* refactor : ๋ถˆํ•„์š”ํ•œ ๋ฌธ๋ฒ• ์ œ๊ฑฐ (#192)
  • Loading branch information
binary-ho authored Feb 27, 2024
1 parent fc4e067 commit 47d6ea2
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ class EmojiService(
.map(EmojiResponse::from)

@Transactional(readOnly = true)
fun findAllReactedEmojisByGoalId(goalId: Long): ReactedEmojisResponse {
fun findAllReactedEmojisByGoalId(goalId: Long, currentUserUsername: String): ReactedEmojisResponse {
val goal = goalRepository.getReferenceById(goalId)
val reactedEmojis = reactedEmojiRepository.findAllByGoal(goal)
return ReactedEmojisResponse.of(reactedEmojis)
return ReactedEmojisResponse.of(reactedEmojis, currentUserUsername)
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ class EmojiController(

@Operation(summary = "Goal์— ๋ฐ˜์‘๋œ ์ด๋ชจ์ง€์™€ ์œ ์ € ์ •๋ณด ์ „์ฒด ์กฐํšŒ API")
@GetMapping("/{goalId}")
fun findAllReactedEmojisAtGoal(@PathVariable goalId: Long): ResponseEntity<ApiResponse<ReactedEmojisResponse>> {
val response = emojiService.findAllReactedEmojisByGoalId(goalId)
fun findAllReactedEmojisAtGoal(
@PathVariable goalId: Long,
@AuthenticationPrincipal currentUser: CurrentUser,
): ResponseEntity<ApiResponse<ReactedEmojisResponse>> {
val response = emojiService.findAllReactedEmojisByGoalId(goalId, currentUser.username)
return ResponseEntity.ok(ApiResponse.success(response))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,61 +5,78 @@ import io.raemian.storage.db.core.user.User

data class ReactedEmojisResponse(
val totalReactedEmojisCount: Int,
val reactedEmojis: Map<Long, ReactedEmojiDTO>,
val latestReactUserNickname: String?,
val reactedEmojis: List<ReactedEmojiAndReactUsers>,
) {
companion object {
fun of(reactedEmojis: List<ReactedEmoji>): ReactedEmojisResponse {
val mapValues = reactedEmojis
.filter { it.emoji.id != null }
.groupBy { it.emoji.id!! }
.mapValues(ReactedEmojiDTO.Companion::from)
fun of(reactedEmojis: List<ReactedEmoji>, username: String): ReactedEmojisResponse {
val reactedEmojiAndReactUsers = convert(reactedEmojis, username)

val totalEmojisCount = mapValues.values.sumOf { it.count }
return ReactedEmojisResponse(totalEmojisCount, mapValues)
val totalEmojisCount = reactedEmojiAndReactUsers.sumOf { it.reactCount }
val latestReactUserNickname = reactedEmojis.lastOrNull()?.reactUser?.nickname
return ReactedEmojisResponse(
totalReactedEmojisCount = totalEmojisCount,
latestReactUserNickname = latestReactUserNickname,
reactedEmojis = reactedEmojiAndReactUsers,
)
}

private fun convert(
reactedEmojis: List<ReactedEmoji>,
username: String,
): List<ReactedEmojiAndReactUsers> =
reactedEmojis
.filter { it.emoji.id != null }
.groupBy { it.emoji.id }
.mapValues { entry -> ReactedEmojiAndReactUsers.of(entry.value, username) }
.values
.toList()
}

data class ReactedEmojiDTO(
data class ReactedEmojiAndReactUsers(
val id: Long?,
val name: String,
val url: String,
val count: Int,
val reactUsers: Set<ReactUserDTO>,
val reactCount: Int,
val isMyReaction: Boolean,
val reactUsers: List<ReactUser>,
) {
companion object {
fun from(reactedEmojis2: Map.Entry<Long, List<ReactedEmoji>>): ReactedEmojiDTO {
val reactedEmojis = reactedEmojis2.value
fun of(reactedEmojis: List<ReactedEmoji>, username: String): ReactedEmojiAndReactUsers {
val emoji = reactedEmojis.first().emoji
val reactUsers = getReactUsers(reactedEmojis)
val isMyReaction = reactUsers.any { it.username == username }

return ReactedEmojiDTO(
return ReactedEmojiAndReactUsers(
id = emoji.id,
name = emoji.name,
url = emoji.url,
count = reactUsers.size,
reactCount = reactUsers.size,
isMyReaction = isMyReaction,
reactUsers = reactUsers,
)
}

private fun getReactUsers(reactedEmojis: List<ReactedEmoji>) =
reactedEmojis.stream()
reactedEmojis
.map { it.reactUser }
.filter { it.username != null }
.filter { it.nickname != null }
.map(ReactedEmojisResponse::ReactUserDTO)
.toList()
.toSet()
.map(ReactUser::from)
}
}

data class ReactUserDTO(
val id: Long,
data class ReactUser(
val username: String,
val nickname: String,
val image: String,
) {
constructor(user: User) : this(
id = user.id!!,
nickname = user.nickname!!,
image = user.image,
)
companion object {
fun from(user: User) = ReactUser(
username = user.username!!,
nickname = user.nickname!!,
image = user.image,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class EmojiServiceTest {
reactedEmojiRepository.saveAll(listOf(reactedEmoji, reactedEmoji2, reactedEmoji3))

// when
val reactedEmojis = emojiService.findAllReactedEmojisByGoalId(GOAL_FIXTURE.id!!)
val reactedEmojis = emojiService.findAllReactedEmojisByGoalId(GOAL_FIXTURE.id!!, USER_FIXTURE.username!!)

// then
assertThat(reactedEmojis.totalReactedEmojisCount).isEqualTo(3)
Expand Down

0 comments on commit 47d6ea2

Please sign in to comment.