openapi: 3.1.0
info:
  title: PDF Generator API
  version: 2.1.0
  description: |
    AI-ready XeLaTeX PDF generator with full Unicode support.

    ## Features
    - All standard LaTeX packages pre-loaded
    - Turkish language support (polyglossia)
    - Math, tables, code blocks, colored boxes
    - No package configuration needed

    ## Quick Start
    1. Create document: `POST /documents`
    2. Add sections: `POST /documents/{id}/sections/batch`
    3. Compile: `POST /documents/{id}/generate`
    4. Download: `GET /documents/{id}/pdf`

servers:
  - url: https://gptpdf.yusufozbilek.com
    description: Production

components:
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key for authentication

  schemas:
    Document:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Unique document identifier
        title:
          type: string
          description: Document title
        templateId:
          type: string
          default: default
          description: Template ID (default includes all packages)
        metadata:
          type: object
          nullable: true
          description: Optional metadata
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        sections:
          type: array
          items:
            $ref: "#/components/schemas/Section"
        pdfUrl:
          type: string
          nullable: true
          description: URL to download PDF (null if not compiled)

    Section:
      type: object
      properties:
        id:
          type: string
          format: uuid
        documentId:
          type: string
          format: uuid
        title:
          type: string
          description: Section title
        latex:
          type: string
          description: |
            Body-only LaTeX content. 
            DO NOT include: \documentclass, \usepackage, \begin{document}, \end{document}
        type:
          type: string
          enum: [chapter, section, subsection, subsubsection]
          default: section
          description: Section type determines heading level
        orderIndex:
          type: integer
          description: Display order (0-based)
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    CompileResult:
      type: object
      properties:
        status:
          type: string
          enum: [ok]
        pdfUrl:
          type: string
          description: URL to download the generated PDF
        compileLogId:
          type: string
          format: uuid
        compileLogUrl:
          type: string
          description: URL to fetch compilation logs

    CompileLog:
      type: object
      properties:
        id:
          type: string
          format: uuid
        documentId:
          type: string
          format: uuid
        engine:
          type: string
          enum: [latexmk, xelatex]
        exitCode:
          type: integer
          description: Process exit code (0 = success)
        stdout:
          type: string
          description: Standard output (may be truncated)
        stderr:
          type: string
          description: Standard error (may be truncated)
        createdAt:
          type: string
          format: date-time

    Error:
      type: object
      properties:
        error:
          type: string
          description: Error message
        details:
          type: object
          nullable: true
          description: Additional error details

    TestResult:
      type: object
      properties:
        ok:
          type: boolean
        documentId:
          type: string
          format: uuid
        sectionCount:
          type: integer
        logId:
          type: string
          format: uuid
        pdfExists:
          type: boolean
        pdfSize:
          type: integer
          description: PDF file size in bytes
        pdfUrl:
          type: string

