chore: remove deprecated horses, clubs, officials, and persons services
- Deleted obsolete modules related to horses, clubs, officials, and persons services, including their configurations, build files, and database provisioning scripts. - Cleaned up associated references in the project structure (e.g., `settings.gradle.kts`). - Removed unused database tables and Spring beans related to these domains. Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
+8
-9
@@ -1,13 +1,12 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.model.SparteE // Optional, falls Altersklassen stark spartenspezifisch sind
|
||||
import at.mocode.core.domain.serialization.KotlinInstantSerializer
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.core.domain.serialization.InstantSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import kotlin.uuid.Uuid
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.time.Instant
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Definiert eine spezifische Altersklasse für Teilnehmer (Reiter, Fahrer, Voltigierer)
|
||||
@@ -52,8 +51,8 @@ data class AltersklasseDefinition(
|
||||
|
||||
var istAktiv: Boolean = true,
|
||||
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
val createdAt: Instant,
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
var updatedAt: Instant
|
||||
)
|
||||
+7
-8
@@ -1,12 +1,11 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.serialization.KotlinInstantSerializer
|
||||
import at.mocode.core.domain.serialization.InstantSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import kotlin.uuid.Uuid
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.time.Instant
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Definiert ein Bundesland oder eine vergleichbare subnationale Verwaltungseinheit.
|
||||
@@ -44,8 +43,8 @@ data class BundeslandDefinition(
|
||||
var istAktiv: Boolean = true,
|
||||
var sortierReihenfolge: Int? = null,
|
||||
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
val createdAt: Instant,
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
var updatedAt: Instant
|
||||
)
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.model.DatenQuelleE
|
||||
import at.mocode.core.domain.model.FunktionaerRolleE
|
||||
import at.mocode.core.domain.model.RichterQualifikationE
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.core.domain.serialization.InstantSerializer
|
||||
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
|
||||
|
||||
/**
|
||||
* Domain-Modell für einen Funktionär im actor-context.
|
||||
*
|
||||
* Repräsentiert eine Person mit einer definierten Rolle bei Turnieren (Richter, TBA,
|
||||
* Parcoursbauer, etc.). Die Qualifikation wird gegen `RICHT01.DAT` aus dem ZNS geprüft.
|
||||
*
|
||||
* Aggregate Root des `officials`-Bounded Context.
|
||||
*
|
||||
* @property funktionaerId Eindeutige interne ID (UUID).
|
||||
* @property richterNummer ÖPS-Funktionärsnummer aus ZNS (RICHT01.dat), 6-stellig.
|
||||
* @property vorname Vorname der Person.
|
||||
* @property nachname Nachname der Person.
|
||||
* @property geburtsdatum Geburtsdatum (optional, für Altersklassen-Prüfung).
|
||||
* @property rollen Menge der Rollen, die diese Person ausüben darf (TBA, Richter, ...).
|
||||
* @property richterQualifikation Qualifikationsstufe als Richter (GA, G1–G3, International).
|
||||
* @property qualifiziertFuerSparten Sparten, für die eine Richter-Qualifikation vorliegt.
|
||||
* @property email E-Mail-Adresse für Kommunikation.
|
||||
* @property telefon Telefonnummer.
|
||||
* @property vereinsNummer Vereinsnummer des Heimvereins (Referenz auf DomVerein).
|
||||
* @property istAktiv Ob der Funktionär aktuell aktiv/einsatzbereit ist.
|
||||
* @property bemerkungen Interne Notizen.
|
||||
* @property datenQuelle Herkunft des Datensatzes (ZNS-Import oder manuell).
|
||||
* @property createdAt Erstellungszeitpunkt.
|
||||
* @property updatedAt Letzter Änderungszeitpunkt.
|
||||
*/
|
||||
@Serializable
|
||||
data class DomFunktionaer(
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val funktionaerId: Uuid = Uuid.random(),
|
||||
|
||||
// Identifikation
|
||||
val richterNummer: String? = null,
|
||||
|
||||
// Persönliche Daten
|
||||
var vorname: String,
|
||||
var nachname: String,
|
||||
var geburtsdatum: LocalDate? = null,
|
||||
|
||||
// Qualifikation & Rollen
|
||||
var rollen: Set<FunktionaerRolleE> = emptySet(),
|
||||
var richterQualifikation: RichterQualifikationE? = null,
|
||||
var qualifiziertFuerSparten: Set<SparteE> = emptySet(),
|
||||
|
||||
// Kontakt
|
||||
var email: String? = null,
|
||||
var telefon: String? = null,
|
||||
|
||||
// Vereinszugehörigkeit
|
||||
var vereinsNummer: String? = null,
|
||||
|
||||
// Status & Verwaltung
|
||||
var istAktiv: Boolean = true,
|
||||
var bemerkungen: String? = null,
|
||||
var datenQuelle: DatenQuelleE = DatenQuelleE.IMPORT_ZNS,
|
||||
|
||||
// Audit
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
) {
|
||||
/**
|
||||
* Gibt den vollständigen Anzeigenamen zurück.
|
||||
*/
|
||||
fun getDisplayName(): String = "$vorname $nachname"
|
||||
|
||||
/**
|
||||
* Gibt den Anzeigenamen mit Funktionärsnummer zurück (falls vorhanden).
|
||||
*/
|
||||
fun getDisplayNameWithNummer(): String =
|
||||
richterNummer?.let { "${getDisplayName()} ($it)" } ?: getDisplayName()
|
||||
|
||||
/**
|
||||
* Prüft, ob der Funktionär als Richter für eine bestimmte Sparte qualifiziert ist.
|
||||
*/
|
||||
fun istRichterFuerSparte(sparte: SparteE): Boolean =
|
||||
rollen.contains(FunktionaerRolleE.RICHTER) && qualifiziertFuerSparten.contains(sparte)
|
||||
|
||||
/**
|
||||
* Prüft, ob der Funktionär die Rolle TBA ausüben darf.
|
||||
*/
|
||||
fun istTba(): Boolean = rollen.contains(FunktionaerRolleE.TBA)
|
||||
|
||||
/**
|
||||
* Validiert die Pflichtfelder für den Turniereinsatz.
|
||||
* Gibt eine Liste von Warnungen zurück (kein harter Fehler – Override-Event möglich).
|
||||
*/
|
||||
fun validateFuerTurniereinsatz(rolle: FunktionaerRolleE, sparte: SparteE? = null): List<String> {
|
||||
val warnings = mutableListOf<String>()
|
||||
|
||||
if (!istAktiv) {
|
||||
warnings.add("Funktionär ${getDisplayName()} ist nicht aktiv.")
|
||||
}
|
||||
|
||||
if (!rollen.contains(rolle)) {
|
||||
warnings.add("Funktionär ${getDisplayName()} hat keine Qualifikation für Rolle $rolle.")
|
||||
}
|
||||
|
||||
if (rolle == FunktionaerRolleE.RICHTER && sparte != null && !istRichterFuerSparte(sparte)) {
|
||||
warnings.add("Funktionär ${getDisplayName()} ist nicht als Richter für Sparte $sparte qualifiziert.")
|
||||
}
|
||||
|
||||
return warnings
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt eine Kopie mit aktualisiertem Zeitstempel.
|
||||
*/
|
||||
fun withUpdatedTimestamp(): DomFunktionaer = this.copy(updatedAt = Clock.System.now())
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.model.DatenQuelleE
|
||||
import at.mocode.core.domain.model.PferdeGeschlechtE
|
||||
import at.mocode.core.domain.serialization.InstantSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.number
|
||||
import kotlinx.datetime.todayIn
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Domain model representing a horse in the registry system.
|
||||
*
|
||||
* This entity contains all essential information about a horse including
|
||||
* identification, ownership, breeding information, and administrative data.
|
||||
* It serves as the core aggregate root for the horse-registry bounded context.
|
||||
*
|
||||
* @property pferdId Unique internal identifier for this horse (UUID).
|
||||
* @property pferdeName Name of the horse.
|
||||
* @property geschlecht Gender of the horse (Hengst, Stute, Wallach).
|
||||
* @property geburtsdatum Birthdate of the horse.
|
||||
* @property rasse Breed of the horse.
|
||||
* @property farbe Color/coat of the horse.
|
||||
* @property besitzerId ID of the current owner (Person from member-management context).
|
||||
* @property verantwortlichePersonId ID of the responsible person (trainer, rider, etc.).
|
||||
* @property zuechterName Name of the breeder.
|
||||
* @property zuchtbuchNummer Studbook number if registered.
|
||||
* @property lebensnummer Life number (unique identification number).
|
||||
* @property chipNummer Microchip number for identification.
|
||||
* @property passNummer Passport number.
|
||||
* @property oepsNummer OEPS (Austrian Equestrian Federation) number.
|
||||
* @property feiNummer FEI (International Equestrian Federation) number.
|
||||
* @property vaterName Name of the sire (father).
|
||||
* @property mutterName Name of the dam (mother).
|
||||
* @property mutterVaterName Name of the maternal grandsire.
|
||||
* @property stockmass Height of the horse in cm.
|
||||
* @property istAktiv Whether the horse is currently active in the system.
|
||||
* @property bemerkungen Additional notes or comments.
|
||||
* @property datenQuelle Source of the data (manual entry, import, etc.).
|
||||
* @property createdAt Timestamp when this record was created.
|
||||
* @property updatedAt Timestamp when this record was last updated.
|
||||
*/
|
||||
@Serializable
|
||||
data class DomPferd(
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val pferdId: Uuid = Uuid.random(),
|
||||
|
||||
// Basic Information
|
||||
var pferdeName: String,
|
||||
var geschlecht: PferdeGeschlechtE,
|
||||
var geburtsdatum: LocalDate? = null,
|
||||
var rasse: String? = null,
|
||||
var farbe: String? = null,
|
||||
|
||||
// Ownership and Responsibility
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
var besitzerId: Uuid? = null,
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
var verantwortlichePersonId: Uuid? = null,
|
||||
|
||||
// Breeding Information
|
||||
var zuechterName: String? = null,
|
||||
var zuchtbuchNummer: String? = null,
|
||||
|
||||
// Identification Numbers
|
||||
var lebensnummer: String? = null,
|
||||
var chipNummer: String? = null,
|
||||
var passNummer: String? = null,
|
||||
var oepsNummer: String? = null,
|
||||
var feiNummer: String? = null,
|
||||
|
||||
// Pedigree Information
|
||||
var vaterName: String? = null,
|
||||
var mutterName: String? = null,
|
||||
var mutterVaterName: String? = null,
|
||||
|
||||
// Physical Characteristics
|
||||
var stockmass: Int? = null, // Height in cm
|
||||
|
||||
// Status and Administrative
|
||||
var istAktiv: Boolean = true,
|
||||
var bemerkungen: String? = null,
|
||||
var datenQuelle: DatenQuelleE = DatenQuelleE.MANUELL,
|
||||
|
||||
// Audit Fields
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
) {
|
||||
/**
|
||||
* Returns the display name for the horse, combining name and birth year if available.
|
||||
*/
|
||||
fun getDisplayName(): String {
|
||||
return geburtsdatum?.let { birthDate ->
|
||||
"$pferdeName (${birthDate.year})"
|
||||
} ?: pferdeName
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the horse has complete identification information.
|
||||
*/
|
||||
fun hasCompleteIdentification(): Boolean {
|
||||
return !lebensnummer.isNullOrBlank() ||
|
||||
!chipNummer.isNullOrBlank() ||
|
||||
!passNummer.isNullOrBlank()
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the horse is registered with OEPS.
|
||||
*/
|
||||
fun isOepsRegistered(): Boolean {
|
||||
return !oepsNummer.isNullOrBlank()
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the horse is registered with FEI.
|
||||
*/
|
||||
fun isFeiRegistered(): Boolean {
|
||||
return !feiNummer.isNullOrBlank()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the age of the horse in years, or null if birth date is unknown.
|
||||
*/
|
||||
fun getAge(): Int? {
|
||||
return geburtsdatum?.let { birthDate ->
|
||||
val today = Clock.System.todayIn(kotlinx.datetime.TimeZone.currentSystemDefault())
|
||||
var age = today.year - birthDate.year
|
||||
|
||||
// Check if a birthday has occurred this year
|
||||
if (today.month.number < birthDate.month.number ||
|
||||
(today.month.number == birthDate.month.number && today.day < birthDate.day)
|
||||
) {
|
||||
age--
|
||||
}
|
||||
|
||||
age
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that required fields are present for horse registration.
|
||||
*/
|
||||
fun validateForRegistration(): List<String> {
|
||||
val errors = mutableListOf<String>()
|
||||
|
||||
if (pferdeName.isBlank()) {
|
||||
errors.add("Horse name is required")
|
||||
}
|
||||
|
||||
if (!hasCompleteIdentification()) {
|
||||
errors.add("At least one identification number (life number, chip number, or passport number) is required")
|
||||
}
|
||||
|
||||
if (besitzerId == null) {
|
||||
errors.add("Owner is required")
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this horse with an updated timestamp.
|
||||
*/
|
||||
fun withUpdatedTimestamp(): DomPferd {
|
||||
return this.copy(updatedAt = Clock.System.now())
|
||||
}
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.model.DatenQuelleE
|
||||
import at.mocode.core.domain.model.LizenzKlasseE
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.core.domain.serialization.InstantSerializer
|
||||
import at.mocode.core.domain.serialization.LocalDateSerializer
|
||||
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
|
||||
|
||||
/**
|
||||
* Domain model representing a rider (Reiter) in the actor-context.
|
||||
*
|
||||
* A rider is a specialization of a person with additional equestrian-specific
|
||||
* attributes such as license, start card, and competition eligibility.
|
||||
* Data is primarily sourced from the OEPS ZNS (LIZENZ01.DAT).
|
||||
*
|
||||
* Key rules (ÖTO):
|
||||
* - A rider requires an active Startkarte (annual fee paid) to compete nationally.
|
||||
* - LizenzKlasse determines which competition classes the rider may enter.
|
||||
* - Satznummer (6-digit) is the primary key for ZNS data exchange.
|
||||
* - Kopfnummer is NOT a unique identifier – it can change.
|
||||
*
|
||||
* @property reiterId Unique internal identifier (UUID).
|
||||
* @property personId Reference to the base DomPerson record (UUID).
|
||||
* @property satznummer 6-digit ZNS primary key for data exchange. Primary key for ZNS.
|
||||
* @property lizenzNummer OEPS license number (from ZNS LIZENZ01.DAT).
|
||||
* @property lizenzKlasse License class determining competition eligibility (e.g. R1, RD2).
|
||||
* @property lizenzSparten Disciplines for which the license is valid.
|
||||
* @property startkartAktiv Whether the annual start card fee has been paid.
|
||||
* @property startkartSaison Season year for which the start card is valid (e.g. 2026).
|
||||
* @property feiId FEI international rider ID (optional).
|
||||
* @property nation Nation code (e.g. AUT).
|
||||
* @property geburtsdatum Date of birth (for age class validation).
|
||||
* @property vereinsNummer Club number (OEPS).
|
||||
* @property vereinsName Club name.
|
||||
* @property istGastreiter Whether the rider is a guest rider (foreign nationality, not in Austrian club).
|
||||
* @property istAktiv Whether the rider is currently active in the system.
|
||||
* @property datenQuelle Source of the data.
|
||||
* @property createdAt Timestamp when this record was created.
|
||||
* @property updatedAt Timestamp when this record was last updated.
|
||||
*/
|
||||
@Serializable
|
||||
data class DomReiter(
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val reiterId: Uuid = Uuid.random(),
|
||||
|
||||
// Reference to base person
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val personId: Uuid,
|
||||
|
||||
// ZNS Identification
|
||||
val satznummer: String,
|
||||
val lizenzNummer: String? = null,
|
||||
|
||||
// License & Eligibility
|
||||
val lizenzKlasse: LizenzKlasseE = LizenzKlasseE.LIZENZFREI,
|
||||
val lizenzSparten: List<SparteE> = emptyList(),
|
||||
|
||||
// Start Card (Startkarte) – annual fee proof
|
||||
val startkartAktiv: Boolean = false,
|
||||
val startkartSaison: Int? = null,
|
||||
|
||||
// International
|
||||
val feiId: String? = null,
|
||||
val nation: String? = null,
|
||||
|
||||
// Personal Data (denormalized from DomPerson for performance)
|
||||
val nachname: String,
|
||||
val vorname: String,
|
||||
@Serializable(with = LocalDateSerializer::class)
|
||||
val geburtsdatum: LocalDate? = null,
|
||||
|
||||
// Club Affiliation
|
||||
val vereinsNummer: String? = null,
|
||||
val vereinsName: String? = null,
|
||||
|
||||
// Status
|
||||
val istGastreiter: Boolean = false,
|
||||
val istAktiv: Boolean = true,
|
||||
val datenQuelle: DatenQuelleE = DatenQuelleE.IMPORT_ZNS,
|
||||
|
||||
// Audit Fields
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
) {
|
||||
/**
|
||||
* Returns the display name of the rider.
|
||||
*/
|
||||
fun getDisplayName(): String = "$vorname $nachname"
|
||||
|
||||
/**
|
||||
* Checks if the rider is eligible to compete nationally.
|
||||
* Requires an active start card (Startkarte).
|
||||
*/
|
||||
fun isStartberechtigt(): Boolean = istAktiv && startkartAktiv
|
||||
|
||||
/**
|
||||
* Checks if the rider holds a license for the given discipline.
|
||||
*/
|
||||
fun hasLizenzForSparte(sparte: SparteE): Boolean =
|
||||
lizenzKlasse == LizenzKlasseE.LIZENZFREI || lizenzSparten.contains(sparte)
|
||||
|
||||
/**
|
||||
* Validates the rider for competition entry.
|
||||
* Returns a list of warning messages (never hard errors – TBA has final say).
|
||||
*/
|
||||
fun validateForNennung(sparte: SparteE): List<String> {
|
||||
val warnings = mutableListOf<String>()
|
||||
|
||||
if (!istAktiv) {
|
||||
warnings.add("Reiter ${getDisplayName()} ist nicht aktiv")
|
||||
}
|
||||
if (!startkartAktiv) {
|
||||
warnings.add("Reiter ${getDisplayName()} hat keine aktive Startkarte für Saison $startkartSaison")
|
||||
}
|
||||
if (!hasLizenzForSparte(sparte)) {
|
||||
warnings.add("Reiter ${getDisplayName()} hat keine Lizenz für Sparte $sparte (Lizenzklasse: $lizenzKlasse)")
|
||||
}
|
||||
|
||||
return warnings
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this rider with an updated timestamp.
|
||||
*/
|
||||
fun withUpdatedTimestamp(): DomReiter = this.copy(updatedAt = Clock.System.now())
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.model.DatenQuelleE
|
||||
import at.mocode.core.domain.serialization.InstantSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Domain-Modell für einen Verein im actor-context.
|
||||
*
|
||||
* Repräsentiert einen OEPS-Mitgliedsverein, der als Veranstalter von Turnieren
|
||||
* und als Heimverein von Reitern und Funktionären fungiert.
|
||||
* Daten werden primär aus dem ZNS (VEREIN01.dat) importiert.
|
||||
*
|
||||
* Aggregate Root des `clubs`-Bounded Context.
|
||||
*
|
||||
* @property vereinId Eindeutige interne ID (UUID).
|
||||
* @property vereinsNummer ÖPS-Vereinsnummer aus ZNS (VEREIN01.dat), 4-stellig. Primärschlüssel für ZNS-Datenaustausch.
|
||||
* @property name Offizieller Vereinsname.
|
||||
* @property kurzname Kurzbezeichnung des Vereins (optional).
|
||||
* @property bundesland Bundesland, in dem der Verein ansässig ist.
|
||||
* @property ort Ort / Stadt des Vereinssitzes.
|
||||
* @property plz Postleitzahl.
|
||||
* @property strasse Straße und Hausnummer.
|
||||
* @property email Offizielle E-Mail-Adresse des Vereins.
|
||||
* @property telefon Telefonnummer des Vereins.
|
||||
* @property website Website-URL des Vereins.
|
||||
* @property oepsRegionNummer Regionsnummer beim OEPS (Landesverband).
|
||||
* @property istVeranstalter Ob der Verein als Veranstalter von Turnieren zugelassen ist.
|
||||
* @property istAktiv Ob der Verein aktuell aktiv ist.
|
||||
* @property bemerkungen Interne Notizen.
|
||||
* @property datenQuelle Herkunft des Datensatzes (ZNS-Import oder manuell).
|
||||
* @property createdAt Erstellungszeitpunkt.
|
||||
* @property updatedAt Letzter Änderungszeitpunkt.
|
||||
*/
|
||||
@Serializable
|
||||
data class DomVerein(
|
||||
@Serializable(with = UuidSerializer::class)
|
||||
val vereinId: Uuid = Uuid.random(),
|
||||
|
||||
// Identifikation
|
||||
val vereinsNummer: String,
|
||||
|
||||
// Stammdaten
|
||||
var name: String,
|
||||
var kurzname: String? = null,
|
||||
|
||||
// Adresse
|
||||
var bundesland: String? = null,
|
||||
var ort: String? = null,
|
||||
var plz: String? = null,
|
||||
var strasse: String? = null,
|
||||
|
||||
// Kontakt
|
||||
var email: String? = null,
|
||||
var telefon: String? = null,
|
||||
var website: String? = null,
|
||||
|
||||
// OEPS-Verwaltung
|
||||
var oepsRegionNummer: String? = null,
|
||||
var istVeranstalter: Boolean = false,
|
||||
|
||||
// Status & Verwaltung
|
||||
var istAktiv: Boolean = true,
|
||||
var bemerkungen: String? = null,
|
||||
var datenQuelle: DatenQuelleE = DatenQuelleE.IMPORT_ZNS,
|
||||
|
||||
// Audit
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
) {
|
||||
/**
|
||||
* Gibt den Anzeigenamen zurück – Kurzname bevorzugt, sonst vollständiger Name.
|
||||
*/
|
||||
fun getDisplayName(): String = kurzname ?: name
|
||||
|
||||
/**
|
||||
* Gibt den vollständigen Anzeigenamen mit Vereinsnummer zurück.
|
||||
*/
|
||||
fun getDisplayNameWithNummer(): String = "${getDisplayName()} ($vereinsNummer)"
|
||||
|
||||
/**
|
||||
* Prüft, ob vollständige Adressdaten vorhanden sind.
|
||||
*/
|
||||
fun hasCompleteAddress(): Boolean =
|
||||
!ort.isNullOrBlank() && !plz.isNullOrBlank() && !strasse.isNullOrBlank()
|
||||
|
||||
/**
|
||||
* Validiert den Verein für den Einsatz als Veranstalter.
|
||||
* Gibt Warnungen zurück (kein harter Fehler – Override-Event möglich).
|
||||
*/
|
||||
fun validateFuerVeranstaltung(): List<String> {
|
||||
val warnings = mutableListOf<String>()
|
||||
|
||||
if (!istAktiv) {
|
||||
warnings.add("Verein ${getDisplayName()} ist nicht aktiv.")
|
||||
}
|
||||
|
||||
if (!istVeranstalter) {
|
||||
warnings.add("Verein ${getDisplayName()} ist nicht als Veranstalter zugelassen.")
|
||||
}
|
||||
|
||||
if (!hasCompleteAddress()) {
|
||||
warnings.add("Verein ${getDisplayName()} hat keine vollständige Adresse hinterlegt.")
|
||||
}
|
||||
|
||||
return warnings
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt eine Kopie mit aktualisiertem Zeitstempel.
|
||||
*/
|
||||
fun withUpdatedTimestamp(): DomVerein = this.copy(updatedAt = Clock.System.now())
|
||||
}
|
||||
+7
-8
@@ -1,12 +1,11 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.serialization.KotlinInstantSerializer
|
||||
import at.mocode.core.domain.serialization.InstantSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import kotlin.uuid.Uuid
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.time.Instant
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Definiert ein Land/eine Nation mit seinen offiziellen Codes und Bezeichnungen.
|
||||
@@ -44,8 +43,8 @@ data class LandDefinition(
|
||||
var istAktiv: Boolean = true,
|
||||
var sortierReihenfolge: Int? = null,
|
||||
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
val createdAt: Instant,
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
var updatedAt: Instant
|
||||
)
|
||||
+7
-8
@@ -2,12 +2,11 @@
|
||||
package at.mocode.masterdata.domain.model
|
||||
|
||||
import at.mocode.core.domain.model.PlatzTypE
|
||||
import at.mocode.core.domain.serialization.KotlinInstantSerializer
|
||||
import at.mocode.core.domain.serialization.InstantSerializer
|
||||
import at.mocode.core.domain.serialization.UuidSerializer
|
||||
import kotlin.uuid.Uuid
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.time.Instant
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Definiert einen Turnierplatz oder eine Wettkampfstätte.
|
||||
@@ -41,8 +40,8 @@ data class Platz(
|
||||
var istAktiv: Boolean = true,
|
||||
var sortierReihenfolge: Int? = null,
|
||||
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
val createdAt: Instant = Clock.System.now(),
|
||||
@Serializable(with = KotlinInstantSerializer::class)
|
||||
var updatedAt: Instant = Clock.System.now()
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
val createdAt: Instant,
|
||||
@Serializable(with = InstantSerializer::class)
|
||||
var updatedAt: Instant
|
||||
)
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.masterdata.domain.model.AltersklasseDefinition
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Repository interface for AltersklasseDefinition (Age Class) domain operations.
|
||||
*
|
||||
* This interface defines the contract for age class data access operations
|
||||
* without depending on specific implementation details (database, etc.).
|
||||
* Following the hexagonal architecture pattern, this interface belongs
|
||||
* to the domain layer and will be implemented in the infrastructure layer.
|
||||
*/
|
||||
interface AltersklasseRepository {
|
||||
|
||||
/**
|
||||
* Finds an age class by its unique ID.
|
||||
*
|
||||
* @param id The unique identifier of the age class
|
||||
* @return The age class if found, null otherwise
|
||||
*/
|
||||
suspend fun findById(id: Uuid): AltersklasseDefinition?
|
||||
|
||||
/**
|
||||
* Finds an age class by its code.
|
||||
*
|
||||
* @param altersklasseCode The age class code (e.g., "JGD_U16", "JUN_U18")
|
||||
* @return The age class if found, null otherwise
|
||||
*/
|
||||
suspend fun findByCode(altersklasseCode: String): AltersklasseDefinition?
|
||||
|
||||
/**
|
||||
* Finds age classes by name (partial match).
|
||||
*
|
||||
* @param searchTerm The search term to match against age class names
|
||||
* @param limit Maximum number of results to return
|
||||
* @return List of matching age classes
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, limit: Int = 50): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds all active age classes.
|
||||
*
|
||||
* @param sparteFilter Optional filter by sport type
|
||||
* @param geschlechtFilter Optional filter by gender ('M', 'W')
|
||||
* @return List of active age classes
|
||||
*/
|
||||
suspend fun findAllActive(sparteFilter: SparteE? = null, geschlechtFilter: Char? = null): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes applicable for a specific age.
|
||||
*
|
||||
* @param age The age to check
|
||||
* @param sparteFilter Optional filter by sport type
|
||||
* @param geschlechtFilter Optional filter by gender ('M', 'W')
|
||||
* @return List of applicable age classes
|
||||
*/
|
||||
suspend fun findApplicableForAge(
|
||||
age: Int,
|
||||
sparteFilter: SparteE? = null,
|
||||
geschlechtFilter: Char? = null
|
||||
): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by sport type.
|
||||
*
|
||||
* @param sparte The sport type
|
||||
* @param activeOnly Whether to return only active age classes
|
||||
* @return List of age classes for the sport type
|
||||
*/
|
||||
suspend fun findBySparte(sparte: SparteE, activeOnly: Boolean = true): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by gender filter.
|
||||
*
|
||||
* @param geschlecht The gender ('M', 'W')
|
||||
* @param activeOnly Whether to return only active age classes
|
||||
* @return List of age classes for the gender
|
||||
*/
|
||||
suspend fun findByGeschlecht(geschlecht: Char, activeOnly: Boolean = true): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by age range.
|
||||
*
|
||||
* @param minAge Minimum age (inclusive)
|
||||
* @param maxAge Maximum age (inclusive)
|
||||
* @param activeOnly Whether to return only active age classes
|
||||
* @return List of age classes within the age range
|
||||
*/
|
||||
suspend fun findByAgeRange(minAge: Int?, maxAge: Int?, activeOnly: Boolean = true): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by OETO rule reference.
|
||||
*
|
||||
* @param oetoRegelReferenzId The OETO rule reference ID
|
||||
* @return List of age classes linked to the rule
|
||||
*/
|
||||
suspend fun findByOetoRegelReferenz(oetoRegelReferenzId: Uuid): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Saves an age class (create or update).
|
||||
*
|
||||
* @param altersklasse The age class to save
|
||||
* @return The saved age class with updated timestamps
|
||||
*/
|
||||
suspend fun save(altersklasse: AltersklasseDefinition): AltersklasseDefinition
|
||||
|
||||
/**
|
||||
* Deletes an age class by ID.
|
||||
*
|
||||
* @param id The unique identifier of the age class to delete
|
||||
* @return true if the age class was deleted, false if not found
|
||||
*/
|
||||
suspend fun delete(id: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Checks if an age class with the given code exists.
|
||||
*
|
||||
* @param altersklasseCode The age class code to check
|
||||
* @return true if an age class with this code exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByCode(altersklasseCode: String): Boolean
|
||||
|
||||
/**
|
||||
* Counts the total number of active age classes.
|
||||
*
|
||||
* @param sparteFilter Optional filter by sport type
|
||||
* @return The total count of active age classes
|
||||
*/
|
||||
suspend fun countActive(sparteFilter: SparteE? = null): Long
|
||||
|
||||
/**
|
||||
* Validates if a person with given age and gender can participate in an age class.
|
||||
*
|
||||
* @param altersklasseId The age class ID
|
||||
* @param age The person's age
|
||||
* @param geschlecht The person's gender ('M', 'W')
|
||||
* @return true if the person can participate, false otherwise
|
||||
*/
|
||||
suspend fun isEligible(altersklasseId: Uuid, age: Int, geschlecht: Char): Boolean
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.core.domain.model.FunktionaerRolleE
|
||||
import at.mocode.core.domain.model.RichterQualifikationE
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.masterdata.domain.model.DomFunktionaer
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Repository-Interface für DomFunktionaer (Funktionär) Domain-Operationen.
|
||||
*
|
||||
* Definiert den Vertrag für Datenzugriffs-Operationen ohne Abhängigkeit
|
||||
* von konkreten Implementierungsdetails (Datenbank, etc.).
|
||||
*/
|
||||
interface FunktionaerRepository {
|
||||
|
||||
/**
|
||||
* Sucht einen Funktionär anhand seiner eindeutigen ID.
|
||||
*/
|
||||
suspend fun findById(id: Uuid): DomFunktionaer?
|
||||
|
||||
/**
|
||||
* Sucht einen Funktionär anhand seiner Richternummer.
|
||||
*/
|
||||
suspend fun findByRichterNummer(richterNummer: String): DomFunktionaer?
|
||||
|
||||
/**
|
||||
* Sucht Funktionäre anhand von Vor- und/oder Nachname (Teilübereinstimmung).
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, limit: Int = 50): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Sucht alle Funktionäre mit einer bestimmten Rolle.
|
||||
*/
|
||||
suspend fun findByRolle(rolle: FunktionaerRolleE, activeOnly: Boolean = true): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Sucht alle Richter mit einer bestimmten Qualifikation.
|
||||
*/
|
||||
suspend fun findByRichterQualifikation(
|
||||
qualifikation: RichterQualifikationE,
|
||||
activeOnly: Boolean = true
|
||||
): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Sucht alle Funktionäre, die für eine bestimmte Sparte qualifiziert sind.
|
||||
*/
|
||||
suspend fun findBySparte(sparte: SparteE, activeOnly: Boolean = true): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Sucht alle Funktionäre eines bestimmten Vereins.
|
||||
*/
|
||||
suspend fun findByVereinsNummer(vereinsNummer: String, activeOnly: Boolean = true): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Gibt alle aktiven Funktionäre zurück (paginiert).
|
||||
*/
|
||||
suspend fun findAllActive(limit: Int = 100, offset: Int = 0): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Gibt alle Funktionäre zurück (paginiert).
|
||||
*/
|
||||
suspend fun findAll(limit: Int = 100, offset: Int = 0): List<DomFunktionaer>
|
||||
|
||||
/**
|
||||
* Speichert einen Funktionär (Insert oder Update).
|
||||
*/
|
||||
suspend fun save(funktionaer: DomFunktionaer): DomFunktionaer
|
||||
|
||||
/**
|
||||
* Löscht einen Funktionär anhand seiner ID.
|
||||
*
|
||||
* @return true wenn gelöscht, false wenn nicht gefunden
|
||||
*/
|
||||
suspend fun delete(id: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Zählt alle aktiven Funktionäre.
|
||||
*/
|
||||
suspend fun countActive(): Long
|
||||
|
||||
/**
|
||||
* Zählt alle Richter (Rolle = RICHTER) mit einer bestimmten Qualifikation.
|
||||
*/
|
||||
suspend fun countByRichterQualifikation(qualifikation: RichterQualifikationE, activeOnly: Boolean = true): Long
|
||||
|
||||
/**
|
||||
* Prüft ob ein Funktionär mit der gegebenen Richternummer bereits existiert.
|
||||
*/
|
||||
suspend fun existsByRichterNummer(richterNummer: String): Boolean
|
||||
}
|
||||
+248
@@ -0,0 +1,248 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.masterdata.domain.model.DomPferd
|
||||
import at.mocode.core.domain.model.PferdeGeschlechtE
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Repository interface for DomPferd (Horse) domain operations.
|
||||
*
|
||||
* This interface defines the contract for horse data access operations
|
||||
* without depending on specific implementation details (database, etc.).
|
||||
* Following the hexagonal architecture pattern, this interface belongs
|
||||
* to the domain layer and will be implemented in the infrastructure layer.
|
||||
*/
|
||||
interface HorseRepository {
|
||||
|
||||
/**
|
||||
* Finds a horse by its unique ID.
|
||||
*
|
||||
* @param id The unique identifier of the horse
|
||||
* @return The horse if found, null otherwise
|
||||
*/
|
||||
suspend fun findById(id: Uuid): DomPferd?
|
||||
|
||||
/**
|
||||
* Finds a horse by its life number (Lebensnummer).
|
||||
*
|
||||
* @param lebensnummer The life number to search for
|
||||
* @return The horse if found, null otherwise
|
||||
*/
|
||||
suspend fun findByLebensnummer(lebensnummer: String): DomPferd?
|
||||
|
||||
/**
|
||||
* Finds a horse by its chip number.
|
||||
*
|
||||
* @param chipNummer The chip number to search for
|
||||
* @return The horse if found, null otherwise
|
||||
*/
|
||||
suspend fun findByChipNummer(chipNummer: String): DomPferd?
|
||||
|
||||
/**
|
||||
* Finds a horse by its passport number.
|
||||
*
|
||||
* @param passNummer The passport number to search for
|
||||
* @return The horse if found, null otherwise
|
||||
*/
|
||||
suspend fun findByPassNummer(passNummer: String): DomPferd?
|
||||
|
||||
/**
|
||||
* Finds a horse by its OEPS number.
|
||||
*
|
||||
* @param oepsNummer The OEPS number to search for
|
||||
* @return The horse if found, null otherwise
|
||||
*/
|
||||
suspend fun findByOepsNummer(oepsNummer: String): DomPferd?
|
||||
|
||||
/**
|
||||
* Finds a horse by its FEI number.
|
||||
*
|
||||
* @param feiNummer The FEI number to search for
|
||||
* @return The horse if found, null otherwise
|
||||
*/
|
||||
suspend fun findByFeiNummer(feiNummer: String): DomPferd?
|
||||
|
||||
/**
|
||||
* Finds horses by name (partial match).
|
||||
*
|
||||
* @param searchTerm The search term to match against horse names
|
||||
* @param limit Maximum number of results to return
|
||||
* @return List of matching horses
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, limit: Int = 50): List<DomPferd>
|
||||
|
||||
/**
|
||||
* Finds all horses owned by a specific person.
|
||||
*
|
||||
* @param ownerId The ID of the owner (from member-management context)
|
||||
* @param activeOnly Whether to return only active horses
|
||||
* @return List of horses owned by the person
|
||||
*/
|
||||
suspend fun findByOwnerId(ownerId: Uuid, activeOnly: Boolean = true): List<DomPferd>
|
||||
|
||||
/**
|
||||
* Finds all horses for which a person is responsible.
|
||||
*
|
||||
* @param responsiblePersonId The ID of the responsible person
|
||||
* @param activeOnly Whether to return only active horses
|
||||
* @return List of horses for which the person is responsible
|
||||
*/
|
||||
suspend fun findByResponsiblePersonId(responsiblePersonId: Uuid, activeOnly: Boolean = true): List<DomPferd>
|
||||
|
||||
/**
|
||||
* Finds horses by gender.
|
||||
*
|
||||
* @param geschlecht The gender to filter by
|
||||
* @param activeOnly Whether to return only active horses
|
||||
* @param limit Maximum number of results to return
|
||||
* @return List of horses with the specified gender
|
||||
*/
|
||||
suspend fun findByGeschlecht(
|
||||
geschlecht: PferdeGeschlechtE,
|
||||
activeOnly: Boolean = true,
|
||||
limit: Int = 100
|
||||
): List<DomPferd>
|
||||
|
||||
/**
|
||||
* Finds horses by breed.
|
||||
*
|
||||
* @param rasse The breed to filter by
|
||||
* @param activeOnly Whether to return only active horses
|
||||
* @param limit Maximum number of results to return
|
||||
* @return List of horses of the specified breed
|
||||
*/
|
||||
suspend fun findByRasse(rasse: String, activeOnly: Boolean = true, limit: Int = 100): List<DomPferd>
|
||||
|
||||
/**
|
||||
* Finds horses by birth year.
|
||||
*
|
||||
* @param birthYear The birth year to filter by
|
||||
* @param activeOnly Whether to return only active horses
|
||||
* @return List of horses born in the specified year
|
||||
*/
|
||||
suspend fun findByBirthYear(birthYear: Int, activeOnly: Boolean = true): List<DomPferd>
|
||||
|
||||
/**
|
||||
* Finds horses by birth year range.
|
||||
*
|
||||
* @param fromYear The start year (inclusive)
|
||||
* @param toYear The end year (inclusive)
|
||||
* @param activeOnly Whether to return only active horses
|
||||
* @return List of horses born within the specified year range
|
||||
*/
|
||||
suspend fun findByBirthYearRange(fromYear: Int, toYear: Int, activeOnly: Boolean = true): List<DomPferd>
|
||||
|
||||
/**
|
||||
* Finds all active horses.
|
||||
*
|
||||
* @param limit Maximum number of results to return
|
||||
* @return List of active horses
|
||||
*/
|
||||
suspend fun findAllActive(limit: Int = 1000): List<DomPferd>
|
||||
|
||||
/**
|
||||
* Finds horses with OEPS registration.
|
||||
*
|
||||
* @param activeOnly Whether to return only active horses
|
||||
* @return List of OEPS registered horses
|
||||
*/
|
||||
suspend fun findOepsRegistered(activeOnly: Boolean = true): List<DomPferd>
|
||||
|
||||
/**
|
||||
* Finds horses with FEI registration.
|
||||
*
|
||||
* @param activeOnly Whether to return only active horses
|
||||
* @return List of FEI registered horses
|
||||
*/
|
||||
suspend fun findFeiRegistered(activeOnly: Boolean = true): List<DomPferd>
|
||||
|
||||
/**
|
||||
* Saves a horse (create or update).
|
||||
*
|
||||
* @param horse The horse to save
|
||||
* @return The saved horse with updated timestamps
|
||||
*/
|
||||
suspend fun save(horse: DomPferd): DomPferd
|
||||
|
||||
/**
|
||||
* Deletes a horse by ID.
|
||||
*
|
||||
* @param id The unique identifier of the horse to delete
|
||||
* @return true if the horse was deleted, false if not found
|
||||
*/
|
||||
suspend fun delete(id: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Checks if a horse with the given life number exists.
|
||||
*
|
||||
* @param lebensnummer The life number to check
|
||||
* @return true if a horse with this life number exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByLebensnummer(lebensnummer: String): Boolean
|
||||
|
||||
/**
|
||||
* Checks if a horse with the given chip number exists.
|
||||
*
|
||||
* @param chipNummer The chip number to check
|
||||
* @return true if a horse with this chip number exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByChipNummer(chipNummer: String): Boolean
|
||||
|
||||
/**
|
||||
* Checks if a horse with the given passport number exists.
|
||||
*
|
||||
* @param passNummer The passport number to check
|
||||
* @return true if a horse with this passport number exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByPassNummer(passNummer: String): Boolean
|
||||
|
||||
/**
|
||||
* Checks if a horse with the given OEPS number exists.
|
||||
*
|
||||
* @param oepsNummer The OEPS number to check
|
||||
* @return true if a horse with this OEPS number exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByOepsNummer(oepsNummer: String): Boolean
|
||||
|
||||
/**
|
||||
* Checks if a horse with the given FEI number exists.
|
||||
*
|
||||
* @param feiNummer The FEI number to check
|
||||
* @return true if a horse with this FEI number exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByFeiNummer(feiNummer: String): Boolean
|
||||
|
||||
/**
|
||||
* Counts the total number of active horses.
|
||||
*
|
||||
* @return The total count of active horses
|
||||
*/
|
||||
suspend fun countActive(): Long
|
||||
|
||||
/**
|
||||
* Counts horses by owner.
|
||||
*
|
||||
* @param ownerId The ID of the owner
|
||||
* @param activeOnly Whether to count only active horses
|
||||
* @return The count of horses owned by the person
|
||||
*/
|
||||
suspend fun countByOwnerId(ownerId: Uuid, activeOnly: Boolean = true): Long
|
||||
|
||||
/**
|
||||
* Counts horses with OEPS registration.
|
||||
*
|
||||
* @param activeOnly Whether to count only active horses
|
||||
* @return The count of OEPS registered horses
|
||||
*/
|
||||
suspend fun countOepsRegistered(activeOnly: Boolean = true): Long
|
||||
|
||||
/**
|
||||
* Counts horses with FEI registration.
|
||||
*
|
||||
* @param activeOnly Whether to count only active horses
|
||||
* @return The count of FEI registered horses
|
||||
*/
|
||||
suspend fun countFeiRegistered(activeOnly: Boolean = true): Long
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.core.domain.model.LizenzKlasseE
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.masterdata.domain.model.DomReiter
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Repository-Interface für DomReiter (Reiter) Domain-Operationen.
|
||||
*
|
||||
* Definiert den Vertrag für Datenzugriffs-Operationen ohne Abhängigkeit
|
||||
* von konkreten Implementierungsdetails (Datenbank, etc.).
|
||||
*/
|
||||
interface ReiterRepository {
|
||||
|
||||
/**
|
||||
* Sucht einen Reiter anhand seiner eindeutigen ID.
|
||||
*/
|
||||
suspend fun findById(id: Uuid): DomReiter?
|
||||
|
||||
/**
|
||||
* Sucht einen Reiter anhand seiner Satznummer (OEPS-Mitgliedsnummer).
|
||||
*/
|
||||
suspend fun findBySatznummer(satznummer: String): DomReiter?
|
||||
|
||||
/**
|
||||
* Sucht einen Reiter anhand seiner FEI-ID.
|
||||
*/
|
||||
suspend fun findByFeiId(feiId: String): DomReiter?
|
||||
|
||||
/**
|
||||
* Sucht Reiter anhand von Vor- und/oder Nachname (Teilübereinstimmung).
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, limit: Int = 50): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Sucht alle Reiter eines bestimmten Vereins.
|
||||
*/
|
||||
suspend fun findByVereinsNummer(vereinsNummer: String, activeOnly: Boolean = true): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Sucht alle Reiter mit einer bestimmten Lizenzklasse.
|
||||
*/
|
||||
suspend fun findByLizenzKlasse(lizenzKlasse: LizenzKlasseE, activeOnly: Boolean = true): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Sucht alle Reiter, die für eine bestimmte Sparte lizenziert sind.
|
||||
*/
|
||||
suspend fun findBySparte(sparte: SparteE, activeOnly: Boolean = true): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Sucht alle Gastreiter.
|
||||
*/
|
||||
suspend fun findGastreiter(activeOnly: Boolean = true): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Gibt alle aktiven Reiter zurück (paginiert).
|
||||
*/
|
||||
suspend fun findAllActive(limit: Int = 100, offset: Int = 0): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Gibt alle Reiter zurück (paginiert).
|
||||
*/
|
||||
suspend fun findAll(limit: Int = 100, offset: Int = 0): List<DomReiter>
|
||||
|
||||
/**
|
||||
* Speichert einen Reiter (Insert oder Update).
|
||||
*/
|
||||
suspend fun save(reiter: DomReiter): DomReiter
|
||||
|
||||
/**
|
||||
* Löscht einen Reiter anhand seiner ID.
|
||||
*
|
||||
* @return true wenn gelöscht, false wenn nicht gefunden
|
||||
*/
|
||||
suspend fun delete(id: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Zählt alle aktiven Reiter.
|
||||
*/
|
||||
suspend fun countActive(): Long
|
||||
|
||||
/**
|
||||
* Prüft ob ein Reiter mit der gegebenen Satznummer bereits existiert.
|
||||
*/
|
||||
suspend fun existsBySatznummer(satznummer: String): Boolean
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.masterdata.domain.model.DomVerein
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Repository-Interface für DomVerein (Verein) Domain-Operationen.
|
||||
*
|
||||
* Definiert den Vertrag für Datenzugriffs-Operationen ohne Abhängigkeit
|
||||
* von konkreten Implementierungsdetails (Datenbank etc.).
|
||||
*/
|
||||
interface VereinRepository {
|
||||
|
||||
/**
|
||||
* Sucht einen Verein anhand seiner eindeutigen ID.
|
||||
*/
|
||||
suspend fun findById(id: Uuid): DomVerein?
|
||||
|
||||
/**
|
||||
* Sucht einen Verein anhand seiner OEPS-Vereinsnummer.
|
||||
*/
|
||||
suspend fun findByVereinsNummer(vereinsNummer: String): DomVerein?
|
||||
|
||||
/**
|
||||
* Sucht Vereine anhand des Namens (Teilübereinstimmung).
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, limit: Int = 50): List<DomVerein>
|
||||
|
||||
/**
|
||||
* Sucht alle Vereine eines Bundeslandes.
|
||||
*/
|
||||
suspend fun findByBundesland(bundesland: String, activeOnly: Boolean = true): List<DomVerein>
|
||||
|
||||
/**
|
||||
* Sucht alle Vereine, die als Veranstalter markiert sind.
|
||||
*/
|
||||
suspend fun findVeranstalter(activeOnly: Boolean = true): List<DomVerein>
|
||||
|
||||
/**
|
||||
* Gibt alle aktiven Vereine zurück (paginiert).
|
||||
*/
|
||||
suspend fun findAllActive(limit: Int = 100, offset: Int = 0): List<DomVerein>
|
||||
|
||||
/**
|
||||
* Gibt alle Vereine zurück (paginiert).
|
||||
*/
|
||||
suspend fun findAll(limit: Int = 100, offset: Int = 0): List<DomVerein>
|
||||
|
||||
/**
|
||||
* Speichert einen Verein (Insert oder Update).
|
||||
*/
|
||||
suspend fun save(verein: DomVerein): DomVerein
|
||||
|
||||
/**
|
||||
* Löscht einen Verein anhand seiner ID.
|
||||
*
|
||||
* @return true wenn gelöscht, false wenn nicht gefunden
|
||||
*/
|
||||
suspend fun delete(id: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Zählt alle aktiven Vereine.
|
||||
*/
|
||||
suspend fun countActive(): Long
|
||||
|
||||
/**
|
||||
* Prüft ob ein Verein mit der gegebenen Vereinsnummer bereits existiert.
|
||||
*/
|
||||
suspend fun existsByVereinsNummer(vereinsNummer: String): Boolean
|
||||
}
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
|
||||
package at.mocode.masterdata.domain.repository
|
||||
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.masterdata.domain.model.AltersklasseDefinition
|
||||
import kotlin.uuid.Uuid
|
||||
|
||||
/**
|
||||
* Repository interface for AltersklasseDefinition (Age Class) domain operations.
|
||||
*
|
||||
* This interface defines the contract for age class data access operations
|
||||
* without depending on specific implementation details (database, etc.).
|
||||
* Following the hexagonal architecture pattern, this interface belongs
|
||||
* to the domain layer and will be implemented in the infrastructure layer.
|
||||
*/
|
||||
interface AltersklasseRepository {
|
||||
|
||||
/**
|
||||
* Finds an age class by its unique ID.
|
||||
*
|
||||
* @param id The unique identifier of the age class
|
||||
* @return The age class if found, null otherwise
|
||||
*/
|
||||
suspend fun findById(id: Uuid): AltersklasseDefinition?
|
||||
|
||||
/**
|
||||
* Finds an age class by its code.
|
||||
*
|
||||
* @param altersklasseCode The age class code (e.g., "JGD_U16", "JUN_U18")
|
||||
* @return The age class if found, null otherwise
|
||||
*/
|
||||
suspend fun findByCode(altersklasseCode: String): AltersklasseDefinition?
|
||||
|
||||
/**
|
||||
* Finds age classes by name (partial match).
|
||||
*
|
||||
* @param searchTerm The search term to match against age class names
|
||||
* @param limit Maximum number of results to return
|
||||
* @return List of matching age classes
|
||||
*/
|
||||
suspend fun findByName(searchTerm: String, limit: Int = 50): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds all active age classes.
|
||||
*
|
||||
* @param sparteFilter Optional filter by sport type
|
||||
* @param geschlechtFilter Optional filter by gender ('M', 'W')
|
||||
* @return List of active age classes
|
||||
*/
|
||||
suspend fun findAllActive(sparteFilter: SparteE? = null, geschlechtFilter: Char? = null): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes applicable for a specific age.
|
||||
*
|
||||
* @param age The age to check
|
||||
* @param sparteFilter Optional filter by sport type
|
||||
* @param geschlechtFilter Optional filter by gender ('M', 'W')
|
||||
* @return List of applicable age classes
|
||||
*/
|
||||
suspend fun findApplicableForAge(age: Int, sparteFilter: SparteE? = null, geschlechtFilter: Char? = null): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by sport type.
|
||||
*
|
||||
* @param sparte The sport type
|
||||
* @param activeOnly Whether to return only active age classes
|
||||
* @return List of age classes for the sport type
|
||||
*/
|
||||
suspend fun findBySparte(sparte: SparteE, activeOnly: Boolean = true): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by gender filter.
|
||||
*
|
||||
* @param geschlecht The gender ('M', 'W')
|
||||
* @param activeOnly Whether to return only active age classes
|
||||
* @return List of age classes for the gender
|
||||
*/
|
||||
suspend fun findByGeschlecht(geschlecht: Char, activeOnly: Boolean = true): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by age range.
|
||||
*
|
||||
* @param minAge Minimum age (inclusive)
|
||||
* @param maxAge Maximum age (inclusive)
|
||||
* @param activeOnly Whether to return only active age classes
|
||||
* @return List of age classes within the age range
|
||||
*/
|
||||
suspend fun findByAgeRange(minAge: Int?, maxAge: Int?, activeOnly: Boolean = true): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Finds age classes by OETO rule reference.
|
||||
*
|
||||
* @param oetoRegelReferenzId The OETO rule reference ID
|
||||
* @return List of age classes linked to the rule
|
||||
*/
|
||||
suspend fun findByOetoRegelReferenz(oetoRegelReferenzId: Uuid): List<AltersklasseDefinition>
|
||||
|
||||
/**
|
||||
* Saves an age class (create or update).
|
||||
*
|
||||
* @param altersklasse The age class to save
|
||||
* @return The saved age class with updated timestamps
|
||||
*/
|
||||
suspend fun save(altersklasse: AltersklasseDefinition): AltersklasseDefinition
|
||||
|
||||
/**
|
||||
* Deletes an age class by ID.
|
||||
*
|
||||
* @param id The unique identifier of the age class to delete
|
||||
* @return true if the age class was deleted, false if not found
|
||||
*/
|
||||
suspend fun delete(id: Uuid): Boolean
|
||||
|
||||
/**
|
||||
* Checks if an age class with the given code exists.
|
||||
*
|
||||
* @param altersklasseCode The age class code to check
|
||||
* @return true if an age class with this code exists, false otherwise
|
||||
*/
|
||||
suspend fun existsByCode(altersklasseCode: String): Boolean
|
||||
|
||||
/**
|
||||
* Counts the total number of active age classes.
|
||||
*
|
||||
* @param sparteFilter Optional filter by sport type
|
||||
* @return The total count of active age classes
|
||||
*/
|
||||
suspend fun countActive(sparteFilter: SparteE? = null): Long
|
||||
|
||||
/**
|
||||
* Validates if a person with given age and gender can participate in an age class.
|
||||
*
|
||||
* @param altersklasseId The age class ID
|
||||
* @param age The person's age
|
||||
* @param geschlecht The person's gender ('M', 'W')
|
||||
* @return true if the person can participate, false otherwise
|
||||
*/
|
||||
suspend fun isEligible(altersklasseId: Uuid, age: Int, geschlecht: Char): Boolean
|
||||
}
|
||||
Reference in New Issue
Block a user