refactor(build): remove docker-compose hardcoded file, update compose dependencies, and resolve library conflicts

Deleted the unused `compose.hardcoded.yaml` file. Updated Gradle build scripts to resolve issues with Jackson and Resilience4j library bundles by explicitly specifying direct dependencies. Removed the `sqldelight` plugin and related dependencies from `local-db` module. Consolidated `docker-compose.yaml` to standardize restart policies. Adjusted `.env` to include cautions for sensitive data and rechecked Java version comments.
This commit is contained in:
Stefan Mogeritsch 2026-01-08 16:46:40 +01:00
parent 98f1abf374
commit ac5717c912
17 changed files with 556 additions and 670 deletions

3
.env
View File

@ -2,6 +2,8 @@
# Meldestelle Docker Compose Environment
# Single Source of Truth (SSoT)
# ==========================================
# WARNING: This file contains secrets (passwords).
# Do NOT commit this file to version control if it contains production secrets.
# --- PROJECT ---
PROJECT_NAME=meldestelle
@ -11,6 +13,7 @@ RESTART_POLICY=no
DOCKER_VERSION=1.0.0-SNAPSHOT
DOCKER_BUILD_DATE=2025-12-22T15:00:00Z
DOCKER_GRADLE_VERSION=9.2.1
# Check if 25 is intended (Early Access) or if LTS 21 was meant
DOCKER_JAVA_VERSION=25
DOCKER_NODE_VERSION=24.12.0
DOCKER_NGINX_VERSION=1.28.0-alpine

129
AGENTS.md Normal file
View File

@ -0,0 +1,129 @@
# Project Agents & Personas
Dieses Dokument definiert die spezialisierten KI-Rollen (Personas) für das Projekt **Meldestelle**. Jede Rolle ist auf einen spezifischen Teil des Tech-Stacks und der Architektur zugeschnitten.
## Globaler Tech-Stack & Regeln
* **Sprachen:** Kotlin 2.3.0 (JVM 25), Java 25.
* **Build System:** Gradle 9.x mit Version Catalogs (`libs.versions.toml`) und zentralem `platform`-Modul.
* **Architektur:** Microservices (Spring Boot) + Modulith-Ansätze, Event-Driven, Clean Architecture / DDD.
* **Frontend:** Kotlin Multiplatform (KMP) mit Compose Multiplatform (Desktop & Web/Wasm).
* **Infrastruktur:** Docker Compose, PostgreSQL 16, Redis 7.4, Keycloak 26, Consul, Prometheus/Grafana.
---
## 1. Rolle: Lead Architect (System & Build)
**Beschreibung:** Verantwortlich für die Gesamtarchitektur, das Build-System und die Integration der Komponenten.
**System Prompt:**
```text
Du bist der Lead Software Architect des Projekts "Meldestelle".
Deine Expertise umfasst:
- Kotlin 2.3 & Java 25 im Enterprise-Umfeld.
- Gradle Build-Optimierung (Composite Builds, Version Catalogs, Platform BOMs).
- Microservices-Architektur mit Spring Cloud (Gateway, Consul, CircuitBreaker).
- Infrastruktur-Orchestrierung mit Docker Compose.
Deine Aufgaben:
1. Überwache die Einhaltung der Architektur-Regeln (Trennung von API, Domain, Infrastructure).
2. Verwalte zentrale Abhängigkeiten im `platform`-Modul und `libs.versions.toml`.
3. Löse komplexe Integrationsprobleme zwischen Services, Gateway und Frontend.
4. Achte strikt darauf, dass keine Versionen hardcodiert werden, sondern über das Platform-Modul referenziert werden.
```
---
## 2. Rolle: Senior Backend Developer (Spring Boot & DDD)
**Beschreibung:** Spezialist für die Implementierung der Fachlogik in den Backend-Services.
**System Prompt:**
```text
Du bist ein Senior Backend Developer, spezialisiert auf Kotlin und Spring Boot 3.5.x.
Du arbeitest an den Microservices.
Technologien & Standards:
- Framework: Spring Boot 3.5.9, Spring WebFlux (Gateway), Spring MVC (Services).
- DB: PostgreSQL, Redis, Mongo.
- Architektur: Domain-Driven Design (DDD). Halte Domänenlogik rein und getrennt von Infrastruktur.
- Testing: JUnit 5, MockK, Testcontainers (Postgres, Keycloak).
- API: REST, OpenAPI (SpringDoc).
Regeln:
1. Nutze `val` und Immutability wo immer möglich.
2. Implementiere Business-Logik in der Domain-Schicht, nicht im Controller.
3. Nutze Testcontainers für Integrationstests.
4. Beachte die Modul-Struktur: `:api` (Interfaces/DTOs), `:domain` (Core Logic), `:service` (Application/Infra).
```
---
## 3. Rolle: KMP Frontend Expert (Compose Multiplatform)
**Beschreibung:** Spezialist für das Frontend "Meldestelle Portal" auf Basis von Compose Multiplatform.
**System Prompt:**
```text
Du bist ein Senior Frontend Developer und Experte für Kotlin Multiplatform (KMP) und Compose Multiplatform.
Du entwickelst das "Meldestelle Portal" für Desktop (JVM) und Web (JS/Wasm).
Technologien & Standards:
- UI: Compose Multiplatform 1.10.x (Material 3).
- State Management: ViewModel, Kotlin Coroutines/Flow.
- DI: Koin 4.x (Compose Integration).
- Network: Ktor Client 3.x.
- Navigation: Eigene Navigations-Lösung oder JetBrains Navigation (falls integriert).
Regeln:
1. Schreibe UI-Code im `commonMain` SourceSet, um Wiederverwendbarkeit zu maximieren.
2. Nutze das `design-system` Modul für konsistentes Styling.
3. Trenne UI (Composables) strikt von Logik (ViewModels).
4. Beachte die Besonderheiten der Targets: Desktop (Swing/AWT Interop) und Web (Canvas/DOM).
```
---
## 4. Rolle: Infrastructure & DevOps Engineer
**Beschreibung:** Verantwortlich für die Laufzeitumgebung, Sicherheit und Observability.
**System Prompt:**
```text
Du bist ein DevOps & Infrastructure Engineer.
Du verwaltest die Docker-Umgebung und die operativen Aspekte der "Meldestelle".
Technologien:
- Container: Docker, Docker Compose.
- IAM: Keycloak 26 (OIDC/OAuth2 Konfiguration).
- Service Discovery: HashiCorp Consul.
- Monitoring: Prometheus, Grafana, Zipkin, Micrometer Tracing.
- DB Ops: PostgreSQL Administration, Flyway Migrationen.
Aufgaben:
1. Stelle sicher, dass alle Container im `docker-compose.yaml` korrekt konfiguriert und vernetzt sind.
2. Verwalte Secrets und Umgebungsvariablen (`.env`).
3. Konfiguriere Keycloak Realms und Clients für die Services und das Frontend.
4. Überwache die Health-Checks und Resiliency-Patterns (Circuit Breaker).
```
---
## 5. Rolle: QA & Testing Specialist
**Beschreibung:** Fokus auf Teststrategie, Testdaten und End-to-End Qualitätssicherung.
**System Prompt:**
```text
Du bist der QA & Testing Specialist für das Projekt.
Dein Ziel ist eine hohe Testabdeckung und stabile Builds.
Tools:
- Backend: JUnit 5, AssertJ, MockK, Testcontainers.
- Frontend: Compose UI Tests (sofern möglich), Unit Tests für ViewModels.
- CI: Gradle Check Tasks.
Regeln:
1. Fördere "Testing Pyramid": Viele Unit Tests, moderate Integration Tests, gezielte E2E Tests.
2. Stelle sicher, dass Tests deterministisch sind (keine Flakiness).
3. Nutze das `platform-testing` Modul für konsistente Test-Abhängigkeiten.
```

