openapi: 3.0.3
info:
  title: Groenewold IT Solutions – Universal API
  description: >-
    Öffentliche API von Groenewold IT Solutions. Ermöglicht den programmatischen
    Zugriff auf alle Website-Inhalte: Blog-Artikel, Leistungen, Referenzen, FAQ
    und IT-Glossar. Enthält außerdem interaktive Kostenrechner für
    Softwareprojekte, ROI-Analysen für Investitionsentscheidungen sowie einen
    strukturierten Knowledge Graph. Kostenlos und ohne Authentifizierung nutzbar.
  version: 1.0.1
  contact:
    name: Groenewold IT Solutions
    url: https://www.groenewold-it.solutions/kontakt
    email: info@groenewold-it.solutions
  license:
    name: Proprietary
    url: https://www.groenewold-it.solutions

servers:
  - url: https://www.groenewold-it.solutions/api/v1
    description: Produktion

tags:
  - name: Content
    description: Lesender Zugriff auf Website-Inhalte (Blog, Leistungen, Referenzen, FAQ, Glossar)
  - name: Calculators
    description: Kostenrechner für Softwareprojekte (30 Rechner, POST für Berechnung, GET für Parameter-Schema)
  - name: ROI-Analyzers
    description: ROI-Rechner für Investitionsentscheidungen (8 Rechner, POST für Analyse, GET für Parameter-Schema)
  - name: Knowledge
    description: Strukturierter Knowledge Graph über das Unternehmen

