feat(build): Refactor infrastructure modules and establish single source of truth

This commit introduces a major refactoring of the build system and the core infrastructure modules. The primary goal is to establish a strict "Single Source of Truth" for all dependencies using Gradle Version Catalogs and to create a clean, maintainable, and scalable foundation for all current and future services.

### 1. Centralized Dependency Management (`libs.versions.toml`)

- **Established Single Source of Truth:** All dependency versions are now exclusively managed in `gradle/libs.versions.toml`. Hardcoded versions have been removed from all build scripts.
- **Introduced Gradle Bundles:** To simplify module dependencies, several bundles have been created (e.g., `testing-jvm`, `redis-cache`, `spring-cloud-gateway`, `monitoring-client`). This drastically reduces boilerplate in the `build.gradle.kts` files and improves readability.
- **Cleaned up Aliases:** All library and plugin aliases have been standardized for consistency.

### 2. Infrastructure Module Refactoring

All infrastructure modules (`core`, `platform`, `auth`, `cache`, `event-store`, `messaging`, `monitoring`, `gateway`) have been refactored to align with the new dependency management strategy.

- **Simplified Build Scripts:** The `build.gradle.kts` for each module now uses the new bundles and aliases, making them significantly cleaner and easier to understand.
- **Consistent Structure:** The architecture of each module now clearly follows the Port-Adapter pattern where applicable (e.g., `cache-api`/`redis-cache`).
- **Standardized `platform-bom`:** The project's own Bill of Materials (`platform-bom`) now also includes the Spring Cloud BOM, ensuring version consistency for all Spring-related dependencies.

### 3. Added Infrastructure Documentation

To improve onboarding and architectural understanding, a dedicated `README-*.md` file has been created for each refactored infrastructure module:
- `README-CORE.md`
- `README-PLATFORM.md`
- `README-INFRA-AUTH.md`
- `README-INFRA-CACHE.md`
- `README-INFRA-EVENT-STORE.md`
- `README-INFRA-MESSAGING.md`
- `README-INFRA-MONITORING.md`
- `README-INFRA-GATEWAY.md`