paths:
  # ============================================================================
  # Health & Info
  # ============================================================================
  /health:
    get:
      operationId: healthCheck
      summary: Health check
      description: Returns server status
      security: []
      tags: [System]
      responses:
        "200":
          description: Server is healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok
                  timestamp:
                    type: string
                    format: date-time

  /openapi.yaml:
    get:
      operationId: getOpenApiSpec
      summary: Get OpenAPI specification
      security: []
      tags: [System]
      responses:
        "200":
          description: OpenAPI YAML specification
          content:
            application/yaml:
              schema:
                type: string

  # ============================================================================
  # Documents
  # ============================================================================
  /documents:
    post:
      operationId: createDocument
      summary: Create a new document
      tags: [Documents]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [title]
              properties:
                title:
                  type: string
                  description: Document title
                  example: "Python Programlama Rehberi"
                templateId:
                  type: string
                  default: default
                metadata:
                  type: object
                  description: Optional metadata (not typically needed)
      responses:
        "201":
          description: Document created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Document"

    get:
      operationId: listDocuments
      summary: List all documents
      tags: [Documents]
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            default: 1
            minimum: 1
        - name: pageSize
          in: query
          schema:
            type: integer
            default: 20
            minimum: 1
            maximum: 100
        - name: search
          in: query
          schema:
            type: string
          description: Search in document titles
      responses:
        "200":
          description: Paginated document list
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: "#/components/schemas/Document"
                  total:
                    type: integer
                  page:
                    type: integer
                  pageSize:
                    type: integer

  /documents/{id}:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid

    get:
      operationId: getDocument
      summary: Get document with sections
      tags: [Documents]
      responses:
        "200":
          description: Document with all sections
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Document"
        "404":
          description: Document not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    put:
      operationId: updateDocument
      summary: Update document and replace sections
      tags: [Documents]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [title]
              properties:
                title:
                  type: string
                templateId:
                  type: string
                sections:
                  type: array
                  items:
                    type: object
                    required: [title, latex]
                    properties:
                      title:
                        type: string
                      latex:
                        type: string
                      type:
                        type: string
                      order:
                        type: integer
      responses:
        "200":
          description: Document updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Document"
        "404":
          description: Document not found

    delete:
      operationId: deleteDocument
      summary: Delete document
      tags: [Documents]
      responses:
        "204":
          description: Document deleted
        "404":
          description: Document not found

  # ============================================================================
  # Sections
  # ============================================================================
  /documents/{id}/sections:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid

    get:
      operationId: listSections
      summary: List all sections of a document
      tags: [Sections]
      responses:
        "200":
          description: Section list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Section"
        "404":
          description: Document not found

    post:
      operationId: createSection
      summary: Create a new section
      tags: [Sections]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [title, latex]
              properties:
                title:
                  type: string
                  example: "Giriş"
                latex:
                  type: string
                  example: "Bu bölümde temel kavramları inceliyoruz.\n\n\\textbf{Önemli:} LaTeX komutları kullanılabilir."
                type:
                  type: string
                  enum: [chapter, section, subsection, subsubsection]
                  default: section
                order:
                  type: integer
                  description: Optional order index
      responses:
        "201":
          description: Section created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Section"

  /documents/{id}/sections/batch:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid

    post:
      operationId: createSectionsBatch
      summary: Create multiple sections at once
      description: Optimized for AI-generated multi-section documents
      tags: [Sections]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [sections]
              properties:
                sections:
                  type: array
                  maxItems: 50
                  items:
                    type: object
                    required: [title, latex]
                    properties:
                      title:
                        type: string
                      latex:
                        type: string
                      type:
                        type: string
                        enum: [chapter, section, subsection, subsubsection]
                      order:
                        type: integer
            example:
              sections:
                - title: "Giriş"
                  type: "section"
                  latex: "Bu belgede API kullanımını öğreneceksiniz."
                - title: "Kurulum"
                  type: "section"
                  latex: "\\begin{enumerate}\n\\item Adım 1: Kurulum\n\\item Adım 2: Yapılandırma\n\\end{enumerate}"
                - title: "Sonuç"
                  type: "section"
                  latex: "Bu belgede temel konuları ele aldık."
      responses:
        "201":
          description: Sections created
          content:
            application/json:
              schema:
                type: object
                properties:
                  created:
                    type: integer
                  sections:
                    type: array
                    items:
                      $ref: "#/components/schemas/Section"

  /documents/{id}/sections/{sectionId}:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: sectionId
        in: path
        required: true
        schema:
          type: string
          format: uuid

    get:
      operationId: getSection
      summary: Get a single section
      tags: [Sections]
      responses:
        "200":
          description: Section details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Section"
        "404":
          description: Section not found

    put:
      operationId: updateSection
      summary: Update a section
      tags: [Sections]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                latex:
                  type: string
                type:
                  type: string
                order:
                  type: integer
      responses:
        "200":
          description: Section updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Section"
        "404":
          description: Section not found

    delete:
      operationId: deleteSection
      summary: Delete a section
      tags: [Sections]
      responses:
        "204":
          description: Section deleted
        "404":
          description: Section not found

  /documents/{id}/sections/reorder:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid

    patch:
      operationId: reorderSections
      summary: Reorder sections
      tags: [Sections]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [orderedSectionIds]
              properties:
                orderedSectionIds:
                  type: array
                  items:
                    type: string
                    format: uuid
                  description: Section IDs in desired order
      responses:
        "200":
          description: Sections reordered
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Section"

  # ============================================================================
  # Compilation
  # ============================================================================
  /documents/{id}/generate:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid

    post:
      operationId: generatePdf
      summary: Compile document to PDF
      description: |
        Compiles the document using XeLaTeX. All packages are pre-loaded.
        On success, returns URL to download the PDF.
      tags: [Compilation]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                engine:
                  type: string
                  enum: [latexmk, xelatex]
                  default: latexmk
                draft:
                  type: boolean
                  default: false
                  description: Skip PDF generation (faster, for testing)
      responses:
        "200":
          description: PDF compiled successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompileResult"
        "400":
          description: Compilation failed
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  logId:
                    type: string
                  compileLogUrl:
                    type: string
                  exitCode:
                    type: integer
        "404":
          description: Document not found
        "409":
          description: Compilation already in progress

  /documents/{id}/pdf:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid

    get:
      operationId: downloadPdf
      summary: Download generated PDF
      tags: [Compilation]
      responses:
        "200":
          description: PDF file
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        "404":
          description: PDF not found (compile first)

  /documents/{id}/compile-log:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid

    get:
      operationId: getCompileLogs
      summary: Get compilation logs
      description: Returns all compilation logs for debugging
      tags: [Compilation]
      responses:
        "200":
          description: Compilation logs
          content:
            application/json:
              schema:
                type: object
                properties:
                  lastLog:
                    $ref: "#/components/schemas/CompileLog"
                  logs:
                    type: array
                    items:
                      $ref: "#/components/schemas/CompileLog"

  # ============================================================================
  # Tests
  # ============================================================================
  /tests/run:
    post:
      operationId: runBasicTest
      summary: Run basic test
      description: Creates a simple test document and compiles it
      tags: [Tests]
      responses:
        "200":
          description: Test result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TestResult"

  /tests/full-run:
    post:
      operationId: runFullTest
      summary: Run full test
      description: Same as basic test with detailed output
      tags: [Tests]
      responses:
        "200":
          description: Test result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TestResult"

  /tests/complex-test:
    post:
      operationId: runComplexTest
      summary: Run complex feature test
      description: Tests math, tables, code blocks, and colored boxes
      tags: [Tests]
      responses:
        "200":
          description: Test result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TestResult"

  /tests/stress-test:
    post:
      operationId: runStressTest
      summary: Run 100-page stress test
      description: |
        Generates a 100-page document with complex content:
        - Mathematics (equations, matrices)
        - Tables (booktabs style)
        - Code blocks (Python)
        - Colored boxes (tcolorbox)
        - Nested lists
        - Long paragraphs
      tags: [Tests]
      responses:
        "200":
          description: Test result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TestResult"

  /tests/list:
    get:
      operationId: listTestDocuments
      summary: List test documents
      tags: [Tests]
      responses:
        "200":
          description: Test documents
          content:
            application/json:
              schema:
                type: object
                properties:
                  count:
                    type: integer
                  documents:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        title:
                          type: string
                        isTest:
                          type: boolean
                        createdAt:
                          type: string
                          format: date-time

  /tests/cleanup:
    delete:
      operationId: cleanupTests
      summary: Delete all test documents
      tags: [Tests]
      responses:
        "200":
          description: Cleanup result
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  deleted:
                    type: integer
                  message:
                    type: string

  /tests/health:
    get:
      operationId: testHealth
      summary: Test endpoint health check
      tags: [Tests]
      responses:
        "200":
          description: Health status
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  timestamp:
                    type: string
                    format: date-time

  /tests/{id}:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid

    delete:
      operationId: deleteTestDocument
      summary: Delete a specific test document
      tags: [Tests]
      responses:
        "200":
          description: Deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  deleted:
                    type: string
        "400":
          description: Not a test document
        "404":
          description: Document not found

security:
  - apiKeyAuth: []

tags:
  - name: System
    description: Health and info endpoints
  - name: Documents
    description: Document CRUD operations
  - name: Sections
    description: Section management
  - name: Compilation
    description: PDF generation and logs
  - name: Tests
    description: Test endpoints for verification