paths:
  /content/articles:
    get:
      tags: [Content]
      summary: Blog-Artikel abrufen
      description: >-
        Liefert eine Liste von Blog-Artikeln. Filterbar nach Kategorie, Autor,
        Suchbegriff oder Tag. Enthält den vollständigen Markdown-Content.
      operationId: getArticles
      parameters:
        - name: category
          in: query
          schema:
            type: string
          description: Artikel nach Kategorie-Slug filtern (z.B. "ki", "app-dev", "laravel")
          example: ki
        - name: author
          in: query
          schema:
            type: string
          description: Artikel nach Autorname filtern
          example: Björn Groenewold
        - name: tag
          in: query
          schema:
            type: string
          description: Artikel nach Schlagwort durchsuchen
        - name: query
          in: query
          schema:
            type: string
          description: Volltextsuche in Titel, Excerpt und Inhalt
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
          description: Maximale Anzahl zurückgegebener Artikel
        - name: format
          in: query
          schema:
            type: string
            enum: [json, md, jsonld]
            default: json
          description: 'Ausgabeformat: json (Standard), md (Markdown), jsonld (Schema.org JSON-LD)'
      responses:
        "200":
          description: Liste von Blog-Artikeln
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ArticleListResponse"
        "429":
          $ref: "#/components/responses/RateLimitExceeded"
        "500":
          $ref: "#/components/responses/InternalError"

  /content/services:
    get:
      tags: [Content]
      summary: Leistungen abrufen
      description: >-
        Liefert alle Leistungen / Services von Groenewold IT Solutions.
        Filterbar nach Kategorie oder Suchbegriff.
      operationId: getServices
      parameters:
        - name: category
          in: query
          schema:
            type: string
          description: >-
            Leistungs-Kategorie (z.B. "platform", "ai", "integration", "data",
            "advisory", "support", "finance", "automation", "security")
          example: ai
        - name: query
          in: query
          schema:
            type: string
          description: Suchbegriff in Leistungsname und Kategorie
        - name: format
          in: query
          schema:
            type: string
            enum: [json, md, jsonld]
            default: json
          description: 'Ausgabeformat: json (Standard), md (Markdown), jsonld (Schema.org JSON-LD)'
      responses:
        "200":
          description: Liste von Leistungen
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ServiceListResponse"
        "429":
          $ref: "#/components/responses/RateLimitExceeded"
        "500":
          $ref: "#/components/responses/InternalError"

  /content/references:
    get:
      tags: [Content]
      summary: Referenzen / Case Studies abrufen
      description: >-
        Liefert Referenzprojekte und Case Studies. Filterbar nach Branche,
        Dienstleistung oder Suchbegriff.
      operationId: getReferences
      parameters:
        - name: industry
          in: query
          schema:
            type: string
          description: Nach Branche oder Projektart filtern
          example: Logistik
        - name: service
          in: query
          schema:
            type: string
          description: Nach Dienstleistungs-Kategorie filtern
          example: Künstliche Intelligenz
        - name: query
          in: query
          schema:
            type: string
          description: Volltextsuche in Titel, Beschreibung und Case-Study-Details
        - name: format
          in: query
          schema:
            type: string
            enum: [json, md, jsonld]
            default: json
          description: 'Ausgabeformat: json (Standard), md (Markdown), jsonld (Schema.org JSON-LD)'
      responses:
        "200":
          description: Liste von Referenzen
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReferenceListResponse"
        "429":
          $ref: "#/components/responses/RateLimitExceeded"
        "500":
          $ref: "#/components/responses/InternalError"

  /content/faq:
    get:
      tags: [Content]
      summary: FAQ abrufen
      description: >-
        Liefert häufig gestellte Fragen und Antworten, gruppiert nach Kategorien
        (z.B. Projektablauf, Kosten, Technologie, KI, Datenschutz etc.).
      operationId: getFAQ
      parameters:
        - name: category
          in: query
          schema:
            type: string
          description: >-
            FAQ-Kategorie-ID (z.B. "projektablauf", "kosten", "technologie",
            "ki", "datenschutz", "mobile", "schnittstellen", "ecommerce",
            "legacy", "cloud", "zusammenarbeit", "testing", "support")
          example: ki
        - name: query
          in: query
          schema:
            type: string
          description: Volltextsuche in Fragen und Antworten
        - name: format
          in: query
          schema:
            type: string
            enum: [json, md, jsonld]
            default: json
          description: 'Ausgabeformat: json (Standard), md (Markdown), jsonld (Schema.org JSON-LD)'
      responses:
        "200":
          description: Liste von FAQ-Einträgen
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FAQListResponse"
        "429":
          $ref: "#/components/responses/RateLimitExceeded"
        "500":
          $ref: "#/components/responses/InternalError"

  /content/glossary:
    get:
      tags: [Content]
      summary: IT-Glossar abrufen
      description: >-
        Liefert IT-Fachbegriffe mit Definitionen, Beispielen, Vor-/Nachteilen
        und FAQ. Umfasst 150+ Begriffe.
      operationId: getGlossary
      parameters:
        - name: category
          in: query
          schema:
            type: string
          description: Glossar-Kategorie filtern
        - name: query
          in: query
          schema:
            type: string
          description: Suchbegriff in Term, Definition und Kategorie
          example: API
        - name: format
          in: query
          schema:
            type: string
            enum: [json, md, jsonld]
            default: json
          description: 'Ausgabeformat: json (Standard), md (Markdown), jsonld (Schema.org JSON-LD)'
      responses:
        "200":
          description: Liste von Glossar-Einträgen
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GlossaryListResponse"
        "429":
          $ref: "#/components/responses/RateLimitExceeded"
        "500":
          $ref: "#/components/responses/InternalError"

  /calculators/{calculatorName}:
    post:
      tags: [Calculators]
      summary: Kostenschätzung berechnen
      description: Sendet Parameter und erhält eine Kostenschätzung zurück.
      operationId: calculateCost
      parameters:
        - name: calculatorName
          in: path
          required: true
          schema:
            type: string
            enum:
              - foerdergeld-rechner
              - app-entwicklung
              - web-entwicklung
              - automatisierung-rpa
              - ki-machine-learning
              - ki-wissensdatenbank
              - online-shop
              - schnittstellen-apis
              - software-wartung
              - odoo-erp-crm
              - delphi-entwicklung
              - software-rettung
              - legacy-modernisierung
              - security-audit
              - cloud-migration
              - mvp
              - data-migration
              - qa-testing
              - devops-ci-cd
              - performance-optimierung
              - api-integration-chaos
              - helpdesk-ticket-system
              - discovery-workshop
              - erp-einfuehrung
              - replatforming
              - mobile-app-wartung
              - dsgvo-compliance
              - observability-monitoring
              - white-label-plattform
              - ki-agent-integration
          description: Slug des gewünschten Kostenrechners
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CalculatorRequest'
            example:
              parameters:
                platform: cross-platform
                complexity: medium
                design: custom
                features: [auth, payment]
                backend: simple
                maintenance: standard
      responses:
        '200':
          description: Erfolgreiche Kostenschätzung
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CalculatorResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
    get:
      tags: [Calculators]
      summary: Parameter-Schema abrufen
      description: Gibt die erwarteten Parameter und deren mögliche Werte für den gewählten Rechner zurück.
      operationId: getCalculatorSchema
      parameters:
        - name: calculatorName
          in: path
          required: true
          schema:
            type: string
            enum:
              - foerdergeld-rechner
              - app-entwicklung
              - web-entwicklung
              - automatisierung-rpa
              - ki-machine-learning
              - ki-wissensdatenbank
              - online-shop
              - schnittstellen-apis
              - software-wartung
              - odoo-erp-crm
              - delphi-entwicklung
              - software-rettung
              - legacy-modernisierung
              - security-audit
              - cloud-migration
              - mvp
              - data-migration
              - qa-testing
              - devops-ci-cd
              - performance-optimierung
              - api-integration-chaos
              - helpdesk-ticket-system
              - discovery-workshop
              - erp-einfuehrung
              - replatforming
              - mobile-app-wartung
              - dsgvo-compliance
              - observability-monitoring
              - white-label-plattform
              - ki-agent-integration
      responses:
        '200':
          description: Parameter-Schema des Rechners
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'

  /roi-analyzers/{analyzerName}:
    post:
      tags: [ROI-Analyzers]
      summary: ROI-Analyse durchführen
      description: Vergleicht zwei Optionen über 5 Jahre und ermittelt den Break-even-Punkt.
      operationId: analyzeRoi
      parameters:
        - name: analyzerName
          in: path
          required: true
          schema:
            type: string
            enum: [individual-vs-standard, automatisierung-vs-manuell, modernisierung-vs-weiterbetrieb, ki-vs-manuell, api-vs-manuell, wartung-vs-ausfall, shop-vs-marktplatz, erp-vs-inselloesungen]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoiAnalyzerRequest'
            example:
              parameters:
                users: 25
                licenseCost: 80
                licenseIncrease: 5
                devCost: 80000
                maintenanceCost: 800
                leasing: false
      responses:
        '200':
          description: ROI-Analyse-Ergebnis
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoiAnalyzerResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
    get:
      tags: [ROI-Analyzers]
      summary: Parameter-Schema abrufen
      operationId: getRoiAnalyzerSchema
      parameters:
        - name: analyzerName
          in: path
          required: true
          schema:
            type: string
            enum: [individual-vs-standard, automatisierung-vs-manuell, modernisierung-vs-weiterbetrieb, ki-vs-manuell, api-vs-manuell, wartung-vs-ausfall, shop-vs-marktplatz, erp-vs-inselloesungen]
      responses:
        '200':
          description: Parameter-Schema
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'

  /knowledge:
    get:
      tags: [Knowledge]
      summary: Knowledge Graph abrufen
      description: Gibt einen strukturierten Knowledge Graph mit Unternehmens-, Leistungs- und Technologiedaten zurück.
      operationId: getKnowledgeGraph
      parameters:
        - name: format
          in: query
          schema:
            type: string
            enum: [json, md, markdown, jsonld, json-ld]
            default: json
          description: >-
            Ausgabeformat: json (Standard), md oder markdown (Markdown),
            jsonld oder json-ld (Schema.org JSON-LD)
      responses:
        '200':
          description: Knowledge Graph
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KnowledgeGraph'
            text/markdown:
              schema:
                type: string
            application/ld+json:
              schema:
                type: object
        '429':
          $ref: '#/components/responses/RateLimitExceeded'

