openapi: 3.0.3
info:
  title: RoadBoy API
  description: Backend API für die RoadBoy Schichtplanungs-App
  version: 1.0.0
  contact:
    name: RoadBoy Team

servers:
  - url: http://localhost:3000
    description: Development Server
  - url: https://api.roadboy.de
    description: Production Server

tags:
  - name: Auth
    description: Authentifizierung und Autorisierung
  - name: User
    description: Benutzerverwaltung
  - name: Availability
    description: Verfügbarkeitsverwaltung
  - name: Organization
    description: Organisationsverwaltung
  - name: SuperAdmin
    description: SuperAdmin-Verwaltung
  - name: Shifts
    description: Schichtverwaltung
  - name: Nodes
    description: Haltepunkte-Verwaltung für Schichten
  - name: Items
    description: Item-Verwaltung für Haltepunkte
  - name: API Key
    description: API Key Verwaltung für Admins
  - name: Webhooks
    description: Webhook-Verwaltung für Manager und Admins

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT Access Token
    
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API Key für externe Integrationen (nur für Admins verfügbar)

  schemas:
    # Enums
    SocialProvider:
      type: string
      enum:
        - LOCAL
        - GOOGLE
        - APPLE
        - FACEBOOK

    UserRole:
      type: string
      enum:
        - EMPLOYEE
        - MANAGER
        - ADMIN
        - SUPERADMIN

    AvailabilityStatus:
      type: string
      enum:
        - AVAILABLE
        - UNAVAILABLE
        - MAYBE

    NodeStatus:
      type: string
      enum:
        - NOT_STARTED
        - ARRIVED
        - DELIVERED
        - FAILED

    ItemStatus:
      type: string
      enum:
        - PENDING
        - LOADED
        - DELIVERED
        - MISSING

    WebhookEvent:
      type: string
      enum:
        - SHIFT_CREATED
        - SHIFT_UPDATED
        - SHIFT_DELETED
        - SHIFT_ASSIGNED
        - SHIFT_UNASSIGNED
        - AVAILABILITY_CREATED
        - AVAILABILITY_UPDATED
        - AVAILABILITY_DELETED

    WebhookAuthType:
      type: string
      enum:
        - NONE
        - BASIC_AUTH
        - API_KEY

    # Models
    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
          format: email
        name:
          type: string
        foreignId:
          type: string
          nullable: true
        personnelNumber:
          type: string
          nullable: true
        socialProvider:
          $ref: '#/components/schemas/SocialProvider'
        role:
          $ref: '#/components/schemas/UserRole'
        isAdmin:
          type: boolean
        organizationId:
          type: string
          format: uuid
        avatarUrl:
          type: string
          nullable: true
        maxWeeklyHours:
          type: integer
          description: Maximale Wochenarbeitszeit in Minuten
          default: 2400
        maxDailyHours:
          type: integer
          description: Maximale Tagesarbeitszeit in Minuten
          default: 480
        preferences:
          type: array
          items:
            type: string
          description: Schicht-Präferenzen (basierend auf Tags)
        priorityScore:
          type: integer
          minimum: 0
          maximum: 10
          nullable: true
          description: Admin-Präferenz (0-10, nur für Admin/Manager sichtbar)
        isEmailVerified:
          type: boolean
          default: false
          description: E-Mail-Verifizierungsstatus
        emailVerifiedAt:
          type: string
          format: date-time
          nullable: true
          description: Zeitpunkt der E-Mail-Verifizierung
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    Organization:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        slug:
          type: string
        address:
          type: string
          nullable: true
        website:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    Availability:
      type: object
      properties:
        id:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        date:
          type: string
          format: date-time
        startTime:
          type: string
          format: date-time
        endTime:
          type: string
          format: date-time
        status:
          $ref: '#/components/schemas/AvailabilityStatus'
        notes:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    Shift:
      type: object
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        description:
          type: string
          nullable: true
        location:
          type: string
          nullable: true
        startTime:
          type: string
          format: date-time
        duration:
          type: integer
          description: Dauer in Minuten
        tags:
          type: array
          items:
            type: string
        resources:
          type: array
          items:
            type: string
          description: Ressourcen für die Tour (z.B. Fahrzeuge, Geräte)
        foreignId:
          type: string
          nullable: true
          description: Eindeutige Foreign-ID für externe Systeme
        organizationId:
          type: string
          format: uuid
        createdBy:
          type: string
          format: uuid
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        creator:
          type: object
          properties:
            id:
              type: string
            name:
              type: string
            email:
              type: string
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/ShiftAssignment'

    ShiftAssignment:
      type: object
      properties:
        id:
          type: string
          format: uuid
        shiftId:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        assignedBy:
          type: string
          format: uuid
        assignedAt:
          type: string
          format: date-time
        user:
          type: object
          properties:
            id:
              type: string
            name:
              type: string
            email:
              type: string
            avatarUrl:
              type: string
              nullable: true
        assigner:
          type: object
          nullable: true
          properties:
            id:
              type: string
            name:
              type: string

    Node:
      type: object
      properties:
        id:
          type: string
          format: uuid
        shiftId:
          type: string
          format: uuid
        name:
          type: string
        address:
          type: string
          nullable: true
        order:
          type: integer
        coordinates:
          type: object
          nullable: true
          properties:
            lat:
              type: number
              format: double
            lng:
              type: number
              format: double
        plannedDeliveryTime:
          type: string
          format: date-time
          nullable: true
        earliestDeliveryTime:
          type: string
          format: date-time
          nullable: true
        latestDeliveryTime:
          type: string
          format: date-time
          nullable: true
        description:
          type: string
          nullable: true
        status:
          $ref: '#/components/schemas/NodeStatus'
        actualDeliveryTime:
          type: string
          format: date-time
          nullable: true
        imageUrl:
          type: string
          nullable: true
        foreignId:
          type: string
          nullable: true
          description: Eindeutige Foreign-ID für externe Systeme
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        items:
          type: array
          items:
            $ref: '#/components/schemas/Item'

    Item:
      type: object
      properties:
        id:
          type: string
          format: uuid
        nodeId:
          type: string
          format: uuid
        name:
          type: string
        quantity:
          type: integer
        info:
          type: string
          nullable: true
        recipient:
          type: string
          nullable: true
        status:
          $ref: '#/components/schemas/ItemStatus'
        foreignId:
          type: string
          nullable: true
          description: Eindeutige Foreign-ID für externe Systeme
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    # Request/Response Types
    RegisterRequest:
      type: object
      required:
        - email
        - password
        - name
        - organizationSlug
      properties:
        email:
          type: string
          format: email
        password:
          type: string
          minLength: 6
        name:
          type: string
        organizationSlug:
          type: string
        foreignId:
          type: string
          nullable: true
        personnelNumber:
          type: string
          nullable: true

    LoginRequest:
      type: object
      required:
        - email
        - password
      properties:
        email:
          type: string
          format: email
        password:
          type: string

    AuthResponse:
      type: object
      properties:
        user:
          $ref: '#/components/schemas/User'
        accessToken:
          type: string
        refreshToken:
          type: string

    RefreshTokenRequest:
      type: object
      required:
        - refreshToken
      properties:
        refreshToken:
          type: string

    RequestPasswordResetRequest:
      type: object
      required:
        - email
      properties:
        email:
          type: string
          format: email

    ResetPasswordRequest:
      type: object
      required:
        - token
        - password
      properties:
        token:
          type: string
        password:
          type: string
          minLength: 6

    UpdateProfileRequest:
      type: object
      properties:
        name:
          type: string
        maxWeeklyHours:
          type: integer
        maxDailyHours:
          type: integer

    ChangePasswordRequest:
      type: object
      required:
        - currentPassword
        - newPassword
      properties:
        currentPassword:
          type: string
        newPassword:
          type: string
          minLength: 6

    UpdatePreferencesRequest:
      type: object
      required:
        - preferences
      properties:
        preferences:
          type: array
          items:
            type: string

    UpdateUserPreferencesRequest:
      type: object
      properties:
        preferences:
          type: array
          items:
            type: string
        priorityScore:
          type: integer
          minimum: 0
          maximum: 10

    CreateAvailabilityRequest:
      type: object
      required:
        - date
        - startTime
        - endTime
      properties:
        date:
          type: string
          format: date-time
        startTime:
          type: string
          format: date-time
        endTime:
          type: string
          format: date-time
        status:
          $ref: '#/components/schemas/AvailabilityStatus'
        notes:
          type: string

    UpdateAvailabilityRequest:
      type: object
      properties:
        date:
          type: string
          format: date-time
        startTime:
          type: string
          format: date-time
        endTime:
          type: string
          format: date-time
        status:
          $ref: '#/components/schemas/AvailabilityStatus'
        notes:
          type: string

    CreateShiftRequest:
      type: object
      required:
        - title
        - startTime
        - duration
      properties:
        title:
          type: string
        description:
          type: string
        location:
          type: string
        startTime:
          type: string
          format: date-time
        duration:
          type: integer
          description: Dauer in Minuten
        tags:
          type: array
          items:
            type: string
        resources:
          type: array
          items:
            type: string
        foreignId:
          type: string
          description: Eindeutige Foreign-ID für externe Systeme

    UpdateShiftRequest:
      type: object
      properties:
        title:
          type: string
        description:
          type: string
        location:
          type: string
        startTime:
          type: string
          format: date-time
        duration:
          type: integer
        tags:
          type: array
          items:
            type: string
        resources:
          type: array
          items:
            type: string
        foreignId:
          type: string
          description: Eindeutige Foreign-ID für externe Systeme

    AssignUserRequest:
      type: object
      required:
        - userId
      properties:
        userId:
          type: string
          format: uuid

    CreateOrganizationUserRequest:
      type: object
      required:
        - email
        - name
        - password
      properties:
        email:
          type: string
          format: email
        name:
          type: string
        password:
          type: string
          minLength: 6
        foreignId:
          type: string
        personnelNumber:
          type: string
        role:
          $ref: '#/components/schemas/UserRole'
        isAdmin:
          type: boolean

    UpdateOrganizationUserRequest:
      type: object
      properties:
        email:
          type: string
          format: email
        name:
          type: string
        foreignId:
          type: string
        personnelNumber:
          type: string
        role:
          $ref: '#/components/schemas/UserRole'
        isAdmin:
          type: boolean
        maxWeeklyHours:
          type: integer
        maxDailyHours:
          type: integer

    UpdateOrganizationRequest:
      type: object
      properties:
        name:
          type: string
        slug:
          type: string
        address:
          type: string
        website:
          type: string

    CreateOrganizationRequest:
      type: object
      required:
        - name
        - slug
      properties:
        name:
          type: string
        slug:
          type: string
        address:
          type: string
        website:
          type: string

    ApiKeyStatus:
      type: object
      properties:
        hasApiKey:
          type: boolean
          description: Gibt an, ob der Benutzer einen aktiven API Key hat
        createdAt:
          type: string
          format: date-time
          description: Zeitpunkt der Erstellung des API Keys
        lastUsedAt:
          type: string
          format: date-time
          nullable: true
          description: Zeitpunkt der letzten Verwendung des API Keys

    ApiKeyResponse:
      type: object
      properties:
        apiKey:
          type: string
          description: Der generierte API Key (wird nur einmal angezeigt, mit Prefix rbk_)
          example: rbk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0
        createdAt:
          type: string
          format: date-time
          description: Zeitpunkt der Erstellung

    Error:
      type: object
      properties:
        message:
          type: string
        errors:
          type: array
          items:
            type: object

    Webhook:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        name:
          type: string
          description: Name des Webhooks
        url:
          type: string
          format: uri
          description: URL an die der Webhook gesendet wird
        secret:
          type: string
          nullable: true
          description: Optionaler Secret für HMAC-Signatur
        events:
          type: array
          items:
            $ref: '#/components/schemas/WebhookEvent'
          description: Liste der Events, die den Webhook triggern
        isActive:
          type: boolean
          description: Ob der Webhook aktiv ist
        authType:
          $ref: '#/components/schemas/WebhookAuthType'
          description: Authentifizierungstyp für den Webhook
        basicAuthUsername:
          type: string
          nullable: true
          description: Benutzername für Basic Authentication
        basicAuthPassword:
          type: string
          nullable: true
          description: Passwort für Basic Authentication
        apiKeyHeader:
          type: string
          nullable: true
          description: Header-Name für API Key (z.B. "X-API-Key")
        apiKeyValue:
          type: string
          nullable: true
          description: API Key Wert
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    WebhookDelivery:
      type: object
      properties:
        id:
          type: string
          format: uuid
        webhookId:
          type: string
          format: uuid
        event:
          $ref: '#/components/schemas/WebhookEvent'
        payload:
          type: string
          description: JSON-String des Payloads
        responseStatus:
          type: integer
          nullable: true
          description: HTTP-Status der Response
        attemptCount:
          type: integer
          description: Anzahl der Versuche
        nextRetryAt:
          type: string
          format: date-time
          nullable: true
          description: Nächster Retry-Zeitpunkt
        lastError:
          type: string
          nullable: true
          description: Fehlermeldung vom letzten Versuch
        succeededAt:
          type: string
          format: date-time
          nullable: true
          description: Zeitpunkt des erfolgreichen Versands
        failedAt:
          type: string
          format: date-time
          nullable: true
          description: Zeitpunkt nach maximal 7 fehlgeschlagenen Versuchen
        createdAt:
          type: string
          format: date-time

