openapi: 3.0.3
info:
  title: Global Travel Monitor Plugin Domain API
  description: |
    REST API zur programmatischen Verwaltung erlaubter Domains für das
    Global Travel Monitor Plugin. Ermöglicht Einzel- und Massenoperationen
    für Domain-Verwaltung.
  version: 1.0.0
  contact:
    name: Global Travel Monitor Support

servers:
  - url: https://api.global-travel-monitor.de/v1/plugin/gtm
    description: Produktionsserver
  - url: https://global-travel-monitor.eu/api/v1/plugin/gtm
    description: Alternativer Server

security:
  - PluginKeyAuth: []

tags:
  - name: Domains
    description: Domain-Verwaltung (CRUD + Bulk)

paths:
  /domains:
    get:
      tags: [Domains]
      summary: Domains auflisten
      description: |
        Gibt eine paginierte Liste aller registrierten Domains zurück.
        Unterstützt Filterung nach Aktiv-Status und Volltextsuche.
      parameters:
        - name: per_page
          in: query
          schema:
            type: integer
            default: 50
            minimum: 1
            maximum: 200
          description: Einträge pro Seite
        - name: page
          in: query
          schema:
            type: integer
            default: 1
            minimum: 1
          description: Seitennummer
        - name: search
          in: query
          schema:
            type: string
            maxLength: 255
          description: Volltextsuche im Domain-Namen
        - name: is_active
          in: query
          schema:
            type: boolean
          description: "Filter: nur aktive (true) oder inaktive (false) Domains"
      responses:
        "200":
          description: Paginierte Domain-Liste
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Domain"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/TooManyRequests"

    post:
      tags: [Domains]
      summary: Einzelne Domain hinzufügen
      description: |
        Fügt eine neue Domain hinzu. Die Domain wird automatisch normalisiert
        (Protokoll, www, Pfade und Ports werden entfernt).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [domain]
              properties:
                domain:
                  type: string
                  maxLength: 255
                  description: "Die Domain (z.B. example.com)"
                  example: "neue-website.de"
                is_active:
                  type: boolean
                  default: true
                  description: Aktiv-Status
      responses:
        "201":
          description: Domain erfolgreich erstellt
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Domain"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "409":
          description: Domain bereits registriert
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          $ref: "#/components/responses/ValidationError"
        "429":
          $ref: "#/components/responses/TooManyRequests"

  /domains/bulk:
    post:
      tags: [Domains]
      summary: Domains im Bulk importieren
      description: |
        Importiert bis zu 1.000 Domains in einem Aufruf.
        Bereits vorhandene Domains werden übersprungen, ungültige Domains
        werden gemeldet aber nicht importiert.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [domains]
              properties:
                domains:
                  type: array
                  minItems: 1
                  maxItems: 1000
                  items:
                    type: string
                    maxLength: 255
                  description: Array von Domain-Strings
                  example: ["website1.de", "website2.com", "app.website3.de"]
      responses:
        "201":
          description: Bulk-Import Ergebnis
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      created:
                        type: array
                        items:
                          $ref: "#/components/schemas/Domain"
                        description: Erfolgreich erstellte Domains
                      skipped:
                        type: array
                        items:
                          type: string
                        description: Bereits vorhandene Domains (übersprungen)
                      invalid:
                        type: array
                        items:
                          type: string
                        description: Ungültige Domain-Strings
                  meta:
                    type: object
                    properties:
                      created_count:
                        type: integer
                      skipped_count:
                        type: integer
                      invalid_count:
                        type: integer
        "401":
          $ref: "#/components/responses/Unauthorized"
        "422":
          $ref: "#/components/responses/ValidationError"
        "429":
          $ref: "#/components/responses/TooManyRequests"

    delete:
      tags: [Domains]
      summary: Domains im Bulk löschen
      description: |
        Löscht bis zu 1.000 Domains anhand ihrer UUIDs.
        Es muss mindestens eine Domain verbleiben.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [uuids]
              properties:
                uuids:
                  type: array
                  minItems: 1
                  maxItems: 1000
                  items:
                    type: string
                    format: uuid
                  description: Array von Domain-UUIDs
                  example:
                    - "550e8400-e29b-41d4-a716-446655440000"
                    - "660e8400-e29b-41d4-a716-446655440001"
      responses:
        "200":
          description: Bulk-Löschung erfolgreich
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      deleted_count:
                        type: integer
                        description: Anzahl gelöschter Domains
        "401":
          $ref: "#/components/responses/Unauthorized"
        "422":
          description: Mindestens eine Domain muss verbleiben
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          $ref: "#/components/responses/TooManyRequests"

  /domains/{uuid}:
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: Eindeutige UUID der Domain

    get:
      tags: [Domains]
      summary: Einzelne Domain abrufen
      responses:
        "200":
          description: Domain-Details
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Domain"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/TooManyRequests"

    put:
      tags: [Domains]
      summary: Domain aktualisieren
      description: |
        Aktualisiert eine Domain. Kann zum Umbenennen oder
        Aktivieren/Deaktivieren verwendet werden.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                domain:
                  type: string
                  maxLength: 255
                  description: Neuer Domain-Name
                is_active:
                  type: boolean
                  description: Aktiv-Status ändern
      responses:
        "200":
          description: Domain erfolgreich aktualisiert
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Domain"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          description: Domain bereits registriert
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          $ref: "#/components/responses/ValidationError"
        "429":
          $ref: "#/components/responses/TooManyRequests"

    delete:
      tags: [Domains]
      summary: Einzelne Domain löschen
      description: |
        Löscht eine Domain. Es muss mindestens eine Domain verbleiben.
      responses:
        "204":
          description: Domain erfolgreich gelöscht
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "422":
          description: Mindestens eine Domain muss verbleiben
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          $ref: "#/components/responses/TooManyRequests"

