meldestelle/events
2025-07-25 23:16:16 +02:00
..
events-api refactor: Migrate from monolithic to modular architecture 2025-07-22 18:44:18 +02:00
events-application refactor: Migrate from monolithic to modular architecture 2025-07-22 18:44:18 +02:00
events-domain refactor: Migrate from monolithic to modular architecture 2025-07-22 18:44:18 +02:00
events-infrastructure refactor: Migrate from monolithic to modular architecture 2025-07-22 18:44:18 +02:00
events-service einige Ergänzungen 2025-07-25 23:16:16 +02:00
README.md docs: Migrationsplan für Projekt-Restrukturierung hinzugefügt 2025-07-25 13:05:42 +02:00

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 suchen
  • save(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 Vereins
  • findAllActive(limit, offset) - Alle aktiven Veranstaltungen
  • findPublicEvents(activeOnly) - Öffentliche Veranstaltungen

Datumsbasierte Abfragen

  • findByDateRange(startDate, endDate, activeOnly) - Veranstaltungen in Datumsbereich
  • findByStartDate(date, activeOnly) - Veranstaltungen nach Startdatum

Zähl-Operationen

  • countActive() - Anzahl aktiver Veranstaltungen
  • countByVeranstalterVereinId(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 ist
  • getDurationInDays() - Berechnung der Veranstaltungsdauer in Tagen
  • isMultiDay() - Prüfung ob mehrtägige Veranstaltung
  • validate() - Datenvalidierung mit Fehlerliste
  • withUpdatedTimestamp() - Kopie mit aktualisiertem Zeitstempel

Enumerationen

SparteE (Sportsparten)

  • DRESSUR - Dressurreiten
  • SPRINGEN - Springreiten
  • VIELSEITIGKEIT - Vielseitigkeitsreiten
  • FAHREN - Fahrsport
  • VOLTIGIEREN - Voltigieren
  • WESTERN - Westernreiten
  • DISTANZ - 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 abrufen
  • GET /api/events/{id} - Veranstaltung nach ID abrufen
  • GET /api/events/search?name={name} - Veranstaltungen nach Namen suchen
  • GET /api/events/club/{clubId} - Veranstaltungen eines Vereins
  • GET /api/events/public - Öffentliche Veranstaltungen
  • GET /api/events/date-range?start={start}&end={end} - Veranstaltungen in Datumsbereich
  • GET /api/events/date/{date} - Veranstaltungen an einem bestimmten Tag
  • POST /api/events - Neue Veranstaltung erstellen
  • PUT /api/events/{id} - Veranstaltung aktualisieren
  • DELETE /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

  1. Datumsvalidierung: Enddatum muss nach oder gleich Startdatum sein
  2. Anmeldeschluss: Muss vor Veranstaltungsbeginn liegen
  3. Teilnehmerbegrenzung: Maximale Teilnehmerzahl muss positiv sein
  4. Ö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

  1. Anmeldungssystem - Vollständiges Teilnehmeranmeldungssystem
  2. Zeitplanung - Detaillierte Zeitpläne und Startlisten
  3. Ergebniserfassung - Integration mit Bewertungssystemen
  4. Livestreaming - Integration mit Streaming-Plattformen
  5. Mobile App - Mobile Anwendung für Teilnehmer
  6. Zahlungsintegration - Startgebühren und Zahlungsabwicklung
  7. Wetterintegration - Wettervorhersage und -warnungen
  8. Kapazitätsmanagement - Stallplätze und Parkplätze
  9. Catering-Management - Verpflegung und Bewirtung
  10. Sponsoring - Sponsoren-Management und -präsentation

Letzte Aktualisierung: 25. Juli 2025

Für weitere Informationen zur Gesamtarchitektur siehe README.md.