meldestelle/docs/api/members-api.md
stefan 65a0084f91 docs: Migrationsplan für Projekt-Restrukturierung hinzugefügt
- Detaillierter Plan zur Migration von alter zu neuer Modulstruktur
- Umfasst Überführung von shared-kernel zu core-Modulen
- Definiert Migration von Fachdomänen zu bounded contexts:
  * master-data → masterdata-Module
  * member-management → members-Module
  * horse-registry → horses-Module
  * event-management → events-Module
- Beschreibt Verlagerung von api-gateway zu infrastructure/gateway
- Strukturiert nach Domain-driven Design Prinzipien
- Berücksichtigt Clean Architecture Layering (domain, application, infrastructure, api)
2025-07-25 13:05:42 +02:00

15 KiB

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

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

GET /api/members?activeOnly=true&limit=50&search=Schmidt
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Erfolgreiche Antwort (200 OK)

{
  "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

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

GET /api/members/123e4567-e89b-12d3-a456-426614174000
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Erfolgreiche Antwort (200 OK)

{
  "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

GET /api/members/by-membership-number/{membershipNumber}

Pfad-Parameter

Parameter Typ Beschreibung
membershipNumber string Mitgliedsnummer

Beispiel-Anfrage

GET /api/members/by-membership-number/M2024001
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

4. Mitglied nach E-Mail abrufen

GET /api/members/by-email/{email}

Pfad-Parameter

Parameter Typ Beschreibung
email string E-Mail-Adresse

Beispiel-Anfrage

GET /api/members/by-email/max.schmidt@example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

5. Mitgliederstatistiken abrufen

GET /api/members/stats

Ruft Statistiken über die Mitgliederdatenbank ab.

Erfolgreiche Antwort (200 OK)

{
  "data": {
    "totalActive": 1250,
    "totalMembers": 1380
  },
  "success": true,
  "message": null,
  "errors": [],
  "timestamp": "2025-07-25T12:37:00Z"
}

6. Neues Mitglied erstellen

POST /api/members

Erstellt ein neues Mitglied mit den bereitgestellten Daten.

Request Body

{
  "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)

{
  "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

PUT /api/members/{id}

Aktualisiert ein bestehendes Mitglied.

Pfad-Parameter

Parameter Typ Beschreibung
id UUID Eindeutige Mitglieder-ID

Request Body

{
  "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

DELETE /api/members/{id}

Löscht ein Mitglied aus dem System.

Pfad-Parameter

Parameter Typ Beschreibung
id UUID Eindeutige Mitglieder-ID

Beispiel-Anfrage

DELETE /api/members/123e4567-e89b-12d3-a456-426614174000
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Erfolgreiche Antwort (200 OK)

{
  "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

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

GET /api/members/expiring-memberships?daysAhead=14
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Erfolgreiche Antwort (200 OK)

{
  "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

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

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

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

GET /api/members/validate/email/test@example.com?excludeMemberId=123e4567-e89b-12d3-a456-426614174000
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Erfolgreiche Antwort (200 OK)

{
  "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

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)

{
  "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

{
  "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

{
  "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)

{
  "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