Refactor domain models (DomFunktionaer, DomReiter, DomPferd) to align with ZNS conventions: simplify naming, update properties, and enhance parser logic. Adjust related controllers, repository methods, and tests. Update MASTER_ROADMAP with changes to domain models.

This commit is contained in:
2026-04-06 00:00:20 +02:00
parent 1e5fa3d053
commit f50d4deb16
57 changed files with 811 additions and 532 deletions
@@ -2,7 +2,7 @@
package at.mocode.entries.domain.model
import at.mocode.core.domain.model.NennungsStatusE
import at.mocode.core.domain.model.NennStatusE
import at.mocode.core.domain.model.StartwunschE
import at.mocode.core.domain.serialization.InstantSerializer
import at.mocode.core.domain.serialization.UuidSerializer
@@ -28,8 +28,8 @@ import kotlin.uuid.Uuid
* @property abteilungId Reference to the Abteilung (smallest entry unit).
* @property bewerbId Reference to the parent Bewerb (for display/reporting).
* @property turnierId Reference to the Turnier.
* @property reiterId Reference to the DomReiter (actor-context).
* @property pferdId Reference to the DomPferd (actor-context).
* @property reiterId Reference to the Reiter (actor-context).
* @property pferdId Reference to the Pferd (actor-context).
* @property zahlerId Reference to the payer (may differ from rider, e.g. club pays).
* @property status Current status of this entry.
* @property startwunsch Rider's preferred starting position (vorne/hinten).
@@ -63,7 +63,7 @@ data class DomNennung(
val zahlerId: Uuid? = null,
// Entry Details
val status: NennungsStatusE = NennungsStatusE.EINGEGANGEN,
val status: NennStatusE = NennStatusE.EINGEGANGEN,
val startwunsch: StartwunschE = StartwunschE.KEIN_WUNSCH,
// Late Entry (Nachnennung)
@@ -83,8 +83,8 @@ data class DomNennung(
* Checks if this entry is still active (not withdrawn or cancelled).
*/
fun isAktiv(): Boolean = status !in listOf(
NennungsStatusE.ZURUECKGEZOGEN,
NennungsStatusE.NICHT_ANGETRETEN
NennStatusE.ZURUECKGEZOGEN,
NennStatusE.NICHT_ANGETRETEN
)
/**
@@ -2,7 +2,7 @@
package at.mocode.entries.domain.repository
import at.mocode.core.domain.model.NennungsStatusE
import at.mocode.core.domain.model.NennStatusE
import at.mocode.entries.domain.model.DomNennung
import kotlin.uuid.Uuid
@@ -52,7 +52,7 @@ interface NennungRepository {
/**
* Sucht alle Nennungen mit einem bestimmten Status.
*/
suspend fun findByStatus(status: NennungsStatusE): List<DomNennung>
suspend fun findByStatus(status: NennStatusE): List<DomNennung>
/**
* Sucht alle Nachnennungen für einen Bewerb.
@@ -84,5 +84,5 @@ interface NennungRepository {
/**
* Zählt alle Nennungen für ein Turnier mit einem bestimmten Status.
*/
suspend fun countByTurnierIdAndStatus(turnierId: Uuid, status: NennungsStatusE): Long
suspend fun countByTurnierIdAndStatus(turnierId: Uuid, status: NennStatusE): Long
}
@@ -3,12 +3,12 @@
package at.mocode.entries.domain.service
import at.mocode.core.domain.model.AbteilungsTeilungsTypE
import at.mocode.core.domain.model.LizenzKlasseE
import at.mocode.core.domain.model.ReiterLizenzKlasseE
import at.mocode.core.domain.model.PruefungsTypE
import at.mocode.core.domain.model.SparteE
import at.mocode.entries.domain.model.DomAbteilung
import at.mocode.entries.domain.model.DomBewerb
import at.mocode.masterdata.domain.model.DomReiter
import at.mocode.masterdata.domain.model.Reiter
/**
* Service für die Anwendung der Abteilungs-Regeln gemäß ÖTO § 39.
@@ -37,14 +37,14 @@ class AbteilungsRegelService {
fun bestimmeAbteilung(
bewerb: DomBewerb,
abteilungen: List<DomAbteilung>,
reiter: DomReiter
reiter: Reiter
): DomAbteilung? {
if (abteilungen.isEmpty()) return null
if (abteilungen.size == 1) return abteilungen.first()
return when (bewerb.teilungsTyp) {
AbteilungsTeilungsTypE.NACH_LIZENZ -> {
val istLizenzfrei = reiter.lizenzKlasse == LizenzKlasseE.LIZENZFREI
val istLizenzfrei = reiter.lizenzKlasse == ReiterLizenzKlasseE.LIZENZFREI
if (istLizenzfrei) {
// Suche Abteilung für Lizenzfreie (oft Abt. 1 oder explizit benannt)
abteilungen.find { it.bezeichnung?.contains("frei", ignoreCase = true) == true }
@@ -61,7 +61,7 @@ class AbteilungsRegelService {
AbteilungsTeilungsTypE.STRUKTURELL -> {
// Bei strukturellen Teilungen (z.B. Caprilli oder CSN-C-NEU)
if (bewerb.pruefungsTyp == PruefungsTypE.CAPRILLI) {
val istLizenzfrei = reiter.lizenzKlasse == LizenzKlasseE.LIZENZFREI
val istLizenzfrei = reiter.lizenzKlasse == ReiterLizenzKlasseE.LIZENZFREI
if (istLizenzfrei) abteilungen.find { it.abteilungsNummer == 1 }
else abteilungen.find { it.abteilungsNummer == 2 }
} else if (bewerb.sparte == SparteE.SPRINGEN && bewerb.hoeheCm != null) {
@@ -70,7 +70,7 @@ class AbteilungsRegelService {
// ≥ 100 cm: nur R1+ erlaubt → alle in Abt. 1 (R1/R2+)
val hoehe = bewerb.hoeheCm!!
if (hoehe <= 95) {
val istLizenzfrei = reiter.lizenzKlasse == LizenzKlasseE.LIZENZFREI
val istLizenzfrei = reiter.lizenzKlasse == ReiterLizenzKlasseE.LIZENZFREI
if (istLizenzfrei) {
abteilungen.find { it.bezeichnung?.contains("ohne", ignoreCase = true) == true }
?: abteilungen.minByOrNull { it.abteilungsNummer }
@@ -80,7 +80,7 @@ class AbteilungsRegelService {
}
} else {
// ≥ 100 cm: Pflicht-Teilung R1 / R2+
val istR1 = reiter.lizenzKlasse == LizenzKlasseE.R1
val istR1 = reiter.lizenzKlasse == ReiterLizenzKlasseE.R1
if (istR1) {
abteilungen.find { it.bezeichnung?.contains("R1", ignoreCase = false) == true }
?: abteilungen.minByOrNull { it.abteilungsNummer }
@@ -5,7 +5,7 @@ package at.mocode.entries.domain.service
import at.mocode.core.domain.model.*
import at.mocode.entries.domain.model.DomAbteilung
import at.mocode.entries.domain.model.DomBewerb
import at.mocode.masterdata.domain.model.DomReiter
import at.mocode.masterdata.domain.model.Reiter
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.uuid.Uuid
@@ -30,7 +30,7 @@ class AbteilungsRegelServiceTest {
val abt1 = createAbteilung(bewerb.bewerbId, 1, "lizenzfrei")
val abt2 = createAbteilung(bewerb.bewerbId, 2, "R1 und hoeher")
val reiter = createReiter(lizenzKlasse = LizenzKlasseE.LIZENZFREI)
val reiter = createReiter(lizenzKlasse = ReiterLizenzKlasseE.LIZENZFREI)
val result = service.bestimmeAbteilung(bewerb, listOf(abt1, abt2), reiter)
@@ -43,7 +43,7 @@ class AbteilungsRegelServiceTest {
val abt1 = createAbteilung(bewerb.bewerbId, 1, "lizenzfrei")
val abt2 = createAbteilung(bewerb.bewerbId, 2, "Lizenz")
val reiter = createReiter(lizenzKlasse = LizenzKlasseE.R1)
val reiter = createReiter(lizenzKlasse = ReiterLizenzKlasseE.R1)
val result = service.bestimmeAbteilung(bewerb, listOf(abt1, abt2), reiter)
@@ -68,7 +68,7 @@ class AbteilungsRegelServiceTest {
val bewerb = createBewerb(teilungsTyp = AbteilungsTeilungsTypE.STRUKTURELL, hoeheCm = 95)
val abtOhne = createAbteilung(bewerb.bewerbId, 1, "ohne Lizenz")
val abtMit = createAbteilung(bewerb.bewerbId, 2, "mit Lizenz")
val reiter = createReiter(LizenzKlasseE.LIZENZFREI)
val reiter = createReiter(ReiterLizenzKlasseE.LIZENZFREI)
val result = service.bestimmeAbteilung(bewerb, listOf(abtOhne, abtMit), reiter)
@@ -80,7 +80,7 @@ class AbteilungsRegelServiceTest {
val bewerb = createBewerb(teilungsTyp = AbteilungsTeilungsTypE.STRUKTURELL, hoeheCm = 95)
val abtOhne = createAbteilung(bewerb.bewerbId, 1, "ohne Lizenz")
val abtMit = createAbteilung(bewerb.bewerbId, 2, "mit Lizenz")
val reiter = createReiter(LizenzKlasseE.R1)
val reiter = createReiter(ReiterLizenzKlasseE.R1)
val result = service.bestimmeAbteilung(bewerb, listOf(abtOhne, abtMit), reiter)
@@ -93,7 +93,7 @@ class AbteilungsRegelServiceTest {
val abtOhne = createAbteilung(bewerb.bewerbId, 1, "ohne Lizenz")
val abtMit = createAbteilung(bewerb.bewerbId, 2, "mit Lizenz")
val result = service.bestimmeAbteilung(bewerb, listOf(abtOhne, abtMit), createReiter(LizenzKlasseE.LIZENZFREI))
val result = service.bestimmeAbteilung(bewerb, listOf(abtOhne, abtMit), createReiter(ReiterLizenzKlasseE.LIZENZFREI))
assertEquals(abtOhne.abteilungId, result?.abteilungId)
}
@@ -105,7 +105,7 @@ class AbteilungsRegelServiceTest {
val bewerb = createBewerb(teilungsTyp = AbteilungsTeilungsTypE.STRUKTURELL, hoeheCm = 100)
val abtR1 = createAbteilung(bewerb.bewerbId, 1, "R1")
val abtR2 = createAbteilung(bewerb.bewerbId, 2, "R2+")
val reiter = createReiter(LizenzKlasseE.R1)
val reiter = createReiter(ReiterLizenzKlasseE.R1)
val result = service.bestimmeAbteilung(bewerb, listOf(abtR1, abtR2), reiter)
@@ -117,7 +117,7 @@ class AbteilungsRegelServiceTest {
val bewerb = createBewerb(teilungsTyp = AbteilungsTeilungsTypE.STRUKTURELL, hoeheCm = 100)
val abtR1 = createAbteilung(bewerb.bewerbId, 1, "R1")
val abtR2 = createAbteilung(bewerb.bewerbId, 2, "R2+")
val reiter = createReiter(LizenzKlasseE.R2)
val reiter = createReiter(ReiterLizenzKlasseE.R2)
val result = service.bestimmeAbteilung(bewerb, listOf(abtR1, abtR2), reiter)
@@ -130,7 +130,7 @@ class AbteilungsRegelServiceTest {
val abtR1 = createAbteilung(bewerb.bewerbId, 1, "R1")
val abtR2 = createAbteilung(bewerb.bewerbId, 2, "R2+")
val result = service.bestimmeAbteilung(bewerb, listOf(abtR1, abtR2), createReiter(LizenzKlasseE.R1))
val result = service.bestimmeAbteilung(bewerb, listOf(abtR1, abtR2), createReiter(ReiterLizenzKlasseE.R1))
assertEquals(abtR1.abteilungId, result?.abteilungId)
}
@@ -191,7 +191,7 @@ class AbteilungsRegelServiceTest {
val abt1 = createAbteilung(bewerb.bewerbId, 1, "ohne Lizenz")
val abt2 = createAbteilung(bewerb.bewerbId, 2, "mit Lizenz")
val result = service.bestimmeAbteilung(bewerb, listOf(abt1, abt2), createReiter(LizenzKlasseE.LIZENZFREI))
val result = service.bestimmeAbteilung(bewerb, listOf(abt1, abt2), createReiter(ReiterLizenzKlasseE.LIZENZFREI))
assertEquals(abt1.abteilungId, result?.abteilungId)
}
@@ -202,7 +202,7 @@ class AbteilungsRegelServiceTest {
val abt1 = createAbteilung(bewerb.bewerbId, 1, "ohne Lizenz")
val abt2 = createAbteilung(bewerb.bewerbId, 2, "mit Lizenz")
val result = service.bestimmeAbteilung(bewerb, listOf(abt1, abt2), createReiter(LizenzKlasseE.R1))
val result = service.bestimmeAbteilung(bewerb, listOf(abt1, abt2), createReiter(ReiterLizenzKlasseE.R1))
assertEquals(abt2.abteilungId, result?.abteilungId)
}
@@ -236,7 +236,7 @@ class AbteilungsRegelServiceTest {
starterAnzahl = starterAnzahl
)
private fun createReiter(lizenzKlasse: LizenzKlasseE = LizenzKlasseE.LIZENZFREI) = DomReiter(
private fun createReiter(lizenzKlasse: ReiterLizenzKlasseE = ReiterLizenzKlasseE.LIZENZFREI) = Reiter(
personId = Uuid.random(),
satznummer = "123456",
nachname = "Mustermann",