openapi: 3.0.3
info:
  title: AnnexShow Reporting Contract
  description: |
    Reporting-Contract für die ma-kom Console. Alle `/api/v1/reporting/*`
    Endpunkte erfordern den Header `X-Reporting-Key`.
  version: 1.0.0
  contact:
    name: AnnexShow Support
    email: mail@annexshow.com
servers:
  - url: https://annexshow.com
    description: Production
  - url: http://127.0.0.1:8000
    description: Local development

security:
  - reportingKeyAuth: []

paths:
  /api/v1/reporting/health:
    get:
      summary: Health status
      operationId: reportingHealth
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok
                  project_id:
                    type: string
                  app_version:
                    type: string

  /api/v1/reporting/revenue:
    get:
      summary: Revenue overview
      operationId: reportingRevenue
      responses:
        '200':
          description: Revenue data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RevenueReport'

  /api/v1/reporting/usage:
    get:
      summary: Usage metrics
      operationId: reportingUsage
      responses:
        '200':
          description: Usage data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UsageReport'

  /api/v1/reporting/errors:
    get:
      summary: Error overview
      operationId: reportingErrors
      parameters:
        - name: days
          in: query
          schema:
            type: integer
            default: 30
      responses:
        '200':
          description: Error data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorReport'

  /api/v1/reporting/tickets:
    get:
      summary: Support ticket overview
      operationId: reportingTickets
      parameters:
        - name: days
          in: query
          schema:
            type: integer
            default: 30
      responses:
        '200':
          description: Ticket data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TicketReport'

  /api/v1/reporting/tickets/{ticket_number}:
    get:
      summary: Ticket detail
      operationId: reportingTicketDetail
      parameters:
        - name: ticket_number
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Ticket detail
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TicketDetail'
        '404':
          description: Ticket not found

  /api/v1/reporting/tickets/{ticket_number}/reply:
    post:
      summary: Console reply to ticket
      operationId: reportingTicketReply
      parameters:
        - name: ticket_number
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - message
              properties:
                message:
                  type: string
                  maxLength: 5000
                is_internal:
                  type: boolean
                  default: false
      responses:
        '201':
          description: Reply created
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  ticket_number:
                    type: string
                  reply_id:
                    type: integer
        '404':
          description: Ticket not found
        '422':
          description: Validation error

  /api/v1/reporting/campaigns:
    get:
      summary: Marketing campaigns
      operationId: reportingCampaigns
      responses:
        '200':
          description: Campaign data
          content:
            application/json:
              schema:
                type: object
                properties:
                  project_id:
                    type: string
                  app_version:
                    type: string
                  generated_at:
                    type: string
                    format: date-time
                  campaigns:
                    type: array
                    items:
                      type: object
                  note:
                    type: string

  /api/v1/frontend-bugs/ingest:
    post:
      summary: Public frontend error ingest
      operationId: ingestFrontendBug
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - message
              properties:
                message:
                  type: string
                  maxLength: 5000
                source:
                  type: string
                  maxLength: 500
                stack:
                  type: string
                  maxLength: 10000
                url:
                  type: string
                  maxLength: 1000
      responses:
        '201':
          description: Bug recorded
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

  /api/v1/agent/visualize:
    post:
      summary: Brief oder Struktur (nodes/edges) -> auto-layoutetes Canvas + optional Share-URL
      description: >
        High-Level-Endpunkt (W4 Agent-Magie). Entweder "nodes" (+ optional "edges")
        direkt liefern oder einen "brief" (benoetigt serverseitig aktivierten KI-Pfad,
        sonst 422). AnnexShow ordnet die Knoten automatisch an (tree/radial/grid).
      operationId: agentVisualize
      security:
        - agentKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                project_id:
                  type: integer
                  description: Optional. Fehlt sie, legt der Aufruf automatisch ein Projekt an.
                title:
                  type: string
                brief:
                  type: string
                  maxLength: 4000
                nodes:
                  type: array
                  items:
                    type: object
                    properties:
                      id: { type: string }
                      label: { type: string }
                      color: { type: string }
                edges:
                  type: array
                  items:
                    type: object
                    properties:
                      from: { type: string }
                      to: { type: string }
                      label: { type: string }
                layout:
                  type: string
                  enum: [tree, radial, grid]
                chart:
                  type: object
                  description: Diagramm aus Daten (statt nodes/edges).
                  properties:
                    type: { type: string, enum: [bar, line, pie] }
                    title: { type: string }
                    labels: { type: array, items: { type: string } }
                    series:
                      type: array
                      items:
                        type: object
                        properties:
                          name: { type: string }
                          data: { type: array, items: { type: number } }
                style:
                  type: string
                  enum: [flat, "3d"]
                  description: >
                    "3d" rendert Balkendiagramme als isometrisch projizierte 3D-Balken
                    (Pro-Feature, sonst 403). Default flat.
                objects3d:
                  type: array
                  maxItems: 24
                  description: >
                    Direkte 3D-Primitive (Pro-Feature): Server projiziert sie zu editierbaren
                    Vektor-Gruppen. Ohne x/y automatische Raster-Platzierung.
                  items:
                    type: object
                    required: [definition]
                    properties:
                      x: { type: number }
                      y: { type: number }
                      definition:
                        type: object
                        required: [primitive]
                        properties:
                          primitive: { type: string, enum: [box, cylinder, pyramid, extrude] }
                          width: { type: number }
                          height: { type: number }
                          depth: { type: number }
                          radius: { type: number }
                          segments: { type: integer, minimum: 3, maximum: 48 }
                          profile:
                            type: array
                            items:
                              type: object
                              properties: { x: { type: number }, y: { type: number } }
                          rotation:
                            type: object
                            properties: { x: { type: number }, y: { type: number }, z: { type: number } }
                          color: { type: string }
                          perspective: { type: number, minimum: 0, maximum: 1 }
                          outline: { type: boolean }
                brandkit_id:
                  type: integer
                share:
                  type: boolean
      responses:
        '201':
          description: Canvas erstellt
          content:
            application/json:
              schema:
                type: object
                properties:
                  canvas: { type: object }
                  share_url: { type: string }
                  layout: { type: string }
                  style: { type: string }
                  quality: { type: object }

  /api/v1/agent/brandkits:
    post:
      summary: Brandkit fuer einen Agenten anlegen/fuellen
      operationId: agentCreateBrandkit
      security:
        - agentKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name: { type: string }
                company_name: { type: string }
                slogan: { type: string }
                offer_description: { type: string }
                colors:
                  type: object
                  properties:
                    primary: { type: string }
                    secondary: { type: string }
                    signal: { type: string }
                fonts:
                  type: object
                  properties:
                    heading: { type: string }
                    body: { type: string }
      responses:
        '201':
          description: Brandkit erstellt
          content:
            application/json:
              schema:
                type: object
                properties:
                  brandkit: { type: object }
                  completion: { type: integer }
                  missing: { type: array, items: { type: string } }

