-
Notifications
You must be signed in to change notification settings - Fork 3
[FEAT] home api 연결 #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d2321c2
af0e423
3b39b08
560e0bc
05c2363
e59a0c9
c65418f
28367e2
8a01f26
966f4a7
4a23843
779b4b5
305c18c
3196a80
321b6dc
01f0fa9
ad004e0
6813ccd
857478c
8454484
f88d823
5268aee
704fb9f
3d2eafe
cfa6c14
5a50798
7db7911
9f6ace9
d15b8c7
170d762
6710078
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package com.kuit.ourmenu.data.model.home.request | ||
|
|
||
| import kotlinx.serialization.Serializable | ||
|
|
||
| @Serializable | ||
| data class HomeAnswerRequest( | ||
| val answer: String | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package com.kuit.ourmenu.data.model.home.response | ||
|
|
||
| import kotlinx.serialization.Serializable | ||
|
|
||
| @Serializable | ||
| data class HomeQuestionResponse( | ||
| val question: String, | ||
| val answers: List<Answer> | ||
| ) | ||
|
|
||
| @Serializable | ||
| data class Answer( | ||
| val answer: String, | ||
| val answerImgUrl: String | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package com.kuit.ourmenu.data.model.home.response | ||
|
|
||
| import kotlinx.serialization.Serializable | ||
|
|
||
| @Serializable | ||
| data class HomeResponse( | ||
| val answerImgUrl: String = "", | ||
| val answerRecommendMenus: List<RecommendMenuList> = emptyList(), | ||
| val tagRecommendImgUrl: String = "", | ||
| val tagRecommendMenus: List<RecommendMenuList> = emptyList(), | ||
| val otherRecommendImgUrl: String = "", | ||
| val otherRecommendMenus: List<RecommendMenuList> = emptyList(), | ||
| ) | ||
|
|
||
| @Serializable | ||
| data class RecommendMenuList( | ||
| val menuId: Long = 0, | ||
| val menuTitle: String = "", | ||
| val storeName: String = "", | ||
| val menuImgUrl: String = "", | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package com.kuit.ourmenu.data.repository | ||
|
|
||
| import com.kuit.ourmenu.data.model.base.handleBaseResponse | ||
| import com.kuit.ourmenu.data.model.home.request.HomeAnswerRequest | ||
| import com.kuit.ourmenu.data.service.HomeService | ||
| import javax.inject.Inject | ||
| import javax.inject.Singleton | ||
|
|
||
| @Singleton | ||
| class HomeRepository @Inject constructor( | ||
| private val homeService: HomeService, | ||
| ) { | ||
| suspend fun getHome() = runCatching { | ||
| homeService.getHome().handleBaseResponse().getOrThrow() | ||
| } | ||
|
|
||
| suspend fun postHomeQuestion() = runCatching { | ||
| homeService.postHomeQuestion().handleBaseResponse().getOrThrow() | ||
| } | ||
|
|
||
| suspend fun postHomeAnswer(answer: String) = runCatching { | ||
| homeService.postHomeAnswer(HomeAnswerRequest(answer)) | ||
| .handleBaseResponse() | ||
| .getOrThrow() | ||
| } | ||
|
Comment on lines
+13
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion runCatching이 CancellationException까지 삼킵니다 (코루틴 취소 전파 이슈) 네트워크 호출을 runCatching으로 감싸면 CancellationException까지 Result로 포장되어 취소가 전파되지 않을 수 있어요. 취소는 반드시 재던지거나 runCatching 대체 유틸로 처리하세요. 다음 유틸을 공용 모듈에 추가 후 사용을 권장합니다: // 예: core/common/ResultExt.kt
suspend inline fun <T> cancellableRunCatching(crossinline block: suspend () -> T): Result<T> {
return try {
Result.success(block())
} catch (e: kotlinx.coroutines.CancellationException) {
throw e
} catch (t: Throwable) {
Result.failure(t)
}
}Repository에서는 아래처럼 교체: - suspend fun getHome() = runCatching {
+ suspend fun getHome() = cancellableRunCatching {
homeService.getHome().handleBaseResponse().getOrThrow()
}
- suspend fun postHomeQuestion() = runCatching {
+ suspend fun postHomeQuestion() = cancellableRunCatching {
homeService.postHomeQuestion().handleBaseResponse().getOrThrow()
}
- suspend fun postHomeAnswer(answer: String) = runCatching {
+ suspend fun postHomeAnswer(answer: String) = cancellableRunCatching {
homeService.postHomeAnswer(HomeAnswerRequest(answer))
.handleBaseResponse()
.getOrThrow()
}🤖 Prompt for AI Agents |
||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,22 @@ | ||||||||||||||||||||||||||||||
| package com.kuit.ourmenu.data.service | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| import com.kuit.ourmenu.data.model.base.BaseResponse | ||||||||||||||||||||||||||||||
| import com.kuit.ourmenu.data.model.home.request.HomeAnswerRequest | ||||||||||||||||||||||||||||||
| import com.kuit.ourmenu.data.model.home.response.HomeQuestionResponse | ||||||||||||||||||||||||||||||
| import com.kuit.ourmenu.data.model.home.response.HomeResponse | ||||||||||||||||||||||||||||||
| import retrofit2.http.Body | ||||||||||||||||||||||||||||||
| import retrofit2.http.GET | ||||||||||||||||||||||||||||||
| import retrofit2.http.POST | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| interface HomeService { | ||||||||||||||||||||||||||||||
| @GET("api/home") | ||||||||||||||||||||||||||||||
| suspend fun getHome(): BaseResponse<HomeResponse> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @POST("/api/home/questions") | ||||||||||||||||||||||||||||||
| suspend fun postHomeQuestion(): BaseResponse<HomeQuestionResponse> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @POST("/api/home/questions/answers") | ||||||||||||||||||||||||||||||
| suspend fun postHomeAnswer( | ||||||||||||||||||||||||||||||
| @Body answerRequest: HomeAnswerRequest | ||||||||||||||||||||||||||||||
| ): BaseResponse<Unit> | ||||||||||||||||||||||||||||||
|
Comment on lines
+15
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Retrofit 경로 표기 혼용(선행 슬래시) — BaseUrl path 무시 위험 @post에 선행 슬래시가 있어 baseUrl의 path 세그먼트를 무시할 수 있습니다. 상대 경로로 통일하는 것을 권장합니다. - @POST("/api/home/questions")
+ @POST("api/home/questions")
suspend fun postHomeQuestion(): BaseResponse<HomeQuestionResponse>
- @POST("/api/home/questions/answers")
+ @POST("api/home/questions/answers")
suspend fun postHomeAnswer(
@Body answerRequest: HomeAnswerRequest
): BaseResponse<Unit>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,7 +18,10 @@ import com.kuit.ourmenu.ui.theme.NeutralWhite | |||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| @OptIn(ExperimentalMaterial3Api::class) | ||||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||||
| fun OurMenuAddButtonTopAppBar(modifier: Modifier = Modifier) { | ||||||||||||||||||||||||||||||||||||||
| fun OurMenuAddButtonTopAppBar( | ||||||||||||||||||||||||||||||||||||||
| modifier: Modifier = Modifier, | ||||||||||||||||||||||||||||||||||||||
| onAddMenuClick: () -> Unit = {} | ||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+21
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain기존 사용처에서 업데이트 필요 확인 관련 파일들에서 다음 스크립트로 다른 사용처들이 업데이트가 필요한지 확인해보세요: Also applies to: 41-41 🏁 Script executed: #!/bin/bash
# OurMenuAddButtonTopAppBar 사용처들을 찾아서 콜백 전달 여부 확인
rg -A 3 "OurMenuAddButtonTopAppBar\(" --type kotlinLength of output: 2037 기능 동작용 콜백 전달 필수 – 호출부 수정 필요 SearchMenuScreen.kt와 MenuInfoMapScreen.kt의
📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||
| // 기본 | ||||||||||||||||||||||||||||||||||||||
| TopAppBar( | ||||||||||||||||||||||||||||||||||||||
| modifier = modifier.fillMaxWidth(), | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -35,7 +38,7 @@ fun OurMenuAddButtonTopAppBar(modifier: Modifier = Modifier) { | |||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
| actions = { | ||||||||||||||||||||||||||||||||||||||
| IconButton( | ||||||||||||||||||||||||||||||||||||||
| onClick = { /* TODO : Add Menu Button Click Event */ }, | ||||||||||||||||||||||||||||||||||||||
| onClick = onAddMenuClick, | ||||||||||||||||||||||||||||||||||||||
| modifier = Modifier.padding(end = 20.dp) | ||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||
| Icon( | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
백엔드 필드 네이밍 확인 및 @SerialName 필요 여부 체크
서버가 snake_case를 반환한다면 @SerialName이 필요합니다. 현재 camelCase로 선언되어 있어, Json 설정(namingStrategy) 여부에 따라 디코딩 실패 가능성이 있어요.
아래 스크립트로 Json 설정을 확인해 주세요. namingStrategy나 custom Json 설정이 없으면 @SerialName 추가를 고려하세요.
🏁 Script executed:
Length of output: 1028
DTO 필드 직렬화 이름 확인 및 @SerialName 검토
NetworkModule의 Json 설정(
isLenient,prettyPrint,encodeDefaults,explicitNulls,ignoreUnknownKeys만 사용)에는 snake_case → camelCase 변환 전략이 없어요.따라서 서버가 snake_case 필드를 반환할 경우 아래 DTO 필드 매핑이 실패할 수 있습니다.
▶ 백엔드 필드명이 snake_case인지 확인 후, snake_case로 전달된다면 각 필드에
@SerialName("snake_case_field")어노테이션을 추가하거나커스텀 네이밍 전략 구현을 검토해주세요.
🤖 Prompt for AI Agents