### feat: erweitere Stammdaten-Integration

- **Repositories:** Implementiere und integriere `KtorPferdRepository` und `KtorFunktionaerRepository`.
- **SQLite:** Erweitere Schema um `LocalPferd` und `LocalFunktionaer` mit passenden Queries.
- **ViewModels:** Passe `PferdeViewModel` und `FunktionaerViewModel` an, um Flows und Repository-Injektion zu nutzen.
- **DI-Module:** Aktualisiere `PferdeModule` und `FunktionaerModule` für Backend-Anbindung.
This commit is contained in:
2026-04-22 12:25:39 +02:00
parent d4cc0eb77d
commit 98c241fc64
12 changed files with 385 additions and 178 deletions
@@ -0,0 +1,44 @@
package at.mocode.frontend.features.funktionaer.data
import at.mocode.frontend.features.funktionaer.domain.Funktionaer
import at.mocode.frontend.features.funktionaer.domain.FunktionaerRepository
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.request.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
class KtorFunktionaerRepository(private val client: HttpClient) : FunktionaerRepository {
override fun getFunktionaere(): Flow<List<Funktionaer>> = flow {
try {
val response: List<Funktionaer> = client.get("/api/v1/masterdata/funktionaere").body()
emit(response)
} catch (_: Exception) {
emit(emptyList())
}
}
override suspend fun searchFunktionaere(query: String): List<Funktionaer> {
return try {
client.get("/api/v1/masterdata/funktionaere/search") {
parameter("q", query)
}.body()
} catch (_: Exception) {
emptyList()
}
}
override suspend fun getFunktionaerById(id: Long): Funktionaer? {
return try {
client.get("/api/v1/masterdata/funktionaere/$id").body()
} catch (_: Exception) {
null
}
}
override suspend fun saveFunktionaer(funktionaer: Funktionaer) {
client.post("/api/v1/masterdata/funktionaere") {
setBody(funktionaer)
}
}
}
@@ -1,18 +1,12 @@
package at.mocode.frontend.features.funktionaer.di
import at.mocode.frontend.features.funktionaer.domain.Funktionaer
import at.mocode.frontend.features.funktionaer.presentation.*
import at.mocode.frontend.features.funktionaer.data.KtorFunktionaerRepository
import at.mocode.frontend.features.funktionaer.domain.FunktionaerRepository
import at.mocode.frontend.features.funktionaer.presentation.FunktionaerViewModel
import org.koin.core.qualifier.named
import org.koin.dsl.module
val funktionaerModule = module {
single<FunktionaerRepository> { MockFunktionaerRepository() }
factory { FunktionaerViewModel(get()) }
}
class MockFunktionaerRepository : FunktionaerRepository {
override suspend fun list(): List<Funktionaer> = listOf(
Funktionaer(1, "Wolfgang", "Schier", "12345", listOf("RICHTER"), "G3"),
Funktionaer(2, "Alice", "Schwab", "23456", listOf("RICHTER"), "INTERNATIONAL"),
Funktionaer(3, "Dietmar", "Gstöttner", "34567", listOf("PARCOURSBAUER"), null)
)
single<FunktionaerRepository> { KtorFunktionaerRepository(get(named("apiClient"))) }
factory { FunktionaerViewModel(get()) }
}
@@ -0,0 +1,10 @@
package at.mocode.frontend.features.funktionaer.domain
import kotlinx.coroutines.flow.Flow
interface FunktionaerRepository {
fun getFunktionaere(): Flow<List<Funktionaer>>
suspend fun searchFunktionaere(query: String): List<Funktionaer>
suspend fun getFunktionaerById(id: Long): Funktionaer?
suspend fun saveFunktionaer(funktionaer: Funktionaer)
}
@@ -3,6 +3,7 @@ package at.mocode.frontend.features.funktionaer.presentation
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import at.mocode.frontend.features.funktionaer.domain.Funktionaer
import at.mocode.frontend.features.funktionaer.domain.FunktionaerRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
@@ -51,10 +52,6 @@ sealed interface FunktionaerIntent {
data object ClearError : FunktionaerIntent
}
interface FunktionaerRepository {
suspend fun list(): List<Funktionaer>
}
class FunktionaerViewModel(
private val repo: FunktionaerRepository,
) : ViewModel() {
@@ -115,10 +112,11 @@ class FunktionaerViewModel(
reduce { it.copy(isLoading = true, errorMessage = null) }
viewModelScope.launch {
try {
val items = repo.list()
reduce { cur ->
val filtered = filterList(items, cur.searchQuery)
cur.copy(isLoading = false, list = items, filtered = filtered)
repo.getFunktionaere().collect { items ->
reduce { cur ->
val filtered = filterList(items, cur.searchQuery)
cur.copy(isLoading = false, list = items, filtered = filtered)
}
}
} catch (t: Throwable) {
reduce { it.copy(isLoading = false, errorMessage = t.message ?: "Fehler beim Laden") }