feat(content-ranking): 랭킹 스냅샷 제목 번역을 적용한다

This commit is contained in:
2026-09-09 23:23:19 +09:00
parent e5230c0950
commit 50409e41c0
3 changed files with 247 additions and 17 deletions
@@ -1,5 +1,6 @@
package kr.co.vividnext.sodalive.v2.content.ranking.adapter.out.persistence
import kr.co.vividnext.sodalive.content.translation.ContentTranslationRepository
import kr.co.vividnext.sodalive.v2.content.ranking.domain.AudioRankingType
import kr.co.vividnext.sodalive.v2.content.ranking.port.out.AudioRankingSnapshotPort
import kr.co.vividnext.sodalive.v2.content.ranking.port.out.AudioRankingSnapshotRecord
@@ -9,25 +10,28 @@ import java.time.LocalDateTime
@Repository
class DefaultAudioRankingSnapshotPersistenceAdapter(
private val repository: AudioRankingSnapshotRepository
private val repository: AudioRankingSnapshotRepository,
private val contentTranslationRepository: ContentTranslationRepository
) : AudioRankingSnapshotPort {
override fun findLatestVisibleSnapshots(
rankingType: AudioRankingType,
nowUtc: LocalDateTime
nowUtc: LocalDateTime,
locale: String
): List<AudioRankingSnapshotRecord> {
return repository.findLatestVisibleSnapshots(rankingType.name, nowUtc).map { it.toRecord() }
return repository.findLatestVisibleSnapshots(rankingType.name, nowUtc).toRecords(locale)
}
override fun findPreviousVisibleSnapshots(
rankingType: AudioRankingType,
currentAggregationStartAtUtc: LocalDateTime,
nowUtc: LocalDateTime
nowUtc: LocalDateTime,
locale: String
): List<AudioRankingSnapshotRecord> {
return repository.findPreviousVisibleSnapshots(
rankingType = rankingType.name,
currentAggregationStartAtUtc = currentAggregationStartAtUtc,
nowUtc = nowUtc
).map { it.toRecord() }
).toRecords(locale)
}
@Transactional
@@ -46,14 +50,25 @@ class DefaultAudioRankingSnapshotPersistenceAdapter(
repository.saveAll(newSnapshots.map { it.toEntity(visibleFromAtUtc) })
}
private fun AudioRankingSnapshot.toRecord(): AudioRankingSnapshotRecord {
private fun List<AudioRankingSnapshot>.toRecords(locale: String): List<AudioRankingSnapshotRecord> {
if (isEmpty()) return emptyList()
val translatedTitleByContentId = contentTranslationRepository.findByContentIdInAndLocale(
map { it.contentId },
locale
).mapNotNull { translation ->
translation.renderedPayload.title.takeIf { it.isNotBlank() }?.let { translation.contentId to it }
}.toMap()
return map { snapshot -> snapshot.toRecord(translatedTitleByContentId[snapshot.contentId] ?: snapshot.title) }
}
private fun AudioRankingSnapshot.toRecord(displayTitle: String = title): AudioRankingSnapshotRecord {
return AudioRankingSnapshotRecord(
rankingType = rankingType,
aggregationStartAtUtc = aggregationStartAtUtc,
aggregationEndAtUtc = aggregationEndAtUtc,
visibleFromAtUtc = visibleFromAtUtc,
contentId = contentId,
title = title,
title = displayTitle,
creatorMemberId = creatorMemberId,
creatorNickname = creatorNickname,
coverImageUrl = coverImageUrl,