From 62e1d3935da62c98b52237d38fe9985767be3309 Mon Sep 17 00:00:00 2001 From: Develop-KIM Date: Tue, 30 Jun 2026 15:25:04 +0900 Subject: [PATCH] =?UTF-8?q?feat(home):=20/api/v2/home=EC=97=90=20=ED=98=84?= =?UTF-8?q?=EC=9E=AC=20=EB=AF=B8=EC=85=98=20=ED=8F=AC=ED=95=A8(=ED=99=88?= =?UTF-8?q?=20=EC=A7=91=EA=B3=84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 홈 진입 시 home/mission/profile 3콜 중 mission을 /home에 합침. - HomeV2Response에 mission(CurrentMissionResponse) 추가 - getHomeV2가 ensureInitialized 후 getCurrentMission 포함 반환 (신규 유저 500 방지) - 마이페이지의 /api/v2/users/profile 단독 호출은 유지 Co-Authored-By: Claude Opus 4.8 --- .../com/didit/adapter/webapi/home/HomeApi.kt | 7 +++++ .../adapter/webapi/home/dto/HomeV2Response.kt | 2 ++ .../didit/adapter/webapi/home/HomeApiTest.kt | 29 ++++++++++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/didit/adapter/webapi/home/HomeApi.kt b/src/main/kotlin/com/didit/adapter/webapi/home/HomeApi.kt index dc67719c..154e81c9 100644 --- a/src/main/kotlin/com/didit/adapter/webapi/home/HomeApi.kt +++ b/src/main/kotlin/com/didit/adapter/webapi/home/HomeApi.kt @@ -6,6 +6,8 @@ import com.didit.adapter.webapi.home.dto.HomeResponse import com.didit.adapter.webapi.home.dto.HomeV2Response import com.didit.adapter.webapi.response.SuccessResponse import com.didit.adapter.webapi.retrospect.dto.RetrospectiveListItemV2Response +import com.didit.application.achievement.provided.MissionFinder +import com.didit.application.achievement.provided.UserMissionRegister import com.didit.application.auth.provided.UserFinder import com.didit.application.notification.provided.NotificationHistoryFinder import com.didit.application.retrospect.provided.RetrospectiveFinder @@ -19,6 +21,8 @@ class HomeApi( private val userFinder: UserFinder, private val retrospectiveFinder: RetrospectiveFinder, private val notificationHistoryFinder: NotificationHistoryFinder, + private val missionFinder: MissionFinder, + private val userMissionRegister: UserMissionRegister, ) { @Deprecated("Use v2 endpoint", replaceWith = ReplaceWith("getHomeV2")) @RequireAuth @@ -47,6 +51,8 @@ class HomeApi( fun getHomeV2( @CurrentUserId userId: UUID, ): SuccessResponse { + userMissionRegister.ensureInitialized(userId) + val user = userFinder.findByIdOrThrow(userId) val recentRetros = retrospectiveFinder.findRecentWithProjectAndTagsByUserId(userId, limit = 5) val todayCount = retrospectiveFinder.countByUserIdAndDate(userId, ServiceTime.today()) @@ -56,6 +62,7 @@ class HomeApi( nickname = user.nickname ?: "", todayRetrospectiveCount = todayCount, hasUnreadNotification = notificationHistoryFinder.hasUnread(userId), + mission = missionFinder.getCurrentMission(userId), recentRetrospectives = recentRetros.map { RetrospectiveListItemV2Response.from(it) diff --git a/src/main/kotlin/com/didit/adapter/webapi/home/dto/HomeV2Response.kt b/src/main/kotlin/com/didit/adapter/webapi/home/dto/HomeV2Response.kt index 7adab4e6..0af97a74 100644 --- a/src/main/kotlin/com/didit/adapter/webapi/home/dto/HomeV2Response.kt +++ b/src/main/kotlin/com/didit/adapter/webapi/home/dto/HomeV2Response.kt @@ -1,10 +1,12 @@ package com.didit.adapter.webapi.home.dto import com.didit.adapter.webapi.retrospect.dto.RetrospectiveListItemV2Response +import com.didit.application.achievement.dto.CurrentMissionResponse data class HomeV2Response( val nickname: String, val todayRetrospectiveCount: Int, val hasUnreadNotification: Boolean, + val mission: CurrentMissionResponse, val recentRetrospectives: List, ) diff --git a/src/test/kotlin/com/didit/adapter/webapi/home/HomeApiTest.kt b/src/test/kotlin/com/didit/adapter/webapi/home/HomeApiTest.kt index 930635f2..5eab753e 100644 --- a/src/test/kotlin/com/didit/adapter/webapi/home/HomeApiTest.kt +++ b/src/test/kotlin/com/didit/adapter/webapi/home/HomeApiTest.kt @@ -1,5 +1,10 @@ package com.didit.adapter.webapi.home +import com.didit.application.achievement.dto.CurrentMissionResponse +import com.didit.application.achievement.dto.MissionInfo +import com.didit.application.achievement.dto.PopupStatus +import com.didit.application.achievement.provided.MissionFinder +import com.didit.application.achievement.provided.UserMissionRegister import com.didit.application.auth.provided.UserFinder import com.didit.application.notification.provided.NotificationHistoryFinder import com.didit.application.retrospect.dto.RetrospectiveDetailResult @@ -19,6 +24,7 @@ import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get import org.springframework.restdocs.payload.JsonFieldType import org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath import org.springframework.restdocs.payload.PayloadDocumentation.responseFields +import org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import java.util.UUID @@ -26,8 +32,27 @@ class HomeApiTest : AuthenticatedRestDocsSupport() { private val userFinder: UserFinder = mock(UserFinder::class.java) private val retrospectiveFinder: RetrospectiveFinder = mock(RetrospectiveFinder::class.java) private val notificationHistoryFinder: NotificationHistoryFinder = mock(NotificationHistoryFinder::class.java) + private val missionFinder: MissionFinder = mock(MissionFinder::class.java) + private val userMissionRegister: UserMissionRegister = mock(UserMissionRegister::class.java) - override fun initController() = HomeApi(userFinder, retrospectiveFinder, notificationHistoryFinder) + override fun initController() = HomeApi(userFinder, retrospectiveFinder, notificationHistoryFinder, missionFinder, userMissionRegister) + + private fun currentMission() = + CurrentMissionResponse( + currentLevel = 0, + mission = + MissionInfo( + type = "FIRST_RETRO", + title = "첫 회고 작성하기", + description = "첫 회고를 작성해보세요", + progress = 0, + target = 1, + remainingDays = null, + cta = "회고 시작하기", + ), + weeklyStatus = null, + popup = PopupStatus(exists = false, type = null), + ) @Test fun `홈 조회`() { @@ -74,6 +99,7 @@ class HomeApiTest : AuthenticatedRestDocsSupport() { whenever(retrospectiveFinder.findRecentWithProjectAndTagsByUserId(userId, 5)).thenReturn(listOf(result)) whenever(retrospectiveFinder.countByUserIdAndDate(userId, ServiceTime.today())).thenReturn(1) whenever(notificationHistoryFinder.hasUnread(userId)).thenReturn(true) + whenever(missionFinder.getCurrentMission(userId)).thenReturn(currentMission()) mockMvc .perform(get("/api/v2/home")) @@ -87,6 +113,7 @@ class HomeApiTest : AuthenticatedRestDocsSupport() { fieldWithPath("data.nickname").type(JsonFieldType.STRING).description("닉네임"), fieldWithPath("data.todayRetrospectiveCount").type(JsonFieldType.NUMBER).description("오늘 회고 횟수"), fieldWithPath("data.hasUnreadNotification").type(JsonFieldType.BOOLEAN).description("안 읽은 알림 존재 여부"), + subsectionWithPath("data.mission").description("현재 미션/레벨 정보 (GET /api/v1/missions/current와 동일 구조)"), fieldWithPath("data.recentRetrospectives").type(JsonFieldType.ARRAY).description("최근 회고 목록"), fieldWithPath("data.recentRetrospectives[].id").type(JsonFieldType.STRING).description("회고 ID"), fieldWithPath("data.recentRetrospectives[].title").type(JsonFieldType.STRING).description("회고 제목").optional(),