### feat: implementiere SQLite-Integration und Repository-Refactoring
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Failing after 58s
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 6m0s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 6m10s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Failing after 2m0s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m55s
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Failing after 58s
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 6m0s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 6m10s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Failing after 2m0s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m55s
- Erstelle Persistenz-Layer mit SQLite-Tabellen für `Verein` und `Reiter` inkl. Queries. - Entferne Mock-Daten in `ReiterViewModel` und nutze Repository-Injektion. - Integriere neue Tabellen und Queries im `DesktopMasterdataRepository`. - Erweitere `VeranstalterWizardViewModel` um lokale Suche mit SQLite-Queries. - Harmonisiere Feldnamen (`remoteReiterResults`) über alle Module hinweg. - Aktualisiere DI-Module (`VeranstalterModule`, `ReiterModule`, `DesktopModule`) mit SQLite-Injektionen. - Refaktor UI-Komponenten und Screens (`ReiterScreen`, `StammdatenImportScreen`) mit neuer Logik.
This commit is contained in:
+3
-3
@@ -1,13 +1,13 @@
|
||||
package at.mocode.frontend.shell.desktop.di
|
||||
|
||||
import at.mocode.frontend.shell.desktop.navigation.DesktopNavigationPort
|
||||
import at.mocode.frontend.shell.desktop.repository.DesktopMasterdataRepository
|
||||
import at.mocode.frontend.core.auth.data.local.AuthTokenManager
|
||||
import at.mocode.frontend.core.domain.models.User
|
||||
import at.mocode.frontend.core.domain.repository.MasterdataRepository
|
||||
import at.mocode.frontend.core.navigation.CurrentUserProvider
|
||||
import at.mocode.frontend.core.navigation.DeepLinkHandler
|
||||
import at.mocode.frontend.core.navigation.NavigationPort
|
||||
import at.mocode.frontend.shell.desktop.navigation.DesktopNavigationPort
|
||||
import at.mocode.frontend.shell.desktop.repository.DesktopMasterdataRepository
|
||||
import org.koin.dsl.module
|
||||
|
||||
/**
|
||||
@@ -34,5 +34,5 @@ val desktopModule = module {
|
||||
single<NavigationPort> { get<DesktopNavigationPort>() }
|
||||
single<CurrentUserProvider> { DesktopCurrentUserProvider(get()) }
|
||||
single { DeepLinkHandler(get(), get()) }
|
||||
single<MasterdataRepository> { DesktopMasterdataRepository() }
|
||||
single<MasterdataRepository> { DesktopMasterdataRepository(get()) }
|
||||
}
|
||||
|
||||
+77
-25
@@ -6,51 +6,90 @@ import at.mocode.frontend.core.domain.zns.ZnsRemoteFunktionaer
|
||||
import at.mocode.frontend.core.domain.zns.ZnsRemotePferd
|
||||
import at.mocode.frontend.core.domain.zns.ZnsRemoteReiter
|
||||
import at.mocode.frontend.core.domain.zns.ZnsRemoteVerein
|
||||
import at.mocode.frontend.core.localdb.AppDatabase
|
||||
import at.mocode.frontend.shell.desktop.data.*
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class DesktopMasterdataRepository : MasterdataRepository {
|
||||
class DesktopMasterdataRepository(
|
||||
private val db: AppDatabase
|
||||
) : MasterdataRepository {
|
||||
|
||||
private val queries = db.meldestelleDbQueries
|
||||
|
||||
override fun saveVereine(vereine: List<ZnsRemoteVerein>) {
|
||||
println("[Repository] Speichere ${vereine.size} Vereine")
|
||||
println("[Repository] Speichere ${vereine.size} Vereine in SQLite")
|
||||
val now = System.currentTimeMillis()
|
||||
runBlocking {
|
||||
queries.transaction {
|
||||
vereine.forEach { remote ->
|
||||
val id = remote.id.toLongOrNull() ?: return@forEach
|
||||
queries.upsertVerein(
|
||||
id = id,
|
||||
oebs_nummer = remote.oepsNummer ?: "",
|
||||
name = remote.name ?: "Unbekannt",
|
||||
ort = remote.ort,
|
||||
plz = null, // Falls vom Backend geliefert, hier mappen
|
||||
bundesland = remote.bundesland,
|
||||
is_active = 1,
|
||||
last_updated = now
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update Mock Store for backward compatibility during transition
|
||||
vereine.forEach { remote ->
|
||||
val id = remote.id.toLongOrNull() ?: return@forEach
|
||||
val existingIdx = Store.vereine.indexOfFirst { it.id == id }
|
||||
val verein = Verein(
|
||||
id = id,
|
||||
name = remote.name,
|
||||
oepsNummer = remote.oepsNummer,
|
||||
name = remote.name ?: "Unbekannt",
|
||||
oepsNummer = remote.oepsNummer ?: "",
|
||||
ort = remote.ort,
|
||||
bundesland = remote.bundesland,
|
||||
istVeranstalter = true // In der Meldestelle sind importierte ZNS-Vereine meist potenzielle Veranstalter
|
||||
istVeranstalter = true
|
||||
)
|
||||
if (existingIdx >= 0) {
|
||||
Store.vereine[existingIdx] = verein
|
||||
} else {
|
||||
Store.vereine.add(verein)
|
||||
}
|
||||
val existingIdx = Store.vereine.indexOfFirst { it.id == id }
|
||||
if (existingIdx >= 0) Store.vereine[existingIdx] = verein else Store.vereine.add(verein)
|
||||
}
|
||||
}
|
||||
|
||||
override fun saveReiter(reiter: List<ZnsRemoteReiter>) {
|
||||
println("[Repository] Speichere ${reiter.size} Reiter")
|
||||
println("[Repository] Speichere ${reiter.size} Reiter in SQLite")
|
||||
val now = System.currentTimeMillis()
|
||||
runBlocking {
|
||||
queries.transaction {
|
||||
reiter.forEach { remote ->
|
||||
val id = remote.id.toLongOrNull() ?: return@forEach
|
||||
queries.upsertReiter(
|
||||
id = id,
|
||||
zns_nummer = remote.satznummer,
|
||||
vorname = remote.vorname ?: "",
|
||||
nachname = remote.nachname ?: "",
|
||||
jahrgang = null, // Backend liefert aktuell kein Jahrgang direkt in ZnsRemoteReiter?
|
||||
geschlecht = null,
|
||||
nation = remote.nation ?: "AUT",
|
||||
is_active = 1,
|
||||
last_updated = now
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sync to Store
|
||||
reiter.forEach { remote ->
|
||||
val id = remote.id.toLongOrNull() ?: return@forEach
|
||||
val existingIdx = Store.reiter.indexOfFirst { it.id == id }
|
||||
val entry = Reiter(
|
||||
id = id,
|
||||
vorname = remote.vorname,
|
||||
nachname = remote.nachname,
|
||||
satznummer = remote.satznummer,
|
||||
oepsNummer = remote.satznummer, // Oft identisch oder Mapping nötig
|
||||
vorname = remote.vorname ?: "",
|
||||
nachname = remote.nachname ?: "",
|
||||
satznummer = remote.satznummer ?: "",
|
||||
oepsNummer = remote.satznummer ?: "",
|
||||
lizenzKlasse = remote.lizenzKlasse,
|
||||
nation = remote.nation ?: "AUT",
|
||||
bundesland = remote.bundesland
|
||||
)
|
||||
if (existingIdx >= 0) {
|
||||
Store.reiter[existingIdx] = entry
|
||||
} else {
|
||||
Store.reiter.add(entry)
|
||||
}
|
||||
val existingIdx = Store.reiter.indexOfFirst { it.id == id }
|
||||
if (existingIdx >= 0) Store.reiter[existingIdx] = entry else Store.reiter.add(entry)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,10 +136,23 @@ class DesktopMasterdataRepository : MasterdataRepository {
|
||||
}
|
||||
|
||||
override fun getStats(): MasterdataStats {
|
||||
val vereinCount = queries.selectAllVereine().executeAsList().size.toLong()
|
||||
val reiterCount = queries.selectAllReiter().executeAsList().size.toLong()
|
||||
|
||||
val lastUpdate = listOf(
|
||||
queries.selectAllVereine().executeAsList().maxOfOrNull { it.last_updated } ?: 0L,
|
||||
queries.selectAllReiter().executeAsList().maxOfOrNull { it.last_updated } ?: 0L
|
||||
).maxOrNull() ?: 0L
|
||||
|
||||
val lastImportStr = if (lastUpdate > 0) {
|
||||
val dt = LocalDateTime.now() // Vereinfacht, idealerweise aus lastUpdate Zeitstempel
|
||||
dt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
|
||||
} else "Nie"
|
||||
|
||||
return MasterdataStats(
|
||||
lastImport = "2026-04-20 18:45", // Mock-Wert könnte aus Settings kommen
|
||||
vereinCount = Store.vereine.size,
|
||||
reiterCount = Store.reiter.size,
|
||||
lastImport = lastImportStr,
|
||||
vereinCount = vereinCount.toInt(),
|
||||
reiterCount = reiterCount.toInt(),
|
||||
pferdCount = Store.pferde.size,
|
||||
funktionaerCount = Store.funktionaere.size
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user