openapi: "3.1.0"
info:
  title: "yamiru.com AI API"
  description: "Machine-readable API for Viktor Vasko (Yamiru) portfolio. Entity-first, fact-dense, agent-compatible. No marketing content."
  version: "3.4.0"
  contact:
    name: "Viktor Vasko"
    email: "vaskoviktor@gmail.com"
    url: "https://yamiru.com"
  license:
    name: "CC-BY-4.0"
    url: "https://creativecommons.org/licenses/by/4.0/"

servers:
  - url: "https://yamiru.com"
    description: "Production"

tags:
  - name: "ai"
    description: "AI-readable structured data endpoints"
  - name: "events"
    description: "Real-time server-sent events"

paths:
  /ai/summary.json:
    get:
      operationId: "getSummary"
      tags: ["ai"]
      summary: "Full portfolio summary"
      description: "Returns structured JSON with full entity data: identity, skills, projects, services, work history, certifications."
      responses:
        "200":
          description: "Portfolio summary"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Summary"
          headers:
            X-Content-Source:
              schema:
                type: string
                example: "human"
            X-AI-Endpoint:
              schema:
                type: string
                example: "summary"
        "404":
          $ref: "#/components/responses/NotFound"

  /ai/facts.json:
    get:
      operationId: "getFacts"
      tags: ["ai"]
      summary: "Atomic fact key-value pairs"
      description: "Stable, versionovaný zoznam faktov. Každý kľúč je stály pre citácie a RAG systémy."
      responses:
        "200":
          description: "Fact dataset"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Facts"
        "404":
          $ref: "#/components/responses/NotFound"

  /ai/faq.json:
    get:
      operationId: "getFAQ"
      tags: ["ai"]
      summary: "Q&A pairs for answer engines"
      description: "Short, unambiguous question-answer pairs. Suitable for AEO, voice search, and conversational AI."
      responses:
        "200":
          description: "FAQ dataset"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FAQ"

  /ai/contact.json:
    get:
      operationId: "getContact"
      tags: ["ai"]
      summary: "Contact and escalation data"
      description: "Contact channels and AI agent escalation endpoint."
      responses:
        "200":
          description: "Contact data"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Contact"

  /ai/events:
    get:
      operationId: "getEvents"
      tags: ["events"]
      summary: "Real-time portfolio events (SSE)"
      description: "Server-Sent Events stream for live updates. Agentic layer – Kap. 9."
      responses:
        "200":
          description: "SSE stream"
          content:
            text/event-stream:
              schema:
                type: string
                example: "data: {\"type\":\"ping\",\"timestamp\":\"2026-03-01T12:00:00Z\"}\n\n"

  /ai/actions.json:
    get:
      operationId: "getActions"
      tags: ["ai"]
      summary: "AI agent actions manifest"
      description: "All available actions for AI agents: read, search, contact, subscribe (SSE). Includes rate limits and constraints."
      responses:
        "200":
          description: "Actions manifest"
          content:
            application/json:
              schema:
                type: object
                properties:
                  schemaVersion: {type: string}
                  actions:
                    type: array
                    items:
                      type: object
                      properties:
                        id: {type: string}
                        type: {type: string}
                        endpoint: {type: string}
                        method: {type: string}
        "404":
          $ref: "#/components/responses/NotFound"

  /ai/search:
    get:
      operationId: "searchContent"
      tags: ["ai"]
      summary: "Search portfolio content"
      description: "Simple keyword search across projects, services, and skills."
      parameters:
        - name: q
          in: query
          required: true
          description: "Search query"
          schema:
            type: string
            example: "minecraft server"
        - name: type
          in: query
          required: false
          description: "Filter by type: projects, services, skills"
          schema:
            type: string
            enum: ["projects", "services", "skills", "all"]
            default: "all"
      responses:
        "200":
          description: "Search results"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SearchResults"
        "400":
          $ref: "#/components/responses/BadRequest"
        "404":
          $ref: "#/components/responses/NotFound"

components:
  schemas:
    Summary:
      type: object
      properties:
        schemaVersion:
          type: string
          example: "3.4"
        lastUpdated:
          type: string
          format: date
        entity:
          type: object
          properties:
            name:
              type: string
              example: "Viktor Vasko"
            alternateName:
              type: string
              example: "Yamiru"
            url:
              type: string
              example: "https://yamiru.com"
        facts:
          type: object
        skills:
          type: object
        projects:
          type: array
          items:
            type: object
        services:
          type: array
          items:
            type: object
        contact:
          type: object

    Facts:
      type: object
      properties:
        schemaVersion:
          type: string
        lastUpdated:
          type: string
          format: date
        confidence:
          type: number
          format: float
          example: 1.0
        fullName:
          type: string
          example: "Viktor Vasko"
        alias:
          type: string
          example: "Yamiru"
        country:
          type: string
          example: "Slovakia"
        itExperienceYears:
          type: string
          example: "9+"
        firefighterSince:
          type: string
          example: "2016"

    FAQ:
      type: object
      properties:
        schemaVersion:
          type: string
        questions:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              question:
                type: string
              answer:
                type: string
              category:
                type: string
              confidence:
                type: number

    Contact:
      type: object
      properties:
        schemaVersion:
          type: string
        channels:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
              value:
                type: string
              preferred:
                type: boolean
              responseTime:
                type: string

    SearchResults:
      type: object
      properties:
        query:
          type: string
        resultCount:
          type: integer
        results:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
              name:
                type: string
              description:
                type: string
              url:
                type: string
              relevance:
                type: number

    Error:
      type: object
      properties:
        error:
          type: string
        code:
          type: integer
        endpoint:
          type: string
        canonical:
          type: string

  responses:
    NotFound:
      description: "Resource not found"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error: "Not found"
            code: 404
            endpoint: "/ai/summary.json"
            canonical: "https://yamiru.com/"
    BadRequest:
      description: "Bad request"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
