Compare commits
4 Commits
1a1f67cc1a
...
1649d0b36e
| Author | SHA1 | Date | |
|---|---|---|---|
| 1649d0b36e | |||
| 8c82acacef | |||
| c506f9c92b | |||
| 86c1be1d67 |
@@ -270,13 +270,15 @@ class HomeRecommendationFacade(
|
||||
creatorProfileImage = imageUrl(cloudFrontHost, creatorProfileImage),
|
||||
title = title,
|
||||
coverImage = imageUrl(cloudFrontHost, coverImage),
|
||||
releaseDate = releaseDate.toUtcIso()
|
||||
releaseDate = releaseDate.toUtcIso(),
|
||||
isPointAvailable = isPointAvailable
|
||||
)
|
||||
|
||||
private fun HomeAiCharacterRecommendationRecord.toItem() = HomeAiCharacterItem(
|
||||
characterId = characterId,
|
||||
name = name,
|
||||
description = description,
|
||||
profileImage = imageUrl(cloudFrontHost, profileImage),
|
||||
totalChatCount = totalChatCount,
|
||||
originalWorkTitle = originalWorkTitle
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package kr.co.vividnext.sodalive.v2.api.home.dto
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneOffset
|
||||
|
||||
@@ -66,13 +67,16 @@ data class HomeFirstAudioContentItem(
|
||||
val creatorProfileImage: String?,
|
||||
val title: String,
|
||||
val coverImage: String?,
|
||||
val releaseDate: String
|
||||
val releaseDate: String,
|
||||
@JsonProperty("isPointAvailable")
|
||||
val isPointAvailable: Boolean
|
||||
)
|
||||
|
||||
data class HomeAiCharacterItem(
|
||||
val characterId: Long,
|
||||
val name: String,
|
||||
val description: String,
|
||||
val profileImage: String?,
|
||||
val totalChatCount: Long,
|
||||
val originalWorkTitle: String?
|
||||
)
|
||||
|
||||
@@ -395,6 +395,7 @@ class DefaultHomeRecommendationQueryRepository(
|
||||
ac.cover_image as cover_image,
|
||||
ac.release_date as release_date,
|
||||
ac.is_active as is_active,
|
||||
ac.is_point_available as is_point_available,
|
||||
row_number() over (
|
||||
partition by ac.member_id
|
||||
order by ac.created_at asc, ac.release_date asc, ac.id asc
|
||||
@@ -421,6 +422,7 @@ class DefaultHomeRecommendationQueryRepository(
|
||||
ec.title as title,
|
||||
ec.cover_image as cover_image,
|
||||
ec.release_date as release_date,
|
||||
ec.is_point_available as is_point_available,
|
||||
case
|
||||
when ec.release_date >= :recency3Start then 100
|
||||
when ec.release_date >= :recency7Start then 80
|
||||
@@ -471,8 +473,9 @@ class DefaultHomeRecommendationQueryRepository(
|
||||
title = row[4] as String,
|
||||
coverImage = row[5] as String?,
|
||||
releaseDate = toLocalDateTime(row[6]),
|
||||
recencyScore = (row[7] as Number).toInt(),
|
||||
randomTieBreaker = (row[8] as Number).toDouble()
|
||||
isPointAvailable = row[7] as Boolean,
|
||||
recencyScore = (row[8] as Number).toInt(),
|
||||
randomTieBreaker = (row[9] as Number).toDouble()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -708,6 +711,7 @@ class DefaultHomeRecommendationQueryRepository(
|
||||
chatCharacter.id,
|
||||
chatCharacter.name,
|
||||
chatCharacter.description,
|
||||
chatCharacter.imagePath,
|
||||
chatMessage.id.count(),
|
||||
linkedOriginalWork.title
|
||||
)
|
||||
@@ -724,7 +728,13 @@ class DefaultHomeRecommendationQueryRepository(
|
||||
chatMessage.isActive.isTrue
|
||||
)
|
||||
.where(chatCharacter.isActive.isTrue, chatCharacter.id.`in`(characterIds))
|
||||
.groupBy(chatCharacter.id, chatCharacter.name, chatCharacter.description, linkedOriginalWork.title)
|
||||
.groupBy(
|
||||
chatCharacter.id,
|
||||
chatCharacter.name,
|
||||
chatCharacter.description,
|
||||
chatCharacter.imagePath,
|
||||
linkedOriginalWork.title
|
||||
)
|
||||
.fetch()
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ data class HomeFirstAudioContentRecord(
|
||||
val title: String,
|
||||
val coverImage: String?,
|
||||
val releaseDate: LocalDateTime,
|
||||
val isPointAvailable: Boolean,
|
||||
val recencyScore: Int,
|
||||
val randomTieBreaker: Double
|
||||
)
|
||||
@@ -134,6 +135,7 @@ data class HomeAiCharacterRecommendationRecord(
|
||||
val characterId: Long,
|
||||
val name: String,
|
||||
val description: String,
|
||||
val profileImage: String?,
|
||||
val totalChatCount: Long,
|
||||
val originalWorkTitle: String?
|
||||
)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package kr.co.vividnext.sodalive.v2.api.home.dto
|
||||
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class HomeRecommendationResponseTest {
|
||||
private val objectMapper = jacksonObjectMapper()
|
||||
|
||||
@Test
|
||||
fun shouldSerializeNewHomeRecommendationFields() {
|
||||
val response = HomeRecommendationResponse(
|
||||
lives = emptyList(),
|
||||
banners = emptyList(),
|
||||
recentlyActiveCreators = emptyList(),
|
||||
recentDebutCreators = emptyList(),
|
||||
firstAudioContents = listOf(
|
||||
HomeFirstAudioContentItem(
|
||||
contentId = 1L,
|
||||
creatorId = 2L,
|
||||
creatorNickname = "creator",
|
||||
creatorProfileImage = "https://cdn.test/profile/creator.png",
|
||||
title = "first audio",
|
||||
coverImage = "https://cdn.test/cover/audio.png",
|
||||
releaseDate = "2026-06-01T00:00:00Z",
|
||||
isPointAvailable = true
|
||||
)
|
||||
),
|
||||
aiCharacters = listOf(
|
||||
HomeAiCharacterItem(
|
||||
characterId = 3L,
|
||||
name = "character",
|
||||
description = "description",
|
||||
profileImage = "https://cdn.test/profile/character.png",
|
||||
totalChatCount = 4L,
|
||||
originalWorkTitle = "original"
|
||||
)
|
||||
),
|
||||
genreCreators = emptyList(),
|
||||
cheerCreators = emptyList(),
|
||||
popularCommunities = emptyList()
|
||||
)
|
||||
|
||||
val json = objectMapper.readTree(objectMapper.writeValueAsString(response))
|
||||
|
||||
assertEquals(true, json["firstAudioContents"][0]["isPointAvailable"].asBoolean())
|
||||
assertFalse(json["firstAudioContents"][0].has("pointAvailable"))
|
||||
assertEquals("https://cdn.test/profile/character.png", json["aiCharacters"][0]["profileImage"].asText())
|
||||
}
|
||||
}
|
||||
@@ -154,6 +154,7 @@ class HomeRecommendationQueryServiceTest {
|
||||
characterId = 1L,
|
||||
name = "character-1",
|
||||
description = "description-1",
|
||||
profileImage = "profile/character-1.png",
|
||||
totalChatCount = 3L,
|
||||
originalWorkTitle = "original-work"
|
||||
),
|
||||
@@ -161,6 +162,7 @@ class HomeRecommendationQueryServiceTest {
|
||||
characterId = 2L,
|
||||
name = "character-2",
|
||||
description = "description-2",
|
||||
profileImage = null,
|
||||
totalChatCount = 0L,
|
||||
originalWorkTitle = null
|
||||
)
|
||||
@@ -170,6 +172,8 @@ class HomeRecommendationQueryServiceTest {
|
||||
|
||||
assertEquals((1L..10L).toList(), port.aiCharacterDetailIds)
|
||||
assertEquals(listOf(1L, 2L), characters.map { it.characterId })
|
||||
assertEquals("profile/character-1.png", characters.first().profileImage)
|
||||
assertEquals(null, characters.last().profileImage)
|
||||
assertEquals("original-work", characters.first().originalWorkTitle)
|
||||
assertEquals(null, characters.last().originalWorkTitle)
|
||||
}
|
||||
@@ -488,6 +492,7 @@ class HomeRecommendationQueryServiceTest {
|
||||
title = "first-audio",
|
||||
coverImage = "first-audio.png",
|
||||
releaseDate = LocalDateTime.of(2026, 5, 30, 10, 0),
|
||||
isPointAvailable = true,
|
||||
recencyScore = 100,
|
||||
randomTieBreaker = 0.3
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user