-
Notifications
You must be signed in to change notification settings - Fork 0
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 を元にスケジュールを取得するユースケースを追加 #121
Changes from all commits
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,13 @@ | ||
package club.nito.core.data | ||
|
||
import club.nito.core.model.place.Place | ||
import club.nito.core.model.place.PlaceId | ||
import club.nito.core.network.place.PlaceRemoteDataSource | ||
|
||
public class DefaultPlaceRepository( | ||
private val remoteDataSource: PlaceRemoteDataSource, | ||
) : PlaceRepository { | ||
override suspend fun fetchPlaceList(vararg ids: PlaceId): List<Place> { | ||
return remoteDataSource.fetchPlaceList(ids.toList()) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package club.nito.core.data | ||
|
||
import club.nito.core.model.place.Place | ||
import club.nito.core.model.place.PlaceId | ||
|
||
/** | ||
* 場所に関するリポジトリ | ||
*/ | ||
public sealed interface PlaceRepository { | ||
/** | ||
* 場所を取得する | ||
* @param ids 取得する場所のID | ||
*/ | ||
public suspend fun fetchPlaceList(vararg ids: PlaceId): List<Place> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,15 @@ | ||
package club.nito.core.domain | ||
|
||
import club.nito.core.data.ParticipantRepository | ||
import club.nito.core.data.PlaceRepository | ||
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.place.Place | ||
import club.nito.core.model.schedule.Schedule | ||
import club.nito.core.model.schedule.ScheduleId | ||
import club.nito.core.model.toNitoError | ||
|
@@ -22,6 +24,7 @@ public sealed interface FetchParticipantScheduleByIdUseCase { | |
public class FetchParticipantScheduleByIdExecutor( | ||
private val scheduleRepository: ScheduleRepository, | ||
private val participantRepository: ParticipantRepository, | ||
private val placeRepository: PlaceRepository, | ||
private val userRepository: UserRepository, | ||
) : FetchParticipantScheduleByIdUseCase { | ||
override suspend fun invoke(id: ScheduleId): FetchSingleContentResult<ParticipantSchedule> { | ||
|
@@ -33,10 +36,12 @@ public class FetchParticipantScheduleByIdExecutor( | |
|
||
val participants = participantRepository.getParticipants(id) | ||
val profiles = userRepository.getProfiles(userIds = participants.toUserIdList()) | ||
val places = placeRepository.fetchPlaceList(schedule.venueId, schedule.meetId) | ||
val participantSchedule = transformToParticipantSchedule( | ||
schedule = schedule, | ||
participants = participants, | ||
userProfiles = profiles, | ||
places = places, | ||
) | ||
|
||
return FetchSingleContentResult.Success(participantSchedule) | ||
|
@@ -46,6 +51,7 @@ public class FetchParticipantScheduleByIdExecutor( | |
schedule: Schedule, | ||
participants: List<Participant>, | ||
userProfiles: List<UserProfile>, | ||
places: List<Place>, | ||
): ParticipantSchedule { | ||
val scheduleParticipants = participants.filter { it.scheduleId == schedule.id } | ||
val scheduleParticipantProfiles = userProfiles.filter { profile -> | ||
|
@@ -56,8 +62,8 @@ public class FetchParticipantScheduleByIdExecutor( | |
id = schedule.id, | ||
scheduledAt = schedule.scheduledAt, | ||
metAt = schedule.metAt, | ||
venueId = schedule.venueId, | ||
meetId = schedule.meetId, | ||
venue = places.first { it.id == schedule.venueId }, | ||
meet = places.first { it.id == schedule.meetId }, | ||
Comment on lines
+65
to
+66
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. コードには、 val venue = places.firstOrNull { it.id == schedule.venueId } ?: throw SomeException("Venue not found")
val meet = places.firstOrNull { it.id == schedule.meetId } ?: throw SomeException("Meet not found") |
||
description = schedule.description, | ||
participants = scheduleParticipantProfiles, | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,15 @@ | ||
package club.nito.core.domain | ||
|
||
import club.nito.core.data.ParticipantRepository | ||
import club.nito.core.data.PlaceRepository | ||
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.Schedule | ||
import club.nito.core.model.UserProfile | ||
import club.nito.core.model.participant.Participant | ||
import club.nito.core.model.place.Place | ||
import club.nito.core.model.schedule.Schedule | ||
import club.nito.core.model.toNitoError | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.flow | ||
|
@@ -22,6 +24,7 @@ public sealed interface GetParticipantScheduleListUseCase { | |
public class GetParticipantScheduleListExecutor( | ||
private val scheduleRepository: ScheduleRepository, | ||
private val participantRepository: ParticipantRepository, | ||
private val placeRepository: PlaceRepository, | ||
private val userRepository: UserRepository, | ||
) : GetParticipantScheduleListUseCase { | ||
override fun invoke(): Flow<FetchMultipleContentResult<ParticipantSchedule>> = flow { | ||
|
@@ -40,10 +43,14 @@ public class GetParticipantScheduleListExecutor( | |
val participants = participantRepository.getParticipants(scheduleIds = schedules.map { it.id }) | ||
val profiles = userRepository.getProfiles(userIds = participants.distinctBy { it.userId }.map { it.userId }) | ||
|
||
val placeIds = (schedules.map { it.meetId } + schedules.map { it.venueId }).distinct() | ||
val places = placeRepository.fetchPlaceList(*placeIds.toTypedArray()) | ||
|
||
val participantScheduleList = transformToParticipantScheduleList( | ||
schedules = schedules, | ||
participants = participants, | ||
userProfiles = profiles, | ||
places = places, | ||
) | ||
|
||
emit(FetchMultipleContentResult.Success(participantScheduleList)) | ||
|
@@ -53,6 +60,7 @@ public class GetParticipantScheduleListExecutor( | |
schedules: List<Schedule>, | ||
participants: List<Participant>, | ||
userProfiles: List<UserProfile>, | ||
places: List<Place>, | ||
): List<ParticipantSchedule> = schedules.map { schedule -> | ||
val scheduleParticipants = participants.filter { it.scheduleId == schedule.id } | ||
val scheduleParticipantProfiles = userProfiles.filter { profile -> | ||
|
@@ -63,8 +71,8 @@ public class GetParticipantScheduleListExecutor( | |
id = schedule.id, | ||
scheduledAt = schedule.scheduledAt, | ||
metAt = schedule.metAt, | ||
venueId = schedule.venueId, | ||
meetId = schedule.meetId, | ||
venue = places.first { it.id == schedule.venueId }, | ||
meet = places.first { it.id == schedule.meetId }, | ||
Comment on lines
+74
to
+75
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.
// 事前にIDをキーとするマップを作成
val placesById = places.associateBy { it.id }
// マップから直接参照
val venue = placesById[schedule.venueId]
val meet = placesById[schedule.meetId] |
||
description = schedule.description, | ||
participants = scheduleParticipantProfiles, | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,16 @@ | ||
package club.nito.core.domain.model | ||
|
||
import club.nito.core.model.UserProfile | ||
import club.nito.core.model.place.Place | ||
import club.nito.core.model.schedule.ScheduleId | ||
import kotlinx.datetime.Instant | ||
|
||
public data class ParticipantSchedule( | ||
val id: ScheduleId, | ||
val scheduledAt: Instant, | ||
val metAt: Instant, | ||
val venueId: String, | ||
val meetId: String, | ||
val venue: Place, | ||
val meet: Place, | ||
val description: String, | ||
val participants: List<UserProfile>, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package club.nito.core.model.place | ||
|
||
/** | ||
* 場所 | ||
* @param id ID | ||
* @param name 名前 | ||
* @param description 説明文 | ||
* @param mapUrl 地図URL | ||
* @param imageUrl 画像URL | ||
*/ | ||
public data class Place( | ||
val id: PlaceId, | ||
val name: String, | ||
val description: String, | ||
val mapUrl: String, | ||
val imageUrl: String, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package club.nito.core.model.place | ||
|
||
/** | ||
* 場所ID | ||
*/ | ||
public typealias PlaceId = String |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package club.nito.core.network.place | ||
|
||
import club.nito.core.model.place.Place | ||
import club.nito.core.model.place.PlaceId | ||
import club.nito.core.network.place.model.NetworkPlace | ||
import club.nito.core.network.place.model.createFakeNetworkPlace | ||
|
||
public data object FakePlaceRemoteDataSource : PlaceRemoteDataSource { | ||
override suspend fun fetchPlaceList(idList: List<PlaceId>): List<Place> = idList.map { id -> | ||
createFakeNetworkPlace( | ||
id = id, | ||
).let(NetworkPlace::toPlace) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package club.nito.core.network.place | ||
|
||
import club.nito.core.model.place.Place | ||
import club.nito.core.model.place.PlaceId | ||
|
||
/** | ||
* 場所リモートデータソース | ||
*/ | ||
public sealed interface PlaceRemoteDataSource { | ||
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.
|
||
/** | ||
* リモートから場所を取得する | ||
* @param idList 取得する場所のID | ||
*/ | ||
public suspend fun fetchPlaceList(idList: List<PlaceId>): List<Place> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package club.nito.core.network.place | ||
|
||
import club.nito.core.model.place.Place | ||
import club.nito.core.model.place.PlaceId | ||
import club.nito.core.network.NetworkService | ||
import club.nito.core.network.place.model.NetworkPlace | ||
import io.github.jan.supabase.SupabaseClient | ||
import io.github.jan.supabase.postgrest.postgrest | ||
|
||
private enum class Column(val columnName: String) { | ||
ID(columnName = "id"), | ||
DELETED_AT(columnName = "deleted_at"), | ||
} | ||
|
||
public class SupabasePlaceRemoteDataSource( | ||
private val networkService: NetworkService, | ||
private val client: SupabaseClient, | ||
) : PlaceRemoteDataSource { | ||
private val postgrest = client.postgrest["places"] | ||
|
||
override suspend fun fetchPlaceList(idList: List<PlaceId>): List<Place> = networkService { | ||
postgrest | ||
.select { | ||
filter { | ||
isIn(Column.ID.columnName, idList) | ||
exact(Column.DELETED_AT.columnName, null) | ||
} | ||
} | ||
.decodeList<NetworkPlace>() | ||
.map(NetworkPlace::toPlace) | ||
} | ||
} |
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.
PlaceRepository
がsealed interfaceとして定義されていますが、これはリポジトリパターンには一般的ではありません。sealed interfaceは、限定された実装セットを持つ場合に使用されることが多いです。リポジトリは様々なデータソースによって実装されることが期待されているため、ここではsealedを削除することを検討してください。