Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.eatssu.android.data.remote.dto.response

import com.eatssu.android.domain.model.Partnership
import com.eatssu.common.enums.PeriodType
import com.eatssu.common.enums.StoreType
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down Expand Up @@ -37,7 +38,9 @@ data class PartnershipResponse(
@SerialName("startDate")
val startDate: String? = null,
@SerialName("endDate")
val endDate: String? = null
val endDate: String? = null,
@SerialName("periodType")
val periodType: String? = null

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kotlinx.serialization이 enum 직렬화 처리를 해줘서 String을 받고 아래에서 파싱하는 방법이 아니어도 됩니다! 대신 PeriodType를 @serializable로 달아야 해요.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@serializable로 수정했습니다 !

)
}

Expand All @@ -57,7 +60,11 @@ fun PartnershipResponse.toDomain(): Partnership =
isLiked = it.isLiked ?: false,
description = it.description ?: "",
startDate = it.startDate ?: "",
endDate = it.endDate ?: ""
endDate = it.endDate ?: "",
periodType = when (it.periodType) {
"FESTIVAL" -> PeriodType.FESTIVAL
else -> PeriodType.NORMAL
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

PeriodType enum에 @Serializable을 적용하고 DTO(PartnershipInfo)에서 직접 PeriodType 타입을 사용하면, when 문을 통한 수동 매핑 없이 kotlinx.serialization이 자동으로 처리하게 할 수 있습니다. 이는 코드 가독성을 높이고 오타로 인한 실수를 방지하는 데 도움이 됩니다. 또한, 새로 추가된 이 매핑 로직에 대한 단위 테스트(PartnershipResponseMapperBehaviorSpec)가 누락되었으니 추가가 필요합니다.

)
}
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.eatssu.android.domain.model

import com.eatssu.common.enums.PeriodType
import com.eatssu.common.enums.StoreType

data class Partnership(
Expand All @@ -18,6 +19,7 @@ data class Partnership(
val isLiked: Boolean,
val description: String,
val startDate: String,
val endDate: String
val endDate: String,
val periodType: PeriodType,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.eatssu.common.UiEvent
import com.eatssu.common.UiState
import com.eatssu.common.analytics.AnalyticsTracker
import com.eatssu.common.analytics.MapAnalyticsEvent
import com.eatssu.common.enums.PeriodType
import com.eatssu.common.enums.StoreType
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
Expand Down Expand Up @@ -83,15 +84,16 @@ class MapViewModel @Inject constructor(
// departmentId가 변경되면 필터 자동 설정
val current = uiState.value
val currentData = if (current is UiState.Success) current.data else MapState()
val initialFilter = if (newDepartmentId == -1L) FilterType.All else FilterType.Mine

// val initialFilter = if (newDepartmentId == -1L) FilterType.All else FilterType.Mine // TODO 축제기간 종료 시 주석 해제
val initialFilter = FilterType.Festival // TODO 축제기간 한정 Festival 강제. 축제기간 끝나면 주석

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

축제 기간을 위해 초기 필터를 Festival로 강제하고 기존 로직을 주석 처리하는 방식은 유지보수 시 실수할 위험이 큽니다. 주석 처리 대신, 현재가 축제 기간인지 판단하는 로직(예: 원격 구성이나 상수 플래그)을 도입하여 조건부로 initialFilter를 결정하는 것이 더 안전합니다. 또한, 이 변경으로 인해 기존에 학과가 설정된 사용자의 기본 경험이 변경되므로 의도된 사항인지 확인이 필요합니다.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분 무조건 Festival이 아니라 Festival인 애가 존재하는 경우에만 이렇게 initialFilter를 Festival로 설정해야해요!!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

! 넵!

_uiState.value = UiState.Success(
MapState(selectedFilter = initialFilter)
)

// 초기 필터에 따라 데이터 로드
when (initialFilter) {
FilterType.All -> loadPartnerships()
FilterType.Festival -> loadFestivalPartnerships()
FilterType.Mine -> loadUserCollegePartnerships()
}

Expand Down Expand Up @@ -130,6 +132,10 @@ class MapViewModel @Inject constructor(
analyticsTracker.track(MapAnalyticsEvent.AllClicked)
}

FilterType.Festival -> {
loadFestivalPartnerships()
}

FilterType.Mine -> {
loadUserCollegePartnerships()
analyticsTracker.track(
Expand Down Expand Up @@ -160,6 +166,33 @@ class MapViewModel @Inject constructor(
}
}

// 축제 정보 로딩
private fun loadFestivalPartnerships() {
viewModelScope.launch {
val current = uiState.value
val currentData = if (current is UiState.Success) current.data else MapState()

_uiState.value = UiState.Loading

val partnerships = partnershipRepository.getAllPartnerships().mapNotNull {
val festivalInfos =
it.partnershipInfos.filter { info -> info.periodType == PeriodType.FESTIVAL }
if (festivalInfos.isEmpty()) return@mapNotNull null

it.copy(
partnershipInfos = festivalInfos
)
}

_uiState.value = UiState.Success(
currentData.copy(
partnerships = partnerships,
filterChangeResult = null
)
)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

loadFestivalPartnerships 함수에서 전체 데이터를 가져와 필터링하는 작업은 데이터 양이 많아질 경우 UI 스레드에 부담을 줄 수 있으므로, 계산 집약적인 작업은 백그라운드 스레드에서 수행하는 것이 좋습니다. 또한, 사용자가 필터를 빠르게 전환할 때 이전 요청이 현재 상태를 덮어쓰는 레이스 컨디션이 발생할 수 있으므로 Job 관리를 통한 요청 취소 로직 도입을 권장합니다. 마지막으로, Festival 필터링 로직에 대한 ViewModel 단위 테스트(MapViewModelBehaviorSpec)도 추가해 주세요.


// 사용자 단과대 제휴 정보 로딩
private fun loadUserCollegePartnerships() {
viewModelScope.launch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ import com.eatssu.design_system.theme.White
import timber.log.Timber

enum class FilterType(@StringRes val labelResId: Int) {
Festival(R.string.partnership_filter_festival),
All(R.string.partnership_filter_all),
Mine(R.string.partnership_filter_mine),
All(R.string.partnership_filter_all)
}

@Composable
Expand All @@ -42,6 +43,7 @@ fun FilterType.getLabel(departmentName: String): String {
departmentName
}
}
FilterType.Festival -> stringResource(labelResId)
FilterType.All -> stringResource(labelResId)
}
}
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@
<string name="time">영업 시간</string>
<string name="favorite_partnership">찜한 제휴</string>
<string name="partnership_filter_mine">내 제휴</string>
<string name="partnership_filter_festival">축제</string>
<string name="partnership_filter_all">전체</string>
<string name="partnership_filter_department_placeholder">학과</string>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.eatssu.common.enums

enum class PeriodType {
FESTIVAL, NORMAL
}
Loading