paths:
  /health:
    get:
      summary: Health Check
      description: Überprüft den Server-Status
      responses:
        '200':
          description: Server ist gesund
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok
                  timestamp:
                    type: string
                    format: date-time

  # Auth Endpoints
  /api/auth/register:
    post:
      tags:
        - Auth
      summary: Registrierung eines neuen Benutzers
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterRequest'
      responses:
        '201':
          description: Benutzer erfolgreich registriert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'
        '400':
          description: Ungültige Eingabe
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/auth/login:
    post:
      tags:
        - Auth
      summary: Benutzer-Login
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
      responses:
        '200':
          description: Login erfolgreich
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'
        '401':
          description: Ungültige Anmeldedaten
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/auth/refresh:
    post:
      tags:
        - Auth
      summary: Refresh Access Token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefreshTokenRequest'
      responses:
        '200':
          description: Token erfolgreich erneuert
          content:
            application/json:
              schema:
                type: object
                properties:
                  accessToken:
                    type: string
        '401':
          description: Ungültiger Refresh Token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/auth/logout:
    post:
      tags:
        - Auth
      summary: Benutzer-Logout
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefreshTokenRequest'
      responses:
        '200':
          description: Logout erfolgreich
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/auth/request-reset:
    post:
      tags:
        - Auth
      summary: Passwort-Reset anfordern
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RequestPasswordResetRequest'
      responses:
        '200':
          description: Reset-E-Mail gesendet
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/auth/reset-password:
    post:
      tags:
        - Auth
      summary: Passwort zurücksetzen
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResetPasswordRequest'
      responses:
        '200':
          description: Passwort erfolgreich zurückgesetzt
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/auth/verify-email:
    get:
      tags:
        - Auth
      summary: E-Mail-Adresse verifizieren
      description: Verifiziert die E-Mail-Adresse eines Benutzers mit dem Token aus der Verifizierungs-E-Mail
      parameters:
        - name: token
          in: query
          required: true
          schema:
            type: string
          description: Der Verifizierungs-Token aus der E-Mail
      responses:
        '200':
          description: E-Mail erfolgreich verifiziert
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '400':
          description: Ungültiger oder abgelaufener Token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/auth/resend-verification:
    post:
      tags:
        - Auth
      summary: Verifizierungs-E-Mail erneut senden
      description: Sendet eine neue Verifizierungs-E-Mail an den Benutzer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - email
              properties:
                email:
                  type: string
                  format: email
      responses:
        '200':
          description: Verifizierungs-E-Mail wurde gesendet
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '400':
          description: E-Mail bereits verifiziert oder ungültige E-Mail
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/auth/google:
    get:
      tags:
        - Auth
      summary: Google OAuth Login
      description: Initiiert den Google OAuth Flow
      responses:
        '302':
          description: Weiterleitung zu Google

  /api/auth/google/callback:
    get:
      tags:
        - Auth
      summary: Google OAuth Callback
      responses:
        '200':
          description: Login erfolgreich
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'

  /api/auth/apple:
    post:
      tags:
        - Auth
      summary: Apple OAuth Login
      responses:
        '200':
          description: Login erfolgreich
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'

  /api/auth/apple/callback:
    post:
      tags:
        - Auth
      summary: Apple OAuth Callback
      responses:
        '200':
          description: Login erfolgreich
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'

  /api/auth/facebook:
    get:
      tags:
        - Auth
      summary: Facebook OAuth Login
      responses:
        '302':
          description: Weiterleitung zu Facebook

  /api/auth/facebook/callback:
    get:
      tags:
        - Auth
      summary: Facebook OAuth Callback
      responses:
        '200':
          description: Login erfolgreich
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'

  # API Key Endpoints
  /api/apikey/generate:
    post:
      tags:
        - API Key
      summary: Neuen API Key generieren
      description: Generiert einen neuen API Key für den authentifizierten Admin. Überschreibt einen bestehenden Key falls vorhanden. Der Key wird nur einmal angezeigt.
      security:
        - BearerAuth: []
      responses:
        '201':
          description: API Key erfolgreich generiert
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  data:
                    $ref: '#/components/schemas/ApiKeyResponse'
        '403':
          description: Keine Admin-Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/apikey/status:
    get:
      tags:
        - API Key
      summary: API Key Status abrufen
      description: Zeigt ob der authentifizierte Admin einen aktiven API Key hat (ohne den Key preiszugeben)
      security:
        - BearerAuth: []
      responses:
        '200':
          description: Status erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  data:
                    $ref: '#/components/schemas/ApiKeyStatus'
        '403':
          description: Keine Admin-Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/apikey/revoke:
    delete:
      tags:
        - API Key
      summary: API Key widerrufen
      description: Widerruft (löscht) den API Key des authentifizierten Admins
      security:
        - BearerAuth: []
      responses:
        '200':
          description: API Key erfolgreich widerrufen
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '403':
          description: Keine Admin-Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  # User Endpoints
  /api/user/profile:
    get:
      tags:
        - User
      summary: Benutzerprofil abrufen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      responses:
        '200':
          description: Profil erfolgreich abgerufen
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '401':
          description: Nicht authentifiziert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    put:
      tags:
        - User
      summary: Benutzerprofil aktualisieren
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateProfileRequest'
      responses:
        '200':
          description: Profil erfolgreich aktualisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'

  /api/user/avatar:
    post:
      tags:
        - User
      summary: Avatar hochladen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                avatar:
                  type: string
                  format: binary
      responses:
        '200':
          description: Avatar erfolgreich hochgeladen
          content:
            application/json:
              schema:
                type: object
                properties:
                  avatarUrl:
                    type: string

  /api/user/change-password:
    post:
      tags:
        - User
      summary: Passwort ändern
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChangePasswordRequest'
      responses:
        '200':
          description: Passwort erfolgreich geändert
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/user/available-tags:
    get:
      tags:
        - User
      summary: Verfügbare Schicht-Tags abrufen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      responses:
        '200':
          description: Tags erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: object
                properties:
                  tags:
                    type: array
                    items:
                      type: string

  /api/user/profile/preferences:
    put:
      tags:
        - User
      summary: Eigene Präferenzen aktualisieren
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdatePreferencesRequest'
      responses:
        '200':
          description: Präferenzen erfolgreich aktualisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'

  /api/user/{userId}/preferences:
    put:
      tags:
        - User
      summary: Benutzer-Präferenzen aktualisieren (Manager/Admin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateUserPreferencesRequest'
      responses:
        '200':
          description: Präferenzen erfolgreich aktualisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'

  # Availability Endpoints
  /api/availability:
    get:
      tags:
        - Availability
      summary: Verfügbarkeiten abrufen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: startDate
          in: query
          schema:
            type: string
            format: date-time
        - name: endDate
          in: query
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Verfügbarkeiten erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Availability'

    post:
      tags:
        - Availability
      summary: Verfügbarkeit erstellen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAvailabilityRequest'
      responses:
        '201':
          description: Verfügbarkeit erfolgreich erstellt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Availability'

  /api/availability/month/{year}/{month}:
    get:
      tags:
        - Availability
      summary: Verfügbarkeiten für einen Monat abrufen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: year
          in: path
          required: true
          schema:
            type: integer
        - name: month
          in: path
          required: true
          schema:
            type: integer
            minimum: 1
            maximum: 12
      responses:
        '200':
          description: Verfügbarkeiten erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Availability'

  /api/availability/{id}:
    put:
      tags:
        - Availability
      summary: Verfügbarkeit aktualisieren
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateAvailabilityRequest'
      responses:
        '200':
          description: Verfügbarkeit erfolgreich aktualisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Availability'

    delete:
      tags:
        - Availability
      summary: Verfügbarkeit löschen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Verfügbarkeit erfolgreich gelöscht
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/availability/user/{userId}:
    get:
      tags:
        - Availability
      summary: Verfügbarkeiten eines Benutzers abrufen (Manager/Admin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: startDate
          in: query
          schema:
            type: string
            format: date-time
        - name: endDate
          in: query
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Verfügbarkeiten erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Availability'
        '403':
          description: Keine Manager/Admin-Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    post:
      tags:
        - Availability
      summary: Verfügbarkeit für einen Benutzer erstellen (Manager/Admin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAvailabilityRequest'
      responses:
        '201':
          description: Verfügbarkeit erfolgreich erstellt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Availability'
        '403':
          description: Keine Manager/Admin-Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/availability/{id}/manage:
    put:
      tags:
        - Availability
      summary: Verfügbarkeit eines Benutzers aktualisieren (Manager/Admin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateAvailabilityRequest'
      responses:
        '200':
          description: Verfügbarkeit erfolgreich aktualisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Availability'
        '403':
          description: Keine Manager/Admin-Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    delete:
      tags:
        - Availability
      summary: Verfügbarkeit eines Benutzers löschen (Manager/Admin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Verfügbarkeit erfolgreich gelöscht
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '403':
          description: Keine Manager/Admin-Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  # Organization Endpoints
  /api/organization:
    get:
      tags:
        - Organization
      summary: Eigene Organisation abrufen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      responses:
        '200':
          description: Organisation erfolgreich abgerufen
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'

    put:
      tags:
        - Organization
      summary: Organisation aktualisieren (nur Admins)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOrganizationRequest'
      responses:
        '200':
          description: Organisation erfolgreich aktualisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'

  /api/organization/users:
    get:
      tags:
        - Organization
      summary: Alle Benutzer der Organisation abrufen (Manager/Admin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      responses:
        '200':
          description: Benutzer erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'

    post:
      tags:
        - Organization
      summary: Benutzer in Organisation erstellen (nur Admins)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrganizationUserRequest'
      responses:
        '201':
          description: Benutzer erfolgreich erstellt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'

  /api/organization/users/{userId}:
    put:
      tags:
        - Organization
      summary: Benutzer aktualisieren (nur Admins)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOrganizationUserRequest'
      responses:
        '200':
          description: Benutzer erfolgreich aktualisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'

    delete:
      tags:
        - Organization
      summary: Benutzer löschen (nur Admins)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Benutzer erfolgreich gelöscht
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/organization/users/{userId}/verify:
    post:
      tags:
        - Organization
      summary: Benutzer manuell verifizieren (nur Admins)
      description: Verifiziert die E-Mail-Adresse eines Benutzers manuell, ohne dass dieser den Verifizierungs-Link anklicken muss
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Benutzer erfolgreich verifiziert
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      user:
                        $ref: '#/components/schemas/User'
        '400':
          description: Benutzer bereits verifiziert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Keine Admin-Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Benutzer nicht gefunden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  # Shift Endpoints
  /api/shifts:
    get:
      tags:
        - Shifts
      summary: Alle Schichten abrufen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: startDate
          in: query
          schema:
            type: string
            format: date-time
        - name: endDate
          in: query
          schema:
            type: string
            format: date-time
        - name: tags
          in: query
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: Schichten erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Shift'

    post:
      tags:
        - Shifts
      summary: Schicht erstellen (Manager/Admin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateShiftRequest'
      responses:
        '201':
          description: Schicht erfolgreich erstellt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Shift'

  /api/shifts/{id}:
    get:
      tags:
        - Shifts
      summary: Schicht nach ID abrufen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Schicht erfolgreich abgerufen
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Shift'

    put:
      tags:
        - Shifts
      summary: Schicht aktualisieren (Manager/Admin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateShiftRequest'
      responses:
        '200':
          description: Schicht erfolgreich aktualisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Shift'

    delete:
      tags:
        - Shifts
      summary: Schicht löschen (Manager/Admin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Schicht erfolgreich gelöscht
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/shifts/assigned/me:
    get:
      tags:
        - Shifts
      summary: Zugewiesene Schichten des eingeloggten Benutzers abrufen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      responses:
        '200':
          description: Zugewiesene Schichten erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Shift'

  /api/shifts/available/me:
    get:
      tags:
        - Shifts
      summary: Verfügbare Schichten für eingeloggten Mitarbeiter abrufen
      description: Ruft alle Schichten ab, für die der eingeloggte Mitarbeiter basierend auf seinen Verfügbarkeiten in Frage kommt
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      responses:
        '200':
          description: Verfügbare Schichten erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Shift'

  /api/shifts/{id}/self-assign:
    post:
      tags:
        - Shifts
      summary: Selbst einer Schicht zuweisen
      description: Erlaubt einem Mitarbeiter, sich selbst einer Schicht zuzuweisen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Erfolgreich zur Schicht zugewiesen
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ShiftAssignment'
        '400':
          description: Ungültige Anfrage oder Schicht bereits zugewiesen
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Schicht nicht gefunden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/shifts/{id}/self-unassign:
    delete:
      tags:
        - Shifts
      summary: Selbst von einer Schicht abmelden
      description: Erlaubt einem Mitarbeiter, sich selbst von einer zugewiesenen Schicht abzumelden
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Erfolgreich von der Schicht abgemeldet
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '400':
          description: Ungültige Anfrage oder nicht zur Schicht zugewiesen
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Schicht nicht gefunden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/shifts/{shiftId}/available-users:
    get:
      tags:
        - Shifts
      summary: Verfügbare Mitarbeiter für eine Schicht abrufen (Manager/Admin)
      description: Ruft alle Mitarbeiter ab, die basierend auf ihren Verfügbarkeiten für eine bestimmte Schicht in Frage kommen
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: shiftId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Verfügbare Mitarbeiter erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
        '403':
          description: Keine Manager/Admin-Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Schicht nicht gefunden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/shifts/{id}/assign:
    post:
      tags:
        - Shifts
      summary: Benutzer einer Schicht zuweisen (Manager/Admin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssignUserRequest'
      responses:
        '200':
          description: Benutzer erfolgreich zugewiesen
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ShiftAssignment'

  /api/shifts/{id}/assign/{userId}:
    delete:
      tags:
        - Shifts
      summary: Benutzer von Schicht entfernen (Manager/Admin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Zuweisung erfolgreich entfernt
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  # SuperAdmin Endpoints
  /api/superadmin/organizations:
    get:
      tags:
        - SuperAdmin
      summary: Alle Organisationen abrufen (SuperAdmin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      responses:
        '200':
          description: Organisationen erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Organization'

    post:
      tags:
        - SuperAdmin
      summary: Organisation erstellen (SuperAdmin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrganizationRequest'
      responses:
        '201':
          description: Organisation erfolgreich erstellt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'

  /api/superadmin/organizations/{organizationId}:
    get:
      tags:
        - SuperAdmin
      summary: Organisation nach ID abrufen (SuperAdmin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: organizationId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Organisation erfolgreich abgerufen
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'

    put:
      tags:
        - SuperAdmin
      summary: Organisation aktualisieren (SuperAdmin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: organizationId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOrganizationRequest'
      responses:
        '200':
          description: Organisation erfolgreich aktualisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'

    delete:
      tags:
        - SuperAdmin
      summary: Organisation löschen (SuperAdmin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: organizationId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Organisation erfolgreich gelöscht
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/superadmin/organizations/{organizationId}/users:
    get:
      tags:
        - SuperAdmin
      summary: Benutzer einer Organisation abrufen (SuperAdmin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: organizationId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Benutzer erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'

  /api/superadmin/organizations/{organizationId}/users/{userId}:
    put:
      tags:
        - SuperAdmin
      summary: Benutzer aktualisieren (SuperAdmin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: organizationId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOrganizationUserRequest'
      responses:
        '200':
          description: Benutzer erfolgreich aktualisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'

    delete:
      tags:
        - SuperAdmin
      summary: Benutzer löschen (SuperAdmin)
      security:
        - BearerAuth: []
        - ApiKeyAuth: []
      parameters:
        - name: organizationId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Benutzer erfolgreich gelöscht
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/shifts/{shiftId}/nodes:
    post:
      tags:
        - Nodes
      summary: Node für Schicht erstellen
      description: Erstellt einen neuen Haltepunkt für eine Schicht (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: shiftId
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - order
              properties:
                name:
                  type: string
                address:
                  type: string
                order:
                  type: integer
                coordinates:
                  type: object
                  properties:
                    lat:
                      type: number
                    lng:
                      type: number
                plannedDeliveryTime:
                  type: string
                  format: date-time
                earliestDeliveryTime:
                  type: string
                  format: date-time
                latestDeliveryTime:
                  type: string
                  format: date-time
                description:
                  type: string
                status:
                  $ref: '#/components/schemas/NodeStatus'
                imageUrl:
                  type: string
                foreignId:
                  type: string
                  description: Eindeutige Foreign-ID für externe Systeme
      responses:
        '201':
          description: Node erfolgreich erstellt
          content:
            application/json:
              schema:
                type: object
                properties:
                  node:
                    $ref: '#/components/schemas/Node'
    get:
      tags:
        - Nodes
      summary: Alle Nodes einer Schicht abrufen
      description: Ruft alle Haltepunkte einer Schicht ab
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: shiftId
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Nodes erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: object
                properties:
                  nodes:
                    type: array
                    items:
                      $ref: '#/components/schemas/Node'

  /api/nodes/{id}:
    get:
      tags:
        - Nodes
      summary: Einzelnen Node abrufen
      description: Ruft einen einzelnen Haltepunkt ab
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Node erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: object
                properties:
                  node:
                    $ref: '#/components/schemas/Node'
    patch:
      tags:
        - Nodes
      summary: Node aktualisieren
      description: Aktualisiert einen Haltepunkt (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                address:
                  type: string
                order:
                  type: integer
                coordinates:
                  type: object
                  properties:
                    lat:
                      type: number
                    lng:
                      type: number
                status:
                  $ref: '#/components/schemas/NodeStatus'
                foreignId:
                  type: string
                  description: Eindeutige Foreign-ID für externe Systeme
      responses:
        '200':
          description: Node erfolgreich aktualisiert
          content:
            application/json:
              schema:
                type: object
                properties:
                  node:
                    $ref: '#/components/schemas/Node'
    delete:
      tags:
        - Nodes
      summary: Node löschen
      description: Löscht einen Haltepunkt (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Node erfolgreich gelöscht
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/nodes/{id}/upload-image:
    post:
      tags:
        - Nodes
      summary: Bild für Node hochladen
      description: Lädt ein Bild für einen Haltepunkt hoch (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                image:
                  type: string
                  format: binary
      responses:
        '200':
          description: Bild erfolgreich hochgeladen
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  node:
                    $ref: '#/components/schemas/Node'

  /api/nodes/{nodeId}/items:
    post:
      tags:
        - Items
      summary: Item für Node erstellen
      description: Erstellt ein neues Item für einen Haltepunkt (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: nodeId
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
                quantity:
                  type: integer
                info:
                  type: string
                recipient:
                  type: string
                status:
                  $ref: '#/components/schemas/ItemStatus'
                foreignId:
                  type: string
                  description: Eindeutige Foreign-ID für externe Systeme
      responses:
        '201':
          description: Item erfolgreich erstellt
          content:
            application/json:
              schema:
                type: object
                properties:
                  item:
                    $ref: '#/components/schemas/Item'
    get:
      tags:
        - Items
      summary: Alle Items eines Nodes abrufen
      description: Ruft alle Items eines Haltepunkts ab
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: nodeId
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Items erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Item'

  /api/items/{id}:
    patch:
      tags:
        - Items
      summary: Item aktualisieren
      description: Aktualisiert ein Item (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                quantity:
                  type: integer
                info:
                  type: string
                recipient:
                  type: string
                status:
                  $ref: '#/components/schemas/ItemStatus'
                foreignId:
                  type: string
                  description: Eindeutige Foreign-ID für externe Systeme
      responses:
        '200':
          description: Item erfolgreich aktualisiert
          content:
            application/json:
              schema:
                type: object
                properties:
                  item:
                    $ref: '#/components/schemas/Item'
    delete:
      tags:
        - Items
      summary: Item löschen
      description: Löscht ein Item (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Item erfolgreich gelöscht
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/webhooks:
    get:
      tags:
        - Webhooks
      summary: Alle Webhooks abrufen
      description: Ruft alle Webhooks der Organisation ab (nur Manager/Admin)
      security:
        - BearerAuth: []
      responses:
        '200':
          description: Webhooks erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      webhooks:
                        type: array
                        items:
                          $ref: '#/components/schemas/Webhook'
                      count:
                        type: integer

    post:
      tags:
        - Webhooks
      summary: Neuen Webhook erstellen
      description: Erstellt einen neuen Webhook (nur Manager/Admin)
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - url
                - events
              properties:
                name:
                  type: string
                url:
                  type: string
                  format: uri
                secret:
                  type: string
                events:
                  type: array
                  items:
                    $ref: '#/components/schemas/WebhookEvent'
                isActive:
                  type: boolean
                authType:
                  $ref: '#/components/schemas/WebhookAuthType'
                basicAuthUsername:
                  type: string
                  description: Benutzername für Basic Authentication (nur wenn authType = BASIC_AUTH)
                basicAuthPassword:
                  type: string
                  description: Passwort für Basic Authentication (nur wenn authType = BASIC_AUTH)
                apiKeyHeader:
                  type: string
                  description: Header-Name für API Key (nur wenn authType = API_KEY)
                apiKeyValue:
                  type: string
                  description: API Key Wert (nur wenn authType = API_KEY)
      responses:
        '201':
          description: Webhook erfolgreich erstellt
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      webhook:
                        $ref: '#/components/schemas/Webhook'

  /api/webhooks/{id}:
    get:
      tags:
        - Webhooks
      summary: Webhook abrufen
      description: Ruft einen einzelnen Webhook ab (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Webhook erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      webhook:
                        $ref: '#/components/schemas/Webhook'
        '403':
          description: Keine Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Webhook nicht gefunden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    put:
      tags:
        - Webhooks
      summary: Webhook aktualisieren
      description: Aktualisiert einen Webhook (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                url:
                  type: string
                  format: uri
                secret:
                  type: string
                events:
                  type: array
                  items:
                    $ref: '#/components/schemas/WebhookEvent'
                isActive:
                  type: boolean
                authType:
                  $ref: '#/components/schemas/WebhookAuthType'
                basicAuthUsername:
                  type: string
                  description: Benutzername für Basic Authentication (nur wenn authType = BASIC_AUTH)
                basicAuthPassword:
                  type: string
                  description: Passwort für Basic Authentication (nur wenn authType = BASIC_AUTH)
                apiKeyHeader:
                  type: string
                  description: Header-Name für API Key (nur wenn authType = API_KEY)
                apiKeyValue:
                  type: string
                  description: API Key Wert (nur wenn authType = API_KEY)
      responses:
        '200':
          description: Webhook erfolgreich aktualisiert
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      webhook:
                        $ref: '#/components/schemas/Webhook'

    delete:
      tags:
        - Webhooks
      summary: Webhook löschen
      description: Löscht einen Webhook (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Webhook erfolgreich gelöscht
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '403':
          description: Keine Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Webhook nicht gefunden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/webhooks/{id}/deliveries:
    get:
      tags:
        - Webhooks
      summary: Webhook-Deliveries abrufen
      description: Ruft die Delivery-Historie eines Webhooks ab (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            default: 50
      responses:
        '200':
          description: Deliveries erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      deliveries:
                        type: array
                        items:
                          $ref: '#/components/schemas/WebhookDelivery'
                      count:
                        type: integer

  /api/webhooks/{id}/deliveries/{deliveryId}:
    delete:
      tags:
        - Webhooks
      summary: Webhook-Delivery löschen
      description: Löscht eine einzelne Webhook-Delivery aus der Historie (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: Webhook ID
        - name: deliveryId
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: Delivery ID
      responses:
        '200':
          description: Delivery erfolgreich gelöscht
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '403':
          description: Keine Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Webhook oder Delivery nicht gefunden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/webhooks/{id}/test:
    post:
      tags:
        - Webhooks
      summary: Test-Webhook senden
      description: Sendet einen Test-Webhook (nur Manager/Admin)
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Test-Webhook wurde gesendet
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      delivery:
                        $ref: '#/components/schemas/WebhookDelivery'
        '403':
          description: Keine Berechtigung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Webhook nicht gefunden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
