feat(creator-community): 게시물 언어 감지 파이프라인을 추가한다

This commit is contained in:
2026-09-10 15:12:16 +09:00
parent 0284070667
commit 1b19ade69e
2 changed files with 876 additions and 2 deletions
@@ -7,8 +7,11 @@ import kr.co.vividnext.sodalive.content.category.CategoryRepository
import kr.co.vividnext.sodalive.content.comment.AudioContentCommentRepository
import kr.co.vividnext.sodalive.content.series.ContentSeriesRepository
import kr.co.vividnext.sodalive.explorer.profile.CreatorCheersRepository
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunityRepository
import kr.co.vividnext.sodalive.i18n.translation.LanguageTranslationEvent
import kr.co.vividnext.sodalive.i18n.translation.LanguageTranslationTargetType
import kr.co.vividnext.sodalive.i18n.translation.PapagoTranslationService.Companion.getTranslatableLanguageCodes
import kr.co.vividnext.sodalive.v2.creator.channel.community.translation.application.CreatorCommunityTranslationService
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.ApplicationEventPublisher
@@ -22,8 +25,12 @@ import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional
import org.springframework.transaction.event.TransactionPhase
import org.springframework.transaction.event.TransactionalEventListener
import org.springframework.transaction.support.TransactionSynchronization
import org.springframework.transaction.support.TransactionSynchronizationManager
import org.springframework.util.LinkedMultiValueMap
import org.springframework.web.client.RestTemplate
import javax.persistence.EntityManager
import javax.persistence.LockModeType
/**
* 텍스트 기반 데이터(콘텐츠, 댓글 등)에 대해 파파고 언어 감지를 요청하기 위한 이벤트.
@@ -37,13 +44,16 @@ enum class LanguageDetectTargetType {
SERIES,
ORIGINAL_WORK,
CREATOR_CONTENT_CATEGORY
CREATOR_CONTENT_CATEGORY,
CREATOR_COMMUNITY
}
class LanguageDetectEvent(
val id: Long,
val query: String,
val targetType: LanguageDetectTargetType = LanguageDetectTargetType.CONTENT
val targetType: LanguageDetectTargetType = LanguageDetectTargetType.CONTENT,
val sourceRevision: Long? = null,
val targetLanguage: String? = null
)
data class PapagoLanguageDetectResponse(
@@ -60,7 +70,10 @@ class LanguageDetectListener(
private val seriesRepository: ContentSeriesRepository,
private val originalWorkRepository: OriginalWorkRepository,
private val categoryRepository: CategoryRepository,
private val creatorCommunityRepository: CreatorCommunityRepository,
private val languageDetectionCacheService: LanguageDetectionCacheService,
private val creatorCommunityTranslationService: CreatorCommunityTranslationService,
private val entityManager: EntityManager,
private val applicationEventPublisher: ApplicationEventPublisher,
@@ -95,6 +108,7 @@ class LanguageDetectListener(
LanguageDetectTargetType.SERIES -> handleSeriesLanguageDetect(event)
LanguageDetectTargetType.ORIGINAL_WORK -> handleOriginalWorkLanguageDetect(event)
LanguageDetectTargetType.CREATOR_CONTENT_CATEGORY -> handleCreatorContentCategoryLanguageDetect(event)
LanguageDetectTargetType.CREATOR_COMMUNITY -> handleCreatorCommunityLanguageDetect(event)
}
}
@@ -366,6 +380,53 @@ class LanguageDetectListener(
)
}
private fun handleCreatorCommunityLanguageDetect(event: LanguageDetectEvent) {
val sourceRevision = event.sourceRevision ?: return
val creatorCommunity = creatorCommunityRepository.findByIdAndIsActiveTrue(event.id) ?: return
if (
creatorCommunity.contentRevision != sourceRevision ||
creatorCommunity.content != event.query
) {
return
}
if (!creatorCommunity.languageCode.isNullOrBlank()) {
requestTranslationsAfterCommit(event)
return
}
val languageCode = detectLanguageCode(event, event.id) ?: return
if (languageCode !in getTranslatableLanguageCodes(null)) return
val currentCreatorCommunity = creatorCommunityRepository.findByIdAndIsActiveTrueForUpdate(event.id) ?: return
entityManager.refresh(currentCreatorCommunity, LockModeType.PESSIMISTIC_WRITE)
if (
currentCreatorCommunity.contentRevision != sourceRevision ||
currentCreatorCommunity.content != event.query
) {
return
}
if (!currentCreatorCommunity.languageCode.isNullOrBlank()) {
requestTranslationsAfterCommit(event)
return
}
currentCreatorCommunity.languageCode = languageCode
creatorCommunityRepository.save(currentCreatorCommunity)
requestTranslationsAfterCommit(event)
}
private fun requestTranslationsAfterCommit(event: LanguageDetectEvent) {
TransactionSynchronizationManager.registerSynchronization(
object : TransactionSynchronization {
override fun afterCommit() {
creatorCommunityTranslationService.requestTranslations(event.id, event.targetLanguage)
}
}
)
}
private fun detectLanguageCode(event: LanguageDetectEvent, targetIdForLog: Long): String? {
return languageDetectionCacheService.detectWithCache(event.query) {
requestPapagoLanguageCode(event.query, targetIdForLog)