openapi: 3.0.3

info:
  title: Markdown to PDF API — Tesmotech
  description: |
    Servicio de conversión de Markdown a PDF con branding corporativo Tesmotech
    (plantilla, portada, logo, fuentes Unbounded/Montserrat/Poppins y paleta de colores púrpura embebidos).

    ## Acceso
    El servicio es **interno**: solo es alcanzable desde la red corporativa / VPN.
    No requiere autenticación.

    ## Uso rápido (curl)
    ```bash
    curl -X POST https://mdtopdf.tesmotech.com/api/convert \
      -F "file=@documento.md" \
      -F "title=Título del Documento" \
      -F "subtitle=Subtítulo opcional" \
      -F "reference=REF-001" \
      -o documento.pdf
    ```

    ## Uso rápido (PowerShell)
    ```powershell
    $form = @{
        file  = Get-Item "documento.md"
        title = "Título del Documento"
    }
    Invoke-WebRequest -Uri "https://mdtopdf.tesmotech.com/api/convert" `
        -Method Post -Form $form -OutFile "documento.pdf"
    ```

    ## Recomendaciones para clientes
    - **Tiempos reales** (medidos en producción): la conversión típica toma **1.5–3 segundos**.
      El primer request tras un despliegue puede tomar ~3–5 segundos (arranque del navegador
      de render) y los documentos con muchos diagramas Mermaid suman ~1–2 segundos.
      Configure el timeout HTTP del cliente en **≥ 60 segundos** como margen para documentos
      muy grandes o picos de carga.
    - **Concurrencia**: el servicio corre en 2 réplicas y cada una procesa hasta 4 renders
      simultáneos; los requests que exceden el cupo esperan en cola automáticamente. Para
      lotes grandes de documentos, un paralelismo de 4–8 llamados simultáneos es razonable.

    ## Tips de conversión
    - **Imágenes: embeber en base64.** El servidor no tiene acceso a rutas locales del
      cliente y las URLs externas no son confiables (el render no espera descargas remotas).
      Formato: `![diagrama](data:image/png;base64,iVBORw0KG...)`. Recuerde que el archivo
      resultante cuenta contra el límite de 5 MB.
    - **Diagramas Mermaid**: los bloques ` ```mermaid ` se renderizan como diagramas vectoriales
      (flowchart, sequence, state, pie, gantt, class, etc.). El render es local al servidor —
      no requiere internet.
    - **Saltos de página**: `<!-- pagebreak -->` en el Markdown fuerza página nueva en el PDF.
      Útil antes de secciones importantes o para evitar que una tabla quede cortada.
    - **Bloques de código**: se renderizan en fuente monoespaciada (sin resaltado de sintaxis).
      El código inline largo (rutas, comandos) se parte automáticamente en celdas de tabla.
    - **HTML inline**: el Markdown acepta HTML embebido (marked lo pasa tal cual) para
      necesidades puntuales de layout; usar con moderación.
  version: 1.0.0
  contact:
    name: Tesmotech

# Sin autenticación: el acceso se controla por red (NLB interno + VPN)
security: []

servers:
  - url: https://mdtopdf.tesmotech.com
    description: Producción
  - url: http://localhost:3000
    description: Desarrollo local (`npm start`)

paths:
  /api/convert:
    post:
      summary: Convierte un archivo Markdown a PDF con branding Tesmotech
      description: |
        Recibe un archivo Markdown vía `multipart/form-data` y devuelve el PDF generado
        con la plantilla corporativa Tesmotech (`templates/tesmotech.html`, fija — no seleccionable).

        ### Capacidades del Markdown soportado
        - **GitHub Flavored Markdown**: tablas, bloques de código, listas de tareas.
          Los saltos de línea simples se convierten en `<br>` (opción `breaks` activa).
        - **Diagramas Mermaid**: los bloques ` ```mermaid ` se renderizan como diagramas
          dentro del PDF (mermaid v11 empaquetado en el servidor — no requiere internet).
        - **Imágenes**: deben ir embebidas como data URI base64
          (`![alt](data:image/png;base64,...)`); rutas locales o URLs externas no son confiables.
        - **Saltos de página manuales**: insertar `<!-- pagebreak -->` en el Markdown
          fuerza un salto de página en el PDF.

        ### Composición del PDF resultante
        - **Portada** con título, subtítulo y referencia (si la portada está habilitada
          en la configuración del servidor).
        - **Header/footer** en cada página con logo, título y numeración "Página X de Y".
        - **Fecha del documento**: se genera automáticamente en el servidor con la fecha
          actual en formato español (es-ES). No es configurable vía API.
        - Formato A4 con fuentes y colores corporativos embebidos.
      operationId: convertMarkdownToPdf
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: |
                    Archivo Markdown a convertir. Obligatorio.
                    - Extensiones permitidas: `.md`, `.markdown`, `.txt`
                      (validadas por extensión del nombre de archivo, no por contenido).
                    - Tamaño máximo: **5 MB**.
                    - El nombre del archivo determina el nombre del PDF descargado
                      (`documento.md` → `documento.pdf`).
                title:
                  type: string
                  description: |
                    Título del documento. Aparece en la portada, el encabezado de cada
                    página y el cuerpo del documento.
                    Si se omite, se usa el valor por defecto `"Documento"`.
                  example: Validaciones Bancarias — Reglas de Negocio
                subtitle:
                  type: string
                  description: |
                    Subtítulo del documento. Opcional.
                    Si se omite o va vacío, la sección de subtítulo **no aparece** en el
                    PDF (render condicional de la plantilla).
                  example: Especificación funcional v2
                reference:
                  type: string
                  description: |
                    Código de referencia del documento. Opcional.
                    Si se omite o va vacío, la sección de referencia **no aparece** en el
                    PDF (render condicional de la plantilla).
                  example: GDI-32
            encoding:
              file:
                contentType: text/markdown, text/plain
      responses:
        '200':
          description: PDF generado exitosamente. Se devuelve como descarga adjunta.
          headers:
            Content-Disposition:
              description: >-
                `attachment; filename="<nombre-original>.pdf"` — el nombre se deriva
                del archivo Markdown subido.
              schema:
                type: string
                example: attachment; filename="documento.pdf"
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        '400':
          description: |
            Solicitud inválida. Casos:
            - No se envió el campo `file`.
            - La extensión del archivo no está permitida (solo `.md`, `.markdown`, `.txt`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                sinArchivo:
                  summary: Campo file ausente
                  value:
                    error: No se proporcionó archivo
                extensionInvalida:
                  summary: Extensión no permitida
                  value:
                    error: 'Extensión no permitida: .docx. Use .md, .markdown, .txt'
        '413':
          description: El archivo excede el límite de 5 MB.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                archivoGrande:
                  summary: Archivo demasiado grande
                  value:
                    error: File too large
        '500':
          description: |
            Error interno durante la conversión (por ejemplo, timeout de renderizado
            en documentos muy grandes).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                errorConversion:
                  summary: Error de conversión
                  value:
                    error: 'Error al convertir: La generacion del PDF excedio el timeout configurado.'

  /api/v1/health:
    get:
      summary: Health check
      description: >-
        Endpoint de salud usado por los probes de Kubernetes (readiness/liveness).
        Útil para verificar conectividad con el servicio antes de convertir.
      operationId: healthCheck
      responses:
        '200':
          description: El servicio está operativo.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok

components:
  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
          description: Mensaje de error legible (en español).
      required:
        - error
