# Members API Documentation ## Überblick Die Members API bietet umfassende Funktionalität zur Verwaltung von Vereinsmitgliedern und deren Mitgliedschaftsdaten. Sie unterstützt vollständige CRUD-Operationen sowie spezialisierte Funktionen für Mitgliedschaftsverwaltung, Validierung und Statistiken. ## Basis-Informationen - **Basis-URL**: `/api/members` - **Controller**: `MemberController` - **Authentifizierung**: JWT Bearer Token erforderlich - **Content-Type**: `application/json` - **Zeichenkodierung**: UTF-8 ## Endpunkte Übersicht | Methode | Endpunkt | Beschreibung | |---------|----------|--------------| | GET | `/api/members` | Alle Mitglieder abrufen | | GET | `/api/members/{id}` | Mitglied nach ID abrufen | | GET | `/api/members/by-membership-number/{membershipNumber}` | Mitglied nach Mitgliedsnummer | | GET | `/api/members/by-email/{email}` | Mitglied nach E-Mail | | GET | `/api/members/stats` | Mitgliederstatistiken | | POST | `/api/members` | Neues Mitglied erstellen | | PUT | `/api/members/{id}` | Mitglied aktualisieren | | DELETE | `/api/members/{id}` | Mitglied löschen | | GET | `/api/members/expiring-memberships` | Ablaufende Mitgliedschaften | | GET | `/api/members/by-date-range` | Mitglieder nach Datumsbereich | | GET | `/api/members/validate/email/{email}` | E-Mail-Eindeutigkeit prüfen | | GET | `/api/members/validate/membership-number/{membershipNumber}` | Mitgliedsnummer-Eindeutigkeit prüfen | ## Detaillierte Endpunkt-Dokumentation ### 1. Alle Mitglieder abrufen ```http GET /api/members ``` Ruft eine Liste aller Mitglieder ab mit optionaler Filterung und Suche. #### Query-Parameter | Parameter | Typ | Standard | Beschreibung | |-----------|-----|----------|--------------| | `activeOnly` | boolean | `true` | Nur aktive Mitglieder anzeigen | | `limit` | integer | `100` | Maximale Anzahl Ergebnisse | | `offset` | integer | `0` | Anzahl zu überspringende Ergebnisse | | `search` | string | - | Suchbegriff für Mitgliedernamen | #### Beispiel-Anfrage ```http GET /api/members?activeOnly=true&limit=50&search=Schmidt Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` #### Erfolgreiche Antwort (200 OK) ```json { "data": [ { "memberId": "123e4567-e89b-12d3-a456-426614174000", "firstName": "Max", "lastName": "Schmidt", "email": "max.schmidt@example.com", "phone": "+43 1 234 5678", "dateOfBirth": "1985-03-15", "membershipNumber": "M2024001", "membershipStartDate": "2024-01-01", "membershipEndDate": "2024-12-31", "isActive": true, "address": "Musterstraße 123, 1010 Wien", "emergencyContact": "Anna Schmidt, +43 1 234 5679", "createdAt": "2024-01-01T10:00:00Z", "updatedAt": "2024-07-25T12:37:00Z" } ], "success": true, "message": null, "errors": [], "timestamp": "2025-07-25T12:37:00Z" } ``` #### Fehler-Antworten - **500 Internal Server Error**: Serverfehler beim Abrufen der Mitglieder ### 2. Mitglied nach ID abrufen ```http GET /api/members/{id} ``` Ruft ein spezifisches Mitglied anhand seiner eindeutigen ID ab. #### Pfad-Parameter | Parameter | Typ | Beschreibung | |-----------|-----|--------------| | `id` | UUID | Eindeutige Mitglieder-ID | #### Beispiel-Anfrage ```http GET /api/members/123e4567-e89b-12d3-a456-426614174000 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` #### Erfolgreiche Antwort (200 OK) ```json { "data": { "memberId": "123e4567-e89b-12d3-a456-426614174000", "firstName": "Max", "lastName": "Schmidt", "email": "max.schmidt@example.com", "phone": "+43 1 234 5678", "dateOfBirth": "1985-03-15", "membershipNumber": "M2024001", "membershipStartDate": "2024-01-01", "membershipEndDate": "2024-12-31", "isActive": true, "address": "Musterstraße 123, 1010 Wien", "emergencyContact": "Anna Schmidt, +43 1 234 5679", "createdAt": "2024-01-01T10:00:00Z", "updatedAt": "2024-07-25T12:37:00Z" }, "success": true, "message": null, "errors": [], "timestamp": "2025-07-25T12:37:00Z" } ``` #### Fehler-Antworten - **400 Bad Request**: Ungültiges UUID-Format - **404 Not Found**: Mitglied nicht gefunden - **500 Internal Server Error**: Serverfehler ### 3. Mitglied nach Mitgliedsnummer abrufen ```http GET /api/members/by-membership-number/{membershipNumber} ``` #### Pfad-Parameter | Parameter | Typ | Beschreibung | |-----------|-----|--------------| | `membershipNumber` | string | Mitgliedsnummer | #### Beispiel-Anfrage ```http GET /api/members/by-membership-number/M2024001 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` ### 4. Mitglied nach E-Mail abrufen ```http GET /api/members/by-email/{email} ``` #### Pfad-Parameter | Parameter | Typ | Beschreibung | |-----------|-----|--------------| | `email` | string | E-Mail-Adresse | #### Beispiel-Anfrage ```http GET /api/members/by-email/max.schmidt@example.com Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` ### 5. Mitgliederstatistiken abrufen ```http GET /api/members/stats ``` Ruft Statistiken über die Mitgliederdatenbank ab. #### Erfolgreiche Antwort (200 OK) ```json { "data": { "totalActive": 1250, "totalMembers": 1380 }, "success": true, "message": null, "errors": [], "timestamp": "2025-07-25T12:37:00Z" } ``` ### 6. Neues Mitglied erstellen ```http POST /api/members ``` Erstellt ein neues Mitglied mit den bereitgestellten Daten. #### Request Body ```json { "firstName": "Max", "lastName": "Mustermann", "email": "max.mustermann@example.com", "phone": "+43 1 234 5678", "dateOfBirth": "1985-03-15", "membershipNumber": "M2024002", "membershipStartDate": "2024-08-01", "membershipEndDate": "2024-12-31", "isActive": true, "address": "Beispielstraße 456, 1020 Wien", "emergencyContact": "Anna Mustermann, +43 1 234 5679" } ``` #### Erfolgreiche Antwort (201 Created) ```json { "data": { "memberId": "456e7890-e89b-12d3-a456-426614174001", "firstName": "Max", "lastName": "Mustermann", "email": "max.mustermann@example.com", "phone": "+43 1 234 5678", "dateOfBirth": "1985-03-15", "membershipNumber": "M2024002", "membershipStartDate": "2024-08-01", "membershipEndDate": "2024-12-31", "isActive": true, "address": "Beispielstraße 456, 1020 Wien", "emergencyContact": "Anna Mustermann, +43 1 234 5679", "createdAt": "2025-07-25T12:37:00Z", "updatedAt": "2025-07-25T12:37:00Z" }, "success": true, "message": null, "errors": [], "timestamp": "2025-07-25T12:37:00Z" } ``` #### Fehler-Antworten - **400 Bad Request**: Ungültige Anfragedaten - **409 Conflict**: E-Mail oder Mitgliedsnummer bereits vorhanden - **422 Unprocessable Entity**: Validierungsfehler ### 7. Mitglied aktualisieren ```http PUT /api/members/{id} ``` Aktualisiert ein bestehendes Mitglied. #### Pfad-Parameter | Parameter | Typ | Beschreibung | |-----------|-----|--------------| | `id` | UUID | Eindeutige Mitglieder-ID | #### Request Body ```json { "firstName": "Max", "lastName": "Mustermann", "email": "max.mustermann.updated@example.com", "phone": "+43 1 234 5678", "dateOfBirth": "1985-03-15", "membershipNumber": "M2024002", "membershipStartDate": "2024-08-01", "membershipEndDate": "2025-07-31", "isActive": true, "address": "Neue Straße 789, 1030 Wien", "emergencyContact": "Anna Mustermann, +43 1 234 5679" } ``` #### Erfolgreiche Antwort (200 OK) Gleiche Struktur wie bei der Erstellung, aber mit aktualisierten Daten und `updatedAt` Zeitstempel. #### Fehler-Antworten - **400 Bad Request**: Ungültige Anfragedaten oder UUID-Format - **404 Not Found**: Mitglied nicht gefunden - **409 Conflict**: E-Mail oder Mitgliedsnummer bereits vorhanden - **500 Internal Server Error**: Serverfehler ### 8. Mitglied löschen ```http DELETE /api/members/{id} ``` Löscht ein Mitglied aus dem System. #### Pfad-Parameter | Parameter | Typ | Beschreibung | |-----------|-----|--------------| | `id` | UUID | Eindeutige Mitglieder-ID | #### Beispiel-Anfrage ```http DELETE /api/members/123e4567-e89b-12d3-a456-426614174000 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` #### Erfolgreiche Antwort (200 OK) ```json { "data": "Member deleted successfully", "success": true, "message": null, "errors": [], "timestamp": "2025-07-25T12:37:00Z" } ``` #### Fehler-Antworten - **400 Bad Request**: Ungültiges UUID-Format - **404 Not Found**: Mitglied nicht gefunden - **500 Internal Server Error**: Serverfehler ### 9. Ablaufende Mitgliedschaften abrufen ```http GET /api/members/expiring-memberships ``` Ruft Mitglieder ab, deren Mitgliedschaft in den nächsten Tagen abläuft. #### Query-Parameter | Parameter | Typ | Standard | Beschreibung | |-----------|-----|----------|--------------| | `daysAhead` | integer | `30` | Anzahl Tage im Voraus | #### Beispiel-Anfrage ```http GET /api/members/expiring-memberships?daysAhead=14 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` #### Erfolgreiche Antwort (200 OK) ```json { "data": [ { "memberId": "123e4567-e89b-12d3-a456-426614174000", "firstName": "Max", "lastName": "Schmidt", "email": "max.schmidt@example.com", "membershipNumber": "M2024001", "membershipEndDate": "2025-08-10", "daysUntilExpiry": 14 } ], "success": true, "message": null, "errors": [], "timestamp": "2025-07-25T12:37:00Z" } ``` ### 10. Mitglieder nach Datumsbereich abrufen ```http GET /api/members/by-date-range ``` Ruft Mitglieder basierend auf einem Datumsbereich ab. #### Query-Parameter | Parameter | Typ | Erforderlich | Beschreibung | |-----------|-----|--------------|--------------| | `startDate` | string (YYYY-MM-DD) | Ja | Startdatum | | `endDate` | string (YYYY-MM-DD) | Ja | Enddatum | | `dateType` | string | Nein | `MEMBERSHIP_START_DATE` oder `MEMBERSHIP_END_DATE` | #### Beispiel-Anfrage ```http GET /api/members/by-date-range?startDate=2024-01-01&endDate=2024-12-31&dateType=MEMBERSHIP_START_DATE Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` #### Fehler-Antworten - **400 Bad Request**: Ungültiges Datumsformat oder Datumstyp ### 11. E-Mail-Eindeutigkeit validieren ```http GET /api/members/validate/email/{email} ``` Prüft, ob eine E-Mail-Adresse bereits verwendet wird. #### Pfad-Parameter | Parameter | Typ | Beschreibung | |-----------|-----|--------------| | `email` | string | Zu prüfende E-Mail-Adresse | #### Query-Parameter | Parameter | Typ | Beschreibung | |-----------|-----|--------------| | `excludeMemberId` | UUID | Mitglieder-ID zum Ausschließen (für Updates) | #### Beispiel-Anfrage ```http GET /api/members/validate/email/test@example.com?excludeMemberId=123e4567-e89b-12d3-a456-426614174000 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` #### Erfolgreiche Antwort (200 OK) ```json { "data": { "isValid": true, "isUnique": false, "message": "Email address is already in use" }, "success": true, "message": null, "errors": [], "timestamp": "2025-07-25T12:37:00Z" } ``` ### 12. Mitgliedsnummer-Eindeutigkeit validieren ```http GET /api/members/validate/membership-number/{membershipNumber} ``` Prüft, ob eine Mitgliedsnummer bereits verwendet wird. #### Pfad-Parameter | Parameter | Typ | Beschreibung | |-----------|-----|--------------| | `membershipNumber` | string | Zu prüfende Mitgliedsnummer | #### Query-Parameter | Parameter | Typ | Beschreibung | |-----------|-----|--------------| | `excludeMemberId` | UUID | Mitglieder-ID zum Ausschließen (für Updates) | ## Datenmodelle ### Member (Mitglied) ```json { "memberId": "UUID", "firstName": "string", "lastName": "string", "email": "string", "phone": "string (optional)", "dateOfBirth": "string (YYYY-MM-DD, optional)", "membershipNumber": "string", "membershipStartDate": "string (YYYY-MM-DD)", "membershipEndDate": "string (YYYY-MM-DD, optional)", "isActive": "boolean", "address": "string (optional)", "emergencyContact": "string (optional)", "createdAt": "string (ISO 8601)", "updatedAt": "string (ISO 8601)" } ``` ### CreateMemberRequest ```json { "firstName": "string (required)", "lastName": "string (required)", "email": "string (required)", "phone": "string (optional)", "dateOfBirth": "string (YYYY-MM-DD, optional)", "membershipNumber": "string (required)", "membershipStartDate": "string (YYYY-MM-DD, required)", "membershipEndDate": "string (YYYY-MM-DD, optional)", "isActive": "boolean (default: true)", "address": "string (optional)", "emergencyContact": "string (optional)" } ``` ### UpdateMemberRequest Identisch mit `CreateMemberRequest`. ### MemberStats ```json { "totalActive": "number", "totalMembers": "number" } ``` ## Validierungsregeln ### Pflichtfelder - `firstName`: Nicht leer - `lastName`: Nicht leer - `email`: Gültige E-Mail-Adresse, eindeutig - `membershipNumber`: Nicht leer, eindeutig - `membershipStartDate`: Gültiges Datum ### Geschäftsregeln - E-Mail-Adresse muss eindeutig sein - Mitgliedsnummer muss eindeutig sein - `membershipEndDate` muss nach `membershipStartDate` liegen (falls angegeben) - Telefonnummer muss gültiges Format haben (falls angegeben) ## Fehlerbehandlung ### Validierungsfehler (422 Unprocessable Entity) ```json { "data": null, "success": false, "message": "Validation failed", "errors": [ { "field": "email", "message": "Email address is invalid", "code": "INVALID_EMAIL" }, { "field": "membershipNumber", "message": "Membership number already exists", "code": "DUPLICATE_MEMBERSHIP_NUMBER" } ], "timestamp": "2025-07-25T12:37:00Z" } ``` ### Häufige Fehlercodes | Code | Beschreibung | |------|--------------| | `MEMBER_NOT_FOUND` | Mitglied nicht gefunden | | `INVALID_EMAIL` | Ungültige E-Mail-Adresse | | `DUPLICATE_EMAIL` | E-Mail bereits vorhanden | | `DUPLICATE_MEMBERSHIP_NUMBER` | Mitgliedsnummer bereits vorhanden | | `INVALID_DATE_FORMAT` | Ungültiges Datumsformat | | `INVALID_UUID_FORMAT` | Ungültiges UUID-Format | | `MEMBERSHIP_DATE_CONFLICT` | Enddatum vor Startdatum | ## Beispiel-Workflows ### Neues Mitglied registrieren 1. **E-Mail validieren**: `GET /api/members/validate/email/{email}` 2. **Mitgliedsnummer validieren**: `GET /api/members/validate/membership-number/{membershipNumber}` 3. **Mitglied erstellen**: `POST /api/members` ### Mitglied aktualisieren 1. **Aktuelles Mitglied abrufen**: `GET /api/members/{id}` 2. **E-Mail validieren** (falls geändert): `GET /api/members/validate/email/{email}?excludeMemberId={id}` 3. **Mitglied aktualisieren**: `PUT /api/members/{id}` ### Ablaufende Mitgliedschaften verwalten 1. **Ablaufende Mitgliedschaften abrufen**: `GET /api/members/expiring-memberships?daysAhead=30` 2. **Für jedes Mitglied**: Benachrichtigung senden oder Verlängerung anbieten ## Rate Limiting - **Authentifizierte Anfragen**: 1000 Anfragen/Stunde - **Validierungs-Endpunkte**: 100 Anfragen/Minute (zusätzliches Limit) ## Caching - **GET-Anfragen**: 5 Minuten Cache (außer Validierungs-Endpunkte) - **Statistiken**: 15 Minuten Cache - **Cache-Invalidierung**: Bei POST/PUT/DELETE-Operationen --- **Letzte Aktualisierung**: 25. Juli 2025 **API-Version**: v1.0 **Controller-Version**: MemberController v1.0