Compare commits

...

4 Commits

7 changed files with 33 additions and 8 deletions

View File

@@ -269,6 +269,7 @@ class HomeRecommendationFacade(
creatorNickname = creatorNickname, creatorNickname = creatorNickname,
creatorProfileImage = imageUrl(cloudFrontHost, creatorProfileImage), creatorProfileImage = imageUrl(cloudFrontHost, creatorProfileImage),
title = title, title = title,
price = price,
coverImage = imageUrl(cloudFrontHost, coverImage), coverImage = imageUrl(cloudFrontHost, coverImage),
releaseDate = releaseDate.toUtcIso(), releaseDate = releaseDate.toUtcIso(),
isPointAvailable = isPointAvailable isPointAvailable = isPointAvailable
@@ -309,6 +310,7 @@ class HomeRecommendationFacade(
imageUrl = imageUrl(cloudFrontHost, imagePath), imageUrl = imageUrl(cloudFrontHost, imagePath),
audioUrl = imageUrl(cloudFrontHost, audioPath), audioUrl = imageUrl(cloudFrontHost, audioPath),
content = content, content = content,
price = price,
createdAt = createdAt.toUtcIso(), createdAt = createdAt.toUtcIso(),
likeCount = likeCount, likeCount = likeCount,
commentCount = commentCount, commentCount = commentCount,

View File

@@ -66,6 +66,7 @@ data class HomeFirstAudioContentItem(
val creatorNickname: String, val creatorNickname: String,
val creatorProfileImage: String?, val creatorProfileImage: String?,
val title: String, val title: String,
val price: Int,
val coverImage: String?, val coverImage: String?,
val releaseDate: String, val releaseDate: String,
@JsonProperty("isPointAvailable") @JsonProperty("isPointAvailable")
@@ -95,6 +96,7 @@ data class HomePopularCommunityPostItem(
val imageUrl: String?, val imageUrl: String?,
val audioUrl: String?, val audioUrl: String?,
val content: String, val content: String,
val price: Int,
val createdAt: String, val createdAt: String,
val likeCount: Long, val likeCount: Long,
val commentCount: Long, val commentCount: Long,

View File

@@ -394,6 +394,7 @@ class DefaultHomeRecommendationQueryRepository(
select ac.id as content_id, select ac.id as content_id,
ac.member_id as creator_id, ac.member_id as creator_id,
ac.title as title, ac.title as title,
ac.price as price,
ac.cover_image as cover_image, ac.cover_image as cover_image,
ac.release_date as release_date, ac.release_date as release_date,
ac.is_active as is_active, ac.is_active as is_active,
@@ -422,6 +423,7 @@ class DefaultHomeRecommendationQueryRepository(
m.nickname as creator_nickname, m.nickname as creator_nickname,
m.profile_image as creator_profile_image, m.profile_image as creator_profile_image,
ec.title as title, ec.title as title,
ec.price as price,
ec.cover_image as cover_image, ec.cover_image as cover_image,
ec.release_date as release_date, ec.release_date as release_date,
ec.is_point_available as is_point_available, ec.is_point_available as is_point_available,
@@ -473,11 +475,12 @@ class DefaultHomeRecommendationQueryRepository(
creatorNickname = row[2] as String, creatorNickname = row[2] as String,
creatorProfileImage = row[3] as String?, creatorProfileImage = row[3] as String?,
title = row[4] as String, title = row[4] as String,
coverImage = row[5] as String?, price = (row[5] as Number).toInt(),
releaseDate = toLocalDateTime(row[6]), coverImage = row[6] as String?,
isPointAvailable = row[7] as Boolean, releaseDate = toLocalDateTime(row[7]),
recencyScore = (row[8] as Number).toInt(), isPointAvailable = row[8] as Boolean,
randomTieBreaker = (row[9] as Number).toDouble() recencyScore = (row[9] as Number).toInt(),
randomTieBreaker = (row[10] as Number).toDouble()
) )
} }
} }
@@ -778,6 +781,7 @@ class DefaultHomeRecommendationQueryRepository(
creatorCommunity.imagePath, creatorCommunity.imagePath,
creatorCommunity.audioPath, creatorCommunity.audioPath,
creatorCommunity.content, creatorCommunity.content,
creatorCommunity.price,
creatorCommunity.createdAt, creatorCommunity.createdAt,
creatorCommunityLike.id.countDistinct(), creatorCommunityLike.id.countDistinct(),
creatorCommunityComment.id.countDistinct(), creatorCommunityComment.id.countDistinct(),
@@ -810,6 +814,7 @@ class DefaultHomeRecommendationQueryRepository(
creatorCommunity.imagePath, creatorCommunity.imagePath,
creatorCommunity.audioPath, creatorCommunity.audioPath,
creatorCommunity.content, creatorCommunity.content,
creatorCommunity.price,
creatorCommunity.createdAt creatorCommunity.createdAt
) )
.fetch() .fetch()

View File

@@ -124,6 +124,7 @@ data class HomeFirstAudioContentRecord(
val creatorNickname: String, val creatorNickname: String,
val creatorProfileImage: String?, val creatorProfileImage: String?,
val title: String, val title: String,
val price: Int,
val coverImage: String?, val coverImage: String?,
val releaseDate: LocalDateTime, val releaseDate: LocalDateTime,
val isPointAvailable: Boolean, val isPointAvailable: Boolean,
@@ -154,6 +155,7 @@ data class HomePopularCommunityRecommendationRecord(
val imagePath: String?, val imagePath: String?,
val audioPath: String?, val audioPath: String?,
val content: String, val content: String,
val price: Int,
val createdAt: LocalDateTime, val createdAt: LocalDateTime,
val likeCount: Long, val likeCount: Long,
val commentCount: Long, val commentCount: Long,

View File

@@ -22,6 +22,7 @@ class HomeRecommendationResponseTest {
creatorNickname = "creator", creatorNickname = "creator",
creatorProfileImage = "https://cdn.test/profile/creator.png", creatorProfileImage = "https://cdn.test/profile/creator.png",
title = "first audio", title = "first audio",
price = 9,
coverImage = "https://cdn.test/cover/audio.png", coverImage = "https://cdn.test/cover/audio.png",
releaseDate = "2026-06-01T00:00:00Z", releaseDate = "2026-06-01T00:00:00Z",
isPointAvailable = true isPointAvailable = true
@@ -48,6 +49,7 @@ class HomeRecommendationResponseTest {
imageUrl = "https://cdn.test/community/image.png", imageUrl = "https://cdn.test/community/image.png",
audioUrl = "https://cdn.test/community/audio.mp3", audioUrl = "https://cdn.test/community/audio.mp3",
content = "community content", content = "community content",
price = 9,
createdAt = "2026-06-01T00:00:00Z", createdAt = "2026-06-01T00:00:00Z",
likeCount = 7L, likeCount = 7L,
commentCount = 8L, commentCount = 8L,
@@ -58,12 +60,14 @@ class HomeRecommendationResponseTest {
val json = objectMapper.readTree(objectMapper.writeValueAsString(response)) val json = objectMapper.readTree(objectMapper.writeValueAsString(response))
assertEquals(9, json["firstAudioContents"][0]["price"].asInt())
assertEquals(true, json["firstAudioContents"][0]["isPointAvailable"].asBoolean()) assertEquals(true, json["firstAudioContents"][0]["isPointAvailable"].asBoolean())
assertFalse(json["firstAudioContents"][0].has("pointAvailable")) assertFalse(json["firstAudioContents"][0].has("pointAvailable"))
assertEquals("https://cdn.test/profile/character.png", json["aiCharacters"][0]["profileImage"].asText()) assertEquals("https://cdn.test/profile/character.png", json["aiCharacters"][0]["profileImage"].asText())
assertEquals(5L, json["popularCommunityPosts"][0]["postId"].asLong()) assertEquals(5L, json["popularCommunityPosts"][0]["postId"].asLong())
assertEquals("https://cdn.test/community/image.png", json["popularCommunityPosts"][0]["imageUrl"].asText()) assertEquals("https://cdn.test/community/image.png", json["popularCommunityPosts"][0]["imageUrl"].asText())
assertEquals("https://cdn.test/community/audio.mp3", json["popularCommunityPosts"][0]["audioUrl"].asText()) assertEquals("https://cdn.test/community/audio.mp3", json["popularCommunityPosts"][0]["audioUrl"].asText())
assertEquals(9, json["popularCommunityPosts"][0]["price"].asInt())
assertEquals(true, json["popularCommunityPosts"][0]["existOrdered"].asBoolean()) assertEquals(true, json["popularCommunityPosts"][0]["existOrdered"].asBoolean())
} }
} }

View File

@@ -1042,7 +1042,7 @@ class DefaultHomeRecommendationQueryRepositoryTest @Autowired constructor(
val excludedCreator = saveMember("first-audio-excluded", MemberRole.CREATOR) val excludedCreator = saveMember("first-audio-excluded", MemberRole.CREATOR)
val eligibleInactive1 = saveAudioContent(eligibleCreator, now.minusDays(10), isActive = false) val eligibleInactive1 = saveAudioContent(eligibleCreator, now.minusDays(10), isActive = false)
val eligibleInactive2 = saveAudioContent(eligibleCreator, now.minusDays(9), isActive = false) val eligibleInactive2 = saveAudioContent(eligibleCreator, now.minusDays(9), isActive = false)
val eligibleActive = saveAudioContent(eligibleCreator, now.minusDays(2), isActive = true) val eligibleActive = saveAudioContent(eligibleCreator, now.minusDays(2), isActive = true, price = 12)
val excludedInactive1 = saveAudioContent(excludedCreator, now.minusDays(10), isActive = false) val excludedInactive1 = saveAudioContent(excludedCreator, now.minusDays(10), isActive = false)
val excludedInactive2 = saveAudioContent(excludedCreator, now.minusDays(9), isActive = false) val excludedInactive2 = saveAudioContent(excludedCreator, now.minusDays(9), isActive = false)
val excludedInactive3 = saveAudioContent(excludedCreator, now.minusDays(8), isActive = false) val excludedInactive3 = saveAudioContent(excludedCreator, now.minusDays(8), isActive = false)
@@ -1062,6 +1062,7 @@ class DefaultHomeRecommendationQueryRepositoryTest @Autowired constructor(
assertEquals(listOf(eligibleActive.id), contents.map { it.contentId }) assertEquals(listOf(eligibleActive.id), contents.map { it.contentId })
assertEquals(100, contents.single().recencyScore) assertEquals(100, contents.single().recencyScore)
assertEquals(12, contents.single().price)
} }
@Test @Test
@@ -1268,6 +1269,8 @@ class DefaultHomeRecommendationQueryRepositoryTest @Autowired constructor(
assertEquals("content", detailById[eligible.id]!!.content) assertEquals("content", detailById[eligible.id]!!.content)
assertEquals("community/detail-image.png", detailById[eligible.id]!!.imagePath) assertEquals("community/detail-image.png", detailById[eligible.id]!!.imagePath)
assertEquals("community/detail-audio.mp3", detailById[eligible.id]!!.audioPath) assertEquals("community/detail-audio.mp3", detailById[eligible.id]!!.audioPath)
assertEquals(0, detailById[eligible.id]!!.price)
assertEquals(10, detailById[paid.id]!!.price)
assertEquals(LocalDateTime.of(2026, 5, 29, 1, 0), detailById[eligible.id]!!.createdAt) assertEquals(LocalDateTime.of(2026, 5, 29, 1, 0), detailById[eligible.id]!!.createdAt)
assertEquals(2L, detailById[eligible.id]!!.likeCount) assertEquals(2L, detailById[eligible.id]!!.likeCount)
assertEquals(1L, detailById[eligible.id]!!.commentCount) assertEquals(1L, detailById[eligible.id]!!.commentCount)
@@ -1717,14 +1720,16 @@ class DefaultHomeRecommendationQueryRepositoryTest @Autowired constructor(
isActive: Boolean, isActive: Boolean,
themeName: String = "theme-${creator.nickname}-$releaseDate", themeName: String = "theme-${creator.nickname}-$releaseDate",
theme: AudioContentTheme = saveTheme(themeName), theme: AudioContentTheme = saveTheme(themeName),
isAdult: Boolean = false isAdult: Boolean = false,
price: Int = 0
): AudioContent { ): AudioContent {
val content = AudioContent( val content = AudioContent(
title = "content-${creator.nickname}-$releaseDate", title = "content-${creator.nickname}-$releaseDate",
detail = "detail", detail = "detail",
languageCode = "ko", languageCode = "ko",
releaseDate = releaseDate, releaseDate = releaseDate,
isAdult = isAdult isAdult = isAdult,
price = price
) )
content.member = creator content.member = creator
content.theme = theme content.theme = theme

View File

@@ -230,6 +230,7 @@ class HomeRecommendationQueryServiceTest {
imagePath = "community-1.png", imagePath = "community-1.png",
audioPath = "community-1.mp3", audioPath = "community-1.mp3",
content = "content-1", content = "content-1",
price = 10,
createdAt = LocalDateTime.of(2026, 5, 29, 1, 0), createdAt = LocalDateTime.of(2026, 5, 29, 1, 0),
likeCount = 3L, likeCount = 3L,
commentCount = 2L, commentCount = 2L,
@@ -243,6 +244,7 @@ class HomeRecommendationQueryServiceTest {
imagePath = null, imagePath = null,
audioPath = null, audioPath = null,
content = "content-2", content = "content-2",
price = 0,
createdAt = LocalDateTime.of(2026, 5, 29, 2, 0), createdAt = LocalDateTime.of(2026, 5, 29, 2, 0),
likeCount = 1L, likeCount = 1L,
commentCount = 1L, commentCount = 1L,
@@ -256,6 +258,7 @@ class HomeRecommendationQueryServiceTest {
imagePath = null, imagePath = null,
audioPath = null, audioPath = null,
content = "content-3", content = "content-3",
price = 0,
createdAt = LocalDateTime.of(2026, 5, 29, 3, 0), createdAt = LocalDateTime.of(2026, 5, 29, 3, 0),
likeCount = 0L, likeCount = 0L,
commentCount = 0L, commentCount = 0L,
@@ -296,6 +299,7 @@ class HomeRecommendationQueryServiceTest {
imagePath = null, imagePath = null,
audioPath = null, audioPath = null,
content = "content-$communityId", content = "content-$communityId",
price = 0,
createdAt = LocalDateTime.of(2026, 5, 29, 1, 0).plusMinutes(communityId), createdAt = LocalDateTime.of(2026, 5, 29, 1, 0).plusMinutes(communityId),
likeCount = 0L, likeCount = 0L,
commentCount = 0L, commentCount = 0L,
@@ -505,6 +509,7 @@ class HomeRecommendationQueryServiceTest {
creatorNickname = "debut-creator", creatorNickname = "debut-creator",
creatorProfileImage = "debut-profile.png", creatorProfileImage = "debut-profile.png",
title = "first-audio", title = "first-audio",
price = 10,
coverImage = "first-audio.png", coverImage = "first-audio.png",
releaseDate = LocalDateTime.of(2026, 5, 30, 10, 0), releaseDate = LocalDateTime.of(2026, 5, 30, 10, 0),
isPointAvailable = true, isPointAvailable = true,