components:
  responses:
    RateLimitExceeded:
      description: Zu viele Anfragen – Rate Limit überschritten
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
                example: Too Many Requests
              message:
                type: string
              retry_after_seconds:
                type: integer
    BadRequest:
      description: Ungültige oder fehlende Parameter
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/BadRequestError'
    NotFound:
      description: Ressource nicht gefunden
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/NotFoundError'
    InternalError:
      description: Interner Serverfehler
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
                example: Internal Server Error
              message:
                type: string

  schemas:
    ArticleListResponse:
      type: object
      properties:
        content_type:
          type: string
          example: articles
        filter:
          type: object
          additionalProperties:
            type: string
        count:
          type: integer
        items:
          type: array
          items:
            $ref: "#/components/schemas/Article"

    Article:
      type: object
      properties:
        id:
          type: integer
        title:
          type: string
          example: Wie KI den Mittelstand revolutioniert
        slug:
          type: string
          example: ki-mittelstand-revolution
        category:
          type: string
          example: Künstliche Intelligenz
        category_slug:
          type: string
          example: ki
        author:
          type: string
          example: Björn Groenewold
        published_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
          nullable: true
        summary:
          type: string
        url:
          type: string
          format: uri
        content_markdown:
          type: string

    ServiceListResponse:
      type: object
      properties:
        content_type:
          type: string
          example: services
        filter:
          type: object
          additionalProperties:
            type: string
        count:
          type: integer
        items:
          type: array
          items:
            $ref: "#/components/schemas/Service"

    Service:
      type: object
      properties:
        slug:
          type: string
          example: kuenstliche-intelligenz
        name:
          type: string
          example: "KI & Machine Learning"
        category:
          type: string
          example: "KI & Machine Learning"
        category_id:
          type: string
          example: ai
        category_description:
          type: string
        url:
          type: string
          format: uri

    ReferenceListResponse:
      type: object
      properties:
        content_type:
          type: string
          example: references
        filter:
          type: object
          additionalProperties:
            type: string
        count:
          type: integer
        items:
          type: array
          items:
            $ref: "#/components/schemas/Reference"

    Reference:
      type: object
      properties:
        id:
          type: string
        title:
          type: string
        category:
          type: string
        description:
          type: string
        url:
          type: string
          format: uri
          nullable: true
        story:
          nullable: true
          type: object
          properties:
            summary:
              type: string
              nullable: true
            challenge:
              type: string
              nullable: true
            solution:
              type: string
              nullable: true
            result:
              type: string
              nullable: true
            customer_quote:
              nullable: true
              type: object
              properties:
                text:
                  type: string
                author:
                  type: string

    FAQListResponse:
      type: object
      properties:
        content_type:
          type: string
          example: faq
        filter:
          type: object
          additionalProperties:
            type: string
        count:
          type: integer
        items:
          type: array
          items:
            $ref: "#/components/schemas/FAQItem"

    FAQItem:
      type: object
      properties:
        category_id:
          type: string
          example: ki
        category_name:
          type: string
          example: "Künstliche Intelligenz & Automatisierung"
        question:
          type: string
        answer:
          type: string

    GlossaryListResponse:
      type: object
      properties:
        content_type:
          type: string
          example: glossary
        filter:
          type: object
          additionalProperties:
            type: string
        count:
          type: integer
        items:
          type: array
          items:
            $ref: "#/components/schemas/GlossaryTerm"

    GlossaryTerm:
      type: object
      properties:
        slug:
          type: string
          example: rest-api
        term:
          type: string
          example: REST-API
        category:
          type: string
        short_definition:
          type: string
        definition:
          type: string
        how_it_works:
          type: string
          nullable: true
        examples:
          type: array
          items:
            type: string
        use_cases:
          type: array
          items:
            type: string
        pros:
          type: array
          items:
            type: string
        cons:
          type: array
          items:
            type: string
        faqs:
          type: array
          items:
            type: object
            properties:
              question:
                type: string
              answer:
                type: string
        related_terms:
          type: array
          items:
            type: string
        url:
          type: string
          format: uri

    CalculatorRequest:
      type: object
      required: [parameters]
      properties:
        parameters:
          type: object
          description: Die Parameter für den gewählten Rechner (variiert je nach Rechner, GET-Endpunkt für Schema nutzen)

    CalculatorResponse:
      type: object
      properties:
        calculator_id:
          type: string
          example: app-entwicklung
        calculator_name:
          type: string
          example: App-Entwicklung Kostenrechner
        parameters:
          type: object
        cost_estimation:
          type: object
          properties:
            min_cost:
              type: number
              example: 25000
            max_cost:
              type: number
              example: 55000
            total_estimate:
              type: number
            monthly_cost:
              type: number
            yearly_cost:
              type: number
            currency:
              type: string
              example: EUR
            vat_included:
              type: boolean
              example: false
            summary:
              type: string
        disclaimer:
          type: string
        next_steps:
          type: object
          properties:
            consultation_url:
              type: string
              format: uri
            contact_url:
              type: string
              format: uri

    RoiAnalyzerRequest:
      type: object
      required: [parameters]
      properties:
        parameters:
          type: object
          description: Die Parameter für den gewählten ROI-Rechner (variiert je nach Rechner)

    RoiAnalyzerResponse:
      type: object
      properties:
        analyzer_id:
          type: string
          example: individual-vs-standard
        analyzer_name:
          type: string
        parameters:
          type: object
        roi_analysis:
          type: object
          properties:
            option_a:
              type: object
              properties:
                label:
                  type: string
                total_cost_5y:
                  type: number
                monthly_costs:
                  type: array
                  items:
                    type: number
            option_b:
              type: object
              properties:
                label:
                  type: string
                total_cost_5y:
                  type: number
                monthly_costs:
                  type: array
                  items:
                    type: number
            breakeven_month:
              type: integer
              nullable: true
            savings_year_1:
              type: number
            savings_year_3:
              type: number
            savings_year_5:
              type: number
            summary:
              type: string
        disclaimer:
          type: string
        next_steps:
          type: object
          properties:
            consultation_url:
              type: string
              format: uri
            contact_url:
              type: string
              format: uri

    KnowledgeGraph:
      type: object
      properties:
        '@context':
          type: string
          example: https://schema.org
        '@graph':
          type: array
          items:
            type: object
        api_endpoints:
          type: object

    BadRequestError:
      type: object
      properties:
        error:
          type: string
          example: Bad Request
        message:
          type: string
          example: 'Fehlender Parameter: platform'

    NotFoundError:
      type: object
      properties:
        error:
          type: string
          example: Not Found
        message:
          type: string
