-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/#134 일정 API 연결 및 기능 연동 #135
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
8243888
a346f02
cf90390
b5ad265
2b48168
ed78497
990243d
fc1d46f
74b6574
fddab4a
4e9f9ed
e3e5a80
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 |
|---|---|---|
| @@ -1,8 +1,11 @@ | ||
| package com.yapp.dataapi | ||
|
|
||
| import com.yapp.model.ScheduleList | ||
| import com.yapp.model.Sessions | ||
| import kotlinx.coroutines.flow.Flow | ||
|
|
||
| interface SessionRepository { | ||
| interface ScheduleRepository { | ||
| fun getSessions(): Flow<List<Sessions>> | ||
|
|
||
| fun getSchedules(year: Int, month: Int): Flow<ScheduleList> | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package com.yapp.core.data.remote.api | ||
|
|
||
| import com.yapp.core.data.remote.model.response.DateGroupedScheduleResponse | ||
| import com.yapp.core.data.remote.model.response.SessionResponse | ||
| import retrofit2.http.GET | ||
| import retrofit2.http.Query | ||
|
|
||
| interface ScheduleApi { | ||
| @GET("v1/sessions") | ||
| suspend fun getSessions(): List<SessionResponse> | ||
|
|
||
| @GET("v1/schedules") | ||
| suspend fun getSchedules( | ||
| @Query("year") year: Int, | ||
| @Query("month") month: Int, | ||
| ): DateGroupedScheduleResponse | ||
| } | ||
|
Comment on lines
+8
to
+17
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. 🧹 Nitpick (assertive) API 인터페이스 문서화 추가 권장 API 인터페이스에 KDoc 주석을 추가하여 각 엔드포인트의 목적과 반환되는 데이터를 설명하는 것이 좋습니다. 이는 다른 개발자들이 API를 더 쉽게 이해하고 사용할 수 있게 도와줍니다. 또한 interface ScheduleApi {
/**
* 모든 세션 목록을 가져옵니다.
* @return 세션 응답 목록
*/
@GET("v1/sessions")
suspend fun getSessions(): List<SessionResponse>
/**
* 특정 연도와 월의 일정을 그룹화하여 가져옵니다.
* @param year 연도 (예: 2023)
* @param month 월 (1-12)
* @return 날짜별로 그룹화된 일정 응답
*/
@GET("v1/schedules")
suspend fun getSchedules(
@Query("year") year: Int,
@Query("month") month: Int,
): DateGroupedScheduleResponse
} |
||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| package com.yapp.core.data.remote.model.response | ||
|
|
||
| import com.yapp.model.AttendanceStatus | ||
| import com.yapp.model.DateGroupedSchedule | ||
| import com.yapp.model.ScheduleInfo | ||
| import com.yapp.model.ScheduleList | ||
| import com.yapp.model.ScheduleProgressPhase | ||
| import com.yapp.model.ScheduleType | ||
| import com.yapp.model.SessionType | ||
| import kotlinx.serialization.SerialName | ||
| import kotlinx.serialization.Serializable | ||
|
|
||
| @Serializable | ||
| data class DateGroupedScheduleResponse( | ||
| @SerialName("dates") | ||
| val dates: List<ScheduleListResponse> | ||
| ) { | ||
| fun toScheduleListModel() = ScheduleList( | ||
| dates | ||
| .filter { it.schedules.isNotEmpty() } | ||
| .map { it.toScheduleListModel() } | ||
| ) | ||
| } | ||
|
|
||
| @Serializable | ||
| data class ScheduleListResponse( | ||
| @SerialName("date") | ||
| val date: String, | ||
|
|
||
| @SerialName("isToday") | ||
| val isToday: Boolean, | ||
|
|
||
| @SerialName("dayOfTheWeek") | ||
| val dayOfTheWeek: String, | ||
|
|
||
| @SerialName("schedules") | ||
| val schedules: List<ScheduleResponse>, | ||
| ) { | ||
| fun toScheduleListModel() = DateGroupedSchedule( | ||
| date = date, | ||
| isToday = isToday, | ||
| dayOfTheWeek = dayOfTheWeek, | ||
| schedules = schedules.map { it.toScheduleModel() } | ||
| ) | ||
| } | ||
|
|
||
| @Serializable | ||
| data class ScheduleResponse( | ||
| @SerialName("id") | ||
| val id: String, | ||
|
|
||
| @SerialName("name") | ||
| val name: String, | ||
|
|
||
| @SerialName("place") | ||
| val place: String?, | ||
|
|
||
| @SerialName("date") | ||
| val date: String, | ||
|
|
||
| @SerialName("endDate") | ||
| val endDate: String?, | ||
|
|
||
| @SerialName("time") | ||
| val time: String?, | ||
|
|
||
| @SerialName("endTime") | ||
| val endTime: String?, | ||
|
|
||
| @SerialName("scheduleType") | ||
| val scheduleType: String, | ||
|
|
||
| @SerialName("sessionType") | ||
| val sessionType: String?, | ||
|
|
||
| @SerialName("scheduleProgressPhase") | ||
| val scheduleProgressPhase: String, | ||
|
|
||
| @SerialName("attendanceStatus") | ||
| val attendanceStatus: String?, | ||
| ) { | ||
| fun toScheduleModel() = ScheduleInfo( | ||
| id = id, | ||
| name = name, | ||
| place = place, | ||
| date = date, | ||
| endDate = endDate, | ||
| time = time, | ||
| endTime = endTime, | ||
| scheduleType = scheduleType.toScheduleType(), | ||
| sessionType = sessionType.toSessionType(), | ||
| scheduleProgressPhase = scheduleProgressPhase.toScheduleProgressPhase(), | ||
| attendanceStatus = attendanceStatus.toAttendanceStatus(), | ||
| ) | ||
|
|
||
| companion object { | ||
| fun String.toScheduleType() = | ||
| ScheduleType.entries.firstOrNull { it.name == this } ?: ScheduleType.ETC | ||
|
|
||
| fun String?.toSessionType() = | ||
| SessionType.entries.firstOrNull { it.name == this } | ||
|
|
||
| fun String?.toScheduleProgressPhase() = | ||
| ScheduleProgressPhase.entries.firstOrNull { it.name == this } | ||
| ?: ScheduleProgressPhase.PENDING | ||
|
|
||
| fun String?.toAttendanceStatus() = | ||
| AttendanceStatus.entries.firstOrNull { it.name == this } ?: AttendanceStatus.SCHEDULED | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,42 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.yapp.model | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data class ScheduleList( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val dates: List<DateGroupedSchedule> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data class DateGroupedSchedule( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val date: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val isToday: Boolean, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val dayOfTheWeek: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val schedules: List<ScheduleInfo> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data class ScheduleInfo( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val id: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val name: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val place: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val date: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val endDate: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val time: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val endTime: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val scheduleType: ScheduleType, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val sessionType: SessionType?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val scheduleProgressPhase: ScheduleProgressPhase, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val attendanceStatus: AttendanceStatus, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+14
to
+26
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. 🧹 Nitpick (assertive) 도메인 모델에서 날짜·시간을 문자열로 보관하면 추후 파싱 비용이 반복됩니다
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enum class ScheduleType { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SESSION, TASK, ETC; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enum class SessionType { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| OFFLINE, ONLINE, TEAM; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enum class ScheduleProgressPhase { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DONE, TODAY, ONGOING, PENDING; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enum class AttendanceStatus { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SCHEDULED, ATTENDED, LATE, ABSENT, EARLY_LEAVE, EXCUSED; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+28
to
+42
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. 🧹 Nitpick (assertive) enum 끝에 세미콜론은 생략 가능합니다 Kotlin 에서는 열거형 상수 선언 뒤 마지막 -enum class ScheduleType {
- SESSION, TASK, ETC;
-}
+enum class ScheduleType {
+ SESSION, TASK, ETC
+}다른 enum 들도 동일하게 정리하면 좋겠습니다. 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,51 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||
| package com.yapp.core.ui.util | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| import android.content.Context | ||||||||||||||||||||||||||||||||||||||||||||||||
| import com.yapp.core.ui.R | ||||||||||||||||||||||||||||||||||||||||||||||||
| import java.time.LocalDate | ||||||||||||||||||||||||||||||||||||||||||||||||
| import java.time.LocalTime | ||||||||||||||||||||||||||||||||||||||||||||||||
| import java.time.format.DateTimeFormatter | ||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Locale | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| fun formatToDay(context: Context, date: String): String { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return try { | ||||||||||||||||||||||||||||||||||||||||||||||||
| val parsedDate = LocalDate.parse(date) | ||||||||||||||||||||||||||||||||||||||||||||||||
| context.getString(R.string.time_format_day, parsedDate.dayOfMonth) | ||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e: Exception) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| date | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+10
to
+17
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 예외 처리를 개선하세요. 현재 코드에서는 너무 일반적인 특정 예외를 캐치하고 적절한 로깅을 추가하는 것이 좋습니다: fun formatToDay(context: Context, date: String): String {
return try {
val parsedDate = LocalDate.parse(date)
context.getString(R.string.time_format_day, parsedDate.dayOfMonth)
- } catch (e: Exception) {
+ } catch (e: DateTimeParseException) {
+ android.util.Log.e("DateTime", "Failed to parse date: $date", e)
date
}
}📝 Committable suggestion
Suggested change
🧰 Tools🪛 detekt (1.23.7)[warning] 13-13: The caught exception is too generic. Prefer catching specific exceptions to the case that is currently handled. (detekt.exceptions.TooGenericExceptionCaught) [warning] 13-13: The caught exception is swallowed. The original exception could be lost. (detekt.exceptions.SwallowedException) |
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| fun formatTimeRange(context: Context, startTime: String?, endTime: String?): String? { | ||||||||||||||||||||||||||||||||||||||||||||||||
| if (startTime.isNullOrBlank() || endTime.isNullOrBlank()) return null | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| return "${formatToKoreanTime(context, startTime)} - ${formatToKoreanTime(context, endTime)}" | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| fun formatToKoreanTime(context: Context, time: String): String { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return try { | ||||||||||||||||||||||||||||||||||||||||||||||||
| val parsedTime = LocalTime.parse(time) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| val pattern = context.getString(R.string.time_format_base) | ||||||||||||||||||||||||||||||||||||||||||||||||
| val formatter = DateTimeFormatter.ofPattern(pattern, Locale.KOREAN) | ||||||||||||||||||||||||||||||||||||||||||||||||
| val base = parsedTime.format(formatter) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| when (parsedTime.minute) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| 0 -> base | ||||||||||||||||||||||||||||||||||||||||||||||||
| 30 -> context.getString(R.string.time_format_half_hour_with_base, base) | ||||||||||||||||||||||||||||||||||||||||||||||||
| else -> context.getString(R.string.time_format_hour_minute_with_base, base, parsedTime.minute) | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e: Exception) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| time | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| fun isPastDate(dateString: String, pattern: String = "yyyy-MM-dd"): Boolean { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return try { | ||||||||||||||||||||||||||||||||||||||||||||||||
| val formatter = DateTimeFormatter.ofPattern(pattern) | ||||||||||||||||||||||||||||||||||||||||||||||||
| val inputDate = LocalDate.parse(dateString, formatter) | ||||||||||||||||||||||||||||||||||||||||||||||||
| inputDate.isBefore(LocalDate.now()) | ||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e: Exception) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| false | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+43
to
+51
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 isPastDate 함수의 예외 처리를 개선하세요. 여기서도 일반적인 다음과 같이 개선할 수 있습니다: fun isPastDate(dateString: String, pattern: String = "yyyy-MM-dd"): Boolean {
return try {
val formatter = DateTimeFormatter.ofPattern(pattern)
val inputDate = LocalDate.parse(dateString, formatter)
inputDate.isBefore(LocalDate.now())
- } catch (e: Exception) {
+ } catch (e: DateTimeParseException) {
+ android.util.Log.e("DateTime", "Failed to parse date: $dateString with pattern: $pattern", e)
+ // 애플리케이션의 요구사항에 따라 기본값 결정
false
+ } catch (e: IllegalArgumentException) {
+ android.util.Log.e("DateTime", "Invalid pattern: $pattern", e)
+ false
}
}📝 Committable suggestion
Suggested change
🧰 Tools🪛 detekt (1.23.7)[warning] 57-57: The caught exception is too generic. Prefer catching specific exceptions to the case that is currently handled. (detekt.exceptions.TooGenericExceptionCaught) [warning] 57-57: The caught exception is swallowed. The original exception could be lost. (detekt.exceptions.SwallowedException)
Comment on lines
+43
to
+51
Contributor
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. C : 오전 오후를 표시하고 싶으면 a 패턴을 사용하면 간편하게 사용할 수 있습니다 ~
https://developer.android.com/reference/java/time/format/DateTimeFormatter
Member
Author
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. 반영했습니다! |
||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,28 @@ | ||||||||||||||||||||||||||||||||
| package com.yapp.feature.schedule | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| import com.yapp.model.ScheduleList | ||||||||||||||||||||||||||||||||
| import java.time.LocalDate | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| data class ScheduleState( | ||||||||||||||||||||||||||||||||
| val isLoading: Boolean = true, | ||||||||||||||||||||||||||||||||
| val selectedTab: ScheduleTab = ScheduleTab.ALL, | ||||||||||||||||||||||||||||||||
| val selectedYear: Int = LocalDate.now().year, | ||||||||||||||||||||||||||||||||
| val selectedMonth: Int = LocalDate.now().monthValue, | ||||||||||||||||||||||||||||||||
| val schedules: ScheduleList = ScheduleList(dates = emptyList()) | ||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||
|
Comment on lines
+6
to
+12
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 ScheduleState에 에러 상태 추가 고려 현재 상태에는 data class ScheduleState(
val isLoading: Boolean = true,
+ val error: String? = null,
val selectedTab: ScheduleTab = ScheduleTab.ALL,
val selectedYear: Int = LocalDate.now().year,
val selectedMonth: Int = LocalDate.now().monthValue,
val schedules: ScheduleList = ScheduleList(dates = emptyList())
)📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| sealed interface ScheduleIntent { | ||||||||||||||||||||||||||||||||
| data object EnterScheduleScreen: ScheduleIntent | ||||||||||||||||||||||||||||||||
| data class SelectTab(val tab: ScheduleTab): ScheduleIntent | ||||||||||||||||||||||||||||||||
| data object ClickPreviousMonth: ScheduleIntent | ||||||||||||||||||||||||||||||||
| data object ClickNextMonth: ScheduleIntent | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+14
to
+19
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. 🧹 Nitpick (assertive) 추가 Intent 고려: 에러 발생 시 재시도 기능 API 호출 실패 시 사용자가 재시도할 수 있는 Intent를 추가하면 좋을 것 같습니다. sealed interface ScheduleIntent {
data object EnterScheduleScreen: ScheduleIntent
data class SelectTab(val tab: ScheduleTab): ScheduleIntent
data object ClickPreviousMonth: ScheduleIntent
data object ClickNextMonth: ScheduleIntent
+ data object RetryLoading: ScheduleIntent
}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| sealed interface ScheduleSideEffect { | ||||||||||||||||||||||||||||||||
| data class ShowToast(val message: String): ScheduleSideEffect | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+21
to
+23
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. 🧹 Nitpick (assertive) 다양한 SideEffect 추가 고려 현재는 토스트 메시지만 있지만, 화면 이동이나 다이얼로그 표시 같은 다른 사이드 이펙트도 필요할 수 있습니다. sealed interface ScheduleSideEffect {
data class ShowToast(val message: String): ScheduleSideEffect
+ data object NavigateBack: ScheduleSideEffect
+ data class ShowDialog(val title: String, val message: String): ScheduleSideEffect
}
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| enum class ScheduleTab(val index: Int, val labelResId: Int) { | ||||||||||||||||||||||||||||||||
| ALL(0, R.string.schedule_tab_all), | ||||||||||||||||||||||||||||||||
| SESSION(1, R.string.schedule_tab_session); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||

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.
getSchedules 메서드도 에러 처리가 필요합니다.
API 호출 시 발생할 수 있는 오류에 대한 처리가 누락되어 있습니다.
다음과 같이 에러 처리를 추가하는 것을 고려해보세요:
override fun getSchedules(year: Int, month: Int) = flow { + try { emit(scheduleApi.getSchedules(year, month).toScheduleListModel()) + } catch (e: Exception) { + // 적절한 에러 로깅 + throw e + } }📝 Committable suggestion
🧹 Nitpick (assertive)
선택적: getSchedules의 파라미터 유효성 검사 추가
year와 month 파라미터에 대한 유효성 검사를 추가하면 API 호출 전에 잠재적인 문제를 방지할 수 있습니다.
override fun getSchedules(year: Int, month: Int) = flow { + // 유효성 검사: month는 1-12 사이여야 함 + require(month in 1..12) { "Month must be between 1 and 12" } + // 유효성 검사: year는 합리적인 범위여야 함 (예: 2000년 이후) + require(year >= 2000) { "Year must be 2000 or later" } emit(scheduleApi.getSchedules(year, month).toScheduleListModel()) }📝 Committable suggestion