Skip to content
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

✨ ID を元にスケジュールを取得するユースケースを追加 #117

Merged
merged 5 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
Expand Up @@ -2,13 +2,14 @@ package club.nito.ios.combined

import club.nito.core.data.AuthRepository
import club.nito.core.data.ScheduleRepository
import club.nito.core.domain.AuthStatusStreamUseCase
import club.nito.core.domain.FetchParticipantScheduleByIdUseCase
import club.nito.core.domain.GetParticipantScheduleListUseCase
import club.nito.core.domain.GetRecentScheduleUseCase
import club.nito.core.domain.ModifyPasswordUseCase
import club.nito.core.domain.AuthStatusStreamUseCase
import club.nito.core.domain.ParticipateUseCase
import club.nito.core.domain.LoginUseCase
import club.nito.core.domain.LogoutUseCase
import club.nito.core.domain.ModifyPasswordUseCase
import club.nito.core.domain.ParticipateUseCase
import club.nito.core.network.auth.AuthRemoteDataSource
import club.nito.core.network.participation.ParticipantRemoteDataSource
import club.nito.core.network.schedule.ScheduleRemoteDataSource
Expand Down Expand Up @@ -39,6 +40,7 @@ class EntryPointTest {
assertNotNull(kmpEntryPoint.get<LoginUseCase>())
assertNotNull(kmpEntryPoint.get<ModifyPasswordUseCase>())
assertNotNull(kmpEntryPoint.get<LogoutUseCase>())
assertNotNull(kmpEntryPoint.get<FetchParticipantScheduleByIdUseCase>())
assertNotNull(kmpEntryPoint.get<GetRecentScheduleUseCase>())
assertNotNull(kmpEntryPoint.get<GetParticipantScheduleListUseCase>())
assertNotNull(kmpEntryPoint.get<ParticipateUseCase>())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ public struct ComposeScheduleListScreen: UIViewControllerRepresentable {

public func makeUIViewController(context: Context) -> UIViewController {
return ScheduleListScreen_iosKt.ScheduleListRouteViewController(
viewModel: ScheduleListViewModel(
getParticipantScheduleListUseCase: Container.shared.get(
stateMachine: ScheduleListStateMachine(
getParticipantScheduleList: Container.shared.get(
type: GetParticipantScheduleListUseCase.self),
userMessageStateHolder: Container.shared.get(type: UserMessageStateHolder.self),
dateTimeFormatter: Container.shared.get(type: CommonNitoDateFormatter.self)
dateFormatter: Container.shared.get(type: CommonNitoDateFormatter.self)
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import club.nito.core.model.AuthStatus
import club.nito.feature.auth.loginNavigationRoute
import club.nito.feature.auth.loginScreen
import club.nito.feature.auth.navigateToLogin
import club.nito.feature.schedule.navigateToSchedule
import club.nito.feature.schedule.scheduleScreen
import club.nito.feature.schedule.list.navigateToScheduleList
import club.nito.feature.schedule.list.scheduleListScreen
import club.nito.feature.settings.navigateToSettings
import club.nito.feature.settings.settingsScreen
import club.nito.feature.top.navigateToTop
Expand Down Expand Up @@ -41,7 +41,7 @@ fun NitoNavHost(
)

topScreen(
onScheduleListClick = navigator::navigateToSchedule,
onScheduleListClick = navigator::navigateToScheduleList,
onSettingsClick = navigator::navigateToSettings,
)
loginScreen(
Expand All @@ -56,7 +56,7 @@ fun NitoNavHost(
)
},
)
scheduleScreen()
scheduleListScreen()
settingsScreen(
onSignedOut = {
navigator.navigateToLogin(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package club.nito.core.data

import club.nito.core.model.Order
import club.nito.core.model.schedule.Schedule
import club.nito.core.model.schedule.ScheduleId
import club.nito.core.network.schedule.ScheduleRemoteDataSource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
Expand All @@ -25,8 +26,5 @@ public class OfflineFirstScheduleRepository(
after = after,
)

override fun scheduleFlow(id: String): Flow<Schedule> = flow {
// TODO: LocalDataSource
emit(remoteDataSource.getSchedule(id = id))
}
override suspend fun fetchSchedule(id: ScheduleId): Schedule = remoteDataSource.fetchSchedule(id = id)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package club.nito.core.data

import club.nito.core.model.Order
import club.nito.core.model.schedule.Schedule
import club.nito.core.model.schedule.ScheduleId
import kotlinx.coroutines.flow.Flow
import kotlinx.datetime.Instant

Expand All @@ -16,5 +17,8 @@ public sealed interface ScheduleRepository {
after: Instant? = null,
): List<Schedule>

public fun scheduleFlow(id: String): Flow<Schedule>
/**
* スケジュールを取得する
*/
public suspend fun fetchSchedule(id: ScheduleId): Schedule
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package club.nito.core.domain

import club.nito.core.data.ParticipantRepository
import club.nito.core.data.ScheduleRepository
import club.nito.core.data.UserRepository
import club.nito.core.domain.extension.toUserIdList
import club.nito.core.domain.model.ParticipantSchedule
import club.nito.core.model.FetchSingleContentResult
import club.nito.core.model.UserProfile
import club.nito.core.model.participant.Participant
import club.nito.core.model.schedule.Schedule
import club.nito.core.model.schedule.ScheduleId
import club.nito.core.model.toNitoError

/**
* ID を元にスケジュールを取得するユースケース
*/
public sealed interface FetchParticipantScheduleByIdUseCase {
public suspend operator fun invoke(id: ScheduleId): FetchSingleContentResult<ParticipantSchedule>
}

public class FetchParticipantScheduleByIdExecutor(
private val scheduleRepository: ScheduleRepository,
private val participantRepository: ParticipantRepository,
private val userRepository: UserRepository,
) : FetchParticipantScheduleByIdUseCase {
override suspend fun invoke(id: ScheduleId): FetchSingleContentResult<ParticipantSchedule> {
val schedule = try {
scheduleRepository.fetchSchedule(id = id)
} catch (e: Throwable) {
return FetchSingleContentResult.Failure(error = e.toNitoError())
}

val participants = participantRepository.getParticipants(id)
val profiles = userRepository.getProfiles(userIds = participants.toUserIdList())
val participantSchedule = transformToParticipantSchedule(
schedule = schedule,
participants = participants,
userProfiles = profiles,
)

return FetchSingleContentResult.Success(participantSchedule)
}

private fun transformToParticipantSchedule(
schedule: Schedule,
participants: List<Participant>,
userProfiles: List<UserProfile>,
): ParticipantSchedule {
val scheduleParticipants = participants.filter { it.scheduleId == schedule.id }
val scheduleParticipantProfiles = userProfiles.filter { profile ->
scheduleParticipants.any { it.userId == profile.id }
}

return ParticipantSchedule(
id = schedule.id,
scheduledAt = schedule.scheduledAt,
metAt = schedule.metAt,
venueId = schedule.venueId,
meetId = schedule.meetId,
description = schedule.description,
participants = scheduleParticipantProfiles,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package club.nito.core.domain.di

import club.nito.core.domain.AuthStatusStreamExecutor
import club.nito.core.domain.AuthStatusStreamUseCase
import club.nito.core.domain.FetchParticipantScheduleByIdExecutor
import club.nito.core.domain.FetchParticipantScheduleByIdUseCase
import club.nito.core.domain.GetParticipantScheduleListExecutor
import club.nito.core.domain.GetParticipantScheduleListUseCase
import club.nito.core.domain.GetRecentScheduleExecutor
Expand All @@ -24,6 +26,7 @@ public val useCaseModule: Module = module {
singleOf(::LoginExecutor) bind LoginUseCase::class
singleOf(::ModifyPasswordExecutor) bind ModifyPasswordUseCase::class
singleOf(::LogoutExecutor) bind LogoutUseCase::class
singleOf(::FetchParticipantScheduleByIdExecutor) bind FetchParticipantScheduleByIdUseCase::class
singleOf(::GetRecentScheduleExecutor) bind GetRecentScheduleUseCase::class
singleOf(::GetParticipantScheduleListExecutor) bind GetParticipantScheduleListUseCase::class
singleOf(::ParticipateExecutor) bind ParticipateUseCase::class
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package club.nito.core.domain.extension

import club.nito.core.model.participant.Participant

/**
* 重複を除いたユーザー ID のリストに変換する
*/
internal fun List<Participant>.toDistinctUserIdList(): List<String> = distinctBy { it.userId }.toUserIdList()

/**
* ユーザー ID のリストに変換する
*/
internal fun List<Participant>.toUserIdList(): List<String> = map { it.userId }
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package club.nito.core.domain.model

import club.nito.core.model.UserProfile
import club.nito.core.model.schedule.ScheduleId
import kotlinx.datetime.Instant

public data class ParticipantSchedule(
val id: String,
val id: ScheduleId,
val scheduledAt: Instant,
val metAt: Instant,
val venueId: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ package club.nito.core.model.schedule

import kotlinx.datetime.Instant

/**
* スケジュールID
*/
public typealias ScheduleId = String

/**
* スケジュール
* @param id ID
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package club.nito.core.model.schedule

/**
* スケジュールID
*/
public typealias ScheduleId = String
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package club.nito.core.network.schedule

import club.nito.core.model.Order
import club.nito.core.model.schedule.Schedule
import club.nito.core.model.schedule.ScheduleId
import club.nito.core.network.schedule.model.NetworkSchedule
import club.nito.core.network.schedule.model.createFakeNetworkSchedule
import kotlinx.datetime.Clock
Expand All @@ -27,10 +28,10 @@ public data object FakeScheduleRemoteDataSource : ScheduleRemoteDataSource {
}.map(NetworkSchedule::toSchedule)
}

override suspend fun getSchedule(id: String): Schedule {
override suspend fun fetchSchedule(id: ScheduleId): Schedule {
return createFakeNetworkSchedule(
id = id,
scheduledAt = Clock.System.now(),
).toSchedule()
).let(NetworkSchedule::toSchedule)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package club.nito.core.network.schedule

import club.nito.core.model.Order
import club.nito.core.model.schedule.Schedule
import club.nito.core.model.schedule.ScheduleId
import kotlinx.datetime.Instant

public sealed interface ScheduleRemoteDataSource {
Expand All @@ -11,5 +12,8 @@ public sealed interface ScheduleRemoteDataSource {
after: Instant? = null,
): List<Schedule>

public suspend fun getSchedule(id: String): Schedule
/**
* リモートからスケジュールを取得する
*/
public suspend fun fetchSchedule(id: ScheduleId): Schedule
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package club.nito.core.network.schedule

import club.nito.core.model.Order
import club.nito.core.model.schedule.Schedule
import club.nito.core.model.schedule.ScheduleId
import club.nito.core.network.NetworkService
import club.nito.core.network.schedule.model.NetworkSchedule
import club.nito.core.network.toSupabaseOrder
Expand All @@ -10,6 +11,7 @@ import io.github.jan.supabase.postgrest.postgrest
import kotlinx.datetime.Instant

private enum class Column(val columnName: String) {
ID(columnName = "id"),
DELETED_AT(columnName = "deleted_at"),
SCHEDULED_AT(columnName = "scheduled_at"),
}
Expand Down Expand Up @@ -38,15 +40,16 @@ public class SupabaseScheduleRemoteDataSource(
.map(NetworkSchedule::toSchedule)
}

override suspend fun getSchedule(id: String): Schedule = networkService {
override suspend fun fetchSchedule(id: ScheduleId): Schedule = networkService {
postgrest
.select {
single()
filter {
eq(Column.ID.columnName, id)
exact(Column.DELETED_AT.columnName, null)
}
}
.decodeSingle<NetworkSchedule>()
.toSchedule()
.let(NetworkSchedule::toSchedule)
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package club.nito.feature.schedule.di

import club.nito.feature.schedule.ScheduleListViewModel
import club.nito.feature.schedule.list.ScheduleListStateMachine
import org.koin.core.module.Module
import org.koin.dsl.module

public val scheduleFeatureModule: Module = module {
factory {
ScheduleListViewModel(
getParticipantScheduleListUseCase = get(),
ScheduleListStateMachine(
getParticipantScheduleList = get(),
userMessageStateHolder = get(),
dateTimeFormatter = get(),
dateFormatter = get(),
)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package club.nito.feature.schedule
package club.nito.feature.schedule.list

public sealed class ScheduleListEvent {
public data class NavigateToScheduleDetail(val scheduleId: String) : ScheduleListEvent()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package club.nito.feature.schedule
package club.nito.feature.schedule.list

import club.nito.core.domain.model.ParticipantSchedule

Expand Down
Loading