View File

@ -19,12 +19,21 @@ dependencies {
implementation(libs.bundles.spring.boot.service.complete)
implementation(libs.postgresql.driver)
implementation(libs.spring.boot.starter.web)
implementation(libs.bundles.jackson.kotlin)
// KORREKTUR: Jackson Bundle aufgelöst, da Accessor fehlschlägt
implementation(libs.jackson.module.kotlin)
implementation(libs.jackson.datatype.jsr310)
implementation(libs.kotlin.reflect)
implementation(libs.spring.cloud.starter.consul.discovery)
implementation(libs.caffeine)
implementation(libs.spring.web)
implementation(libs.bundles.resilience)
// Resilience Dependencies (manuell aufgelöst)
implementation(libs.resilience4j.spring.boot3)
implementation(libs.resilience4j.reactor)
implementation(libs.spring.boot.starter.aop)
implementation(libs.springdoc.openapi.starter.webmvc.ui)
testImplementation(projects.platform.platformTesting)

View File

@ -7,7 +7,7 @@ plugins {
kotlin {
compilerOptions {
// Aktiviert die experimentelle UUID API von Kotlin 2.3.0
// Aktiviert die experimentelle UUID-API von Kotlin 2.3.0
freeCompilerArgs.add("-opt-in=kotlin.uuid.ExperimentalUuidApi")
}
}
@ -21,13 +21,20 @@ dependencies {
implementation(libs.bundles.spring.boot.service.complete)
// WICHTIG: Da wir JPA (blockierend) nutzen, brauchen wir Spring MVC (nicht WebFlux)
implementation(libs.spring.boot.starter.web)
implementation(libs.bundles.spring.cloud.gateway) // Für Discovery Client
// KORREKTUR: Bundle aufgelöst, da Accessor fehlschlägt
// libs.bundles.spring.cloud.gateway -> spring-cloud-gateway
implementation(libs.spring.cloud.starter.gateway.server.webflux)
implementation(libs.spring.cloud.starter.consul.discovery)
// === Database & Persistence ===
implementation(libs.bundles.database.complete)
// === Resilience ===
implementation(libs.bundles.resilience)
// KORREKTUR: Bundle aufgelöst
implementation(libs.resilience4j.spring.boot3)
implementation(libs.resilience4j.reactor)
implementation(libs.spring.boot.starter.aop)
// === Testing ===
testImplementation(libs.bundles.testing.jvm)

View File

@ -18,12 +18,21 @@ dependencies {
implementation(libs.bundles.spring.boot.service.complete)
implementation(libs.postgresql.driver)
implementation(libs.spring.boot.starter.web)
implementation(libs.bundles.jackson.kotlin)
// KORREKTUR: Jackson Bundle aufgelöst
implementation(libs.jackson.module.kotlin)
implementation(libs.jackson.datatype.jsr310)
implementation(libs.kotlin.reflect)
implementation(libs.spring.cloud.starter.consul.discovery)
implementation(libs.caffeine)
implementation(libs.spring.web)
implementation(libs.bundles.resilience)
// KORREKTUR: Resilience Bundle aufgelöst
implementation(libs.resilience4j.spring.boot3)
implementation(libs.resilience4j.reactor)
implementation(libs.spring.boot.starter.aop)
implementation(libs.springdoc.openapi.starter.webmvc.ui)
testImplementation(projects.platform.platformTesting)

View File

@ -1,153 +0,0 @@
name: meldestelle-hardcoded
services:
# --- DATENBANK ---
postgres:
image: postgres:16-alpine
container_name: meldestelle-postgres
restart: unless-stopped
ports:
- "5432:5432"
environment:
POSTGRES_USER: pg-user
POSTGRES_PASSWORD: pg-password
POSTGRES_DB: meldestelle
volumes:
- postgres-data:/var/lib/postgresql/data
# Falls du Init-Scripte hast, lassen wir die erstmal weg,
# um Fehlerquellen zu reduzieren, oder lassen den Pfad, falls er existiert:
- ./docker/core/postgres:/docker-entrypoint-initdb.d:Z
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U pg-user -d meldestelle" ]
interval: 1s
timeout: 5s
retries: 3
start_period: 30s
networks:
- meldestelle-network
# --- DATENBANK-MANAGEMENT-TOOL ---
pgadmin:
image: dpage/pgadmin4:8
container_name: pgadmin4_container
restart: unless-stopped
ports:
- "8888:80"
environment:
PGADMIN_DEFAULT_EMAIL: user@domain.com
PGADMIN_DEFAULT_PASSWORD: strong-password
volumes:
- pgadmin-data:/var/lib/pgadmin
healthcheck:
test: [ "CMD-SHELL", "wget --spider -q http://localhost:80/ || exit 1" ]
interval: 1s
timeout: 5s
retries: 3
start_period: 30s
networks:
- meldestelle-network
# --- CACHE ---
redis:
image: redis:7-alpine
container_name: meldestelle-redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis-data:/data
command: redis-server --appendonly yes
healthcheck:
test: [ "CMD", "redis-cli" ]
interval: 1s
timeout: 5s
retries: 3
networks:
- meldestelle-network
# --- IDENTITY PROVIDER (Wartet auf Postgres) ---
keycloak:
image: quay.io/keycloak/keycloak:26.4
container_name: meldestelle-keycloak
restart: unless-stopped
environment:
KC_HEALTH_ENABLED: true
KC_METRICS_ENABLED: true
KC_BOOTSTRAP_ADMIN_USERNAME: kc-admin
KC_BOOTSTRAP_ADMIN_PASSWORD: kc-password
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres:5432/meldestelle
KC_DB_USERNAME: pg-user
KC_DB_PASSWORD: pg-password
KC_HOSTNAME: localhost
ports:
- "8180:8080"
depends_on:
postgres:
condition: service_healthy
volumes:
- ./docker/core/keycloak:/opt/keycloak/data/import:Z
command: start-dev --import-realm
healthcheck:
test: [ "CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/9000" ]
interval: 20s
timeout: 10s
retries: 5
start_period: 60s
networks:
- meldestelle-network
# --- MONITORING ---
prometheus:
image: prom/prometheus:v2.54.1
container_name: meldestelle-prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- prometheus-data:/prometheus
- ./docker/monitoring/prometheus:/etc/prometheus:Z
command:
- --config.file=/etc/prometheus/prometheus.yaml
- --storage.tsdb.retention.time=15d
healthcheck:
test: [ "CMD", "wget", "--spider", "-q", "http://localhost:9090/-/healthy" ]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
networks:
- meldestelle-network
grafana:
image: grafana/grafana:11.3.0
container_name: meldestelle-grafana
environment:
GF_SECURITY_ADMIN_USER: gf-admin
GF_SECURITY_ADMIN_PASSWORD: gf-password
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
- ./docker/monitoring/grafana:/etc/grafana/provisioning:Z
depends_on:
- prometheus
healthcheck:
test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health" ]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
networks:
- meldestelle-network
volumes:
postgres-data:
pgadmin-data:
redis-data:
prometheus-data:
grafana-data:
networks:
meldestelle-network:
driver: bridge

View File

@ -9,7 +9,7 @@ services:
postgres:
image: "${POSTGRES_IMAGE:-postgres:16-alpine}"
container_name: "${PROJECT_NAME:-meldestelle}-postgres"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "${POSTGRES_PORT:-5432:5432}"
environment:
@ -37,7 +37,7 @@ services:
redis:
image: "${REDIS_IMAGE:-redis:7.4-alpine}"
container_name: "${PROJECT_NAME:-meldestelle}-redis"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "${REDIS_PORT:-6379:6379}"
volumes:
@ -59,7 +59,7 @@ services:
keycloak:
image: "meldestelle-keycloak:latest"
container_name: "${PROJECT_NAME:-meldestelle}-keycloak"
restart: "${RESTART_POLICY:-no}"
restart: no
build:
context: "./config/docker/keycloak"
args:
@ -107,7 +107,7 @@ services:
pgadmin:
image: "${PGADMIN_IMAGE:-dpage/pgadmin4:8}"
container_name: "${PROJECT_NAME:-meldestelle}-pgadmin"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "${PGADMIN_PORT:-8888:80}"
environment:
@ -125,7 +125,7 @@ services:
postgres-exporter:
image: "${POSTGRES_EXPORTER_IMAGE:-prometheuscommunity/postgres-exporter:v0.18.0}"
container_name: "${PROJECT_NAME:-meldestelle}-postgres-exporter"
restart: "${RESTART_POLICY:-no}"
restart: no
environment:
DATA_SOURCE_NAME: "postgresql://${POSTGRES_USER:-pg-user}:${POSTGRES_PASSWORD:-pg-password}@postgres:5432/${POSTGRES_DB:-pg-meldestelle-db}?sslmode=disable"
depends_on:
@ -141,7 +141,7 @@ services:
alertmanager:
image: "${ALERTMANAGER_IMAGE:-prom/alertmanager:v0.29.0}"
container_name: "${PROJECT_NAME:-meldestelle}-alertmanager"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "${ALERTMANAGER_PORT:-9093:9093}"
volumes:
@ -161,7 +161,7 @@ services:
prometheus:
image: "${PROMETHEUS_IMAGE:-prom/prometheus:v3.7.3}"
container_name: "${PROJECT_NAME:-meldestelle}-prometheus"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "${PROMETHEUS_PORT:-9090:9090}"
volumes:
@ -188,7 +188,7 @@ services:
grafana:
image: "${GF_IMAGE:-grafana/grafana:12.3}"
container_name: "${PROJECT_NAME:-meldestelle}-grafana"
restart: "${RESTART_POLICY:-no}"
restart: no
environment:
GF_SECURITY_ADMIN_USER: "${GF_ADMIN_USER:-gf-admin}"
GF_SECURITY_ADMIN_PASSWORD: "${GF_ADMIN_PASSWORD:-gf-password}"
@ -219,7 +219,7 @@ services:
consul:
image: "${CONSUL_IMAGE:-hashicorp/consul:1.22.1}"
container_name: "${PROJECT_NAME:-meldestelle}-consul"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "${CONSUL_PORT:-8500:8500}"
- "${CONSUL_UDP_PORT:-8600:8600/udp}"
@ -249,7 +249,7 @@ services:
labels:
- "org.opencontainers.image.created=${DOCKER_BUILD_DATE}"
container_name: "${PROJECT_NAME:-meldestelle}-gateway"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "${GATEWAY_PORT:-8081:8081}"
- "${GATEWAY_DEBUG_PORT:-5005:5005}"
@ -323,7 +323,7 @@ services:
labels:
- "org.opencontainers.image.created=${DOCKER_BUILD_DATE}"
container_name: "${PROJECT_NAME:-meldestelle}-ping-service"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "${PING_PORT:-8082:8082}"
- "${PING_DEBUG_PORT:-5006:5006}"
@ -379,7 +379,7 @@ services:
labels:
- "org.opencontainers.image.created=${DOCKER_BUILD_DATE}"
container_name: "${PROJECT_NAME:-meldestelle}-entries-service"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "8083:8083"
environment:
@ -417,7 +417,7 @@ services:
labels:
- "org.opencontainers.image.created=${DOCKER_BUILD_DATE}"
container_name: "${PROJECT_NAME:-meldestelle}-results-service"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "8084:8084"
environment:
@ -455,7 +455,7 @@ services:
labels:
- "org.opencontainers.image.created=${DOCKER_BUILD_DATE}"
container_name: "${PROJECT_NAME:-meldestelle}-scheduling-service"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "8085:8085"
environment:
@ -503,7 +503,7 @@ services:
labels:
- "org.opencontainers.image.created=${DOCKER_BUILD_DATE}"
container_name: "${PROJECT_NAME:-meldestelle}-web-app"
restart: "${RESTART_POLICY:-no}"
restart: no
ports:
- "${WEB_APP_PORT:-4000:4000}"
environment:
@ -533,7 +533,7 @@ services:
labels:
- "org.opencontainers.image.created=${DOCKER_BUILD_DATE}"
container_name: "${PROJECT_NAME:-meldestelle}-desktop-app"
restart: "${RESTART_POLICY:-no}"
restart: no
environment:
API_BASE_URL: "http://api-gateway:8081"
ports:

View File

@ -29,11 +29,11 @@ kotlin {
implementation(projects.frontend.shared)
// Compose dependencies
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.ui)
implementation(compose.components.resources)
implementation("org.jetbrains.compose.runtime:runtime:1.10.0-rc02")
implementation("org.jetbrains.compose.foundation:foundation:1.10.0-rc02")
implementation("org.jetbrains.compose.material3:material3:1.9.0-beta03")
implementation("org.jetbrains.compose.ui:ui:1.10.0-rc02")
implementation("org.jetbrains.compose.components:components-resources:1.10.0-rc02")
// Coroutines
implementation(libs.kotlinx.coroutines.core)

View File

@ -5,7 +5,6 @@ import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.kotlinSerialization)
alias(libs.plugins.sqldelight)
}
kotlin {
@ -21,18 +20,13 @@ kotlin {
sourceSets {
commonMain.dependencies {
implementation(libs.koin.core)
implementation(libs.sqldelight.coroutines)
implementation(libs.kotlinx.coroutines.core)
}
jvmMain.dependencies {
implementation(libs.sqldelight.driver.sqlite)
}
jsMain.dependencies {
implementation(libs.sqldelight.driver.webworker)
implementation(npm("@cashapp/sqldelight-sqljs-worker", libs.versions.sqldelight.get()))
implementation(npm("sql.js", "^1.8.0"))
}
commonTest.dependencies {
@ -40,12 +34,3 @@ kotlin {
}
}
}
sqldelight {
databases {
register("MeldestelleDb") {
packageName.set("at.mocode.frontend.core.localdb")
// Sources are placed under src/commonMain/sqldelight by convention
}
}
}

View File

@ -35,7 +35,7 @@ kotlin {
// ktor-client-resources optional; disabled until version is added to catalog
// Kotlinx core bundles
implementation(libs.bundles.kotlinx.core)
implementation(libs.kotlinx.coroutines.core)
// DI (Koin)
api(libs.koin.core)

View File

@ -46,12 +46,13 @@ kotlin {
implementation(projects.frontend.shared)
// Compose dependencies
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.materialIconsExtended)
//implementation("org.jetbrains.compose.runtime:runtime:1.10.0-rc02")
implementation("org.jetbrains.compose.runtime:runtime:1.10.0-rc02")
implementation("org.jetbrains.compose.foundation:foundation:1.10.0-rc02")
implementation("org.jetbrains.compose.material3:material3:1.9.0-beta03")
implementation("org.jetbrains.compose.ui:ui:1.10.0-rc02")
implementation("org.jetbrains.compose.components:components-resources:1.10.0-rc02")
implementation("org.jetbrains.compose.material:material-icons-extended:1.7.3")
// Ktor client for HTTP calls
implementation(libs.ktor.client.core)
@ -110,9 +111,11 @@ kotlin {
implementation(libs.ktor.client.js) // WASM verwendet JS-Client [cite: 7]
// ✅ HINZUFÜGEN: Compose für shared UI components für WASM
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation("org.jetbrains.compose.runtime:runtime:1.10.0-rc02")
implementation("org.jetbrains.compose.foundation:foundation:1.10.0-rc02")
implementation("org.jetbrains.compose.material3:material3:1.9.0-beta03")
}
}
}

View File

@ -49,18 +49,18 @@ kotlin {
implementation(projects.frontend.shared)
// Compose dependencies
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.materialIconsExtended)
implementation("org.jetbrains.compose.foundation:foundation:1.10.0-rc02")
implementation("org.jetbrains.compose.runtime:runtime:1.10.0-rc02")
implementation("org.jetbrains.compose.material3:material3:1.9.0-beta03")
implementation("org.jetbrains.compose.ui:ui:1.10.0-rc02")
implementation("org.jetbrains.compose.components:components-resources:1.10.0-rc02")
implementation("org.jetbrains.compose.material:material-icons-extended:1.7.3")
// Ktor client for HTTP calls
implementation(libs.bundles.ktor.client.common)
implementation(libs.ktor.client.core)
// Coroutines and serialization
implementation(libs.bundles.kotlinx.core)
implementation(libs.kotlinx.coroutines.core)
// DI (Koin) for resolving apiClient from container
implementation(libs.koin.core)
@ -101,9 +101,10 @@ kotlin {
implementation(libs.ktor.client.js) // WASM verwendet JS-Client [cite: 7]
// ✅ HINZUFÜGEN: Compose für shared UI components für WASM
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation("org.jetbrains.compose.runtime:runtime:1.10.0-rc02")
implementation("org.jetbrains.compose.foundation:foundation:1.10.0-rc02")
implementation("org.jetbrains.compose.material3:material3:1.9.0-beta03")
}
}
}

View File

@ -48,7 +48,13 @@ kotlin {
api(project(":frontend:core:domain"))
// Kotlinx core dependencies (coroutines, serialization, datetime)
implementation(libs.bundles.kotlinx.core)
// KORREKTUR: Zugriff auf Bundle korrigiert.
// In libs.versions.toml: [bundles] kotlinx-core = [...]
// Gradle Accessor: libs.bundles.kotlinx.core
// Falls das fehlschlägt, listen wir die Libs einzeln auf, um den Build zu fixen.
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.datetime)
// HTTP Client
implementation(libs.ktor.client.core)
@ -66,9 +72,10 @@ kotlin {
implementation(projects.frontend.core.network)
// Compose für shared UI components (common)
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
// KORREKTUR: Verwendung der korrekten Compose-Dependencies ohne Deprecation-Warnung
implementation("org.jetbrains.compose.runtime:runtime:1.10.0-rc02")
implementation("org.jetbrains.compose.foundation:foundation:1.10.0-rc02")
implementation("org.jetbrains.compose.material3:material3:1.9.0-beta03")
}
commonTest.dependencies {
@ -88,10 +95,11 @@ kotlin {
if (enableWasm) {
val wasmJsMain = getByName("wasmJsMain")
wasmJsMain.dependencies {
implementation(libs.ktor.client.js) // WASM verwendet JS-Client
implementation(libs.ktor.client.js) // WASM verwendet JS-Clients
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
}
}
}

View File

@ -10,169 +10,176 @@ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
* setzt sie zu einer lauffähigen Anwendung zusammen.
*/
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.composeCompiler)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.kotlinSerialization)
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.composeCompiler)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.kotlinSerialization)
}
kotlin {
// Toolchain is now handled centrally in the root build.gradle.kts
val enableWasm = providers.gradleProperty("enableWasm").orNull == "true"
// JVM Target für Desktop
jvm {
binaries {
executable {
mainClass.set("MainKt")
}
}
// JVM Target für Desktop
jvm {
binaries {
executable {
mainClass.set("MainKt")
}
}
}
// JavaScript Target für Web
js(IR) {
browser {
commonWebpackConfig {
cssSupport { enabled = true }
// Webpack-Mode abhängig von Build-Typ
mode = if (project.hasProperty("production"))
KotlinWebpackConfig.Mode.PRODUCTION
else
KotlinWebpackConfig.Mode.DEVELOPMENT
}
// JavaScript Target für Web
js(IR) {
browser {
commonWebpackConfig {
cssSupport { enabled = true }
// Webpack-Mode abhängig von Build-Typ
mode = if (project.hasProperty("production"))
KotlinWebpackConfig.Mode.PRODUCTION
else
KotlinWebpackConfig.Mode.DEVELOPMENT
}
webpackTask {
mainOutputFileName = "web-app.js"
}
webpackTask {
mainOutputFileName = "web-app.js"
}
// Development Server konfigurieren
runTask {
mainOutputFileName.set("web-app.js")
}
// Browser-Tests komplett deaktivieren (Configuration Cache kompatibel)
testTask {
// Development Server konfigurieren
runTask {
mainOutputFileName.set("web-app.js")
}
// Browser-Tests komplett deaktivieren (Configuration Cache kompatibel)
testTask {
// enabled = false
useKarma {
useChromeHeadless()
environment("CHROME_BIN", "/usr/bin/google-chrome-stable")
}
}
useKarma {
useChromeHeadless()
environment("CHROME_BIN", "/usr/bin/google-chrome-stable")
}
binaries.executable()
}
}
binaries.executable()
}
// WASM, nur wenn explizit aktiviert
if (enableWasm) {
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class)
wasmJs {
browser()
binaries.executable()
}
}
sourceSets {
commonMain.dependencies {
// Shared modules
implementation(projects.frontend.shared)
implementation(projects.frontend.core.designSystem)
implementation(projects.frontend.core.navigation)
implementation(projects.frontend.core.network)
implementation(project(":frontend:core:local-db"))
implementation(projects.frontend.features.authFeature)
implementation(projects.frontend.features.pingFeature)
// DI (Koin) needed to call initKoin { modules(...) }
implementation(libs.koin.core)
implementation(libs.koin.compose)
implementation(libs.koin.compose.viewmodel)
// Compose Multiplatform
// KORREKTUR: Verwendung der Plugin-Extension 'compose' statt hardcodierter Strings oder libs
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.materialIconsExtended)
// ViewModel lifecycle
implementation(libs.bundles.compose.common)
// Coroutines, Serialization, DateTime
// KORREKTUR: Explizite Auflistung statt Bundle, um Accessor-Probleme zu vermeiden
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.datetime)
}
// WASM, nur wenn explizit aktiviert
jvmMain.dependencies {
implementation(compose.desktop.currentOs)
implementation(libs.kotlinx.coroutines.swing)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.koin.core)
}
jsMain.dependencies {
// KORREKTUR: compose.html.core statt libs.compose.html.core
implementation(compose.html.core)
}
// WASM SourceSet, nur wenn aktiviert
if (enableWasm) {
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class)
wasmJs {
browser()
binaries.executable()
}
val wasmJsMain = getByName("wasmJsMain")
wasmJsMain.dependencies {
implementation(libs.ktor.client.js) // WASM verwendet JS-Client [cite: 7]
// ✅ HINZUFÜGEN: Compose für shared UI components für WASM
// KORREKTUR: Verwendung der Plugin-Extension
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
}
}
sourceSets {
commonMain.dependencies {
// Shared modules
implementation(projects.frontend.shared)
implementation(projects.frontend.core.designSystem)
implementation(projects.frontend.core.navigation)
implementation(projects.frontend.core.network)
implementation(project(":frontend:core:local-db"))
implementation(projects.frontend.features.authFeature)
implementation(projects.frontend.features.pingFeature)
// DI (Koin) needed to call initKoin { modules(...) }
implementation(libs.koin.core)
implementation(libs.koin.compose)
implementation(libs.koin.compose.viewmodel)
// Compose Multiplatform
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.materialIconsExtended)
// ViewModel lifecycle
implementation(libs.bundles.compose.common)
// Coroutines, Serialization, DateTime
implementation(libs.bundles.kotlinx.core)
}
jvmMain.dependencies {
implementation(compose.desktop.currentOs)
implementation(libs.kotlinx.coroutines.swing)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.koin.core)
}
jsMain.dependencies {
implementation(compose.html.core)
}
// WASM SourceSet, nur wenn aktiviert
if (enableWasm) {
val wasmJsMain = getByName("wasmJsMain")
wasmJsMain.dependencies {
implementation(libs.ktor.client.js) // WASM verwendet JS-Client [cite: 7]
// ✅ HINZUFÜGEN: Compose für shared UI components für WASM
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
}
}
commonTest.dependencies {
implementation(libs.kotlin.test)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
}
}
}
// KMP Compile-Optionen
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_25)
freeCompilerArgs.addAll(
"-opt-in=kotlin.RequiresOptIn",
"-Xskip-metadata-version-check", // Für bleeding-edge Versionen
// Suppress beta warning for expect/actual declarations used in this module
"-Xexpect-actual-classes"
)
}
compilerOptions {
jvmTarget.set(JvmTarget.JVM_25)
freeCompilerArgs.addAll(
"-opt-in=kotlin.RequiresOptIn",
"-Xskip-metadata-version-check", // Für bleeding-edge Versionen
// Suppress beta warning for expect/actual declarations used in this module
"-Xexpect-actual-classes"
)
}
}
// Configure a duplicate handling strategy for distribution tasks
tasks.withType<Tar> {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.withType<Zip> {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
// Duplicate-Handling für Distribution
tasks.withType<Copy> {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Statt EXCLUDE
duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Statt EXCLUDE
}
tasks.withType<Sync> {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
// Desktop Application Configuration
compose.desktop {
application {
mainClass = "MainKt"
application {
mainClass = "MainKt"
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "Meldestelle"
packageVersion = "1.0.0"
description = "Meldestelle Development App"
}
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "Meldestelle"
packageVersion = "1.0.0"
description = "Meldestelle Development App"
}
}
}

View File

@ -1,29 +1,32 @@
# This file is the SINGLE SOURCE OF TRUTH for all project dependencies.
# It allows for centralized version management and ensures consistency.
# Last updated: 2025-07-31
# Last updated: 2026-01-08
[versions]
# --- Android Ecosystem ---
# agp = "8.13"
# --- Kotlin Ecosystem ---
# --- Kotlin & Core ---
kotlin = "2.3.0"
kotlin-logging = "7.0.13"
# KSP version must match Kotlin version. Assuming 2.3.0-1.0.0 for Kotlin 2.3.0
ksp = "2.3.0-1.0.0"
kotlinx = "1.10.2"
kotlinx-serialization-json = "1.9.0"
kotlinx-datetime = "0.7.1"
kotlinx-coroutines = "1.10.2"
# --- Spring Ecosystem ---
# Spring Boot 3.5.x Linie (kompatibel zu Spring Framework 6.2)
springBoot = "3.5.9"
# Spring Cloud Release Train kompatibel zu Spring Boot 3.5.x → Northfields (2025.0.x)
springCloud = "2025.0.1"
# springCloudGateway = "4.3.0"
springDependencyManagement = "1.1.7"
springdoc = "3.0.0"
# --- KMP & UI ---
# Für Kotlin 2.3.0 erforderlich (R8/StackTrace Fixes, Wasm Reife)
composeMultiplatform = "1.10.0-rc02"
composeHotReload = "1.0.0"
androidx-lifecycle = "2.9.6"
uiDesktop = "1.7.0"
# --- Ktor (API Layer & Client) ---
# Kotlin 2.3.0 Alignment + iOS SSE Fix
ktor = "3.3.3"
@ -32,30 +35,26 @@ ktor = "3.3.3"
koin = "4.1.1"
koinCompose = "4.1.1"
# --- Compose UI ---
androidx-lifecycle = "2.9.6"
composeHotReload = "1.0.0"
# Für Kotlin 2.3.0 erforderlich (R8/StackTrace Fixes, Wasm Reife)
composeMultiplatform = "1.10.0-rc02"
# --- Database & Persistence ---
# Stabil für Kotlin 2.3.0 (anstelle von 0.61.0)
exposed = "0.61.0"
# --- Data & Persistence ---
# Stabil für Kotlin 2.3.0
exposed = "1.0.0-rc-4"
postgresql = "42.7.8"
hikari = "7.0.2"
h2 = "2.4.240"
flyway = "11.19.1"
redisson = "4.0.0"
lettuce = "7.2.1.RELEASE"
sqldelight = "2.2.1"
# --- Service Discovery & Monitoring ---
# Room & SQLite (KMP)
room = "2.8.4"
sqlite = "2.6.2"
# --- Infrastructure & Observability ---
micrometer = "1.16.1"
micrometerTracing = "1.6.1"
zipkin = "3.5.1"
zipkinReporter = "3.5.1"
# --- Authentication ---
resilience4j = "2.3.0"
auth0Jwt = "4.5.0"
keycloakAdminClient = "26.0.7"
@ -71,37 +70,27 @@ testcontainersJunitJupiter = "1.21.4"
testcontainersPostgresql = "1.21.4"
testcontainersKafka = "1.21.4"
# --- Resilience4j ---
resilience4j = "2.3.0"
# --- Utilities ---
# uuid = "0.9.0"
bignum = "0.3.10"
logback = "1.5.22"
caffeine = "3.2.3"
# KORREKTUR: Version für reactor-kafka wieder aktiviert
reactorKafka = "1.3.23"
jackson = "3.0.3"
jakartaAnnotation = "3.0.0"
roomCommonJvm = "2.8.4"
uiDesktop = "1.7.0"
# --- Logging ---
slf4j = "2.0.17"
java = "25"
kotlin-logging = "7.0.13"
# --- Gradle Plugins ---
foojayResolver = "1.0.0"
[libraries]
# --- Platform BOMs (Bill of Materials) ---
# === BOMs (Bill of Materials) ===
kotlin-bom = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" }
kotlinx-coroutines-bom = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-bom", version.ref = "kotlinx" }
spring-boot-dependencies = { module = "org.springframework.boot:spring-boot-dependencies", version.ref = "springBoot" }
spring-cloud-dependencies = { module = "org.springframework.cloud:spring-cloud-dependencies", version.ref = "springCloud" }
# --- Kotlin & Coroutines ---
# === Kotlin Core ===
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }
@ -112,7 +101,33 @@ kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-
kotlinx-coroutines-reactor = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-reactor",version.ref = "kotlinx-coroutines" } # Version from BOM
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
# --- Ktor Server ---
# === Spring Boot & Cloud ===
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-data-jpa = { module = "org.springframework.boot:spring-boot-starter-data-jpa" }
spring-boot-starter-data-redis = { module = "org.springframework.boot:spring-boot-starter-data-redis" }
spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test" }
spring-boot-starter-oauth2-client = { module = "org.springframework.boot:spring-boot-starter-oauth2-client" }
spring-boot-starter-oauth2-resource-server = { module = "org.springframework.boot:spring-boot-starter-oauth2-resource-server" }
spring-boot-starter-security = { module = "org.springframework.boot:spring-boot-starter-security" }
spring-boot-starter-webflux = { module = "org.springframework.boot:spring-boot-starter-webflux" }
spring-boot-starter-json = { module = "org.springframework.boot:spring-boot-starter-json" }
spring-boot-starter-aop = { module = "org.springframework.boot:spring-boot-starter-aop", version.ref = "springBoot" }
spring-kafka = { module = "org.springframework.kafka:spring-kafka" }
spring-security-oauth2-jose = { module = "org.springframework.security:spring-security-oauth2-jose" }
spring-web = { module = "org.springframework:spring-web" }
springdoc-openapi-starter-common = { module = "org.springdoc:springdoc-openapi-starter-common", version.ref = "springdoc" }
springdoc-openapi-starter-webmvc-ui = { module = "org.springdoc:springdoc-openapi-starter-webmvc-ui", version.ref = "springdoc" }
springdoc-openapi-starter-webflux-ui = { module = "org.springdoc:springdoc-openapi-starter-webflux-ui", version.ref = "springdoc" }
spring-cloud-starter-gateway-server-webflux = { module = "org.springframework.cloud:spring-cloud-starter-gateway-server-webflux" }
spring-cloud-starter-consul-discovery = { module = "org.springframework.cloud:spring-cloud-starter-consul-discovery" }
spring-cloud-starter-circuitbreaker-resilience4j = { module = "org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j" }
# === 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-contentNegotiation = { module = "io.ktor:ktor-server-content-negotiation-jvm", version.ref = "ktor" }
@ -125,17 +140,12 @@ ktor-server-callLogging = { module = "io.ktor:ktor-server-call-logging-jvm", ver
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" }
# --- Koin (DI) ---
koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koinCompose" }
koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koinCompose" }
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-tests = { module = "io.ktor:ktor-server-tests-jvm", version.ref = "ktor" }
ktor-server-testHost = { module = "io.ktor:ktor-server-test-host-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" }
@ -145,105 +155,69 @@ ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "k
ktor-client-auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" }
ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" }
# --- Spring Boot (Versions from spring-boot-dependencies BOM) ---
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-data-jpa = { module = "org.springframework.boot:spring-boot-starter-data-jpa" }
spring-boot-starter-data-redis = { module = "org.springframework.boot:spring-boot-starter-data-redis" }
spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test" }
spring-boot-starter-oauth2-client = { module = "org.springframework.boot:spring-boot-starter-oauth2-client" }
spring-boot-starter-oauth2-resource-server = { module = "org.springframework.boot:spring-boot-starter-oauth2-resource-server" }
spring-boot-starter-security = { module = "org.springframework.boot:spring-boot-starter-security" }
spring-boot-starter-webflux = { module = "org.springframework.boot:spring-boot-starter-webflux" }
spring-boot-starter-json = { module = "org.springframework.boot:spring-boot-starter-json" }
# KORREKTUR: Explizite Versionierung über BOM-Referenz
spring-boot-starter-aop = { module = "org.springframework.boot:spring-boot-starter-aop", version.ref = "springBoot" }
spring-kafka = { module = "org.springframework.kafka:spring-kafka" }
spring-security-oauth2-jose = { module = "org.springframework.security:spring-security-oauth2-jose" }
spring-web = { module = "org.springframework:spring-web" }
springdoc-openapi-starter-common = { module = "org.springdoc:springdoc-openapi-starter-common", version.ref = "springdoc" }
springdoc-openapi-starter-webmvc-ui = { module = "org.springdoc:springdoc-openapi-starter-webmvc-ui", version.ref = "springdoc" }
# KORREKTUR: WebFlux-Variante von SpringDoc hinzugefügt.
springdoc-openapi-starter-webflux-ui = { module = "org.springdoc:springdoc-openapi-starter-webflux-ui", version.ref = "springdoc" }
# === Koin (DI) ===
koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koinCompose" }
koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koinCompose" }
# === Compose UI ===
androidx-lifecycle-viewmodelCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
androidx-lifecycle-runtimeCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
ui-desktop = { module = "androidx.compose.ui:ui-desktop", version.ref = "uiDesktop" }
# --- Spring Cloud ---
spring-cloud-starter-gateway-server-webflux = { module = "org.springframework.cloud:spring-cloud-starter-gateway-server-webflux" }
spring-cloud-starter-consul-discovery = { module = "org.springframework.cloud:spring-cloud-starter-consul-discovery" }
spring-cloud-starter-circuitbreaker-resilience4j = { module = "org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j" }
# --- Database & Persistence ---
# === Persistence (DB & Cache) ===
exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" }
exposed-dao = { module = "org.jetbrains.exposed:exposed-dao", version.ref = "exposed" }
exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" }
exposed-kotlin-datetime = { module = "org.jetbrains.exposed:exposed-kotlin-datetime", version.ref = "exposed" }
postgresql-driver = { module = "org.postgresql:postgresql", version.ref = "postgresql" }
hikari-cp = { module = "com.zaxxer:HikariCP", version.ref = "hikari" }
h2-driver = { module = "com.h2database:h2", version.ref = "h2" }
flyway-core = { module = "org.flywaydb:flyway-core", version.ref = "flyway" }
flyway-postgresql = { module = "org.flywaydb:flyway-database-postgresql", version.ref = "flyway" }
redisson = { module = "org.redisson:redisson", version.ref = "redisson" }
lettuce-core = { module = "io.lettuce:lettuce-core", version.ref = "lettuce" }
# --- SQLDelight ---
sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions", version.ref = "sqldelight" }
sqldelight-driver-sqlite = { module = "app.cash.sqldelight:sqlite-driver", version.ref = "sqldelight" }
sqldelight-driver-webworker = { module = "app.cash.sqldelight:web-worker-driver", version.ref = "sqldelight" }
# --- Room & SQLite (KMP) ---
androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" }
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
androidx-room-sqlite-wrapper = { module = "androidx.room:room-sqlite-wrapper", version.ref = "room" }
# --- Service Discovery & Monitoring ---
# === Observability & Resilience ===
micrometer-prometheus = { module = "io.micrometer:micrometer-registry-prometheus", version.ref = "micrometer" }
micrometer-tracing-bridge-brave = { module = "io.micrometer:micrometer-tracing-bridge-brave", version.ref = "micrometerTracing" }
zipkin-reporter-brave = { module = "io.zipkin.reporter2:zipkin-reporter-brave", version.ref = "zipkinReporter" }
zipkin-sender-okhttp3 = { module = "io.zipkin.reporter2:zipkin-sender-okhttp3", version.ref = "zipkinReporter" }
zipkin-server = { module = "io.zipkin:zipkin-server", version.ref = "zipkin" }
# --- Resilience4j ---
resilience4j-spring-boot3 = { module = "io.github.resilience4j:resilience4j-spring-boot3", version.ref = "resilience4j" }
resilience4j-reactor = { module = "io.github.resilience4j:resilience4j-reactor", version.ref = "resilience4j" }
# --- Authentication ---
# === Authentication ===
auth0-java-jwt = { module = "com.auth0:java-jwt", version.ref = "auth0Jwt" }
keycloak-admin-client = { module = "org.keycloak:keycloak-admin-client", version.ref = "keycloakAdminClient" }
# --- Utilities ---
#uuid = { module = "com.benasher44:uuid", version.ref = "uuid" }
#uuid-jvm = { module = "com.benasher44:uuid-jvm", version.ref = "uuid" }
# === Utilities ===
bignum = { module = "com.ionspin.kotlin:bignum", version.ref = "bignum" }
slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
logback-core = { module = "ch.qos.logback:logback-core", version.ref = "logback" }
kotlin-logging-jvm = { module = "io.github.oshai:kotlin-logging-jvm", version.ref = "kotlin-logging" }
caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" }
# KORREKTUR: reactor-kafka mit expliziter Version versehen.
reactor-kafka = { module = "io.projectreactor.kafka:reactor-kafka", version.ref = "reactorKafka" }
jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin" }
jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" }
jakarta-annotation-api = { module = "jakarta.annotation:jakarta.annotation-api", version.ref = "jakartaAnnotation" }
# --- Compose UI ---
androidx-lifecycle-viewmodelCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
androidx-lifecycle-runtimeCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
#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" }
#compose-html-core = { module = "org.jetbrains.compose.html:html-core", version.ref = "composeMultiplatform" }
#compose-html-core-js = { module = "org.jetbrains.compose.html:html-core-js", version.ref = "composeMultiplatform" }
#compose-html-svg-js = { module = "org.jetbrains.compose.html:html-svg-js", version.ref = "composeMultiplatform"}
#compose-desktop-currentOs = { module = "org.jetbrains.compose.desktop:desktop", version.ref = "composeMultiplatform" }
# --- Testing ---
# === Testing ===
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" }
junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junitJupiter" }
junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junitPlatform" }
reactor-test = { module = "io.projectreactor:reactor-test" } # Version wird von der Spring BOM verwaltet
reactor-test = { module = "io.projectreactor:reactor-test" }
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
assertj-core = { module = "org.assertj:assertj-core", version.ref = "assertj" }
testcontainers-core = { module = "org.testcontainers:testcontainers", version.ref = "testcontainers" }
@ -251,11 +225,11 @@ testcontainers-junit-jupiter = { module = "org.testcontainers:junit-jupiter", ve
testcontainers-postgresql = { module = "org.testcontainers:postgresql", version.ref = "testcontainersPostgresql" }
testcontainers-kafka = { module = "org.testcontainers:kafka", version.ref = "testcontainersKafka" }
testcontainers-keycloak = { module = "com.github.dasniko:testcontainers-keycloak", version.ref = "testcontainersKeycloak" }
room-common-jvm = { module = "androidx.room:room-common-jvm", version.ref = "roomCommonJvm" }
ui-desktop = { module = "androidx.compose.ui:ui-desktop", version.ref = "uiDesktop" }
room-common-jvm = { module = "androidx.room:room-common-jvm", version.ref = "room" }
[bundles]
# --- Server Bundles ---
ktor-server-essentials = [
"ktor-server-core",
"ktor-server-netty",
@ -265,208 +239,6 @@ ktor-server-essentials = [
"ktor-server-callLogging"
]
ktor-client-essentials = [
"ktor-client-core",
"ktor-client-cio",
"ktor-client-contentNegotiation",
"ktor-client-serialization-kotlinx-json"
]
exposed = [
"exposed-core",
"exposed-dao",
"exposed-jdbc",
"exposed-kotlin-datetime"
]
flyway = [
"flyway-core",
"flyway-postgresql"
]
spring-boot-essentials = [
# "spring-boot-starter-web",
"spring-boot-starter-validation",
"spring-boot-starter-actuator"
]
redis-cache = [
"spring-boot-starter-data-redis",
"lettuce-core",
"jackson-module-kotlin",
"jackson-datatype-jsr310"
]
kafka-config = [
"spring-kafka",
"spring-boot-starter-json",
"jackson-module-kotlin",
"jackson-datatype-jsr310"
]
testing-jvm = [
"junit-jupiter-api",
"junit-jupiter-engine",
"junit-jupiter-params",
"junit-platform-launcher",
"mockk",
"assertj-core",
"kotlinx-coroutines-test"
]
testcontainers = [
"testcontainers-core",
"testcontainers-junit-jupiter",
"testcontainers-postgresql",
"testcontainers-keycloak"
]
# Bündelt alle Abhängigkeiten, die ein Service für Metriken und Tracing benötigt.
monitoring-client = [
"spring-boot-starter-actuator",
"micrometer-prometheus",
"micrometer-tracing-bridge-brave",
"zipkin-reporter-brave",
"zipkin-sender-okhttp3"
]
# Bündelt die Kernabhängigkeiten für das Spring Cloud Gateway.
spring-cloud-gateway = [
"spring-cloud-starter-gateway-server-webflux",
"spring-cloud-starter-consul-discovery"
]
# --- Gateway spezifische Bundles ---
# Kernabhängigkeiten des Gateways, ohne optionale Observability/DB.
gateway-core = [
"spring-cloud-starter-gateway-server-webflux",
"spring-cloud-starter-consul-discovery",
"spring-boot-starter-actuator",
"spring-boot-starter-security",
"spring-boot-starter-oauth2-resource-server",
"spring-security-oauth2-jose",
"spring-cloud-starter-circuitbreaker-resilience4j"
]
# Ergänzende Bundles, die das Gateway häufig nutzt (getrennt für klare Steuerung)
gateway-observability = [
"kotlin-logging-jvm",
"logback-classic",
"logback-core",
"jackson-module-kotlin",
"jackson-datatype-jsr310"
]
# --- NEW BUNDLES ---
# Redis für Gateway (Rate Limiting, einfache Konfiguration)
gateway-redis = [
"spring-boot-starter-data-redis"
]
# Ktor Server bundles
ktor-server-common = [
"ktor-server-core",
"ktor-server-netty",
"ktor-server-contentNegotiation",
"ktor-server-serialization-kotlinx-json",
"ktor-server-statusPages",
"ktor-server-cors",
"ktor-server-defaultHeaders"
]
ktor-server-security = [
"ktor-server-auth",
"ktor-server-authJwt"
]
ktor-server-observability = [
"ktor-server-callLogging",
"ktor-server-metrics-micrometer"
]
ktor-server-docs = [
"ktor-server-openapi",
"ktor-server-swagger"
]
# Ktor Client bundles
ktor-client-common = [
"ktor-client-core",
"ktor-client-contentNegotiation",
"ktor-client-serialization-kotlinx-json",
"ktor-client-logging",
"ktor-client-auth"
]
# Spring Boot bundles
spring-boot-web = [
"spring-boot-starter-web",
"spring-boot-starter-validation",
"spring-boot-starter-actuator"
]
spring-boot-security = [
"spring-boot-starter-security",
"spring-boot-starter-oauth2-client",
"spring-boot-starter-oauth2-resource-server",
"spring-security-oauth2-jose"
]
spring-boot-data = [
"spring-boot-starter-data-jpa",
"spring-boot-starter-data-redis"
]
spring-boot-observability = [
"spring-boot-starter-actuator",
"micrometer-prometheus",
"micrometer-tracing-bridge-brave",
"zipkin-reporter-brave"
]
# Compose bundles
compose-common = [
"androidx-lifecycle-viewmodelCompose",
"androidx-lifecycle-runtimeCompose"
]
# Jackson bundles
jackson-kotlin = [
"jackson-module-kotlin",
"jackson-datatype-jsr310"
]
# Kotlinx bundles
kotlinx-core = [
"kotlinx-coroutines-core",
"kotlinx-serialization-json",
"kotlinx-datetime"
]
# Persistence bundles
persistence-postgres = [
"exposed-core",
"exposed-dao",
"exposed-jdbc",
"postgresql-driver"
]
# Resilience bundles
resilience = [
"resilience4j-spring-boot3",
"resilience4j-reactor",
"spring-boot-starter-aop"
]
# Logging bundles
logging = [
"kotlin-logging-jvm",
"logback-classic",
"logback-core"
]
# --- COMPLETE BUNDLES (Phase 1) ---
# Complete Ktor Server bundle - combines all server bundles for full-featured Ktor services
ktor-server-complete = [
"ktor-server-core",
"ktor-server-netty",
@ -484,9 +256,12 @@ ktor-server-complete = [
"ktor-server-rateLimit"
]
# Complete Spring Boot Service bundle - combines all Spring Boot bundles for full-featured services
spring-boot-essentials = [
"spring-boot-starter-validation",
"spring-boot-starter-actuator"
]
spring-boot-service-complete = [
# "spring-boot-starter-web",
"spring-boot-starter-validation",
"spring-boot-starter-actuator",
"spring-boot-starter-security",
@ -500,7 +275,49 @@ spring-boot-service-complete = [
"zipkin-reporter-brave"
]
# Complete Database bundle - all database and persistence dependencies
gateway-core = [
"spring-cloud-starter-gateway-server-webflux",
"spring-cloud-starter-consul-discovery",
"spring-boot-starter-actuator",
"spring-boot-starter-security",
"spring-boot-starter-oauth2-resource-server",
"spring-security-oauth2-jose",
"spring-cloud-starter-circuitbreaker-resilience4j"
]
gateway-observability = [
"kotlin-logging-jvm",
"logback-classic",
"logback-core",
"jackson-module-kotlin",
"jackson-datatype-jsr310"
]
gateway-redis = [
"spring-boot-starter-data-redis"
]
# --- Client Bundles ---
ktor-client-essentials = [
"ktor-client-core",
"ktor-client-cio",
"ktor-client-contentNegotiation",
"ktor-client-serialization-kotlinx-json"
]
compose-common = [
"androidx-lifecycle-viewmodelCompose",
"androidx-lifecycle-runtimeCompose"
]
# --- Persistence Bundles ---
exposed = [
"exposed-core",
"exposed-dao",
"exposed-jdbc",
"exposed-kotlin-datetime"
]
database-complete = [
"exposed-core",
"exposed-dao",
@ -512,19 +329,34 @@ database-complete = [
"flyway-postgresql"
]
# Complete KMP Testing bundle - comprehensive testing for Kotlin Multiplatform
testing-kmp = [
"kotlin-test",
"junit-jupiter-api",
"junit-jupiter-engine",
"junit-jupiter-params",
"junit-platform-launcher",
"mockk",
"assertj-core",
"kotlinx-coroutines-test"
flyway = [
"flyway-core",
"flyway-postgresql"
]
redis-cache = [
"spring-boot-starter-data-redis",
"lettuce-core",
"jackson-module-kotlin",
"jackson-datatype-jsr310"
]
# --- Infrastructure Bundles ---
kafka-config = [
"spring-kafka",
"spring-boot-starter-json",
"jackson-module-kotlin",
"jackson-datatype-jsr310"
]
monitoring-client = [
"spring-boot-starter-actuator",
"micrometer-prometheus",
"micrometer-tracing-bridge-brave",
"zipkin-reporter-brave",
"zipkin-sender-okhttp3"
]
# Complete Monitoring bundle - comprehensive monitoring and observability
monitoring-complete = [
"spring-boot-starter-actuator",
"micrometer-prometheus",
@ -536,26 +368,59 @@ monitoring-complete = [
"slf4j-api"
]
# --- Testing Bundles ---
testing-jvm = [
"junit-jupiter-api",
"junit-jupiter-engine",
"junit-jupiter-params",
"junit-platform-launcher",
"mockk",
"assertj-core",
"kotlinx-coroutines-test"
]
testing-kmp = [
"kotlin-test",
"junit-jupiter-api",
"junit-jupiter-engine",
"junit-jupiter-params",
"junit-platform-launcher",
"mockk",
"assertj-core",
"kotlinx-coroutines-test"
]
testcontainers = [
"testcontainers-core",
"testcontainers-junit-jupiter",
"testcontainers-postgresql",
"testcontainers-keycloak"
]
[plugins]
# androidApplication = { id = "com.android.application", version.ref = "agp" }
# androidLibrary = { id = "com.android.library", version.ref = "agp" }
# --- Kotlin & Android ---
kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
kotlinJpa = { id = "org.jetbrains.kotlin.plugin.jpa", version.ref = "kotlin" }
kotlinSpring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" }
ktor = { id = "io.ktor.plugin", version.ref = "ktor" }
sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
# --- Compose ---
composeHotReload = { id = "org.jetbrains.compose.hot-reload", version.ref = "composeHotReload" }
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" }
composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
# --- Spring ---
spring-boot = { id = "org.springframework.boot", version.ref = "springBoot" }
spring-dependencyManagement = { id = "io.spring.dependency-management", version.ref = "springDependencyManagement" }
foojayResolver = { id = "org.gradle.toolchains.foojay-resolver-convention", version.ref = "foojayResolver" }
# --- Ktor ---
ktor = { id = "io.ktor.plugin", version.ref = "ktor" }
# Dokka plugin
# --- Persistence ---
androidx-room = { id = "androidx.room", version.ref = "room" }
# --- Tools ---
foojayResolver = { id = "org.gradle.toolchains.foojay-resolver-convention", version.ref = "foojayResolver" }
dokka = { id = "org.jetbrains.dokka", version = "2.1.0" }

View File

@ -43,9 +43,16 @@ dependencies {
// KORREKTUR: `webmvc`-Starter durch `webflux`-Starter ersetzt, um Konflikt zu beheben.
api(libs.springdoc.openapi.starter.webflux.ui)
// --- Database & Persistence ---
// CHIRURGISCHER EINGRIFF: `exposed`-Bundle entfernt, um Kotlin-Versionskonflikt zu beheben.
// api(libs.bundles.exposed)
api(libs.bundles.flyway)
// Exposed Bundle wieder aktiviert, da Version jetzt kompatibel ist
api(libs.exposed.core)
api(libs.exposed.dao)
api(libs.exposed.jdbc)
api(libs.exposed.kotlin.datetime)
// Flyway Bundle kann nicht direkt in constraints verwendet werden, müssen einzeln gelistet werden
api(libs.flyway.core)
api(libs.flyway.postgresql)
api(libs.postgresql.driver)
api(libs.hikari.cp)
api(libs.h2.driver)
@ -57,7 +64,11 @@ dependencies {
api(libs.jackson.module.kotlin)
api(libs.jackson.datatype.jsr310)
// --- Testcontainers ---
api(libs.bundles.testcontainers)
// Testcontainers Bundle kann nicht direkt in constraints verwendet werden
api(libs.testcontainers.core)
api(libs.testcontainers.junit.jupiter)
api(libs.testcontainers.postgresql)
api(libs.testcontainers.keycloak)
}
}

View File

@ -28,6 +28,8 @@ dependencyResolutionManagement {
maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/") }
maven { url = uri("https://maven.pkg.jetbrains.space/public/p/compose/dev") }
maven { url = uri("https://us-central1-maven.pkg.dev/varabyte-repos/public") }
// Add JetBrains Compose repository for RC versions
maven { url = uri("https://maven.pkg.jetbrains.space/public/p/compose/dev") }
}
}