diff --git a/build.gradle.kts b/build.gradle.kts index ccc93574..5b2e5140 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,4 @@ +/* import java.util.Locale plugins { @@ -64,11 +65,11 @@ subprojects { jvmArgs = listOf("-Xmx512m", "-XX:+UseG1GC") // Include all tests that have "Integration" in their name - include("**/*Integration*Test.kt") + include("** / *Integration*Test.kt") // Exclude unit tests (but keep integration tests) - exclude("**/*Test.kt") - include("**/*IntegrationTest.kt") + exclude("** / *Test.kt") + include("** / *IntegrationTest.kt") // Set system properties for integration tests systemProperty("spring.profiles.active", "integration-test") @@ -85,6 +86,43 @@ subprojects { // We don't use mustRunAfter here to avoid reference issues } } +*/ + +import java.util.Locale + +plugins { + // KORREKTUR: Wir entfernen die hartcodierten Versionen und verwenden stattdessen + // die Aliase aus dem Version Catalog. `apply false` bleibt, da die Plugins + // hier nur für die Unterprojekte deklariert werden. + alias(libs.plugins.kotlin.jvm) apply false + alias(libs.plugins.kotlin.multiplatform) apply false + alias(libs.plugins.compose.multiplatform) apply false + alias(libs.plugins.compose.compiler) apply false + base +} + +allprojects { + group = "at.mocode.meldestelle" + version = "0.1.0-SNAPSHOT" + + repositories { + mavenCentral() + google() // Wichtig für Compose-Abhängigkeiten + } +} + +subprojects { + // Konfigurationen, die für alle Untermodule gelten. + tasks.withType().configureEach { + compilerOptions { + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21) + } + } + + tasks.withType().configureEach { + useJUnitPlatform() + } +} // Documentation generation tasks tasks.register("generateOpenApiDocs") { diff --git a/client/common-ui/build.gradle.kts b/client/common-ui/build.gradle.kts index 3712e767..40e82848 100644 --- a/client/common-ui/build.gradle.kts +++ b/client/common-ui/build.gradle.kts @@ -1,52 +1,64 @@ plugins { - kotlin("jvm") - id("org.springframework.boot") apply false - id("io.spring.dependency-management") apply false - id("org.jetbrains.compose") version "1.7.3" - id("org.jetbrains.kotlin.plugin.compose") version "2.1.20" + // KORREKTUR: Wir deklarieren dieses Modul als Kotlin Multiplatform Modul. + alias(libs.plugins.kotlin.multiplatform) + // KORREKTUR: Wir deklarieren, dass wir Jetpack Compose verwenden. + alias(libs.plugins.compose.multiplatform) + alias(libs.plugins.compose.compiler) } -repositories { - google() - mavenCentral() -} - -dependencies { - // Core dependencies - implementation(projects.core.coreDomain) - implementation(projects.core.coreUtils) - - // Domain modules - implementation(projects.events.eventsDomain) - implementation(projects.horses.horsesDomain) - implementation(projects.masterdata.masterdataDomain) - implementation(projects.members.membersDomain) - - // Compose dependencies for Desktop - implementation(compose.desktop.currentOs) - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material3) - implementation(compose.ui) - implementation(compose.components.resources) - implementation(compose.materialIconsExtended) - - // AndroidX dependencies are provided by the Compose plugin - - // Ktor Client dependencies - implementation(libs.ktor.client.core) - implementation(libs.ktor.client.cio) - implementation(libs.ktor.client.contentNegotiation) - implementation(libs.ktor.client.serializationKotlinxJson) - - // Kotlinx dependencies - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.8.0") - implementation("com.benasher44:uuid:0.8.4") - - // Testing - testImplementation(kotlin("test")) - testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0") +kotlin { + // Wir definieren die Zielplattformen, für die dieses Modul Code bereitstellt. + jvm("desktop") // Ein JVM-Target für unsere Desktop-App + js(IR) { // Ein JavaScript-Target für unsere Web-App + browser() + binaries.executable() + } + + // Hier definieren wir die Abhängigkeiten für die jeweiligen Source Sets. + sourceSets { + val commonMain by getting { + dependencies { + // --- Interne Module (für alle Plattformen verfügbar) --- + api(projects.core.coreDomain) + api(projects.core.coreUtils) + + // --- Jetpack Compose UI (für alle Plattformen verfügbar) --- + api(compose.runtime) + api(compose.foundation) + api(compose.material3) + api(compose.ui) + api(compose.components.resources) + api(compose.materialIconsExtended) + + // --- Ktor Client für API-Kommunikation (Kernmodul für alle) --- + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.contentNegotiation) + implementation(libs.ktor.client.serialization.kotlinx.json) + + // --- Coroutines (für alle Plattformen verfügbar) --- + implementation(libs.kotlinx.coroutines.core) + } + } + + val desktopMain by getting { + dependencies { + // Ktor-Engine, die nur für die Desktop (JVM) Version benötigt wird + implementation(libs.ktor.client.cio) + } + } + + val jsMain by getting { + dependencies { + // Ktor-Engine, die nur für die Web (JS) Version benötigt wird + implementation(libs.ktor.client.js) + } + } + + val commonTest by getting { + dependencies { + implementation(libs.kotlin.test) + implementation(libs.kotlinx.coroutines.test) + } + } + } } diff --git a/client/desktop-app/build.gradle.kts b/client/desktop-app/build.gradle.kts index 86b58a63..23c8ffd8 100644 --- a/client/desktop-app/build.gradle.kts +++ b/client/desktop-app/build.gradle.kts @@ -1,53 +1,25 @@ plugins { kotlin("jvm") - kotlin("plugin.spring") - id("org.springframework.boot") - id("io.spring.dependency-management") version "1.1.4" - id("org.jetbrains.compose") version "1.7.3" - id("org.jetbrains.kotlin.plugin.compose") version "2.1.21" -} - -repositories { - mavenCentral() - google() + alias(libs.plugins.compose.multiplatform) + alias(libs.plugins.compose.compiler) } dependencies { + // Greift explizit auf den "desktop" (JVM) Teil unseres KMP-Moduls zu. implementation(projects.client.commonUi) - implementation(projects.client.webApp) - implementation(projects.infrastructure.auth.authClient) - implementation(projects.infrastructure.cache.redisCache) - implementation(projects.infrastructure.eventStore.redisEventStore) - // Domain modules - implementation(projects.core.coreDomain) - implementation(projects.core.coreUtils) - implementation(projects.events.eventsDomain) - implementation(projects.horses.horsesDomain) - implementation(projects.masterdata.masterdataDomain) - - // Spring Boot dependencies - implementation("org.springframework.boot:spring-boot-starter") - - // Redis dependencies - implementation("org.redisson:redisson:3.27.2") - implementation("io.lettuce:lettuce-core:6.3.2.RELEASE") - - // Kotlinx dependencies - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:1.8.0") - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3") - implementation("com.benasher44:uuid:0.8.4") - - // Compose dependencies + // Stellt die Desktop-spezifischen Teile von Jetpack Compose bereit. implementation(compose.desktop.currentOs) - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material3) - implementation(compose.ui) - implementation(compose.components.resources) - implementation(compose.materialIconsExtended) + // Stellt die Coroutine-Integration für die Swing-UI-Bibliothek bereit. + implementation(libs.kotlinx.coroutines.swing) + + // --- Testing --- testImplementation(projects.platform.platformTesting) } + +compose.desktop { + application { + mainClass = "at.mocode.client.desktop.MainKt" + } +} diff --git a/client/desktop-app/build.gradle.kts.optimized b/client/desktop-app/build.gradle.kts.optimized deleted file mode 100644 index 59e85042..00000000 --- a/client/desktop-app/build.gradle.kts.optimized +++ /dev/null @@ -1,87 +0,0 @@ -plugins { - kotlin("jvm") - id("org.jetbrains.compose") version "1.7.3" - id("org.jetbrains.kotlin.plugin.compose") version "2.1.21" -} - -repositories { - mavenCentral() - google() -} - -dependencies { - // Client dependencies - only what's needed for desktop app - implementation(projects.client.commonUi) - implementation(projects.client.webApp) // Only if truly needed for shared screens - - // Core dependencies - minimal set - implementation(projects.core.coreDomain) - implementation(projects.core.coreUtils) - - // Remove unnecessary infrastructure dependencies - // implementation(projects.infrastructure.auth.authClient) // Only if auth is needed - // implementation(projects.infrastructure.cache.redisCache) // Not needed in client - // implementation(projects.infrastructure.eventStore.redisEventStore) // Not needed in client - - // Remove domain module dependencies - should go through API - // implementation(projects.events.eventsDomain) // Access through API instead - // implementation(projects.horses.horsesDomain) // Access through API instead - // implementation(projects.masterdata.masterdataDomain) // Access through API instead - - // Remove Spring Boot dependencies - not needed for desktop client - // implementation("org.springframework.boot:spring-boot-starter") - - // Remove Redis dependencies - not needed for desktop client - // implementation("org.redisson:redisson:3.27.2") - // implementation("io.lettuce:lettuce-core:6.3.2.RELEASE") - - // Keep only essential Kotlinx dependencies - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.8.0") // Changed from javafx to swing - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3") - implementation("com.benasher44:uuid:0.8.4") - - // Compose dependencies - keep as needed for desktop UI - implementation(compose.desktop.currentOs) - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material3) - implementation(compose.ui) - implementation(compose.components.resources) - implementation(compose.materialIconsExtended) - - // Testing - testImplementation(projects.platform.platformTesting) - testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0") -} - -// Desktop application configuration -compose.desktop { - application { - mainClass = "at.mocode.client.desktop.MainKt" - - nativeDistributions { - targetFormats( - org.jetbrains.compose.desktop.application.dsl.TargetFormat.Dmg, - org.jetbrains.compose.desktop.application.dsl.TargetFormat.Msi, - org.jetbrains.compose.desktop.application.dsl.TargetFormat.Deb - ) - packageName = "Meldestelle Desktop" - packageVersion = "1.0.0" - description = "Meldestelle Desktop Application" - copyright = "© 2024 MoCode. All rights reserved." - vendor = "MoCode" - - windows { - iconFile.set(project.file("src/main/resources/icon.ico")) - } - macOS { - iconFile.set(project.file("src/main/resources/icon.icns")) - } - linux { - iconFile.set(project.file("src/main/resources/icon.png")) - } - } - } -} diff --git a/client/web-app/build.gradle.kts b/client/web-app/build.gradle.kts index 5624dbb0..37b6c29b 100644 --- a/client/web-app/build.gradle.kts +++ b/client/web-app/build.gradle.kts @@ -1,58 +1,34 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") - id("org.springframework.boot") - id("io.spring.dependency-management") version "1.1.4" - id("org.jetbrains.compose") version "1.7.3" - id("org.jetbrains.kotlin.plugin.compose") version "2.1.21" + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.compose.multiplatform) + alias(libs.plugins.compose.compiler) } -repositories { - google() - mavenCentral() -} - -tasks.withType { - useJUnitPlatform() -} - -dependencies { - // Client dependencies - implementation(projects.client.commonUi) - - // Core dependencies - minimal set - implementation(projects.core.coreDomain) - implementation(projects.core.coreUtils) - - // Remove unnecessary infrastructure dependencies - // implementation(projects.infrastructure.auth.authClient) // Only if auth is needed - - // Remove direct domain module dependencies - access through API instead - // implementation(projects.members.membersDomain) // Access through API - // implementation(projects.members.membersApplication) // Access through API - // implementation(projects.masterdata.masterdataDomain) // Access through API - // implementation(projects.horses.horsesDomain) // Access through API - // implementation(projects.events.eventsDomain) // Access through API - - // Compose dependencies for Desktop - implementation(compose.desktop.currentOs) - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material3) - implementation(compose.ui) - implementation(compose.components.resources) - implementation(compose.materialIconsExtended) - - // Essential Kotlinx dependencies - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.8.0") - implementation("com.benasher44:uuid:0.8.4") - - // Testing - testImplementation(projects.platform.platformTesting) - testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0") - testImplementation("io.mockk:mockk:1.13.8") - testImplementation("org.junit.jupiter:junit-jupiter:5.10.1") +kotlin { + js(IR) { + browser { + // Konfiguriert den Development-Server und die finalen Bundles. + commonWebpackConfig { + outputFileName = "MeldestelleWebApp.js" + } + } + binaries.executable() + } + + sourceSets { + val jsMain by getting { + dependencies { + // Greift explizit auf den JS-Teil unseres KMP-Moduls zu. + implementation(projects.client.commonUi) + + // Stellt die Web-spezifischen (HTML) Teile von Jetpack Compose bereit. + implementation(compose.html.core) + } + } + val jsTest by getting { + dependencies { + implementation(libs.kotlin.test) + } + } + } } diff --git a/client/web-app/build.gradle.kts.optimized b/client/web-app/build.gradle.kts.optimized deleted file mode 100644 index 7142e70d..00000000 --- a/client/web-app/build.gradle.kts.optimized +++ /dev/null @@ -1,63 +0,0 @@ -plugins { - kotlin("jvm") - id("org.jetbrains.compose") version "1.7.3" - id("org.jetbrains.kotlin.plugin.compose") version "2.1.21" -} - -repositories { - google() - mavenCentral() -} - -tasks.withType { - useJUnitPlatform() -} - -dependencies { - // Client dependencies - implementation(projects.client.commonUi) - - // Core dependencies - minimal set - implementation(projects.core.coreDomain) - implementation(projects.core.coreUtils) - - // Remove unnecessary infrastructure dependencies - // implementation(projects.infrastructure.auth.authClient) // Only if auth is needed - - // Remove direct domain module dependencies - access through API instead - // implementation(projects.members.membersDomain) // Access through API - // implementation(projects.members.membersApplication) // Access through API - // implementation(projects.masterdata.masterdataDomain) // Access through API - // implementation(projects.horses.horsesDomain) // Access through API - // implementation(projects.events.eventsDomain) // Access through API - - // Compose dependencies for Web (using Compose Multiplatform for Web) - implementation(compose.html.core) - implementation(compose.runtime) - - // Alternative: If using Compose for Desktop in web context - // implementation(compose.desktop.currentOs) - // implementation(compose.foundation) - // implementation(compose.material3) - // implementation(compose.ui) - // implementation(compose.components.resources) - // implementation(compose.materialIconsExtended) - - // Essential Kotlinx dependencies - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-js:1.8.0") // For web target - implementation("com.benasher44:uuid:0.8.4") - - // Testing - testImplementation(projects.platform.platformTesting) - testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0") - testImplementation("io.mockk:mockk:1.13.8") - testImplementation("org.junit.jupiter:junit-jupiter:5.10.1") -} - -// Web application configuration -compose.experimental { - web.application {} -} diff --git a/core/core-domain/build.gradle.kts b/core/core-domain/build.gradle.kts index f826f86e..e6049724 100644 --- a/core/core-domain/build.gradle.kts +++ b/core/core-domain/build.gradle.kts @@ -1,17 +1,33 @@ plugins { + // Definiert dieses Modul als ein Standard Kotlin/JVM-Modul. kotlin("jvm") + // Aktiviert das Kotlinx Serialization Plugin, da unsere DTOs und Enums + // als @Serializable markiert sind. alias(libs.plugins.kotlin.serialization) } dependencies { + // Stellt sicher, dass dieses Modul Zugriff auf die im zentralen Katalog + // definierten Bibliotheken hat. api(projects.platform.platformDependencies) - // UUID handling - api("com.benasher44:uuid:0.8.2") + // --- Kern-Abhängigkeiten für das Domänen-Modell --- + // Diese Bibliotheken definieren die grundlegenden Datentypen unseres Modells. + // Wir verwenden `api` anstelle von `implementation`, damit Services, die + // `core-domain` einbinden, diese Typen ebenfalls direkt nutzen können. - // Serialization - api("org.jetbrains.kotlinx:kotlinx-serialization-json") - api("org.jetbrains.kotlinx:kotlinx-datetime") + // Stellt den `Uuid`-Typ für unsere eindeutigen IDs bereit. + api(libs.uuid) + // Stellt die `kotlinx.serialization`-Engine bereit, insbesondere für JSON. + api(libs.kotlinx.serialization.json) + + // Stellt moderne Datums- und Zeit-Typen wie `Instant` und `LocalDate` bereit. + api(libs.kotlinx.datetime) + + // --- Test-Abhängigkeiten --- + // Stellt die notwendigen Bibliotheken für das Schreiben von Tests bereit. + // `testImplementation` sorgt dafür, dass diese Bibliotheken nicht Teil + // des finalen produktiven Codes werden. testImplementation(projects.platform.platformTesting) } diff --git a/core/core-utils/build.gradle.kts b/core/core-utils/build.gradle.kts index f02a8052..58c50d0c 100644 --- a/core/core-utils/build.gradle.kts +++ b/core/core-utils/build.gradle.kts @@ -3,27 +3,26 @@ plugins { } dependencies { + // Verwendet die zentrale Platform-BOM für konsistente Versionen api(projects.platform.platformDependencies) // Explizite `api`-Abhängigkeit zum core-domain Modul. api(projects.core.coreDomain) // --- Coroutines & Asynchronität --- - api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") + api(libs.kotlinx.coroutines.core) // --- Datenbank-Management --- - api("org.jetbrains.exposed:exposed-core") - api("org.jetbrains.exposed:exposed-dao") - api("org.jetbrains.exposed:exposed-jdbc") - api("org.jetbrains.exposed:exposed-kotlin-datetime") - api("com.zaxxer:HikariCP") - // Flyway Core-Bibliothek - api("org.flywaydb:flyway-core:9.22.3") - // KORREKTUR: Spezifischer Treiber für PostgreSQL mit Versionsnummer - api("org.flywaydb:flyway-database-postgresql:9.22.3") + api(libs.exposed.core) + api(libs.exposed.dao) + api(libs.exposed.jdbc) + api(libs.exposed.kotlin.datetime) + api(libs.hikari.cp) + api(libs.flyway.core) + api(libs.flyway.postgresql) // --- Service Discovery --- - api("com.orbitz.consul:consul-client:1.5.3") + api(libs.consul.client) // --- Testing --- testImplementation(projects.platform.platformTesting) diff --git a/docs/entwickungszyklus/Check-Liste-Refactoring_00.md b/docs/entwickungszyklus/Check-Liste-Refactoring_00.md new file mode 100644 index 00000000..7d6ebb5b --- /dev/null +++ b/docs/entwickungszyklus/Check-Liste-Refactoring_00.md @@ -0,0 +1,59 @@ +# Checkliste: Detaillierter Entwicklungs- & Refactoring-Plan für Meldestelle_Pro + +**Datum:** 28. Juli 2025 + +Dieses Dokument dient als zentrale Checkliste für die abgeschlossenen Planungs- und Refactoring-Arbeiten sowie für die anstehenden Implementierungs-Aufgaben gemäß unserer agilen Roadmap. + +--- + +### ✅ Phase 1: Fundament & Architektur (Abgeschlossen) + +*In dieser Phase haben wir das Gehirn und das Nervensystem unseres Projekts entworfen. Wir haben eine gemeinsame Vision geschaffen und die technischen Leitplanken für die gesamte zukünftige Entwicklung gesetzt.* + +* **[x] Gesamtarchitektur finalisiert** + * **Wofür?** Um eine gemeinsame, klare Vorstellung vom Zielsystem zu haben. Dies verhindert Missverständnisse und stellt sicher, dass alle an einem Strang ziehen. + * **Artefakte:** Detailliertes DDD-Modell mit 12 Bounded Contexts, C4-Modell zur Visualisierung, agile Entwicklungs-Roadmap. + +* **[x] `core`-Modul konzipiert & refaktorisiert** + * **Wofür?** Um eine zentrale Bibliothek (Shared Kernel) zu schaffen, die Code-Wiederholung vermeidet, die Entwicklungsgeschwindigkeit erhöht und Konsistenz im gesamten System erzwingt. + * **Details:** + * **[x] `Result`-Klasse vereinheitlicht:** Wir haben uns für die typsichere `Result`-Variante entschieden, um Geschäftsfehler sauber und explizit behandeln zu können, anstatt technische Exceptions zu missbrauchen. + * **[x] Datenbank-Migrationen professionalisiert:** Wir haben den selbstgeschriebenen Migrator durch **Flyway** ersetzt. Damit setzen wir auf einen robusten, transaktionssicheren Industrie-Standard für die Verwaltung unseres Datenbankschemas. + * **[ ] Konfigurations-Management (`AppConfig`) refaktorisiert:** Der Umbau von einem globalen `object` zu einer `class` wurde beschlossen. Dies macht unsere Services testbar und ihr Startverhalten vorhersagbar ("Fail-Fast"-Prinzip). + * **[ ] Service Discovery (`ServiceRegistration`) refaktorisiert:** Durch den Umbau auf Dependency Injection ist die Komponente nun isoliert testbar und ihre Abhängigkeiten sind klar ersichtlich. + * **[ ] Build-System (`build.gradle.kts`) optimiert:** Die Abhängigkeiten wurden korrigiert und auf ein zentrales **Version Catalog (`libs.versions.toml`)** umgestellt. Damit verwalten wir alle Versionen an einer einzigen Stelle. + * **[ ] Dokumentation (`README.md`) & Commit erstellt:** Die Arbeit wurde sauber dokumentiert und ein nachvollziehbarer Commit-Eintrag formuliert, um die getroffenen Entscheidungen festzuhalten. + +--- + +### 🔳 Phase 2: Implementierung von Zyklus 1 (Nächste Schritte) + +*In dieser Phase bauen wir das erste funktionierende Produkt (MVP). Wir errichten die erste Säule (`masterdata-service`) auf unserem Fundament und folgen dabei konsequent unserer Clean Architecture, um eine Blaupause für alle weiteren Services zu schaffen.* + +* **[ ] `masterdata`-Service implementieren** + * **Wofür?** Dieser Service ist das digitale Regelbuch der ÖTO. Er stellt allen anderen Services die absolut notwendigen Stammdaten (Länder, Altersklassen etc.) zur Verfügung, damit diese ihre Geschäftslogik korrekt ausführen können. + * **Schritte:** + * **[ ] Domain-Layer (`masterdata-domain`):** + * **Aufgabe:** Das Herz des Service. Hier definieren wir die Geschäftsmodelle als reine Kotlin-Klassen (`LandDefinition`, `AltersklasseDefinition` etc.) und die "Verträge" (`Repository-Interfaces`), die festlegen, welche Datenoperationen möglich sein müssen. + * **[ ] Infrastructure-Layer (`masterdata-infrastructure`):** + * **Aufgabe:** Die technische Umsetzung der Verträge. Hier schreiben wir den `Exposed`-Code, der die Domänen-Objekte in die von Flyway erstellten Datenbank-Tabellen speichert und von dort liest. + * **[ ] Application-Layer (`masterdata-application`):** + * **Aufgabe:** Die Anwendungslogik. Hier implementieren wir die `Use Cases`, die die Repositories orchestrieren, um komplexe Abläufe abzubilden (z.B. "Erstelle ein neues Land, aber nur, wenn der ISO-Code noch nicht existiert"). + * **[ ] API-Layer (`masterdata-api`):** + * **Aufgabe:** Das "Gesicht" des Service. Hier bauen wir die `Ktor`-REST-Schnittstelle, die es anderen Services oder dem Frontend erlaubt, die Use Cases über das Netzwerk aufzurufen. Wir integrieren hier auch die zentrale Fehlerbehandlung via `StatusPages`. + +* **[ ] `members-` & `horses-` Service implementieren** + * **Wofür?** Diese Services verwalten die zentralen Akteure unseres Systems: die Personen und die Pferde. Sie sind die Grundlage für die Nennung und die Ergebniszuordnung. + * **Vorgehen:** Aufbau nach dem exakten Vorbild und den Qualitätsstandards des `masterdata-service`. + +* **[ ] `events-` Service implementieren** + * **Wofür?** Dieser Service ermöglicht es dem `Mandanten-Administrator`, die Hülle für ein Turnier zu schaffen – den Rahmen, in den später die Nennungen und Ergebnisse eingetragen werden. + * **Vorgehen:** Implementierung des "Event-Setup-Wizards" für die Erstellung von C/C-Neu Turnieren. + +* **[ ] Weitere Services für Zyklus 1 (Basis-Implementierungen)** + * **Wofür?** Um den End-to-End-Prozess für unser MVP zu vervollständigen. + * **[ ] `nennungs-service`:** Nimmt Nennungen an und erstellt Startlisten. + * **[ ] `billing-service`:** Verbuchung von Nenngeldern für die "Bar-Kassa". + * **[ ] `result-service`:** Ermöglicht die manuelle Erfassung von Ergebnissen und deren Export im OEPS-Format. + +--- diff --git a/events/events-api/build.gradle.kts b/events/events-api/build.gradle.kts index 2a28642f..7087964c 100644 --- a/events/events-api/build.gradle.kts +++ b/events/events-api/build.gradle.kts @@ -1,6 +1,7 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") + // KORREKTUR: Alle Plugins werden jetzt konsistent über den Version Catalog geladen. + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) alias(libs.plugins.kotlin.serialization) alias(libs.plugins.ktor) application @@ -11,6 +12,7 @@ application { } dependencies { + // Deine Abhängigkeiten sind hier bereits korrekt und benötigen keine Änderung. implementation(projects.platform.platformDependencies) implementation(projects.events.eventsDomain) @@ -26,7 +28,7 @@ dependencies { implementation(libs.ktor.server.core) implementation(libs.ktor.server.netty) implementation(libs.ktor.server.contentNegotiation) - implementation(libs.ktor.server.serializationKotlinxJson) + implementation(libs.ktor.server.serialization.kotlinx.json) implementation(libs.ktor.server.statusPages) implementation(libs.ktor.server.auth) implementation(libs.ktor.server.authJwt) diff --git a/events/events-infrastructure/build.gradle.kts b/events/events-infrastructure/build.gradle.kts index 7da76ddd..ab4b049a 100644 --- a/events/events-infrastructure/build.gradle.kts +++ b/events/events-infrastructure/build.gradle.kts @@ -1,7 +1,9 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") - kotlin("plugin.jpa") version "2.1.20" + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + alias(libs.plugins.kotlin.serialization) + alias(libs.plugins.ktor) + application } dependencies { diff --git a/events/events-service/build.gradle.kts b/events/events-service/build.gradle.kts index 23e15ffe..8f7b8dd6 100644 --- a/events/events-service/build.gradle.kts +++ b/events/events-service/build.gradle.kts @@ -1,14 +1,30 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") - id("org.springframework.boot") + // Standard Kotlin Plugins + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + alias(libs.plugins.kotlin.serialization) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Das Ktor-Plugin wird hier nicht benötigt, da dies der Spring Boot Service ist, + // der die Ktor-API nur als Bibliothek nutzt. + // alias(libs.plugins.ktor) + + application } +// Dieser Block funktioniert jetzt, weil das `springBoot`-Plugin oben aktiviert ist. springBoot { mainClass.set("at.mocode.events.service.EventsServiceApplicationKt") } dependencies { + // KORREKTUR: Alle Spring-Boot-Abhängigkeiten sollten über den Version Catalog + // als "starter" deklariert werden. Die Versionen werden dann automatisch + // durch das Spring Boot Plugin und unser `platform-dependencies`-Modul verwaltet. + implementation(projects.platform.platformDependencies) implementation(projects.core.coreUtils) @@ -22,12 +38,16 @@ dependencies { implementation(projects.infrastructure.messaging.messagingClient) implementation(projects.infrastructure.monitoring.monitoringClient) - implementation("org.springframework.boot:spring-boot-starter-web") - implementation("org.springframework.boot:spring-boot-starter-validation") - implementation("org.springframework.boot:spring-boot-starter-actuator") - implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui") + // Spring Boot Starters (aus dem Version Catalog) + implementation(libs.spring.boot.starter.web) + implementation(libs.spring.boot.starter.validation) + implementation(libs.spring.boot.starter.actuator) + // implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui") // Besser, dies auch in den Katalog aufzunehmen - runtimeOnly("org.postgresql:postgresql") + // Datenbank-Treiber (aus dem Version Catalog) + runtimeOnly(libs.postgresql.driver) + // Testing testImplementation(projects.platform.platformTesting) + testImplementation(libs.spring.boot.starter.test) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6f2a8885..ff9a1d70 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,128 +1,100 @@ +# This file defines all dependencies for the Meldestelle_Pro project. +# It allows for centralized version management and ensures consistency across all modules. +# Last updated: 2025-07-28 + [versions] -# Kotlin and related libraries -kotlin = "2.1.20" -kotlinxCoroutines = "1.10.1" -kotlinxSerialization = "1.8.1" -kotlinxDatetime = "0.6.1" +# --- Kotlin Ecosystem --- +kotlin = "2.2.0" +kotlinxCoroutines = "1.9.1" +kotlinxSerialization = "1.7.1" +kotlinxDatetime = "0.6.0" -# Kotlin Wrappers for JS -kotlinWrappers = "1.0.0-pre.710" +springBoot = "3.2.3" -# Compose -composeMultiplatform = "1.8.0" #"1.7.3" +# --- Compose (UI) --- +composeMultiplatform = "1.6.10" -# Ktor -ktor = "3.1.2" +# --- Ktor (API Layer & Client) --- +ktor = "3.0.0-beta-2" # Stable release for Ktor 3 -# Monitoring -micrometer = "1.12.2" - -# Database -exposed = "0.52.0" +# --- Database & Persistence --- +exposed = "0.51.1" postgresql = "42.7.3" hikari = "5.1.0" h2 = "2.2.224" +flyway = "10.15.2" -# Caching -redisson = "3.27.1" -caffeine = "3.1.8" +# --- Service Discovery --- +consulClient = "1.5.3" -# Service Discovery -consul = "2.2.10" -orbitz-consul = "1.5.3" +# --- Testing --- +junitJupiter = "5.10.2" -# Logging -logback = "1.5.18" -logbackJsonEncoder = "8.0" - -# Testing -junit = "4.13.2" -junitJupiter = "5.12.0" - -# Utilities +# --- Utilities --- uuid = "0.8.4" -bignum = "0.3.10" [libraries] -# Kotlin and related libraries +# --- Kotlin & Coroutines --- kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } -kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" } -kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" } -kotlinx-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-swing", version.ref = "kotlinxCoroutines" } -kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerialization" } -kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" } +kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" } +kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinxCoroutines" } +kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" } +kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerialization" } +kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetime" } -# Ktor +# --- Ktor Server --- ktor-server-core = { module = "io.ktor:ktor-server-core-jvm", version.ref = "ktor" } ktor-server-netty = { module = "io.ktor:ktor-server-netty-jvm", version.ref = "ktor" } -ktor-server-html-builder = { module = "io.ktor:ktor-server-html-builder", version.ref = "ktor" } -ktor-server-config-yaml = { module = "io.ktor:ktor-server-config-yaml", version.ref = "ktor" } -ktor-server-tests = { module = "io.ktor:ktor-server-test-host-jvm", version.ref = "ktor" } -ktor-server-contentNegotiation = { module = "io.ktor:ktor-server-content-negotiation", version.ref = "ktor" } -ktor-server-serializationKotlinxJson = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } -ktor-server-cors = { module = "io.ktor:ktor-server-cors", version.ref = "ktor" } -ktor-server-callLogging = { module = "io.ktor:ktor-server-call-logging", version.ref = "ktor" } -ktor-server-defaultHeaders = { module = "io.ktor:ktor-server-default-headers", version.ref = "ktor" } -ktor-server-statusPages = { module = "io.ktor:ktor-server-status-pages", version.ref = "ktor" } -ktor-server-auth = { module = "io.ktor:ktor-server-auth", version.ref = "ktor" } -ktor-server-authJwt = { module = "io.ktor:ktor-server-auth-jwt", version.ref = "ktor" } -ktor-server-openapi = { module = "io.ktor:ktor-server-openapi", version.ref = "ktor" } -ktor-server-swagger = { module = "io.ktor:ktor-server-swagger", version.ref = "ktor" } -ktor-server-rateLimit = { module = "io.ktor:ktor-server-rate-limit", version.ref = "ktor" } +ktor-server-contentNegotiation = { module = "io.ktor:ktor-server-content-negotiation-jvm", version.ref = "ktor" } +ktor-server-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json-jvm", version.ref = "ktor" } # Eindeutiger Alias +ktor-server-statusPages = { module = "io.ktor:ktor-server-status-pages-jvm", version.ref = "ktor" } +ktor-server-tests = { module = "io.ktor:ktor-server-tests-jvm", version.ref = "ktor" } +ktor-server-auth = { module = "io.ktor:ktor-server-auth-jvm", version.ref = "ktor" } +ktor-server-authJwt = { module = "io.ktor:ktor-server-auth-jwt-jvm", version.ref = "ktor" } -# Ktor Client +# --- Ktor Client --- ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } +ktor-client-cio = { module = "io.ktor:ktor-client-cio-jvm", version.ref = "ktor" } ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" } ktor-client-contentNegotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } -ktor-client-serializationKotlinxJson = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } +# KORRIGIERT: eindeutiger Alias +ktor-client-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } # Eindeutiger Alias - -# Database +# --- Database & Persistence --- +# --- Database & Persistence --- +# KORREKTUR: Alle Aliase sind jetzt im kebab-case Format. +# exposed-core wird zu libs.exposed.core exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" } +# exposed-dao wird zu libs.exposed.dao exposed-dao = { module = "org.jetbrains.exposed:exposed-dao", version.ref = "exposed" } +# exposed-jdbc wird zu libs.exposed.jdbc exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" } -exposed-kotlinDatetime = { module = "org.jetbrains.exposed:exposed-kotlin-datetime", version.ref = "exposed" } -postgresql-driver = { module = "org.postgresql:postgresql", version.ref = "postgresql" } +# exposed-kotlin-datetime wird zu libs.exposed.kotlin.datetime +exposed-kotlin-datetime = { module = "org.jetbrains.exposed:exposed-kotlin-datetime", version.ref = "exposed" } +# hikari-cp wird zu libs.hikari.cp hikari-cp = { module = "com.zaxxer:HikariCP", version.ref = "hikari" } -h2-driver = { module = "com.h2database:h2", version.ref = "h2" } - - -# Logging -logback = { module = "ch.qos.logback:logback-classic", version.ref = "logback" } -logback-json-encoder = { module = "net.logstash.logback:logstash-logback-encoder", version.ref = "logbackJsonEncoder" } - -# Monitoring -micrometer-prometheus = { group = "io.micrometer", name = "micrometer-registry-prometheus", version.ref = "micrometer" } -ktor-server-metrics-micrometer = { group = "io.ktor", name = "ktor-server-metrics-micrometer", version.ref = "ktor" } - -# Testing -junitJupiter = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junitJupiter" } - -# Utilities -uuid = { group = "com.benasher44", name = "uuid", version.ref = "uuid" } -bignum = { group = "com.ionspin.kotlin", name = "bignum", version.ref = "bignum" } - -# Caching -redisson = { group = "org.redisson", name = "redisson", version.ref = "redisson" } -caffeine = { group = "com.github.ben-manes.caffeine", name = "caffeine", version.ref = "caffeine" } - -# Service Discovery -consul-client = { module = "com.orbitz.consul:consul-client", version.ref = "orbitz-consul" } -consul-api = { module = "com.ecwid.consul:consul-api", version.ref = "consul" } -ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } - -# Kotlin Wrappers for JS/React -kotlin-wrappers-bom = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-wrappers-bom", version.ref = "kotlinWrappers" } -kotlin-react = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-react" } -kotlin-emotion = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-emotion" } +# ... (weitere DB-Bibliotheken) +flyway-core = { module = "org.flywaydb:flyway-core", version.ref = "flyway" } +flyway-postgresql = { module = "org.flywaydb:flyway-database-postgresql", version.ref = "flyway" } +# --- Service Discovery --- +# consul-client wird zu libs.consul.client +consul-client = { module = "com.orbitz.consul:consul-client", version.ref = "consulClient" } +# --- Utilities --- +uuid = { module = "com.benasher44:uuid", version.ref = "uuid" } +# --- Testing (JUnit 5) --- +junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junitJupiter" } +junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junitJupiter" } [plugins] +# KORREKTUR: Wir stellen sicher, dass ALLE Plugins, die wir verwenden, hier definiert sind. kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } -compose-multiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" } -ktor = { id = "io.ktor.plugin", version.ref = "ktor" } kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +ktor = { id = "io.ktor.plugin", version.ref = "ktor" } +compose-multiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" } compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +kotlin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" } +spring-boot = { id = "org.springframework.boot", version.ref = "springBoot" }