Remove Dom prefix from domain models: delete DomVeranstaltung, rename models like DomNennung to Nennung, update references in repositories, services, and tests for consistency.

This commit is contained in:
2026-04-08 22:59:12 +02:00
parent 085656a85b
commit 2d42578378
13 changed files with 71 additions and 218 deletions
@@ -1,147 +0,0 @@
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
package at.mocode.events.domain.model
import at.mocode.core.domain.model.SparteE
import at.mocode.core.domain.model.VeranstaltungsStatusE
import at.mocode.core.domain.model.VeranstaltungsTypE
import at.mocode.core.domain.serialization.KotlinxInstantSerializer
import at.mocode.core.domain.serialization.UuidSerializer
import kotlinx.datetime.LocalDate
import kotlinx.serialization.Serializable
import kotlin.time.Clock
import kotlin.time.Instant
import kotlin.uuid.Uuid
/**
* Aggregate Root für eine pferdesportliche Veranstaltung gemäß ÖTO § 2 Abs. 1.
*
* Eine Veranstaltung ist der organisatorische Rahmen (z.B. "Frühjahrsturnier Wiener Neustadt").
* Sie kann ein oder mehrere Turniere enthalten. Die Unterscheidung Veranstaltung ≠ Turnier
* ist eine zentrale ADR-Entscheidung (ADR-0003).
*
* @property veranstaltungId Eindeutige interne ID (UUID).
* @property name Offizieller Name der Veranstaltung.
* @property veranstaltungsTyp Typ gemäß ÖTO (z.B. NATIONAL, INTERNATIONAL).
* @property sparten Liste der enthaltenen Sparten (Springen, Dressur, etc.).
* @property veranstalterVereinId ID des veranstaltenden Vereins (Referenz auf clubs-context).
* @property verantwortlicheFunktionaerId ID des verantwortlichen Funktionärs (Referenz auf officials-context).
* @property startDatum Erster Veranstaltungstag.
* @property endDatum Letzter Veranstaltungstag.
* @property ort Veranstaltungsort (Adresse / Reitanlage).
* @property nennschluss Nennschluss-Datum gemäß Ausschreibung.
* @property status Aktueller Status im Planungs-Workflow.
* @property ausschreibungsId Referenz auf die zugehörige Ausschreibung (optional bis Genehmigung).
* @property oepsGenehmigungsNummer Offizielle Genehmigungsnummer des Verbands (nach Genehmigung).
* @property bemerkungen Interne Bemerkungen.
* @property createdAt Erstellungszeitpunkt.
* @property updatedAt Letzter Änderungszeitpunkt.
*/
@Serializable
data class DomVeranstaltung(
@Serializable(with = UuidSerializer::class)
val veranstaltungId: Uuid = Uuid.random(),
// Basis-Informationen
var name: String,
var veranstaltungsTyp: VeranstaltungsTypE,
var sparten: List<SparteE> = emptyList(),
// Organisation
@Serializable(with = UuidSerializer::class)
var veranstalterVereinId: Uuid,
@Serializable(with = UuidSerializer::class)
var verantwortlicheFunktionaerId: Uuid? = null,
// Termine
var startDatum: LocalDate,
var endDatum: LocalDate,
var ort: String,
var nennschluss: LocalDate? = null,
// Workflow-Status
var status: VeranstaltungsStatusE = VeranstaltungsStatusE.IN_PLANUNG,
// Verknüpfungen
@Serializable(with = UuidSerializer::class)
var ausschreibungsId: Uuid? = null,
var oepsGenehmigungsNummer: String? = null,
// Administrativ
var bemerkungen: String? = null,
// Audit
@Serializable(with = KotlinxInstantSerializer::class)
val createdAt: Instant = Clock.System.now(),
@Serializable(with = KotlinxInstantSerializer::class)
var updatedAt: Instant = Clock.System.now()
) {
/**
* Gibt die Dauer der Veranstaltung in Tagen zurück.
*/
fun getDauerInTagen(): Int =
(endDatum.toEpochDays() - startDatum.toEpochDays()).toInt() + 1
/**
* Prüft ob die Veranstaltung mehrtägig ist.
*/
fun istMehrtaegig(): Boolean = startDatum != endDatum
/**
* Prüft ob Nennungen aktuell möglich sind (Status GENEHMIGT und Nennschluss nicht abgelaufen).
* Gibt Warnungen zurück keine harten Fehler (Warn-Logik statt Exception, ADR-0007).
*/
fun validateNennungsmoeglichkeit(): List<String> {
val warnings = mutableListOf<String>()
if (status != VeranstaltungsStatusE.GENEHMIGT) {
warnings.add(
"Veranstaltung ist nicht im Status GENEHMIGT (aktuell: $status). " +
"Nennungen sind erst nach Genehmigung möglich."
)
}
if (nennschluss == null) {
warnings.add("Kein Nennschluss definiert. Bitte Ausschreibung vervollständigen.")
}
if (veranstalterVereinId == null) {
warnings.add("Kein Veranstalter-Verein zugewiesen.")
}
return warnings
}
/**
* Validiert die Pflichtfelder für die Einreichung beim Verband.
* Gibt Warnungen zurück keine harten Fehler (Warn-Logik statt Exception, ADR-0007).
*/
fun validateFuerEinreichung(): List<String> {
val warnings = mutableListOf<String>()
if (name.isBlank()) {
warnings.add("Veranstaltungsname ist erforderlich.")
}
if (ort.isBlank()) {
warnings.add("Veranstaltungsort ist erforderlich.")
}
if (endDatum < startDatum) {
warnings.add("Enddatum darf nicht vor dem Startdatum liegen.")
}
if (sparten.isEmpty()) {
warnings.add("Mindestens eine Sparte muss angegeben werden.")
}
if (nennschluss == null) {
warnings.add("Nennschluss ist für die Einreichung erforderlich.")
}
nennschluss?.let { nl ->
if (nl >= startDatum) {
warnings.add("Nennschluss muss vor dem Veranstaltungsbeginn liegen (§ 2 ÖTO).")
}
}
if (ausschreibungsId == null) {
warnings.add("Keine Ausschreibung verknüpft. Einreichung ohne Ausschreibung nicht möglich.")
}
return warnings
}
/**
* Erstellt eine Kopie mit aktualisiertem Zeitstempel.
*/
fun withUpdatedTimestamp(): DomVeranstaltung = this.copy(updatedAt = Clock.System.now())
}