9.3 KiB
9.3 KiB
Module Structure Design für Self-Contained Systems
Neue Projektstruktur
Meldestelle/
├── shared-kernel/ # Gemeinsame Basis-Komponenten
│ ├── src/commonMain/kotlin/at/mocode/
│ │ ├── enums/ # Gemeinsame Enums
│ │ ├── serializers/ # Gemeinsame Serializer
│ │ ├── validation/ # Basis-Validatoren
│ │ └── dto/base/ # Basis-DTOs
│ └── build.gradle.kts
│
├── member-management/ # Bounded Context 1
│ ├── src/
│ │ ├── commonMain/kotlin/at/mocode/members/
│ │ │ ├── domain/
│ │ │ │ ├── model/ # DomPerson, DomVerein
│ │ │ │ ├── repository/ # Repository Interfaces
│ │ │ │ └── service/ # Domain Services
│ │ │ ├── application/
│ │ │ │ ├── dto/ # Member-spezifische DTOs
│ │ │ │ └── usecase/ # Use Cases
│ │ │ └── infrastructure/
│ │ │ ├── repository/ # Repository Implementierungen
│ │ │ └── api/ # REST Controllers
│ │ └── test/
│ └── build.gradle.kts
│
├── horse-registry/ # Bounded Context 2
│ ├── src/
│ │ ├── commonMain/kotlin/at/mocode/horses/
│ │ │ ├── domain/
│ │ │ │ ├── model/ # DomPferd
│ │ │ │ ├── repository/
│ │ │ │ └── service/
│ │ │ ├── application/
│ │ │ │ ├── dto/
│ │ │ │ └── usecase/
│ │ │ └── infrastructure/
│ │ │ ├── repository/
│ │ │ └── api/
│ │ └── test/
│ └── build.gradle.kts
│
├── license-management/ # Bounded Context 3
│ ├── src/
│ │ ├── commonMain/kotlin/at/mocode/licenses/
│ │ │ ├── domain/
│ │ │ │ ├── model/ # DomLizenz, DomQualifikation
│ │ │ │ ├── repository/
│ │ │ │ └── service/
│ │ │ ├── application/
│ │ │ │ ├── dto/
│ │ │ │ └── usecase/
│ │ │ └── infrastructure/
│ │ │ ├── repository/
│ │ │ └── api/
│ │ └── test/
│ └── build.gradle.kts
│
├── event-management/ # Bounded Context 4
│ ├── src/
│ │ ├── commonMain/kotlin/at/mocode/events/
│ │ │ ├── domain/
│ │ │ │ ├── model/ # Turnier, Veranstaltung
│ │ │ │ ├── repository/
│ │ │ │ └── service/
│ │ │ ├── application/
│ │ │ │ ├── dto/
│ │ │ │ └── usecase/
│ │ │ └── infrastructure/
│ │ │ ├── repository/
│ │ │ └── api/
│ │ └── test/
│ └── build.gradle.kts
│
├── master-data/ # Bounded Context 5
│ ├── src/
│ │ ├── commonMain/kotlin/at/mocode/masterdata/
│ │ │ ├── domain/
│ │ │ │ ├── model/ # LandDefinition, BundeslandDefinition
│ │ │ │ ├── repository/
│ │ │ │ └── service/
│ │ │ ├── application/
│ │ │ │ ├── dto/
│ │ │ │ └── usecase/
│ │ │ └── infrastructure/
│ │ │ ├── repository/
│ │ │ └── api/
│ │ └── test/
│ └── build.gradle.kts
│
├── data-integration/ # Bounded Context 6
│ ├── src/
│ │ ├── commonMain/kotlin/at/mocode/integration/
│ │ │ ├── domain/
│ │ │ │ ├── model/ # ZNS_Staging Models
│ │ │ │ ├── repository/
│ │ │ │ └── service/
│ │ │ ├── application/
│ │ │ │ ├── dto/
│ │ │ │ └── usecase/
│ │ │ └── infrastructure/
│ │ │ ├── repository/
│ │ │ └── api/
│ │ └── test/
│ └── build.gradle.kts
│
├── competition-management/ # Bounded Context 7
│ ├── src/
│ │ ├── commonMain/kotlin/at/mocode/competitions/
│ │ │ ├── domain/
│ │ │ │ ├── model/ # Bewerb, Abteilung, Spezifika
│ │ │ │ ├── repository/
│ │ │ │ └── service/
│ │ │ ├── application/
│ │ │ │ ├── dto/
│ │ │ │ └── usecase/
│ │ │ └── infrastructure/
│ │ │ ├── repository/
│ │ │ └── api/
│ │ └── test/
│ └── build.gradle.kts
│
├── api-gateway/ # API Gateway für einheitliche Schnittstelle
│ ├── src/main/kotlin/at/mocode/gateway/
│ │ ├── config/ # Gateway-Konfiguration
│ │ ├── routing/ # Route-Aggregation
│ │ └── security/ # Authentifizierung/Autorisierung
│ └── build.gradle.kts
│
├── composeApp/ # Frontend (unverändert)
└── settings.gradle.kts # Aktualisiert für neue Module
Architektur-Prinzipien
1. Hexagonal Architecture pro Context
Jeder Bounded Context folgt der Hexagonal Architecture:
- Domain: Geschäftslogik und Entitäten
- Application: Use Cases und DTOs
- Infrastructure: Technische Implementierung
2. Dependency Inversion
- Domain Layer hat keine Abhängigkeiten zu anderen Layern
- Infrastructure implementiert Domain Interfaces
- Application orchestriert Domain Services
3. Clean Boundaries
- Contexts kommunizieren nur über definierte APIs
- Keine direkten Abhängigkeiten zwischen Domain Models
- DTOs für Context-übergreifende Kommunikation
Inter-Context Communication
1. Synchrone Kommunikation
// Beispiel: Member Management ruft Master Data auf
interface CountryService {
suspend fun getCountryById(id: Uuid): CountryDto?
}
// Implementation im API Gateway
class CountryServiceImpl : CountryService {
override suspend fun getCountryById(id: Uuid): CountryDto? {
return masterDataClient.getCountry(id)
}
}
2. Asynchrone Kommunikation
// Domain Events für lose Kopplung
sealed class DomainEvent {
data class PersonCreated(val personId: Uuid, val data: PersonDto) : DomainEvent()
data class HorseRegistered(val horseId: Uuid, val ownerId: Uuid) : DomainEvent()
data class LicenseExpired(val licenseId: Uuid, val personId: Uuid) : DomainEvent()
}
// Event Bus für Context-übergreifende Events
interface EventBus {
suspend fun publish(event: DomainEvent)
fun subscribe(handler: (DomainEvent) -> Unit)
}
3. Shared Kernel
shared-kernel/src/commonMain/kotlin/at/mocode/
├── enums/
│ ├── DatenQuelleE.kt
│ ├── GeschlechtE.kt
│ └── PferdeGeschlechtE.kt
├── dto/base/
│ ├── BaseDto.kt
│ └── ErrorDto.kt
├── serializers/
│ ├── UuidSerializer.kt
│ └── KotlinInstantSerializer.kt
└── validation/
├── ValidationResult.kt
└── BaseValidator.kt
Migration Strategy
Phase 1: Shared Kernel Setup
- Erstelle
shared-kernelModul - Verschiebe gemeinsame Enums und Serializer
- Definiere Basis-DTOs und Validatoren
Phase 2: Master Data Context
- Erstelle
master-dataModul (keine Abhängigkeiten) - Verschiebe Stammdaten-Models
- Implementiere Repository und API
Phase 3: Core Contexts
member-management(abhängig von master-data)horse-registry(abhängig von member-management)license-management(abhängig von member-management)
Phase 4: Business Contexts
event-managementcompetition-managementdata-integration
Phase 5: API Gateway
- Implementiere Gateway für einheitliche API
- Konfiguriere Routing zu Contexts
- Implementiere Authentifizierung
Deployment Options
Option 1: Monolithic Deployment
- Alle Contexts in einer Anwendung
- Einfache Entwicklung und Deployment
- Shared Database
Option 2: Modular Monolith
- Separate JARs pro Context
- Gemeinsame Runtime
- Context-spezifische Schemas
Option 3: Microservices
- Separate Services pro Context
- Unabhängige Deployment
- Separate Datenbanken
Vorteile der neuen Struktur
- Klare Verantwortlichkeiten: Jeder Context hat einen definierten Zweck
- Lose Kopplung: Contexts sind nur über APIs verbunden
- Hohe Kohäsion: Verwandte Funktionalität ist zusammengefasst
- Testbarkeit: Jeder Context kann isoliert getestet werden
- Skalierbarkeit: Contexts können unabhängig skaliert werden
- Team-Autonomie: Teams können an verschiedenen Contexts arbeiten