fix(agent-assignment): 소속 크리에이터 조회 시각을 KST로 변환한다

This commit is contained in:
2026-04-13 14:55:59 +09:00
parent f17dedda20
commit 46b282a817
3 changed files with 67 additions and 1 deletions

View File

@@ -7,6 +7,9 @@
- [x] `LocalDateTimeExtensions`에 타임존 입력 기반 UTC 변환 확장함수를 추가하고 기본 타임존을 KST로 둔다.
- [x] `AdminAgentCreatorService`의 시간 변환을 확장함수 호출로 리팩터링한다.
- [x] 확장함수 테스트와 관련 서비스 테스트를 다시 검증하고 기록한다.
- [x] `AdminAgentReadService.getAssignedCreators` 응답의 `assignedAt`을 UTC에서 KST로 변환해 내려오도록 수정한다.
- [x] `AdminAgentReadServiceTest``getAssignedCreators` 응답 시간이 KST로 변환되는 회귀 테스트를 추가한다.
- [x] 변경 파일 진단과 관련 Gradle 테스트를 수행하고 결과를 기록한다.
---
@@ -33,3 +36,16 @@
- `AdminAgentCreatorService`는 내부 변환 함수를 제거하고 `request.assignedAt.convertToUtc()` / `request.unassignedAt.convertToUtc()`를 사용하도록 수정했다.
- `./gradlew test --tests "kr.co.vividnext.sodalive.extensions.LocalDateTimeExtensionsTest" --tests "kr.co.vividnext.sodalive.admin.partner.agent.assignment.AdminAgentCreatorServiceTest"` 실행: 성공(BUILD SUCCESSFUL).
- `./gradlew ktlintCheck` 실행: 성공(BUILD SUCCESSFUL).
### 3차 수정
- 무엇을: 관리자 에이전트 소속 크리에이터 목록 응답의 `assignedAt`을 UTC 기준 저장값에서 KST 기준 시각으로 변환해 반환하도록 수정.
- 왜: 현재 `getAssignedCreators`는 DB에서 조회한 UTC `assignedAt`을 그대로 내려주고 있어 관리자 화면에서 소속 시각이 9시간 늦게 보일 수 있음.
- 어떻게:
- 내부 패턴 조사 결과, 저장소에서는 UTC raw 값을 유지하고 서비스/DTO 경계에서 `UTC -> Asia/Seoul` 변환을 적용하는 방식이 가장 가까운 관례임을 확인했다.
- `AdminAgentReadServiceTest``assignedAt = 2026-04-10T03:00:00` UTC 조회값이 `2026-04-10T12:00:00` KST로 반환되는 회귀 테스트를 먼저 추가했고, 수정 전 해당 테스트가 실패함을 확인했다.
- `AdminAgentReadService.getAssignedCreators`에서 조회 결과를 매핑하며 `assignedAt.atZone(UTC).withZoneSameInstant(Asia/Seoul).toLocalDateTime()`으로 변환하도록 수정했다.
- `lsp_diagnostics` 실행: `.kt` 확장자용 LSP 서버 미설정으로 도구 진단 불가.
- `./gradlew test --tests "kr.co.vividnext.sodalive.admin.partner.agent.read.AdminAgentReadServiceTest.shouldConvertAssignedAtToKstWhenGettingAssignedCreators"` 실행: 최초 실패 후 수정 뒤 성공(BUILD SUCCESSFUL).
- `./gradlew test --tests "kr.co.vividnext.sodalive.admin.partner.agent.read.AdminAgentReadServiceTest" --tests "kr.co.vividnext.sodalive.admin.partner.agent.read.AdminAgentReadQueryRepositoryTest"` 실행: 성공(BUILD SUCCESSFUL).
- `./gradlew ktlintCheck` 실행: 성공(BUILD SUCCESSFUL).

View File

@@ -56,9 +56,19 @@ class AdminAgentReadService(
fun getAssignedCreators(agentId: Long, offset: Long, limit: Long): GetAdminAgentAssignedCreatorResponse {
validateAgent(agentId)
val now = LocalDateTime.now()
val items = queryRepository.getAssignedCreators(agentId = agentId, offset = offset, limit = limit, currentTime = now)
.map {
it.copy(
assignedAt = it.assignedAt
.atZone(ZoneId.of("UTC"))
.withZoneSameInstant(kstZoneId)
.toLocalDateTime()
)
}
return GetAdminAgentAssignedCreatorResponse(
totalCount = queryRepository.getAssignedCreatorTotalCount(agentId = agentId, currentTime = now),
items = queryRepository.getAssignedCreators(agentId = agentId, offset = offset, limit = limit, currentTime = now)
items = items
)
}

View File

@@ -15,6 +15,7 @@ import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.mockito.Mockito
import java.time.LocalDateTime
import java.time.ZonedDateTime
import java.util.Optional
@@ -117,6 +118,45 @@ class AdminAgentReadServiceTest {
assertEquals("partner.agent.ratio.invalid_agent", exception.messageKey)
}
@Test
@DisplayName("소속 크리에이터 목록 조회는 assignedAt을 UTC에서 KST로 변환해 반환한다")
fun shouldConvertAssignedAtToKstWhenGettingAssignedCreators() {
val agent = Member(
email = "agent@test.com",
password = "password",
nickname = "agent",
role = MemberRole.AGENT
)
agent.id = 11L
Mockito.`when`(memberRepository.findById(11L)).thenReturn(Optional.of(agent))
Mockito.`when`(
queryRepository.getAssignedCreatorTotalCount(
Mockito.eq(11L),
Mockito.any(LocalDateTime::class.java) ?: LocalDateTime.now()
)
).thenReturn(1)
Mockito.doReturn(
listOf(
GetAdminAgentAssignedCreatorItem(
creatorId = 21L,
creatorNickname = "creator-a",
assignedAt = LocalDateTime.of(2026, 4, 10, 3, 0)
)
)
).`when`(queryRepository).getAssignedCreators(
Mockito.eq(11L),
Mockito.eq(0L),
Mockito.eq(20L),
Mockito.any(LocalDateTime::class.java) ?: LocalDateTime.now()
)
val actual = service.getAssignedCreators(agentId = 11L, offset = 0L, limit = 20L)
assertEquals(1, actual.totalCount)
assertEquals(LocalDateTime.of(2026, 4, 10, 12, 0), actual.items.first().assignedAt)
}
@Test
@DisplayName("라이브 정산 상세 조회는 기존 AgentCalculateService로 위임한다")
fun shouldDelegateLiveSettlementToAgentCalculateService() {