# Members Module ## Überblick Das Members-Modul ist eine umfassende Lösung zur Verwaltung von Mitgliedern für Pferdesportorganisationen. Es implementiert eine saubere Architektur mit Domain-Driven Design und bietet vollständige CRUD-Operationen sowie erweiterte Geschäftslogik für die Mitgliederverwaltung. ## Funktionalität ### Verwaltete Entität #### Mitglied (Member) - **Persönliche Informationen**: Vor- und Nachname, E-Mail, Telefon, Geburtsdatum - **Mitgliedschaftsinformationen**: Mitgliedsnummer, Start-/Enddatum, Aktivitätsstatus - **Zusätzliche Informationen**: Adresse, Notfallkontakt - **Audit-Felder**: Erstellungs- und Aktualisierungszeitstempel - **Geschäftslogik**: Validierung, Mitgliedschaftsgültigkeit, Vollständiger Name ### Geschäftsoperationen Das Modul bietet 18+ spezialisierte Repository-Operationen: #### Basis-CRUD-Operationen - `findById(id)` - Mitglied nach UUID suchen - `save(member)` - Mitglied speichern (erstellen/aktualisieren) - `delete(id)` - Mitglied löschen #### Such-Operationen - `findByMembershipNumber(number)` - Nach Mitgliedsnummer suchen - `findByEmail(email)` - Nach E-Mail-Adresse suchen - `findByName(searchTerm, limit)` - Nach Namen suchen (Teilübereinstimmung) - `findAllActive(limit, offset)` - Alle aktiven Mitglieder - `findAll(limit, offset)` - Alle Mitglieder (aktiv und inaktiv) #### Datumsbasierte Abfragen - `findByMembershipStartDateRange(start, end)` - Mitglieder nach Startdatum-Bereich - `findByMembershipEndDateRange(start, end)` - Mitglieder nach Enddatum-Bereich - `findMembersWithExpiringMembership(daysAhead)` - Mitglieder mit ablaufender Mitgliedschaft #### Validierungs-Operationen - `existsByMembershipNumber(number, excludeId)` - Prüfung auf doppelte Mitgliedsnummer - `existsByEmail(email, excludeId)` - Prüfung auf doppelte E-Mail-Adresse #### Zähl-Operationen - `countActive()` - Anzahl aktiver Mitglieder - `countAll()` - Gesamtanzahl aller Mitglieder ## Architektur Das Modul folgt der Clean Architecture mit klarer Trennung der Verantwortlichkeiten: ``` members/ ├── members-domain/ # Domain Layer │ ├── model/ # Domain Models │ │ └── Member.kt # Mitglied-Entität mit Geschäftslogik │ ├── repository/ # Repository Interfaces │ │ └── MemberRepository.kt # 18+ Geschäftsoperationen │ └── events/ # Domain Events │ └── MemberEvents.kt # Mitgliedschafts-Events ├── members-application/ # Application Layer │ └── usecase/ # Use Cases │ └── FindExpiringMembershipsUseCase.kt ├── members-infrastructure/ # Infrastructure Layer │ ├── persistence/ # Database Implementation │ │ ├── MemberRepositoryImpl.kt │ │ └── MemberTable.kt │ └── repository/ # Alternative Implementations │ └── InMemoryMemberRepository.kt ├── members-api/ # API Layer │ └── rest/ # REST Controllers │ └── MemberController.kt └── members-service/ # Service Layer ├── MembersServiceApplication.kt └── test/ # Integration Tests └── MemberServiceIntegrationTest.kt ``` ### Domain Layer - **1 Domain Model** mit reichhaltiger Geschäftslogik - **1 Repository Interface** mit 18+ Geschäftsoperationen - **Domain Events** für Mitgliedschaftsänderungen - **Keine Abhängigkeiten** zu anderen Layern ### Application Layer - **Use Cases** für komplexe Geschäftsoperationen - **Orchestrierung** von Domain-Services - **Anwendungslogik** ohne UI-Abhängigkeiten ### Infrastructure Layer - **Datenbankzugriff** mit Exposed ORM - **Repository-Implementierung** mit PostgreSQL - **In-Memory-Repository** für Tests - **Datenbankschema** und Migrationen ### API Layer - **REST-Controller** für HTTP-Endpunkte - **DTO-Mapping** zwischen Domain und API - **Validierung** und Fehlerbehandlung ### Service Layer - **Spring Boot Anwendung** - **Dependency Injection** Konfiguration - **Integrationstests** ## Domain Model Details ### Member-Entität ```kotlin data class Member( val memberId: Uuid, // Persönliche Informationen var firstName: String, var lastName: String, var email: String, var phone: String? = null, var dateOfBirth: LocalDate? = null, // Mitgliedschaftsinformationen var membershipNumber: String, var membershipStartDate: LocalDate, var membershipEndDate: LocalDate? = null, var isActive: Boolean = true, // Zusätzliche Informationen var address: String? = null, var emergencyContact: String? = null, // Audit-Felder val createdAt: Instant, var updatedAt: Instant ) ``` ### Geschäftslogik-Methoden - `getFullName()` - Vollständiger Name des Mitglieds - `isMembershipValid()` - Prüfung der Mitgliedschaftsgültigkeit - `validate()` - Datenvalidierung mit Fehlerliste - `withUpdatedTimestamp()` - Kopie mit aktualisiertem Zeitstempel ## Repository-Operationen ### Erweiterte Such-Features ```kotlin // Mitglieder mit ablaufender Mitgliedschaft finden val expiringMembers = memberRepository.findMembersWithExpiringMembership(30) // Mitglieder nach Datumsbereich suchen val newMembers = memberRepository.findByMembershipStartDateRange( startDate = LocalDate(2024, 1, 1), endDate = LocalDate(2024, 12, 31) ) // Namenssuche mit Teilübereinstimmung val searchResults = memberRepository.findByName("Schmidt", limit = 10) ``` ### Validierung und Duplikatsprüfung ```kotlin // Prüfung auf doppelte Mitgliedsnummer val numberExists = memberRepository.existsByMembershipNumber("M2024001") // Prüfung auf doppelte E-Mail (mit Ausschluss für Updates) val emailExists = memberRepository.existsByEmail( email = "max@example.com", excludeMemberId = existingMember.memberId ) ``` ## Use Cases ### FindExpiringMembershipsUseCase Findet Mitglieder mit ablaufenden Mitgliedschaften und kann automatische Benachrichtigungen auslösen. ```kotlin class FindExpiringMembershipsUseCase( private val memberRepository: MemberRepository ) { suspend fun execute(daysAhead: Int = 30): List { return memberRepository.findMembersWithExpiringMembership(daysAhead) } } ``` ## API-Endpunkte Das Members-Modul stellt REST-Endpunkte über den MemberController bereit: - `GET /api/members` - Alle aktiven Mitglieder abrufen - `GET /api/members/{id}` - Mitglied nach ID abrufen - `GET /api/members/search?name={name}` - Mitglieder nach Namen suchen - `GET /api/members/expiring?days={days}` - Mitglieder mit ablaufender Mitgliedschaft - `POST /api/members` - Neues Mitglied erstellen - `PUT /api/members/{id}` - Mitglied aktualisieren - `DELETE /api/members/{id}` - Mitglied löschen ## Konfiguration ### Datenbankschema Das Modul verwendet eine `members`-Tabelle mit folgenden Spalten: - `member_id` (UUID, Primary Key) - `first_name`, `last_name`, `email` (Required) - `phone`, `date_of_birth` (Optional) - `membership_number` (Unique) - `membership_start_date`, `membership_end_date` - `is_active` (Boolean) - `address`, `emergency_contact` (Optional) - `created_at`, `updated_at` (Timestamps) ### Service-Konfiguration ```yaml # application.yml members: service: name: members-service port: 8082 database: url: jdbc:postgresql://localhost:5432/meldestelle table: members ``` ## Tests ### Integration Tests Das Modul enthält umfassende Integrationstests: ```kotlin @Test fun `should find members with expiring membership`() { // Test-Implementierung für ablaufende Mitgliedschaften } @Test fun `should validate unique membership number`() { // Test für Eindeutigkeit der Mitgliedsnummer } ``` ### Test-Datenbank Verwendet H2 In-Memory-Datenbank für Tests mit automatischem Schema-Setup. ## Deployment ### Docker ```dockerfile FROM openjdk:21-jre-slim COPY members-service.jar app.jar EXPOSE 8082 ENTRYPOINT ["java", "-jar", "/app.jar"] ``` ### Kubernetes ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: members-service spec: replicas: 2 selector: matchLabels: app: members-service template: spec: containers: - name: members-service image: meldestelle/members-service:latest ports: - containerPort: 8082 ``` ## Monitoring ### Metriken - Anzahl aktiver Mitglieder - Anzahl ablaufender Mitgliedschaften - API-Response-Zeiten - Datenbankverbindungs-Pool ### Health Checks - Datenbankverbindung - Service-Verfügbarkeit - Speicherverbrauch ## Entwicklung ### Lokale Entwicklung ```bash # Service starten ./gradlew :members:members-service:bootRun # Tests ausführen ./gradlew :members:test # Integration Tests ./gradlew :members:members-service:test ``` ### Code-Qualität - **Kotlin Coding Standards** - **100% Test Coverage** für Domain Layer - **Integration Tests** für alle Use Cases - **API-Dokumentation** mit OpenAPI ## Zukünftige Erweiterungen 1. **Mitgliedschaftstypen** - Verschiedene Mitgliedschaftskategorien 2. **Beitragsverwaltung** - Integration mit Zahlungssystem 3. **Mitgliedschaftshistorie** - Tracking von Änderungen 4. **Bulk-Operationen** - Massenimport/-export 5. **Benachrichtigungen** - Automatische E-Mail-Benachrichtigungen 6. **Reporting** - Mitgliedschaftsstatistiken und Reports --- **Letzte Aktualisierung**: 25. Juli 2025 Für weitere Informationen zur Gesamtarchitektur siehe [README.md](../README.md).