Skip to content

Commit

Permalink
✨ スケジュール一覧を取得するユースケースを追加
Browse files Browse the repository at this point in the history
  • Loading branch information
tatsutakein committed Nov 4, 2023
1 parent 998858f commit 6103f75
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package club.nito.ios.combined

import club.nito.core.data.AuthRepository
import club.nito.core.data.ScheduleRepository
import club.nito.core.domain.GetParticipantScheduleListUseCase
import club.nito.core.domain.GetRecentScheduleUseCase
import club.nito.core.domain.ObserveAuthStatusUseCase
import club.nito.core.domain.ParticipateUseCase
Expand Down Expand Up @@ -37,6 +38,7 @@ class EntryPointTest {
assertNotNull(kmpEntryPoint.get<SignInUseCase>())
assertNotNull(kmpEntryPoint.get<SignOutUseCase>())
assertNotNull(kmpEntryPoint.get<GetRecentScheduleUseCase>())
assertNotNull(kmpEntryPoint.get<GetParticipantScheduleListUseCase>())
assertNotNull(kmpEntryPoint.get<ParticipateUseCase>())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class DefaultParticipantRepository(
override suspend fun getParticipants(scheduleId: String): List<Participant> =
remoteDataSource.getParticipants(scheduleId = scheduleId)

override suspend fun getParticipants(scheduleIds: List<String>): List<Participant> =
remoteDataSource.getParticipants(scheduleIds = scheduleIds)

override suspend fun participate(declaration: ParticipantDeclaration): Long =
remoteDataSource.participate(declaration = declaration)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ sealed interface ParticipantRepository {
*/
suspend fun getParticipants(scheduleId: String): List<Participant>

/**
* 該当の予定の参加情報を取得する
*
* @param scheduleIds 参加情報を取得するスケジュールID配列
*/
suspend fun getParticipants(scheduleIds: List<String>): List<Participant>

/**
* 該当のスケジュールに参加する
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import club.nito.core.data.AuthRepository
import club.nito.core.data.ParticipantRepository
import club.nito.core.data.ScheduleRepository
import club.nito.core.data.UserRepository
import club.nito.core.domain.GetParticipantScheduleListExecutor
import club.nito.core.domain.GetParticipantScheduleListUseCase
import club.nito.core.domain.GetRecentScheduleExecutor
import club.nito.core.domain.GetRecentScheduleUseCase
import club.nito.core.domain.ObserveAuthStatusExecutor
Expand Down Expand Up @@ -54,6 +56,17 @@ class UseCaseModule {
userRepository = userRepository,
)

@Provides
fun provideGetParticipantScheduleListUseCase(
scheduleRepository: ScheduleRepository,
participantRepository: ParticipantRepository,
userRepository: UserRepository,
): GetParticipantScheduleListUseCase = GetParticipantScheduleListExecutor(
scheduleRepository = scheduleRepository,
participantRepository = participantRepository,
userRepository = userRepository,
)

@Provides
fun provideParticipateUseCase(
participantRepository: ParticipantRepository,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
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.model.ParticipantSchedule
import club.nito.core.model.FetchMultipleContentResult
import club.nito.core.model.Schedule
import club.nito.core.model.UserProfile
import club.nito.core.model.participant.Participant
import club.nito.core.model.toNitoError
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow

/**
* スケジュール一覧を取得するユースケース
*/
sealed interface GetParticipantScheduleListUseCase {
operator fun invoke(): Flow<FetchMultipleContentResult<ParticipantSchedule>>
}

class GetParticipantScheduleListExecutor(
private val scheduleRepository: ScheduleRepository,
private val participantRepository: ParticipantRepository,
private val userRepository: UserRepository,
) : GetParticipantScheduleListUseCase {
override fun invoke(): Flow<FetchMultipleContentResult<ParticipantSchedule>> = flow {
val schedules = try {
scheduleRepository.getScheduleList(limit = 10)
} catch (e: Throwable) {
emit(FetchMultipleContentResult.Failure(error = e.toNitoError()))
return@flow
}

if (schedules.isEmpty()) {
emit(FetchMultipleContentResult.NoContent)
return@flow
}

val participants = participantRepository.getParticipants(scheduleIds = schedules.map { it.id })
val profiles = userRepository.getProfiles(userIds = participants.distinctBy { it.userId }.map { it.userId })

val participantScheduleList = transformToParticipantScheduleList(
schedules = schedules,
participants = participants,
userProfiles = profiles,
)

emit(FetchMultipleContentResult.Success(participantScheduleList))
}

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

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 @@ -10,5 +10,6 @@ val useCaseModule: Module = module {
singleOf(::SignInExecutor) bind SignInUseCase::class
singleOf(::SignOutExecutor) bind SignOutUseCase::class
singleOf(::GetRecentScheduleExecutor) bind GetRecentScheduleUseCase::class
singleOf(::GetParticipantScheduleListExecutor) bind GetParticipantScheduleListUseCase::class
singleOf(::ParticipateExecutor) bind ParticipateUseCase::class
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package club.nito.core.model

/**
* 複数のコンテンツデータを取得する結果
*/
sealed interface FetchMultipleContentResult<out T> {
/**
* 取得中
*/
data object Loading : FetchMultipleContentResult<Nothing>

/**
* 該当データなし
*/
data object NoContent : FetchMultipleContentResult<Nothing>

/**
* 取得成功
*/
data class Success<T>(val data: List<T>) : FetchMultipleContentResult<T>

/**
* 取得失敗
*/
data class Failure(val error: NitoError?) : FetchMultipleContentResult<Nothing>
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ sealed interface ParticipantRemoteDataSource {
*/
suspend fun getParticipants(scheduleId: String): List<Participant>

/**
* 該当の予定の参加情報を取得する
*
* @param scheduleIds 参加情報を取得するスケジュールID配列
*/
suspend fun getParticipants(scheduleIds: List<String>): List<Participant>

/**
* 該当のスケジュールに参加する
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ class SupabaseParticipantRemoteDataSource(
.decodeList<NetworkParticipant>()
.map(NetworkParticipant::toParticipant)

override suspend fun getParticipants(scheduleIds: List<String>): List<Participant> = postgrest
.select(
filter = {
and {
isIn("schedule_id", scheduleIds)
exact("deleted_at", null)
}
},
)
.decodeList<NetworkParticipant>()
.map(NetworkParticipant::toParticipant)

override suspend fun participate(declaration: ParticipantDeclaration): Long {
val result = postgrest.insert(
value = declaration.toNetworkModel(),
Expand Down

0 comments on commit 6103f75

Please sign in to comment.