fix(admin-chat-character): JP 리전 캐릭터 등록 성별 값을 일본어로 변환한다 #401

Merged
klaus merged 1 commits from test into main 2026-03-16 02:37:52 +00:00
3 changed files with 100 additions and 1 deletions

View File

@@ -0,0 +1,23 @@
# 캐릭터 등록 JP 성별 일본어 변환
- [x] `AdminChatCharacterController.registerCharacter`의 외부 API 호출 경로 확인
- QA: `callExternalApi`에서 `region`/`gender` 바디 구성 위치 확인
- [x] `region == JP`일 때 `gender` 값을 일본어로 변환하는 로직 추가
- QA: `여성 -> 女性`, `남성 -> 男性`, `기타 -> その他` 매핑 확인
- [x] 등록 API 외부 호출 시에만 변환이 적용되도록 구현
- QA: DB 저장용 `request.gender`는 기존 값 유지 여부 확인
- [x] 정적 진단 및 테스트 수행
- QA: Kotlin LSP 미구성으로 `lsp_diagnostics` 불가 확인, `./gradlew test --tests "kr.co.vividnext.sodalive.admin.chat.character.AdminChatCharacterControllerTest"``./gradlew build -x test` 성공
## 검증 기록
### 1차 구현
- 무엇을: `registerCharacter` 외부 API 호출 시 `region == JP` 조건에서만 `gender`를 일본어(`女性`/`男性`/`その他`)로 변환하도록 구현하고, 매핑 단위 테스트를 추가했다.
- 왜: JP 리전 요청에서 외부 API가 일본어 성별 값을 요구하므로 등록 API 요청 바디의 `gender` 값만 조건부 변환이 필요했다.
- 어떻게:
- 코드 확인: `src/main/kotlin/kr/co/vividnext/sodalive/admin/chat/character/AdminChatCharacterController.kt`에서 `callExternalApi` 바디 구성 지점 확인 후 `mapGenderForExternalApi` 헬퍼 추가
- 매핑 검증: `src/test/kotlin/kr/co/vividnext/sodalive/admin/chat/character/AdminChatCharacterControllerTest.kt`에서 JP 매핑(여성/남성/기타) 및 KR 유지 케이스 검증
- 정적 진단: `lsp_diagnostics` 실행 시 Kotlin LSP 미구성으로 불가(환경 제약)
- 실행 검증 1: `./gradlew test --tests "kr.co.vividnext.sodalive.admin.chat.character.AdminChatCharacterControllerTest"` → 성공
- 수동 확인: `build/test-results/test/TEST-kr.co.vividnext.sodalive.admin.chat.character.AdminChatCharacterControllerTest.xml`에서 `tests="4" failures="0" errors="0"` 확인
- 실행 검증 2: `./gradlew build -x test` → 성공

View File

@@ -206,7 +206,7 @@ class AdminChatCharacterController(
body["description"] = request.description
body["region"] = request.region
request.age?.let { body["age"] = it }
request.gender?.let { body["gender"] = it }
request.gender?.let { body["gender"] = mapGenderForExternalApi(request.region, it) }
request.mbti?.let { body["mbti"] = it }
request.speechPattern?.let { body["speechPattern"] = it }
request.speechStyle?.let { body["speechStyle"] = it }
@@ -273,6 +273,19 @@ class AdminChatCharacterController(
}
}
private fun mapGenderForExternalApi(region: String, gender: String): String {
if (!region.equals("JP", ignoreCase = true)) {
return gender
}
return when (gender) {
"여성" -> "女性"
"남성" -> "男性"
"기타" -> "その他"
else -> gender
}
}
/**
* 캐릭터 수정 API
* 1. JSON 문자열을 ChatCharacterUpdateRequest 객체로 변환

View File

@@ -0,0 +1,63 @@
package kr.co.vividnext.sodalive.admin.chat.character
import kr.co.vividnext.sodalive.admin.chat.character.service.AdminChatCharacterService
import kr.co.vividnext.sodalive.admin.chat.original.service.AdminOriginalWorkService
import kr.co.vividnext.sodalive.aws.s3.S3Uploader
import kr.co.vividnext.sodalive.chat.character.service.ChatCharacterService
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.mockito.Mockito
import org.springframework.context.ApplicationEventPublisher
class AdminChatCharacterControllerTest {
private val controller = AdminChatCharacterController(
service = Mockito.mock(ChatCharacterService::class.java),
adminService = Mockito.mock(AdminChatCharacterService::class.java),
s3Uploader = Mockito.mock(S3Uploader::class.java),
originalWorkService = Mockito.mock(AdminOriginalWorkService::class.java),
applicationEventPublisher = Mockito.mock(ApplicationEventPublisher::class.java),
apiKey = "test-api-key",
apiUrl = "https://example.com",
s3Bucket = "test-bucket",
imageHost = "https://cdn.example.com"
)
private fun mapGender(region: String, gender: String): String {
val method = AdminChatCharacterController::class.java.getDeclaredMethod(
"mapGenderForExternalApi",
String::class.java,
String::class.java
)
method.isAccessible = true
return method.invoke(controller, region, gender) as String
}
@Test
fun shouldMapFemaleToJapaneseWhenRegionIsJp() {
val mappedGender = mapGender(region = "JP", gender = "여성")
assertEquals("女性", mappedGender)
}
@Test
fun shouldMapMaleToJapaneseWhenRegionIsJp() {
val mappedGender = mapGender(region = "JP", gender = "남성")
assertEquals("男性", mappedGender)
}
@Test
fun shouldMapOtherToJapaneseWhenRegionIsJp() {
val mappedGender = mapGender(region = "JP", gender = "기타")
assertEquals("その他", mappedGender)
}
@Test
fun shouldKeepGenderWhenRegionIsNotJp() {
val mappedGender = mapGender(region = "KR", gender = "여성")
assertEquals("여성", mappedGender)
}
}