diff --git a/client/README.md b/client/README-CLIENT.md similarity index 100% rename from client/README.md rename to client/README-CLIENT.md diff --git a/config/monitoring/alertmanager/alertmanager.yml b/config/monitoring/alertmanager/alertmanager.yml new file mode 100644 index 00000000..1f22bb6f --- /dev/null +++ b/config/monitoring/alertmanager/alertmanager.yml @@ -0,0 +1,82 @@ +global: + resolve_timeout: 5m + # SMTP configuration for email alerts + smtp_smarthost: 'smtp.example.com:587' + smtp_from: 'alertmanager@meldestelle.at' + smtp_auth_username: 'alertmanager@meldestelle.at' + smtp_auth_password: 'password' # Use environment variable in production + smtp_require_tls: true + +# The root route on which each incoming alert enters. +route: + # The root route must not have any matchers as it is the entry point for all alerts + # The default receiver is the one that handles alerts that don't match any of the specific routes + receiver: 'email-notifications' + + # How long to wait before sending a notification again if it has already been sent successfully + repeat_interval: 4h + + # How long to initially wait to send a notification for a group of alerts + group_wait: 30s + + # How long to wait before sending a notification about new alerts that are added to a group + group_interval: 5m + + # A default grouping of alerts + group_by: ['alertname', 'cluster', 'service'] + + # Child routes for specific alert categories + routes: + - receiver: 'slack-critical' + matchers: + - severity="critical" + repeat_interval: 1h + + - receiver: 'slack-warnings' + matchers: + - severity="warning" + repeat_interval: 12h + +# Inhibition rules allow to mute a set of alerts given that another alert is firing +inhibit_rules: + - source_matchers: + - severity="critical" + target_matchers: + - severity="warning" + # Apply inhibition if the alertname is the same + equal: ['alertname', 'cluster', 'service'] + +# Receivers define notification integrations +receivers: +- name: 'email-notifications' + email_configs: + - to: 'admin@meldestelle.at' + send_resolved: true + +- name: 'slack-critical' + slack_configs: + - api_url: 'https://hooks.slack.com/services/REPLACE_WITH_YOUR_WEBHOOK_URL' + channel: '#alerts-critical' + send_resolved: true + title: '{{ .CommonAnnotations.summary }}' + text: >- + {{ range .Alerts }} + *Alert:* {{ .Annotations.summary }} + *Description:* {{ .Annotations.description }} + *Severity:* {{ .Labels.severity }} + *Instance:* {{ .Labels.instance }} + {{ end }} + +- name: 'slack-warnings' + slack_configs: + - api_url: 'https://hooks.slack.com/services/REPLACE_WITH_YOUR_WEBHOOK_URL' + channel: '#alerts-warnings' + send_resolved: true + title: '{{ .CommonAnnotations.summary }}' + text: >- + {{ range .Alerts }} + *Alert:* {{ .Annotations.summary }} + *Description:* {{ .Annotations.description }} + *Severity:* {{ .Labels.severity }} + *Instance:* {{ .Labels.instance }} + {{ end }} diff --git a/config/monitoring/prometheus/rules/alerts.yml b/config/monitoring/prometheus/rules/alerts.yml new file mode 100644 index 00000000..f9a599d3 --- /dev/null +++ b/config/monitoring/prometheus/rules/alerts.yml @@ -0,0 +1,62 @@ +groups: + - name: meldestelle_alerts + rules: + # Alert for high memory usage + - alert: HighMemoryUsage + expr: (jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) * 100 > 85 + for: 5m + labels: + severity: warning + annotations: + summary: "High memory usage ({{ $value }}%)" + description: "JVM memory usage is above 85% for 5 minutes.\n Instance: {{ $labels.instance }}\n Service: {{ $labels.service }}" + + # Alert for high CPU usage + - alert: HighCpuUsage + expr: process_cpu_usage > 0.85 + for: 5m + labels: + severity: warning + annotations: + summary: "High CPU usage ({{ $value }})" + description: "CPU usage is above 85% for 5 minutes.\n Instance: {{ $labels.instance }}\n Service: {{ $labels.service }}" + + # Alert for high error rate + - alert: HighErrorRate + expr: sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m])) / sum(rate(http_server_requests_seconds_count[5m])) * 100 > 5 + for: 2m + labels: + severity: critical + annotations: + summary: "High error rate ({{ $value }}%)" + description: "Error rate is above 5% for 2 minutes.\n Instance: {{ $labels.instance }}\n Service: {{ $labels.service }}" + + # Alert for service unavailability + - alert: ServiceUnavailable + expr: up{job="meldestelle-server"} == 0 + for: 1m + labels: + severity: critical + annotations: + summary: "Service unavailable" + description: "Meldestelle service is down.\n Instance: {{ $labels.instance }}" + + # Alert for slow response time + - alert: SlowResponseTime + expr: http_server_requests_seconds_sum / http_server_requests_seconds_count > 1 + for: 5m + labels: + severity: warning + annotations: + summary: "Slow response time ({{ $value }}s)" + description: "Average response time is above 1 second for 5 minutes.\n Instance: {{ $labels.instance }}\n Path: {{ $labels.uri }}" + + # Alert for high GC pause time + - alert: HighGcPauseTime + expr: jvm_gc_pause_seconds_sum / jvm_gc_pause_seconds_count > 0.5 + for: 5m + labels: + severity: warning + annotations: + summary: "High GC pause time ({{ $value }}s)" + description: "Average GC pause time is above 0.5 seconds for 5 minutes.\n Instance: {{ $labels.instance }}" diff --git a/core/README.md b/core/README-CORE.md similarity index 100% rename from core/README.md rename to core/README-CORE.md diff --git a/core/core-domain/build.gradle.kts b/core/core-domain/build.gradle.kts index e6049724..abb21029 100644 --- a/core/core-domain/build.gradle.kts +++ b/core/core-domain/build.gradle.kts @@ -1,8 +1,9 @@ plugins { // Definiert dieses Modul als ein Standard Kotlin/JVM-Modul. - kotlin("jvm") +// kotlin("jvm") // Aktiviert das Kotlinx Serialization Plugin, da unsere DTOs und Enums // als @Serializable markiert sind. + alias(libs.plugins.kotlin.jvm) alias(libs.plugins.kotlin.serialization) } diff --git a/core/core-utils/build.gradle.kts b/core/core-utils/build.gradle.kts index 58c50d0c..501297be 100644 --- a/core/core-utils/build.gradle.kts +++ b/core/core-utils/build.gradle.kts @@ -1,12 +1,9 @@ plugins { - kotlin("jvm") + alias(libs.plugins.kotlin.jvm) } 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 --- @@ -24,6 +21,10 @@ dependencies { // --- Service Discovery --- api(libs.consul.client) + // --- Utilities --- + // KORREKTUR: Fehlende Abhängigkeit für den BigDecimalSerializer hinzugefügt. + api(libs.bignum) + // --- Testing --- testImplementation(projects.platform.platformTesting) } diff --git a/core/core-utils/src/main/kotlin/at/mocode/core/utils/discovery/ServiceRegistration.kt b/core/core-utils/src/main/kotlin/at/mocode/core/utils/discovery/ServiceRegistration.kt index 328c2dfd..416a8424 100644 --- a/core/core-utils/src/main/kotlin/at/mocode/core/utils/discovery/ServiceRegistration.kt +++ b/core/core-utils/src/main/kotlin/at/mocode/core/utils/discovery/ServiceRegistration.kt @@ -1,15 +1,10 @@ package at.mocode.core.utils.discovery -import at.mocode.core.utils.config.AppConfig // Angenommen, AppConfig ist jetzt eine Klasse -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import java.net.InetAddress -import java.util.* -import kotlin.time.Duration.Companion.seconds +import at.mocode.core.utils.config.AppConfig // AppConfig ist jetzt eine Klasse import com.orbitz.consul.Consul import com.orbitz.consul.model.agent.ImmutableRegistration +import java.net.InetAddress +import java.util.* /** * Repräsentiert die Registrierung eines einzelnen Service-Exemplars bei Consul. @@ -29,7 +24,8 @@ class ServiceRegistration internal constructor( println("Service '${registration.name()}' mit ID '${registration.id()}' erfolgreich bei Consul registriert.") } catch (e: Exception) { println("FEHLER: Service-Registrierung bei Consul fehlgeschlagen: ${e.message}") - // Optional: Fehler weiterwerfen, um den Anwendungsstart zu stoppen + // Fehler weiterwerfen, um den Anwendungsstart zu stoppen + throw IllegalStateException("Could not register service with Consul", e) } } @@ -70,7 +66,8 @@ class ServiceRegistrar(private val appConfig: AppConfig) { val healthCheck = ImmutableRegistration.RegCheck.http( "http://$hostAddress:$servicePort/health", // Standard-Health-Check-Pfad - 10L // Intervall in Sekunden + 10L, // Intervall in Sekunden + 5L // Timeout in Sekunden ) val registration = ImmutableRegistration.builder() @@ -88,6 +85,7 @@ class ServiceRegistrar(private val appConfig: AppConfig) { // Fügt einen Shutdown-Hook hinzu, um den Service beim Beenden sauber zu deregistrieren Runtime.getRuntime().addShutdownHook(Thread { + println("Shutdown-Hook: Deregistriere Service ${serviceId}...") serviceRegistration.deregister() }) diff --git a/core/core-utils/src/main/kotlin/at/mocode/core/utils/serialization/Serialization.kt b/core/core-utils/src/main/kotlin/at/mocode/core/utils/serialization/Serialization.kt index 3a7fe6a0..a4830d05 100644 --- a/core/core-utils/src/main/kotlin/at/mocode/core/utils/serialization/Serialization.kt +++ b/core/core-utils/src/main/kotlin/at/mocode/core/utils/serialization/Serialization.kt @@ -2,6 +2,7 @@ package at.mocode.core.utils.serialization import com.benasher44.uuid.Uuid import com.benasher44.uuid.uuidFrom +// KORREKTUR: Der Import wurde von java.math.BigDecimal auf die korrekte Bibliothek geändert. import com.ionspin.kotlin.bignum.decimal.BigDecimal import kotlinx.datetime.Instant import kotlinx.datetime.LocalDate diff --git a/events/README.md b/events/README-EVENTS.md similarity index 100% rename from events/README.md rename to events/README-EVENTS.md diff --git a/events/events-service/build.gradle.kts b/events/events-service/build.gradle.kts index 8f7b8dd6..ecd91b3d 100644 --- a/events/events-service/build.gradle.kts +++ b/events/events-service/build.gradle.kts @@ -1,18 +1,13 @@ plugins { - // 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 + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } // Dieser Block funktioniert jetzt, weil das `springBoot`-Plugin oben aktiviert ist. @@ -21,30 +16,28 @@ springBoot { } 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. - + // Interne Module implementation(projects.platform.platformDependencies) implementation(projects.core.coreUtils) - implementation(projects.events.eventsDomain) implementation(projects.events.eventsApplication) implementation(projects.events.eventsInfrastructure) implementation(projects.events.eventsApi) + // Infrastruktur-Clients implementation(projects.infrastructure.auth.authClient) implementation(projects.infrastructure.cache.redisCache) implementation(projects.infrastructure.messaging.messagingClient) implementation(projects.infrastructure.monitoring.monitoringClient) - // Spring Boot Starters (aus dem Version Catalog) + // KORREKTUR: Alle externen Abhängigkeiten werden jetzt über den Version Catalog bezogen. + + // Spring Boot Starters 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 - // Datenbank-Treiber (aus dem Version Catalog) + // Datenbank-Treiber runtimeOnly(libs.postgresql.driver) // Testing diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ff9a1d70..8508685b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,38 +1,44 @@ # 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 +# Last updated: 2025-07-29 [versions] # --- Kotlin Ecosystem --- +# Defines the primary Kotlin version for the compiler and all related plugins. kotlin = "2.2.0" kotlinxCoroutines = "1.9.1" kotlinxSerialization = "1.7.1" kotlinxDatetime = "0.6.0" -springBoot = "3.2.3" +# --- Database & Persistence --- +exposed = "0.51.1" +postgresql = "42.7.3" +h2 = "2.2.224" +hikari = "5.1.0" +flyway = "10.15.2" + +# --- Service Discovery --- +consulClient = "1.5.3" +micrometer = "1.12.2" + +# --- Utilities --- +uuid = "0.8.4" +bignum = "0.3.9" + +springBoot = "3.2.5" +springDependencyManagement = "1.1.5" +springdoc = "2.5.0" # --- Compose (UI) --- composeMultiplatform = "1.6.10" # --- Ktor (API Layer & Client) --- ktor = "3.0.0-beta-2" # Stable release for Ktor 3 - -# --- Database & Persistence --- -exposed = "0.51.1" -postgresql = "42.7.3" -hikari = "5.1.0" -h2 = "2.2.224" -flyway = "10.15.2" - -# --- Service Discovery --- -consulClient = "1.5.3" +ktor-openapi = "2.1.4" # --- Testing --- junitJupiter = "5.10.2" -# --- Utilities --- -uuid = "0.8.4" - [libraries] # --- Kotlin & Coroutines --- kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } @@ -46,43 +52,73 @@ kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version. 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-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-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json-jvm", version.ref = "ktor" } 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-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-cors = { module = "io.ktor:ktor-server-cors-jvm", version.ref = "ktor" } +ktor-server-callLogging = { module = "io.ktor:ktor-server-call-logging-jvm", version.ref = "ktor" } +ktor-server-defaultHeaders = { module = "io.ktor:ktor-server-default-headers-jvm", version.ref = "ktor" } +ktor-server-rateLimit = { module = "io.ktor:ktor-server-rate-limit-jvm", version.ref = "ktor" } +ktor-server-metrics-micrometer = { module = "io.ktor:ktor-server-metrics-micrometer-jvm", version.ref = "ktor" } # --- 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" } -# KORRIGIERT: eindeutiger Alias ktor-client-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } # Eindeutiger Alias +# --- Spring Boot Starters --- +spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web" } +spring-boot-starter-validation = { module = "org.springframework.boot:spring-boot-starter-validation" } +spring-boot-starter-actuator = { module = "org.springframework.boot:spring-boot-starter-actuator" } +spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test" } +spring-boot-starter-data-jpa = { module = "org.springframework.boot:spring-boot-starter-data-jpa" } +# Spring Web als eigenständige Abhängigkeit +spring-web = { module = "org.springframework:spring-web" } + +# --- SpringDoc (OpenAPI) --- +# springdoc-openapi-starter-webmvc-ui = { module = "org.springdoc:springdoc-openapi-starter-webmvc-ui", version.ref = "springdoc" } +springdoc-openapi-starter-common = { module = "org.springdoc:springdoc-openapi-starter-common", version.ref = "springdoc" } + +# --- Datenbank-Treiber --- +postgresql-driver = { module = "org.postgresql:postgresql", version.ref = "postgresql" } +h2-driver = { module = "com.h2database:h2", version.ref = "h2" } + # --- 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-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" } -# ... (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" } +# --- Monitoring --- +micrometer-prometheus = { group = "io.micrometer", name = "micrometer-registry-prometheus", version.ref = "micrometer" } + # --- Utilities --- uuid = { module = "com.benasher44:uuid", version.ref = "uuid" } +bignum = { module = "com.ionspin.kotlin:bignum", version.ref = "bignum" } + +# --- Compose --- +compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "composeMultiplatform" } +compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "composeMultiplatform" } +compose-material3 = { module = "org.jetbrains.compose.material3:material3", version.ref = "composeMultiplatform" } +compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "composeMultiplatform" } +compose-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "composeMultiplatform" } +compose-materialIconsExtended = { module = "org.jetbrains.compose.material:material-icons-extended", version.ref = "composeMultiplatform" } +# NEU: Die Bibliothek für Compose for Web (HTML) +compose-html-core = { module = "org.jetbrains.compose.html:html-core", version.ref = "composeMultiplatform" } +# NEU: Die Bibliothek für die Desktop-Plattform +compose-desktop-currentOs = { module = "org.jetbrains.compose.desktop:desktop", version.ref = "composeMultiplatform" } # --- Testing (JUnit 5) --- junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junitJupiter" } @@ -93,8 +129,10 @@ junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", vers kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +kotlin-jpa = { id = "org.jetbrains.kotlin.plugin.jpa", version.ref = "kotlin" } +kotlin-spring = { id = "org.jetbrains.kotlin.plugin.spring", 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" } +spring-dependencyManagement = { id = "io.spring.dependency-management", version.ref = "springDependencyManagement" } diff --git a/horses/README.md b/horses/README-HORSES.md similarity index 100% rename from horses/README.md rename to horses/README-HORSES.md diff --git a/horses/horses-api/build.gradle.kts b/horses/horses-api/build.gradle.kts index ffaab179..80c7935a 100644 --- a/horses/horses-api/build.gradle.kts +++ b/horses/horses-api/build.gradle.kts @@ -1,36 +1,44 @@ 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 + + // Das Ktor-Plugin wird hier nicht benötigt, da Ktor als Bibliothek in Spring Boot läuft. + // Das 'application'-Plugin wird vom Spring Boot Plugin bereitgestellt. + alias(libs.plugins.spring.boot) + alias(libs.plugins.spring.dependencyManagement) } -application { +// Der springBoot-Block konfiguriert die Anwendung, wenn sie als JAR-Datei ausgeführt wird. +springBoot { mainClass.set("at.mocode.horses.api.ApplicationKt") } dependencies { + // Interne Module implementation(projects.platform.platformDependencies) - implementation(projects.horses.horsesDomain) implementation(projects.horses.horsesApplication) implementation(projects.core.coreDomain) implementation(projects.core.coreUtils) - // Spring dependencies - implementation("org.springframework:spring-web") - implementation("org.springdoc:springdoc-openapi-starter-common") + // KORREKTUR: Alle externen Abhängigkeiten werden jetzt über den Version Catalog bezogen. - // Ktor Server + // Spring dependencies + implementation(libs.spring.web) + + // Ktor Server (als embedded Server in Spring) 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) + // Testing testImplementation(projects.platform.platformTesting) testImplementation(libs.ktor.server.tests) + testImplementation(libs.spring.boot.starter.test) } diff --git a/horses/horses-infrastructure/build.gradle.kts b/horses/horses-infrastructure/build.gradle.kts index e7e3b04e..561ebdf8 100644 --- a/horses/horses-infrastructure/build.gradle.kts +++ b/horses/horses-infrastructure/build.gradle.kts @@ -1,12 +1,14 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") - kotlin("plugin.jpa") version "2.1.20" + // KORREKTUR: Alle Plugins werden jetzt konsistent über den Version Catalog geladen. + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + // Das JPA-Plugin wird jetzt ebenfalls zentral verwaltet. + alias(libs.plugins.kotlin.jpa) } dependencies { + // Interne Module implementation(projects.platform.platformDependencies) - implementation(projects.horses.horsesDomain) implementation(projects.horses.horsesApplication) implementation(projects.core.coreDomain) @@ -15,8 +17,14 @@ dependencies { implementation(projects.infrastructure.eventStore.eventStoreApi) implementation(projects.infrastructure.messaging.messagingClient) - implementation("org.springframework.boot:spring-boot-starter-data-jpa") - implementation("org.postgresql:postgresql") + // KORREKTUR: Alle externen Abhängigkeiten werden jetzt über den Version Catalog bezogen. + // Spring Data JPA + implementation(libs.spring.boot.starter.data.jpa) + + // Datenbank-Treiber + runtimeOnly(libs.postgresql.driver) + + // Testing testImplementation(projects.platform.platformTesting) } diff --git a/horses/horses-service/build.gradle.kts b/horses/horses-service/build.gradle.kts index cbe80ebe..586ff360 100644 --- a/horses/horses-service/build.gradle.kts +++ b/horses/horses-service/build.gradle.kts @@ -1,16 +1,19 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") - id("org.springframework.boot") + // KORREKTUR: Alle Plugins werden jetzt konsistent über den Version Catalog geladen. + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + alias(libs.plugins.spring.boot) + alias(libs.plugins.spring.dependencyManagement) } +// Der springBoot-Block konfiguriert die Anwendung, wenn sie als JAR-Datei ausgeführt wird. springBoot { mainClass.set("at.mocode.horses.service.HorsesServiceApplicationKt") } dependencies { + // Interne Module implementation(projects.platform.platformDependencies) - implementation(projects.core.coreDomain) implementation(projects.core.coreUtils) implementation(projects.horses.horsesDomain) @@ -18,24 +21,30 @@ dependencies { implementation(projects.horses.horsesInfrastructure) implementation(projects.horses.horsesApi) + // Infrastruktur-Clients implementation(projects.infrastructure.auth.authClient) implementation(projects.infrastructure.cache.redisCache) 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") + // KORREKTUR: Alle externen Abhängigkeiten werden jetzt über den Version Catalog bezogen. - // Database dependencies - implementation("org.jetbrains.exposed:exposed-core") - implementation("org.jetbrains.exposed:exposed-dao") - implementation("org.jetbrains.exposed:exposed-jdbc") - implementation("org.jetbrains.exposed:exposed-kotlin-datetime") - implementation("com.zaxxer:HikariCP") - runtimeOnly("org.postgresql:postgresql") - testRuntimeOnly("com.h2database:h2") + // Spring Boot Starters + implementation(libs.spring.boot.starter.web) + implementation(libs.spring.boot.starter.validation) + implementation(libs.spring.boot.starter.actuator) + // Datenbank-Abhängigkeiten + implementation(libs.exposed.core) + implementation(libs.exposed.dao) + implementation(libs.exposed.jdbc) + implementation(libs.exposed.kotlin.datetime) + implementation(libs.hikari.cp) + runtimeOnly(libs.postgresql.driver) + testRuntimeOnly(libs.h2.driver) + + + // Testing testImplementation(projects.platform.platformTesting) + testImplementation(libs.spring.boot.starter.test) } diff --git a/infrastructure/README.md b/infrastructure/README-INFRASTRUCTURE.md similarity index 100% rename from infrastructure/README.md rename to infrastructure/README-INFRASTRUCTURE.md diff --git a/infrastructure/auth/auth-client/build.gradle.kts b/infrastructure/auth/auth-client/build.gradle.kts index 159df01d..dc755813 100644 --- a/infrastructure/auth/auth-client/build.gradle.kts +++ b/infrastructure/auth/auth-client/build.gradle.kts @@ -1,6 +1,16 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") +// kotlin("jvm") +// kotlin("plugin.spring") + + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } dependencies { diff --git a/infrastructure/auth/auth-server/build.gradle.kts b/infrastructure/auth/auth-server/build.gradle.kts index 0ae1cb77..383c60b3 100644 --- a/infrastructure/auth/auth-server/build.gradle.kts +++ b/infrastructure/auth/auth-server/build.gradle.kts @@ -1,7 +1,17 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") - id("org.springframework.boot") +// kotlin("jvm") +// kotlin("plugin.spring") +// id("org.springframework.boot") + + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } // Configure main class for bootJar task diff --git a/infrastructure/cache/redis-cache/build.gradle.kts b/infrastructure/cache/redis-cache/build.gradle.kts index 0ce6577f..881dcc81 100644 --- a/infrastructure/cache/redis-cache/build.gradle.kts +++ b/infrastructure/cache/redis-cache/build.gradle.kts @@ -1,6 +1,16 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") +// kotlin("jvm") +// kotlin("plugin.spring") + + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } dependencies { diff --git a/infrastructure/event-store/redis-event-store/build.gradle.kts b/infrastructure/event-store/redis-event-store/build.gradle.kts index 6146f532..5e13ab38 100644 --- a/infrastructure/event-store/redis-event-store/build.gradle.kts +++ b/infrastructure/event-store/redis-event-store/build.gradle.kts @@ -1,6 +1,16 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") +// kotlin("jvm") +// kotlin("plugin.spring") + + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } dependencies { diff --git a/infrastructure/gateway/build.gradle.kts b/infrastructure/gateway/build.gradle.kts index 921bccce..382376b1 100644 --- a/infrastructure/gateway/build.gradle.kts +++ b/infrastructure/gateway/build.gradle.kts @@ -1,68 +1,55 @@ plugins { - kotlin("jvm") + alias(libs.plugins.kotlin.jvm) alias(libs.plugins.kotlin.serialization) alias(libs.plugins.ktor) + application } application { mainClass.set("at.mocode.infrastructure.gateway.ApplicationKt") } -// Configure tests to use JUnit Platform -tasks.withType { - useJUnitPlatform() -} - dependencies { + // --- Interne Module --- + // Der Gateway benötigt nur die Kern-Definitionen und Utilities. implementation(projects.platform.platformDependencies) implementation(projects.core.coreDomain) implementation(projects.core.coreUtils) + // Der Gateway nutzt den Auth-Client, um Tokens zu validieren. implementation(projects.infrastructure.auth.authClient) implementation(projects.infrastructure.monitoring.monitoringClient) - // Domain modules - implementation(projects.masterdata.masterdataDomain) - implementation(projects.members.membersDomain) - implementation(projects.horses.horsesDomain) - implementation(projects.events.eventsDomain) + // !!! WICHTIG: KEINE direkten Abhängigkeiten zu den Domänen- oder + // Infrastruktur-Modulen der Backend-Services mehr! - // Infrastructure modules - implementation(projects.masterdata.masterdataInfrastructure) - implementation(projects.members.membersInfrastructure) - implementation(projects.horses.horsesInfrastructure) - implementation(projects.events.eventsInfrastructure) - - // Ktor Server + // --- Ktor Server --- 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.cors) implementation(libs.ktor.server.callLogging) implementation(libs.ktor.server.defaultHeaders) implementation(libs.ktor.server.statusPages) implementation(libs.ktor.server.auth) implementation(libs.ktor.server.authJwt) - implementation(libs.ktor.server.openapi) - implementation(libs.ktor.server.swagger) implementation(libs.ktor.server.rateLimit) implementation(libs.ktor.server.metrics.micrometer) - // Monitoring and metrics + // --- OpenAPI & Swagger for Ktor --- + implementation(libs.ktor.server.openapi) + implementation(libs.ktor.server.swagger) + + // --- Ktor Client (damit der Gateway Anfragen an die Backend-Services weiterleiten kann) --- + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.cio) // CIO ist eine gute, asynchrone Engine + implementation(libs.ktor.client.contentNegotiation) + implementation(libs.ktor.client.serialization.kotlinx.json) + + // --- Monitoring --- implementation(libs.micrometer.prometheus) - // Rate limiting - implementation("io.github.resilience4j:resilience4j-ratelimiter:2.2.0") - - // Documentation - implementation("org.springdoc:springdoc-openapi-starter-webflux-ui:2.3.0") - - // Ktor Client - implementation(libs.ktor.client.core) - implementation(libs.ktor.client.cio) - implementation(libs.ktor.client.contentNegotiation) - implementation(libs.ktor.client.serializationKotlinxJson) - + // --- Testing --- testImplementation(projects.platform.platformTesting) testImplementation(libs.ktor.server.tests) } diff --git a/infrastructure/messaging/messaging-client/build.gradle.kts b/infrastructure/messaging/messaging-client/build.gradle.kts index 333ef0d1..f70a08ff 100644 --- a/infrastructure/messaging/messaging-client/build.gradle.kts +++ b/infrastructure/messaging/messaging-client/build.gradle.kts @@ -1,6 +1,16 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") +// kotlin("jvm") +// kotlin("plugin.spring") + + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } dependencies { diff --git a/infrastructure/messaging/messaging-config/build.gradle.kts b/infrastructure/messaging/messaging-config/build.gradle.kts index dea25e3f..416f4a98 100644 --- a/infrastructure/messaging/messaging-config/build.gradle.kts +++ b/infrastructure/messaging/messaging-config/build.gradle.kts @@ -1,6 +1,16 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") +// kotlin("jvm") +// kotlin("plugin.spring") + + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } dependencies { diff --git a/infrastructure/monitoring/monitoring-client/build.gradle.kts b/infrastructure/monitoring/monitoring-client/build.gradle.kts index 218e5e15..38429263 100644 --- a/infrastructure/monitoring/monitoring-client/build.gradle.kts +++ b/infrastructure/monitoring/monitoring-client/build.gradle.kts @@ -1,6 +1,16 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") +// kotlin("jvm") +// kotlin("plugin.spring") + + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } dependencies { diff --git a/infrastructure/monitoring/monitoring-server/build.gradle.kts b/infrastructure/monitoring/monitoring-server/build.gradle.kts index 1dfd9315..36392ab5 100644 --- a/infrastructure/monitoring/monitoring-server/build.gradle.kts +++ b/infrastructure/monitoring/monitoring-server/build.gradle.kts @@ -1,7 +1,18 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") - id("org.springframework.boot") +// kotlin("jvm") +// kotlin("plugin.spring") +// id("org.springframework.boot") + + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) + } // Configure main class for bootJar task diff --git a/masterdata/README.md b/masterdata/README-MASTERDATA.md similarity index 100% rename from masterdata/README.md rename to masterdata/README-MASTERDATA.md diff --git a/masterdata/masterdata-api/build.gradle.kts b/masterdata/masterdata-api/build.gradle.kts index 2ba49aca..480228c9 100644 --- a/masterdata/masterdata-api/build.gradle.kts +++ b/masterdata/masterdata-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,26 +12,29 @@ application { } dependencies { + // Interne Module implementation(projects.platform.platformDependencies) - implementation(projects.masterdata.masterdataDomain) implementation(projects.masterdata.masterdataApplication) implementation(projects.core.coreDomain) implementation(projects.core.coreUtils) + // KORREKTUR: Alle externen Abhängigkeiten werden jetzt über den Version Catalog bezogen. + // Spring dependencies - implementation("org.springframework:spring-web") - implementation("org.springdoc:springdoc-openapi-starter-common") + implementation(libs.spring.web) + implementation(libs.springdoc.openapi.starter.common) // Ktor Server 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) + // Testing testImplementation(projects.platform.platformTesting) testImplementation(libs.ktor.server.tests) } diff --git a/masterdata/masterdata-infrastructure/build.gradle.kts b/masterdata/masterdata-infrastructure/build.gradle.kts index a1bc6e5e..3a007665 100644 --- a/masterdata/masterdata-infrastructure/build.gradle.kts +++ b/masterdata/masterdata-infrastructure/build.gradle.kts @@ -1,7 +1,13 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") - kotlin("plugin.jpa") version "2.1.20" + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } dependencies { diff --git a/masterdata/masterdata-service/build.gradle.kts b/masterdata/masterdata-service/build.gradle.kts index 1f2fa939..359cfd4f 100644 --- a/masterdata/masterdata-service/build.gradle.kts +++ b/masterdata/masterdata-service/build.gradle.kts @@ -1,40 +1,53 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") - id("org.springframework.boot") + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } +// Dieser Block funktioniert jetzt, weil das `springBoot`-Plugin oben aktiviert ist. springBoot { mainClass.set("at.mocode.masterdata.service.MasterdataServiceApplicationKt") } dependencies { + // Interne Module implementation(projects.platform.platformDependencies) - implementation(projects.core.coreUtils) implementation(projects.masterdata.masterdataDomain) implementation(projects.masterdata.masterdataApplication) implementation(projects.masterdata.masterdataInfrastructure) implementation(projects.masterdata.masterdataApi) + // Infrastruktur-Clients implementation(projects.infrastructure.auth.authClient) implementation(projects.infrastructure.cache.redisCache) 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") + // KORREKTUR: Alle externen Abhängigkeiten werden jetzt über den Version Catalog bezogen. - // Database dependencies - implementation("org.jetbrains.exposed:exposed-core") - implementation("org.jetbrains.exposed:exposed-dao") - implementation("org.jetbrains.exposed:exposed-jdbc") - implementation("org.jetbrains.exposed:exposed-kotlin-datetime") - implementation("com.zaxxer:HikariCP") - runtimeOnly("org.postgresql:postgresql") - testRuntimeOnly("com.h2database:h2") + // Spring Boot Starters + implementation(libs.spring.boot.starter.web) + implementation(libs.spring.boot.starter.validation) + implementation(libs.spring.boot.starter.actuator) + //implementation(libs.springdoc.openapi.starter.webmvc.ui) + // Datenbank-Abhängigkeiten + implementation(libs.exposed.core) + implementation(libs.exposed.dao) + implementation(libs.exposed.jdbc) + implementation(libs.exposed.kotlin.datetime) + implementation(libs.hikari.cp) + runtimeOnly(libs.postgresql.driver) + testRuntimeOnly(libs.h2.driver) + + // Testing testImplementation(projects.platform.platformTesting) + testImplementation(libs.spring.boot.starter.test) } diff --git a/members/README.md b/members/README-MEMBERS.md similarity index 100% rename from members/README.md rename to members/README-MEMBERS.md diff --git a/members/members-api/build.gradle.kts b/members/members-api/build.gradle.kts index 3353be0c..7791b4b9 100644 --- a/members/members-api/build.gradle.kts +++ b/members/members-api/build.gradle.kts @@ -1,6 +1,16 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") +// kotlin("jvm") +// kotlin("plugin.spring") + + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } dependencies { diff --git a/members/members-infrastructure/build.gradle.kts b/members/members-infrastructure/build.gradle.kts index 4da2f42b..47b3568d 100644 --- a/members/members-infrastructure/build.gradle.kts +++ b/members/members-infrastructure/build.gradle.kts @@ -1,7 +1,17 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") - kotlin("plugin.jpa") version "2.1.21" +// kotlin("jvm") +// kotlin("plugin.spring") +// kotlin("plugin.jpa") version "2.1.21" + + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } dependencies { diff --git a/members/members-service/build.gradle.kts b/members/members-service/build.gradle.kts index e622df14..0bbc0af8 100644 --- a/members/members-service/build.gradle.kts +++ b/members/members-service/build.gradle.kts @@ -1,7 +1,17 @@ plugins { - kotlin("jvm") - kotlin("plugin.spring") - id("org.springframework.boot") +// kotlin("jvm") +// kotlin("plugin.spring") +// id("org.springframework.boot") + + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + + // KORREKTUR: Dieses Plugin ist entscheidend. Es schaltet den `springBoot`-Block + // und alle Spring-Boot-spezifischen Gradle-Tasks frei. + alias(libs.plugins.spring.boot) + + // Dependency Management für konsistente Spring-Versionen + alias(libs.plugins.spring.dependencyManagement) } springBoot {