| .. | ||
| events-api | ||
| events-application | ||
| events-domain | ||
| events-infrastructure | ||
| events-service | ||
| README.md | ||
Events Module
Überblick
Das Events-Modul ist eine umfassende Lösung zur Verwaltung von Pferdesportveranstaltungen. Es implementiert eine saubere Architektur mit Domain-Driven Design und bietet vollständige CRUD-Operationen sowie erweiterte Geschäftslogik für die Veranstaltungsplanung und -verwaltung.
Funktionalität
Verwaltete Entität
Veranstaltung (Event)
- Grundinformationen: Name, Beschreibung
- Terminverwaltung: Startdatum, Enddatum, Anmeldeschluss
- Ort und Organisation: Veranstaltungsort, Veranstalter-Verein-ID
- Veranstaltungsdetails: Sparten, Aktivitätsstatus, Öffentlichkeit, maximale Teilnehmerzahl
- Audit-Felder: Erstellungs- und Aktualisierungszeitstempel
- Geschäftslogik: Validierung, Anmeldestatus, Dauernberechnung
Geschäftsoperationen
Das Modul bietet 10+ spezialisierte Repository-Operationen:
Basis-CRUD-Operationen
findById(id)- Veranstaltung nach UUID suchensave(veranstaltung)- Veranstaltung speichern (erstellen/aktualisieren)delete(id)- Veranstaltung löschen
Such-Operationen
findByName(searchTerm, limit)- Nach Namen suchen (Teilübereinstimmung)findByVeranstalterVereinId(vereinId, activeOnly)- Veranstaltungen eines VereinsfindAllActive(limit, offset)- Alle aktiven VeranstaltungenfindPublicEvents(activeOnly)- Öffentliche Veranstaltungen
Datumsbasierte Abfragen
findByDateRange(startDate, endDate, activeOnly)- Veranstaltungen in DatumsbereichfindByStartDate(date, activeOnly)- Veranstaltungen nach Startdatum
Zähl-Operationen
countActive()- Anzahl aktiver VeranstaltungencountByVeranstalterVereinId(vereinId, activeOnly)- Anzahl Veranstaltungen pro Verein
Architektur
Das Modul folgt der Clean Architecture mit klarer Trennung der Verantwortlichkeiten:
events/
├── events-domain/ # Domain Layer
│ ├── model/ # Domain Models
│ │ └── Veranstaltung.kt # Veranstaltungs-Entität mit Geschäftslogik
│ ├── repository/ # Repository Interfaces
│ │ └── VeranstaltungRepository.kt # 10+ Geschäftsoperationen
│ └── EventManagement.kt # Domain Service/Facade
├── events-application/ # Application Layer
│ └── usecase/ # Use Cases
│ ├── CreateVeranstaltungUseCase.kt
│ ├── GetVeranstaltungUseCase.kt
│ ├── UpdateVeranstaltungUseCase.kt
│ └── DeleteVeranstaltungUseCase.kt
├── events-infrastructure/ # Infrastructure Layer
│ └── persistence/ # Database Implementation
│ ├── VeranstaltungRepositoryImpl.kt
│ └── VeranstaltungTable.kt
├── events-api/ # API Layer
│ └── rest/ # REST Controllers
│ └── VeranstaltungController.kt
└── events-service/ # Service Layer
└── EventsServiceApplication.kt
Domain Layer
- 1 Domain Model mit reichhaltiger Geschäftslogik
- 1 Repository Interface mit 10+ Geschäftsoperationen
- Domain Service für komplexe Veranstaltungslogik
- Keine Abhängigkeiten zu anderen Layern
Application Layer
- Use Cases für CRUD-Operationen
- Orchestrierung von Domain-Services
- Anwendungslogik ohne UI-Abhängigkeiten
Infrastructure Layer
- Datenbankzugriff mit Exposed ORM
- Repository-Implementierung mit PostgreSQL
- Datenbankschema und Migrationen
API Layer
- REST-Controller für HTTP-Endpunkte
- DTO-Mapping zwischen Domain und API
- Validierung und Fehlerbehandlung
Service Layer
- Spring Boot Anwendung
- Dependency Injection Konfiguration
- Service-Konfiguration
Domain Model Details
Veranstaltung-Entität
data class Veranstaltung(
val veranstaltungId: Uuid,
// Grundinformationen
var name: String,
var beschreibung: String? = null,
// Termine
var startDatum: LocalDate,
var endDatum: LocalDate,
// Ort und Organisation
var ort: String,
var veranstalterVereinId: Uuid,
// Veranstaltungsdetails
var sparten: List<SparteE> = emptyList(),
var istAktiv: Boolean = true,
var istOeffentlich: Boolean = true,
var maxTeilnehmer: Int? = null,
var anmeldeschluss: LocalDate? = null,
// Audit-Felder
val createdAt: Instant,
var updatedAt: Instant
)
Geschäftslogik-Methoden
isRegistrationOpen()- Prüfung ob Anmeldung noch möglich istgetDurationInDays()- Berechnung der Veranstaltungsdauer in TagenisMultiDay()- Prüfung ob mehrtägige Veranstaltungvalidate()- Datenvalidierung mit FehlerlistewithUpdatedTimestamp()- Kopie mit aktualisiertem Zeitstempel
Enumerationen
SparteE (Sportsparten)
DRESSUR- DressurreitenSPRINGEN- SpringreitenVIELSEITIGKEIT- VielseitigkeitsreitenFAHREN- FahrsportVOLTIGIEREN- VoltigierenWESTERN- WesternreitenDISTANZ- Distanzreiten
Repository-Operationen
Erweiterte Such-Features
// Veranstaltungen nach Namen suchen
val events = veranstaltungRepository.findByName("Turnier", limit = 10)
// Veranstaltungen eines Vereins finden
val clubEvents = veranstaltungRepository.findByVeranstalterVereinId(
vereinId = clubId,
activeOnly = true
)
// Veranstaltungen in Datumsbereich suchen
val summerEvents = veranstaltungRepository.findByDateRange(
startDate = LocalDate(2024, 6, 1),
endDate = LocalDate(2024, 8, 31),
activeOnly = true
)
// Öffentliche Veranstaltungen finden
val publicEvents = veranstaltungRepository.findPublicEvents(activeOnly = true)
Datumsbasierte Abfragen
// Veranstaltungen an einem bestimmten Tag
val todayEvents = veranstaltungRepository.findByStartDate(
date = LocalDate.now(),
activeOnly = true
)
// Alle aktiven Veranstaltungen
val activeEvents = veranstaltungRepository.findAllActive(limit = 100)
Statistiken und Zählungen
// Anzahl aktiver Veranstaltungen
val totalActive = veranstaltungRepository.countActive()
// Anzahl Veranstaltungen pro Verein
val clubEventCount = veranstaltungRepository.countByVeranstalterVereinId(
vereinId = clubId,
activeOnly = true
)
Use Cases
CreateVeranstaltungUseCase
Erstellt eine neue Veranstaltung mit Validierung und Geschäftsregeln.
class CreateVeranstaltungUseCase(
private val veranstaltungRepository: VeranstaltungRepository
) {
suspend fun execute(veranstaltung: Veranstaltung): Veranstaltung {
// Validierung
val errors = veranstaltung.validate()
if (errors.isNotEmpty()) {
throw ValidationException(errors)
}
// Geschäftsregeln prüfen
if (veranstaltung.anmeldeschluss != null &&
veranstaltung.anmeldeschluss!! > veranstaltung.startDatum) {
throw BusinessRuleException("Anmeldeschluss muss vor Veranstaltungsbeginn liegen")
}
return veranstaltungRepository.save(veranstaltung)
}
}
GetVeranstaltungUseCase
Ruft Veranstaltungsinformationen ab mit verschiedenen Suchkriterien.
UpdateVeranstaltungUseCase
Aktualisiert Veranstaltungsinformationen mit Validierung.
DeleteVeranstaltungUseCase
Löscht eine Veranstaltung (soft delete durch Deaktivierung).
API-Endpunkte
Das Events-Modul stellt REST-Endpunkte über den VeranstaltungController bereit:
GET /api/events- Alle aktiven Veranstaltungen abrufenGET /api/events/{id}- Veranstaltung nach ID abrufenGET /api/events/search?name={name}- Veranstaltungen nach Namen suchenGET /api/events/club/{clubId}- Veranstaltungen eines VereinsGET /api/events/public- Öffentliche VeranstaltungenGET /api/events/date-range?start={start}&end={end}- Veranstaltungen in DatumsbereichGET /api/events/date/{date}- Veranstaltungen an einem bestimmten TagPOST /api/events- Neue Veranstaltung erstellenPUT /api/events/{id}- Veranstaltung aktualisierenDELETE /api/events/{id}- Veranstaltung löschen
Konfiguration
Datenbankschema
Das Modul verwendet eine events-Tabelle mit folgenden Spalten:
veranstaltung_id(UUID, Primary Key)name(Required)beschreibung(Text, Optional)start_datum,end_datum(Date, Required)ort(Required)veranstalter_verein_id(UUID, Foreign Key)sparten(JSON Array)ist_aktiv,ist_oeffentlich(Boolean)max_teilnehmer(Integer, Optional)anmeldeschluss(Date, Optional)created_at,updated_at(Timestamps)
Service-Konfiguration
# application.yml
events:
service:
name: events-service
port: 8084
database:
url: jdbc:postgresql://localhost:5432/meldestelle
table: events
business-rules:
max-duration-days: 30
min-registration-period-days: 7
allow-past-events: false
Tests
Integration Tests
Das Modul enthält umfassende Integrationstests:
@Test
fun `should create event with valid data`() {
// Test für Veranstaltungserstellung
}
@Test
fun `should find events by date range`() {
// Test für datumsbasierte Suche
}
@Test
fun `should validate registration deadline`() {
// Test für Anmeldeschluss-Validierung
}
@Test
fun `should find public events only`() {
// Test für öffentliche Veranstaltungen
}
Test-Datenbank
Verwendet H2 In-Memory-Datenbank für Tests mit automatischem Schema-Setup.
Deployment
Docker
FROM openjdk:21-jre-slim
COPY events-service.jar app.jar
EXPOSE 8084
ENTRYPOINT ["java", "-jar", "/app.jar"]
Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: events-service
spec:
replicas: 2
selector:
matchLabels:
app: events-service
template:
spec:
containers:
- name: events-service
image: meldestelle/events-service:latest
ports:
- containerPort: 8084
Monitoring
Metriken
- Anzahl aktiver Veranstaltungen
- Anzahl öffentlicher Veranstaltungen
- Durchschnittliche Veranstaltungsdauer
- API-Response-Zeiten
- Datenbankverbindungs-Pool
- Validierungsfehler-Rate
Health Checks
- Datenbankverbindung
- Service-Verfügbarkeit
- Speicherverbrauch
- Externe System-Verbindungen
Entwicklung
Lokale Entwicklung
# Service starten
./gradlew :events:events-service:bootRun
# Tests ausführen
./gradlew :events:test
# Integration Tests
./gradlew :events:events-service:test
Code-Qualität
- Kotlin Coding Standards
- 100% Test Coverage für Domain Layer
- Integration Tests für alle Use Cases
- API-Dokumentation mit OpenAPI
Geschäftsregeln
Veranstaltungsplanung
- Datumsvalidierung: Enddatum muss nach oder gleich Startdatum sein
- Anmeldeschluss: Muss vor Veranstaltungsbeginn liegen
- Teilnehmerbegrenzung: Maximale Teilnehmerzahl muss positiv sein
- Öffentlichkeit: Private Veranstaltungen nur für Vereinsmitglieder
Sparten-Management
- Unterstützung für alle österreichischen Pferdesport-Sparten
- Mehrfachauswahl möglich für kombinierte Veranstaltungen
- Sparten-spezifische Validierungsregeln
Vereins-Integration
- Verknüpfung mit Vereinsverwaltung
- Berechtigung zur Veranstaltungserstellung
- Vereins-spezifische Konfigurationen
Integration
Externe Systeme
OEPS-Integration
- Synchronisation mit OEPS-Veranstaltungskalender
- Automatische Meldung bei OEPS-relevanten Veranstaltungen
- Import von OEPS-Veranstaltungsdaten
FEI-Integration
- Unterstützung für internationale Veranstaltungen
- FEI-Regularien und -Standards
- Automatische Klassifizierung
Interne Module
Members-Modul
- Teilnehmerverwaltung
- Anmeldestatus-Tracking
- Mitgliedschaftsvalidierung
Horses-Modul
- Pferdeanmeldungen
- Eignung für Sparten
- Registrierungsstatus
Zukünftige Erweiterungen
- Anmeldungssystem - Vollständiges Teilnehmeranmeldungssystem
- Zeitplanung - Detaillierte Zeitpläne und Startlisten
- Ergebniserfassung - Integration mit Bewertungssystemen
- Livestreaming - Integration mit Streaming-Plattformen
- Mobile App - Mobile Anwendung für Teilnehmer
- Zahlungsintegration - Startgebühren und Zahlungsabwicklung
- Wetterintegration - Wettervorhersage und -warnungen
- Kapazitätsmanagement - Stallplätze und Parkplätze
- Catering-Management - Verpflegung und Bewirtung
- Sponsoring - Sponsoren-Management und -präsentation
Letzte Aktualisierung: 25. Juli 2025
Für weitere Informationen zur Gesamtarchitektur siehe README.md.