feat(aicharacter): 크리에이터 회원 연결을 추가한다

This commit is contained in:
2026-06-12 10:56:55 +09:00
parent 72e6efe3e6
commit 74414937cf
6 changed files with 301 additions and 2 deletions

View File

@@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.chat.character
import kr.co.vividnext.sodalive.chat.original.OriginalWork
import kr.co.vividnext.sodalive.common.BaseEntity
import kr.co.vividnext.sodalive.member.Member
import javax.persistence.CascadeType
import javax.persistence.Column
import javax.persistence.Entity
@@ -11,6 +12,7 @@ import javax.persistence.FetchType
import javax.persistence.JoinColumn
import javax.persistence.ManyToOne
import javax.persistence.OneToMany
import javax.persistence.OneToOne
@Entity
class ChatCharacter(
@@ -75,6 +77,10 @@ class ChatCharacter(
) : BaseEntity() {
var imagePath: String? = null
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "creator_member_id", nullable = false, unique = true)
var creatorMember: Member? = null
@OneToMany(mappedBy = "chatCharacter", cascade = [CascadeType.ALL], fetch = FetchType.LAZY, orphanRemoval = true)
var memories: MutableList<ChatCharacterMemory> = mutableListOf()

View File

@@ -99,4 +99,6 @@ interface ChatCharacterRepository : JpaRepository<ChatCharacter, Long> {
fun findRandomActiveExcluding(@Param("excludeIds") excludeIds: List<Long>, pageable: Pageable): List<ChatCharacter>
fun findByIdInAndIsActiveTrue(ids: List<Long>): List<ChatCharacter>
fun findByCreatorMemberId(creatorMemberId: Long): ChatCharacter?
fun existsByCreatorMemberId(creatorMemberId: Long): Boolean
}

View File

@@ -0,0 +1,57 @@
package kr.co.vividnext.sodalive.chat.character.service
import kr.co.vividnext.sodalive.chat.character.ChatCharacter
import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.MemberKind
import kr.co.vividnext.sodalive.member.MemberRepository
import kr.co.vividnext.sodalive.member.MemberRole
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
@Service
class ChatCharacterCreatorMemberService(
private val memberRepository: MemberRepository
) {
@Transactional
fun ensureAiCharacterCreatorMember(chatCharacter: ChatCharacter): Member {
val creatorMember = chatCharacter.creatorMember
if (creatorMember != null) {
if (creatorMember.memberKind == MemberKind.AI_CHARACTER) {
syncDisplayFields(creatorMember, chatCharacter)
memberRepository.save(creatorMember)
}
return creatorMember
}
val member = Member(
email = null,
password = "",
nickname = chatCharacter.name,
profileImage = chatCharacter.imagePath,
role = MemberRole.CREATOR,
memberKind = MemberKind.AI_CHARACTER
)
member.introduce = chatCharacter.description
val savedMember = memberRepository.save(member)
chatCharacter.creatorMember = savedMember
return savedMember
}
@Transactional
fun syncAiCharacterCreatorMemberDisplayFields(chatCharacter: ChatCharacter) {
val creatorMember = chatCharacter.creatorMember
?: throw SodaException(messageKey = "common.error.invalid_request")
if (creatorMember.memberKind != MemberKind.AI_CHARACTER) return
syncDisplayFields(creatorMember, chatCharacter)
memberRepository.save(creatorMember)
}
private fun syncDisplayFields(member: Member, chatCharacter: ChatCharacter) {
member.nickname = chatCharacter.name
member.profileImage = chatCharacter.imagePath
member.introduce = chatCharacter.description
}
}

View File

@@ -36,6 +36,7 @@ class ChatCharacterService(
private val goalRepository: ChatCharacterGoalRepository,
private val popularCharacterQuery: PopularCharacterQuery,
private val imageRepository: CharacterImageRepository,
private val creatorMemberService: ChatCharacterCreatorMemberService,
@Value("\${cloud.aws.cloud-front.host}")
private val imageHost: String
@@ -616,6 +617,7 @@ class ChatCharacterService(
addHobbiesToCharacter(chatCharacter, hobbies)
addGoalsToCharacter(chatCharacter, goals)
creatorMemberService.ensureAiCharacterCreatorMember(chatCharacter)
return saveChatCharacter(chatCharacter)
}
@@ -721,7 +723,9 @@ class ChatCharacterService(
val randomSuffix = "_" + java.util.UUID.randomUUID().toString().replace("-", "")
chatCharacter.name = inactiveName + randomSuffix
return saveChatCharacter(chatCharacter)
val savedChatCharacter = saveChatCharacter(chatCharacter)
creatorMemberService.syncAiCharacterCreatorMemberDisplayFields(savedChatCharacter)
return savedChatCharacter
}
// 이미지 경로가 있으면 설정
@@ -779,6 +783,8 @@ class ChatCharacterService(
updateRelationshipsForCharacter(chatCharacter, request.relationships)
}
return saveChatCharacter(chatCharacter)
val savedChatCharacter = saveChatCharacter(chatCharacter)
creatorMemberService.syncAiCharacterCreatorMemberDisplayFields(savedChatCharacter)
return savedChatCharacter
}
}