components:
  securitySchemes:
    reportingKeyAuth:
      type: apiKey
      in: header
      name: X-Reporting-Key
    agentKeyAuth:
      type: apiKey
      in: header
      name: X-AnnexShow-Api-Key

  schemas:
    RevenueReport:
      type: object
      properties:
        project_id:
          type: string
        app_version:
          type: string
        generated_at:
          type: string
          format: date-time
        outstanding:
          type: object
          properties:
            currency:
              type: string
            total:
              type: number
        plan_distribution:
          type: object

    UsageReport:
      type: object
      properties:
        project_id:
          type: string
        app_version:
          type: string
        generated_at:
          type: string
          format: date-time
        users:
          type: object
          properties:
            total:
              type: integer
            active:
              type: integer
            by_plan:
              type: object
        projects:
          type: object
          properties:
            total:
              type: integer
        exports:
          type: object
          properties:
            total:
              type: integer
            by_format:
              type: object

    ErrorReport:
      type: object
      properties:
        project_id:
          type: string
        app_version:
          type: string
        generated_at:
          type: string
          format: date-time
        periods:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
              count:
                type: integer
        top_types:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
              occurrences:
                type: integer
              last_seen:
                type: string
                format: date-time
        unresolved_total:
          type: integer

    TicketReport:
      type: object
      properties:
        project_id:
          type: string
        app_version:
          type: string
        generated_at:
          type: string
          format: date-time
        periods:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
              count:
                type: integer
        by_status:
          type: object
        by_priority:
          type: object
        items:
          type: array
          items:
            type: object
            properties:
              ticket_number:
                type: string
              subject:
                type: string
              status:
                type: string
              priority:
                type: string
              created_at:
                type: string
                format: date-time

    TicketDetail:
      type: object
      properties:
        project_id:
          type: string
        app_version:
          type: string
        generated_at:
          type: string
        ticket_number:
          type: string
        subject:
          type: string
        status:
          type: string
        priority:
          type: string
        category:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        user:
          type: object
          properties:
            id:
              type: integer
            email:
              type: string
        messages:
          type: array
          items:
            type: object
            properties:
              id:
                type: integer
              message:
                type: string
              is_internal:
                type: boolean
              created_at:
                type: string
                format: date-time
              user:
                type: object
                properties:
                  id:
                    type: integer
                  email:
                    type: string
