Refactor BundeslandRepository, implement V012 migration for Reiter master data changes, harmonize domain models, resolve repository interface inconsistencies, and enhance ZNS import with relational mapping improvements.
This commit is contained in:
parent
0ae9a1f1b8
commit
1b6f8e7c59
14
CHANGELOG.md
14
CHANGELOG.md
|
|
@ -57,6 +57,20 @@ Versionierung folgt [Semantic Versioning](https://semver.org/lang/de/).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## [1.0.3-SNAPSHOT] — 2026-04-06
|
||||||
|
|
||||||
|
### Hinzugefügt
|
||||||
|
- **Masterdata:** Refactoring der Reiter-Stammdaten (LIZENZ01.DAT). Bundesland, Verein und Nation werden nun über Master-Tabellen referenziert.
|
||||||
|
- **Domain:** Validierungslogik für die 8-stellige OEPS-Mitgliedsnummer im `Reiter`-Modell implementiert.
|
||||||
|
- **Infrastructure:** Neue Tabellen `reiter_lizenz` (1:n Beziehung) und Migration `V012` zur Schemaanpassung und Datenbereinigung eingeführt.
|
||||||
|
- **ZNS-Import:** Automatisches Auflösen von Relationen (Verein nach Name, Bundesland nach Nummer, Nation nach ISO-Code) während des Reiter-Imports.
|
||||||
|
|
||||||
|
### Behoben
|
||||||
|
- **Build:** Kompilierfehler in `BundeslandExposedRepository.kt` behoben (inkonsistente Rückgabetypen im `BundeslandRepository`-Interface).
|
||||||
|
- **Infrastruktur:** Fehlendes Autowiring im `zns-import-service` durch explizite Bean-Definitionen für alle Repositories in `ZnsImportServiceApplication.kt` behoben.
|
||||||
|
- **Domain:** Kompilierfehler in `Bundesland.kt` behoben (uninitialisierte Eigenschaft `bundeslandId` entfernt).
|
||||||
|
- **Migration:** SQL-Syntaxfehler in `V012` behoben (korrekter Fremdschlüssel-Constraint für `reiter_lizenz` und Wiederherstellung des `DO $$`-Blocks).
|
||||||
|
|
||||||
## [1.0.2-SNAPSHOT] — 2026-04-06
|
## [1.0.2-SNAPSHOT] — 2026-04-06
|
||||||
|
|
||||||
### Geändert
|
### Geändert
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||||
package at.mocode.masterdata.domain.repository
|
package at.mocode.masterdata.domain.repository
|
||||||
|
|
||||||
|
import at.mocode.masterdata.domain.model.Bundesland
|
||||||
import at.mocode.masterdata.domain.model.BundeslandDefinition
|
import at.mocode.masterdata.domain.model.BundeslandDefinition
|
||||||
import kotlin.uuid.Uuid
|
import kotlin.uuid.Uuid
|
||||||
|
|
||||||
|
|
@ -12,7 +13,7 @@ interface BundeslandRepository {
|
||||||
/**
|
/**
|
||||||
* ZNS-Spezifisch: Sucht ein Bundesland anhand seiner Nummer (01-09).
|
* ZNS-Spezifisch: Sucht ein Bundesland anhand seiner Nummer (01-09).
|
||||||
*/
|
*/
|
||||||
suspend fun findByNr(nr: Int): at.mocode.masterdata.domain.model.BundeslandDefinition?
|
suspend fun findByNr(nr: Int): BundeslandDefinition?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a federal state by its unique ID.
|
* Finds a federal state by its unique ID.
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ class BundeslandRepositoryImpl : BundeslandRepository {
|
||||||
it[createdAt] = bundesland.createdAt
|
it[createdAt] = bundesland.createdAt
|
||||||
it[updatedAt] = bundesland.updatedAt
|
it[updatedAt] = bundesland.updatedAt
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (_: Exception) {
|
||||||
// Race-Condition → erneut Update
|
// Race-Condition → erneut Update
|
||||||
if (bundesland.kuerzel != null) {
|
if (bundesland.kuerzel != null) {
|
||||||
BundeslandTable.update({ (BundeslandTable.landId eq bundesland.landId) and (BundeslandTable.kuerzel eq bundesland.kuerzel) }) {
|
BundeslandTable.update({ (BundeslandTable.landId eq bundesland.landId) and (BundeslandTable.kuerzel eq bundesland.kuerzel) }) {
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
package at.mocode.masterdata.infrastructure.persistence.reiter
|
package at.mocode.masterdata.infrastructure.persistence.reiter
|
||||||
|
|
||||||
import at.mocode.masterdata.domain.model.Bundesland
|
|
||||||
import at.mocode.masterdata.domain.model.BundeslandDefinition
|
import at.mocode.masterdata.domain.model.BundeslandDefinition
|
||||||
import at.mocode.masterdata.domain.repository.BundeslandRepository
|
import at.mocode.masterdata.domain.repository.BundeslandRepository
|
||||||
import at.mocode.core.utils.database.DatabaseFactory
|
import at.mocode.core.utils.database.DatabaseFactory
|
||||||
|
import at.mocode.masterdata.infrastructure.persistence.BundeslandTable
|
||||||
|
import kotlinx.datetime.Clock
|
||||||
import org.jetbrains.exposed.v1.core.ResultRow
|
import org.jetbrains.exposed.v1.core.ResultRow
|
||||||
import org.jetbrains.exposed.v1.core.eq
|
import org.jetbrains.exposed.v1.core.eq
|
||||||
import org.jetbrains.exposed.v1.jdbc.*
|
import org.jetbrains.exposed.v1.jdbc.*
|
||||||
|
|
@ -16,14 +17,22 @@ import kotlin.uuid.Uuid
|
||||||
* Hinweis: Implementiert nur die für den ZNS-Import notwendigen Methoden.
|
* Hinweis: Implementiert nur die für den ZNS-Import notwendigen Methoden.
|
||||||
*/
|
*/
|
||||||
class BundeslandExposedRepository : BundeslandRepository {
|
class BundeslandExposedRepository : BundeslandRepository {
|
||||||
private fun rowToDom(row: ResultRow) = Bundesland(
|
private fun rowToDom(row: ResultRow) = BundeslandDefinition(
|
||||||
id = row[BundeslandTable.id],
|
bundeslandId = row[BundeslandTable.id],
|
||||||
|
landId = row[BundeslandTable.landId],
|
||||||
bundeslandNr = row[BundeslandTable.bundeslandNr],
|
bundeslandNr = row[BundeslandTable.bundeslandNr],
|
||||||
bezeichnung = row[BundeslandTable.bezeichnung],
|
oepsCode = row[BundeslandTable.oepsCode],
|
||||||
wappenUrl = row[BundeslandTable.wappenUrl]
|
iso3166_2_Code = row[BundeslandTable.iso3166_2_Code],
|
||||||
|
name = row[BundeslandTable.name],
|
||||||
|
kuerzel = row[BundeslandTable.kuerzel],
|
||||||
|
wappenUrl = row[BundeslandTable.wappenUrl],
|
||||||
|
istAktiv = row[BundeslandTable.istAktiv],
|
||||||
|
sortierReihenfolge = row[BundeslandTable.sortierReihenfolge],
|
||||||
|
createdAt = row[BundeslandTable.createdAt],
|
||||||
|
updatedAt = row[BundeslandTable.updatedAt]
|
||||||
)
|
)
|
||||||
|
|
||||||
override suspend fun findByNr(nr: Int): Bundesland? = DatabaseFactory.dbQuery {
|
override suspend fun findByNr(nr: Int): BundeslandDefinition? = DatabaseFactory.dbQuery {
|
||||||
BundeslandTable.selectAll().where { BundeslandTable.bundeslandNr eq nr }
|
BundeslandTable.selectAll().where { BundeslandTable.bundeslandNr eq nr }
|
||||||
.map(::rowToDom)
|
.map(::rowToDom)
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import at.mocode.masterdata.domain.repository.VereinRepository
|
||||||
import org.jetbrains.exposed.v1.core.ResultRow
|
import org.jetbrains.exposed.v1.core.ResultRow
|
||||||
import org.jetbrains.exposed.v1.core.eq
|
import org.jetbrains.exposed.v1.core.eq
|
||||||
import org.jetbrains.exposed.v1.core.like
|
import org.jetbrains.exposed.v1.core.like
|
||||||
import org.jetbrains.exposed.v1.core.or
|
|
||||||
import org.jetbrains.exposed.v1.jdbc.*
|
import org.jetbrains.exposed.v1.jdbc.*
|
||||||
import kotlin.uuid.ExperimentalUuidApi
|
import kotlin.uuid.ExperimentalUuidApi
|
||||||
import kotlin.uuid.Uuid
|
import kotlin.uuid.Uuid
|
||||||
|
|
|
||||||
|
|
@ -36,16 +36,15 @@ ALTER TABLE reiter ADD COLUMN IF NOT EXISTS nation_id UUID;
|
||||||
-- Fremdschlüssel-Constraints
|
-- Fremdschlüssel-Constraints
|
||||||
ALTER TABLE reiter ADD CONSTRAINT fk_reiter_verein FOREIGN KEY (verein_id) REFERENCES verein(verein_id);
|
ALTER TABLE reiter ADD CONSTRAINT fk_reiter_verein FOREIGN KEY (verein_id) REFERENCES verein(verein_id);
|
||||||
ALTER TABLE reiter ADD CONSTRAINT fk_reiter_bundesland FOREIGN KEY (bundesland_id) REFERENCES bundesland(id);
|
ALTER TABLE reiter ADD CONSTRAINT fk_reiter_bundesland FOREIGN KEY (bundesland_id) REFERENCES bundesland(id);
|
||||||
ALTER TABLE reiter ADD CONSTRAINT fk_reiter_nation FOREIGN KEY (nation_id) REFERENCES land(id);
|
ALTER TABLE reiter ADD CONSTRAINT fk_reiter_nation FOREIGN KEY (nation_id) REFERENCES land(land_id);
|
||||||
ALTER TABLE reiter ADD CONSTRAINT fk_reiter_lizenz_reiter FOREIGN KEY (reiter_id) REFERENCES reiter(reiter_id) ON DELETE CASCADE;
|
ALTER TABLE reiter_lizenz ADD CONSTRAINT fk_reiter_lizenz_reiter FOREIGN KEY (reiter_id) REFERENCES reiter(reiter_id) ON DELETE CASCADE;
|
||||||
|
|
||||||
-- 3. Daten gemäß OEPS-Spezifikation korrigieren (für Österreich)
|
-- 3. Daten gemäß OEPS-Spezifikation korrigieren (für Österreich)
|
||||||
|
|
||||||
DO $$
|
DO $$
|
||||||
DECLARE
|
DECLARE
|
||||||
austria_id UUID;
|
austria_id UUID;
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT id INTO austria_id FROM land WHERE iso_alpha2_code = 'AT';
|
SELECT land_id INTO austria_id FROM land WHERE iso_alpha2_code = 'AT';
|
||||||
|
|
||||||
IF austria_id IS NOT NULL THEN
|
IF austria_id IS NOT NULL THEN
|
||||||
-- Bestehende Einträge löschen oder aktualisieren
|
-- Bestehende Einträge löschen oder aktualisieren
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,57 @@
|
||||||
package at.mocode.zns.import.service
|
package at.mocode.zns.import.service
|
||||||
|
|
||||||
import at.mocode.masterdata.domain.repository.FunktionaerRepository
|
import at.mocode.masterdata.domain.repository.*
|
||||||
import at.mocode.masterdata.domain.repository.HorseRepository
|
import at.mocode.masterdata.infrastructure.persistence.*
|
||||||
import at.mocode.masterdata.domain.repository.ReiterRepository
|
import at.mocode.masterdata.infrastructure.persistence.funktionaer.FunktionaerExposedRepository
|
||||||
import at.mocode.masterdata.domain.repository.VereinRepository
|
import at.mocode.masterdata.infrastructure.persistence.pferd.HorseExposedRepository
|
||||||
|
import at.mocode.masterdata.infrastructure.persistence.reiter.ReiterExposedRepository
|
||||||
|
import at.mocode.masterdata.infrastructure.persistence.verein.VereinExposedRepository
|
||||||
import at.mocode.zns.importer.ZnsImportService
|
import at.mocode.zns.importer.ZnsImportService
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
import org.springframework.boot.runApplication
|
import org.springframework.boot.runApplication
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.ComponentScan
|
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@ComponentScan(
|
|
||||||
basePackages = [
|
|
||||||
"at.mocode.zns.import.service",
|
|
||||||
"at.mocode.masterdata.infrastructure"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
class ZnsImportServiceApplication {
|
class ZnsImportServiceApplication {
|
||||||
|
|
||||||
|
// Manuelle Bean-Definitionen für die Repositories, da diese in der Infrastruktur
|
||||||
|
// keine @Repository-Annotationen haben und wir MasterdataConfiguration nicht importieren wollen.
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun landRepository(): LandRepository = LandRepositoryImpl()
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun bundeslandRepository(): BundeslandRepository = BundeslandRepositoryImpl()
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun vereinRepository(): VereinRepository = VereinExposedRepository()
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun reiterRepository(): ReiterRepository = ReiterExposedRepository()
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun horseRepository(): HorseRepository = HorseExposedRepository()
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun funktionaerRepository(): FunktionaerRepository = FunktionaerExposedRepository()
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
fun znsImportService(
|
fun znsImportService(
|
||||||
vereinRepository: VereinRepository,
|
vereinRepository: VereinRepository,
|
||||||
reiterRepository: ReiterRepository,
|
reiterRepository: ReiterRepository,
|
||||||
horseRepository: HorseRepository,
|
horseRepository: HorseRepository,
|
||||||
funktionaerRepository: FunktionaerRepository
|
funktionaerRepository: FunktionaerRepository,
|
||||||
|
landRepository: LandRepository,
|
||||||
|
bundeslandRepository: BundeslandRepository
|
||||||
): ZnsImportService {
|
): ZnsImportService {
|
||||||
return ZnsImportService(vereinRepository, reiterRepository, horseRepository, funktionaerRepository)
|
return ZnsImportService(
|
||||||
|
vereinRepository,
|
||||||
|
reiterRepository,
|
||||||
|
horseRepository,
|
||||||
|
funktionaerRepository,
|
||||||
|
landRepository,
|
||||||
|
bundeslandRepository
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,8 +125,8 @@ und über definierte Schnittstellen kommunizieren.
|
||||||
|
|
||||||
#### 👷 Agent: Backend Developer
|
#### 👷 Agent: Backend Developer
|
||||||
|
|
||||||
* [x] **ZNS-Importer:** Support für Richter-Import (RICHT01.DAT) vervollständigt.
|
* [x] **ZNS-Importer:** Support für Richter-Import (RICHT01.DAT) und Reiter-Refactoring (LIZENZ01.DAT) vervollständigt.
|
||||||
* [x] **Masterdata:** Qualifikations-System auf professionelle Master-Daten-Referenzierung (`QualifikationMasterTable`) umgestellt.
|
* [x] **Masterdata:** Qualifikations-System und Personen-Referenzen (Vereine, Bundesländer, Nationen) auf professionelle Master-Daten umgestellt.
|
||||||
* [x] **Database:** Initialisierung der Funktionärs-Tabellen stabilisiert (PSQLException Fix).
|
* [x] **Database:** Initialisierung der Funktionärs-Tabellen stabilisiert (PSQLException Fix).
|
||||||
* [x] **`actor-context`:** Domain-Modelle für `Pferd`, `Funktionaer`, `Verein` implementiert.
|
* [x] **`actor-context`:** Domain-Modelle für `Pferd`, `Funktionaer`, `Verein` implementiert.
|
||||||
* [x] **`registration-context`:** `DomBewerb`, `DomAbteilung`, `DomStartliste` implementiert.
|
* [x] **`registration-context`:** `DomBewerb`, `DomAbteilung`, `DomStartliste` implementiert.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user