These documents explain the purpose, architecture, and usage of each component within the system. This lays the groundwork for our "Tracer Bullet" development approach.
This commit is contained in:
stefan
2025-07-31 14:09:22 +02:00
parent 81cb4582d6
commit df5919fac8
27 changed files with 882 additions and 356 deletions
@@ -0,0 +1,70 @@
# Infrastructure/Event-Store Module
## Überblick
Das **Event-Store-Modul** ist eine kritische Komponente der Infrastruktur, die für die Persistenz und Veröffentlichung von Domänen-Events zuständig ist. Es bildet die technische Grundlage für **Event Sourcing** und eine allgemeine **event-getriebene Architektur**. Anstatt nur den aktuellen Zustand einer Entität zu speichern, speichert der Event Store die gesamte Kette von Ereignissen (Events), die zu diesem Zustand geführt haben.
## Architektur: Port-Adapter-Muster
Wie schon das Cache-Modul, folgt auch der Event Store streng dem **Port-Adapter-Muster**, um eine maximale Entkopplung von der konkreten Speichertechnologie zu erreichen.
infrastructure/event-store/
├── event-store-api/ # Der "Port": Definiert die Event-Store-Schnittstelle
└── redis-event-store/ # Der "Adapter": Implementiert die Schnittstelle mit Redis Streams
### `event-store-api`
Dieses Modul ist der **abstrakte "Port"** der Architektur. Es definiert den Vertrag, wie der Rest der Anwendung mit dem Event Store interagiert.
* **Zweck:** Definiert Interfaces wie `EventStore` (zum Speichern und Laden von Event-Streams) und `EventPublisher` (zum Veröffentlichen von Events an interessierte Listener). Es ist eng mit den `DomainEvent`-Definitionen aus dem `:core:core-domain`-Modul verknüpft.
* **Vorteil:** Die Fach-Services (z.B. `members-application`) sind vollständig von der Implementierung des Event Stores entkoppelt. Sie wissen nicht, ob die Events in Redis, Kafka oder einer relationalen Datenbank gespeichert werden.
### `redis-event-store`
Dieses Modul ist der **konkrete "Adapter"**, der die in `event-store-api` definierten Schnittstellen implementiert.
* **Zweck:** Stellt eine Implementierung des `EventStore` bereit, die **Redis Streams** als zugrunde liegenden Datenspeicher verwendet. Redis Streams sind eine leistungsstarke Datenstruktur, die sich ideal für die Implementierung eines append-only Logs eignet, wie es für einen Event Store benötigt wird.
* **Technologie:** Nutzt Spring Data Redis und den Lettuce-Client für die performante Kommunikation mit Redis. Die Domänen-Events werden vor der Speicherung mittels Jackson in ein JSON-Format serialisiert.
* **Vorteil:** Kapselt die gesamte Redis-spezifische Logik. Ein zukünftiger Wechsel zu einem anderen Event-Store-System (z.B. Apache Kafka) würde nur den Austausch dieses einen Moduls erfordern.
## Verwendung in anderen Modulen
Ein Anwendungs-Service, der Event Sourcing verwendet, interagiert wie folgt mit dem Modul:
1. **Abhängigkeit deklarieren:** Das Service-Modul (z.B. `members-application`) fügt eine `implementation`-Abhängigkeit zu `:infrastructure:event-store:redis-event-store` in seiner `build.gradle.kts` hinzu.
2. **Interface injizieren:** Im Service-Code wird nur das `EventStore`-Interface aus der `event-store-api` injiziert.
```kotlin
// In einem Use Case oder Application Service
@Service
class MemberApplicationService(
private val eventStore: EventStore, // Nur das Interface wird verwendet!
private val eventPublisher: EventPublisher
) {
fun registerNewMember(command: RegisterMemberCommand): Member {
// 1. Geschäftslogik ausführen und ein oder mehrere Events erzeugen
val memberRegisteredEvent = MemberRegisteredEvent(
memberId = UUID.randomUUID(),
name = command.name,
// ...
)
// 2. Das Event im Event Store speichern
eventStore.save(memberRegisteredEvent)
// 3. Das Event veröffentlichen, damit andere Teile des Systems
// (z.B. ein E-Mail-Service) darauf reagieren können.
eventPublisher.publish(memberRegisteredEvent)
// ...
}
}
```
Diese Architektur ermöglicht eine hochgradig entkoppelte, skalierbare und resiliente Systemlandschaft, die auf asynchroner Kommunikation basiert.
---
**Letzte Aktualisierung**: 31. Juli 2025
@@ -1,13 +1,19 @@
// Dieses Modul definiert die provider-agnostische API für den Event Store.
// Es enthält die Interfaces (z.B. `EventStore`, `EventPublisher`) und die
// Domänen-Events aus `core-domain`, die gespeichert und publiziert werden.
plugins {
kotlin("jvm")
alias(libs.plugins.kotlin.jvm)
}
dependencies {
// Apply platform BOM for version management
// Stellt sicher, dass alle Versionen aus der zentralen BOM kommen.
implementation(platform(projects.platform.platformBom))
// Abhängigkeit zu den Core-Modulen, um auf Domänenobjekte (Events)
// und technische Hilfsklassen zugreifen zu können.
implementation(projects.core.coreDomain)
implementation(projects.core.coreUtils)
// Stellt alle Test-Abhängigkeiten gebündelt bereit.
testImplementation(projects.platform.platformTesting)
}
@@ -1,33 +1,31 @@
// Dieses Modul stellt eine konkrete Implementierung der `event-store-api`
// unter Verwendung von Redis Streams als Event-Store-Backend bereit.
plugins {
// 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 {
// Apply platform BOM for version management
// Stellt sicher, dass alle Versionen aus der zentralen BOM kommen.
implementation(platform(projects.platform.platformBom))
// Implementiert die provider-agnostische Event-Store-API.
implementation(projects.infrastructure.eventStore.eventStoreApi)
// Benötigt Zugriff auf Core-Module für Domänen-Events und Utilities.
implementation(projects.core.coreDomain)
implementation(projects.core.coreUtils)
implementation("org.springframework.boot:spring-boot-starter-data-redis")
implementation("io.lettuce:lettuce-core")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
implementation("javax.annotation:javax.annotation-api:1.3.2")
// OPTIMIERUNG: Wiederverwendung des `redis-cache`-Bundles, da es die
// gleichen Technologien (Spring Data Redis, Lettuce, Jackson) verwendet.
implementation(libs.bundles.redis.cache)
// Stellt Jakarta Annotations bereit (z.B. @PostConstruct), die von Spring verwendet werden.
implementation(libs.jakarta.annotation.api)
// Stellt alle Test-Abhängigkeiten gebündelt bereit.
testImplementation(projects.platform.platformTesting)
testImplementation("org.testcontainers:testcontainers")
testImplementation("org.testcontainers:junit-jupiter")
// Stellt Testcontainers für Integrationstests mit einer echten Redis-Instanz bereit.
testImplementation(libs.bundles.testcontainers)
}