components:
  securitySchemes:
    PluginKeyAuth:
      type: http
      scheme: bearer
      description: |
        Plugin-Key (beginnt mit pk_live_) als Bearer Token.
        Beispiel: Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

  schemas:
    Domain:
      type: object
      properties:
        uuid:
          type: string
          format: uuid
          description: Eindeutige Domain-ID
          example: "550e8400-e29b-41d4-a716-446655440000"
        domain:
          type: string
          description: Normalisierter Domain-Name
          example: "example.com"
        is_active:
          type: boolean
          description: "true = Domain ist aktiv und erlaubt Plugin-Zugriff"
          example: true
        created_at:
          type: string
          format: date-time
          description: Erstellungszeitpunkt (ISO 8601)
          example: "2026-03-15T10:30:00+00:00"
        updated_at:
          type: string
          format: date-time
          description: Letzter Änderungszeitpunkt (ISO 8601)
          example: "2026-03-15T10:30:00+00:00"

    PaginationMeta:
      type: object
      properties:
        current_page:
          type: integer
          example: 1
        last_page:
          type: integer
          example: 5
        per_page:
          type: integer
          example: 50
        total:
          type: integer
          example: 243

    Error:
      type: object
      properties:
        error:
          type: string
          description: Fehlerbeschreibung
        details:
          type: object
          description: Feldspezifische Validierungsfehler (nur bei 422)

  responses:
    Unauthorized:
      description: Nicht authentifiziert
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error: "API-Key erforderlich. Senden Sie den Key als Bearer Token im Authorization Header."

    NotFound:
      description: Ressource nicht gefunden
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error: "Domain nicht gefunden."

    ValidationError:
      description: Validierungsfehler
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error: "Validierungsfehler."
            details:
              domain: ["The domain field is required."]

    TooManyRequests:
      description: Rate Limit überschritten
      headers:
        Retry-After:
          schema:
            type: integer
          description: Wartezeit in Sekunden
