{
  "openapi": "3.0.3",
  "info": {
    "title": "Invoice API RD",
    "description": "API para procesar facturas de Republica Dominicana desde imagenes. Autentica por header X-API-Key.",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "/"
    }
  ],
  "tags": [
    {
      "name": "health",
      "description": "Estado y dependencias del servicio"
    },
    {
      "name": "invoice",
      "description": "Procesamiento y consulta de requests"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Clave API asignada al proveedor autorizado."
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "error"
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "integer",
                "example": 401
              },
              "message": {
                "type": "string",
                "example": "API Key requerida"
              },
              "details": {
                "type": "string",
                "example": "Missing API Key"
              }
            }
          },
          "request_id": {
            "type": "string",
            "nullable": true,
            "example": null
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "InvoiceProcessResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "success"
          },
          "request_id": {
            "type": "string",
            "example": "REQ/2026/02/00001"
          },
          "invoice": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer",
                "example": 456
              },
              "number": {
                "type": "string",
                "example": "BILL/2026/02/0007"
              },
              "state": {
                "type": "string",
                "example": "draft"
              },
              "partner_id": {
                "type": "integer",
                "example": 89
              },
              "partner_name": {
                "type": "string",
                "example": "Proveedor Ejemplo SRL"
              },
              "date": {
                "type": "string",
                "format": "date"
              },
              "amount_total": {
                "type": "number",
                "format": "float",
                "example": 1180.0
              },
              "url": {
                "type": "string",
                "example": "/web#id=456&model=account.move&view_type=form"
              }
            }
          },
          "processing": {
            "type": "object",
            "properties": {
              "time_seconds": {
                "type": "number",
                "format": "float",
                "example": 0.842
              },
              "confidence": {
                "type": "number",
                "format": "float",
                "example": 0.85
              },
              "extracted_fields": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "example": [
                  "ncf",
                  "rnc",
                  "fecha",
                  "subtotal",
                  "itbis",
                  "total"
                ]
              }
            }
          },
          "message": {
            "type": "string",
            "example": "Factura procesada exitosamente y creada en estado borrador"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RequestStatusResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "success"
          },
          "request": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": "REQ/2026/02/00001"
              },
              "state": {
                "type": "string",
                "example": "success"
              },
              "created_at": {
                "type": "string",
                "format": "date-time"
              },
              "processing_time": {
                "type": "number",
                "format": "float",
                "example": 0.842
              },
              "confidence": {
                "type": "number",
                "format": "float",
                "example": 0.85
              }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/api/rd/v1/health": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Health check basico",
        "description": "Verifica estado general, estadisticas y dependencias.",
        "responses": {
          "200": {
            "description": "Servicio operativo"
          },
          "500": {
            "description": "Error interno del servidor"
          }
        }
      }
    },
    "/api/rd/v1/health/detailed": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Health check detallado por proveedor",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Estado detallado del proveedor"
          },
          "401": {
            "description": "API Key invalida o faltante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Limite diario excedido"
          },
          "500": {
            "description": "Error interno del servidor"
          }
        }
      }
    },
    "/api/rd/v1/invoice/process": {
      "post": {
        "tags": [
          "invoice"
        ],
        "summary": "Procesar factura desde imagen",
        "description": "Acepta multipart/form-data o JSON con imagen en base64. También permite enviar campos directos de factura.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "image"
                ],
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "binary"
                  },
                  "ncf": {
                    "type": "string",
                    "description": "NCF tradicional B + 10 dígitos o e-CF E + 12 dígitos.",
                    "example": "B0100000001"
                  },
                  "rnc": {
                    "type": "string"
                  },
                  "fecha": {
                    "type": "string",
                    "format": "date"
                  },
                  "nombre_proveedor": {
                    "type": "string"
                  },
                  "subtotal": {
                    "type": "number",
                    "format": "float"
                  },
                  "itbis": {
                    "type": "number",
                    "format": "float"
                  },
                  "total": {
                    "type": "number",
                    "format": "float"
                  },
                  "descripcion": {
                    "type": "string"
                  },
                  "moneda": {
                    "type": "string"
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "image"
                ],
                "properties": {
                  "image": {
                    "type": "string",
                    "description": "Imagen codificada en base64."
                  },
                  "image_base64": {
                    "type": "string",
                    "description": "Alias opcional de image para compatibilidad."
                  },
                  "filename": {
                    "type": "string",
                    "example": "factura.jpg"
                  },
                  "ncf": {
                    "type": "string",
                    "description": "NCF tradicional B + 10 dígitos o e-CF E + 12 dígitos.",
                    "example": "E310000001799"
                  },
                  "rnc": {
                    "type": "string"
                  },
                  "fecha": {
                    "type": "string",
                    "format": "date"
                  },
                  "nombre_proveedor": {
                    "type": "string"
                  },
                  "subtotal": {
                    "type": "number",
                    "format": "float"
                  },
                  "itbis": {
                    "type": "number",
                    "format": "float"
                  },
                  "total": {
                    "type": "number",
                    "format": "float"
                  },
                  "descripcion": {
                    "type": "string"
                  },
                  "moneda": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Factura procesada correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceProcessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Request invalido o error de validacion"
          },
          "401": {
            "description": "API Key invalida o faltante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Limite diario excedido"
          },
          "500": {
            "description": "Error interno del servidor"
          }
        }
      }
    },
    "/api/rd/v1/invoice/status/{request_id}": {
      "get": {
        "tags": [
          "invoice"
        ],
        "summary": "Consultar estado de un request",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "REQ/2026/02/00001"
          }
        ],
        "responses": {
          "200": {
            "description": "Estado del request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequestStatusResponse"
                }
              }
            }
          },
          "401": {
            "description": "API Key invalida o faltante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Request no encontrado"
          },
          "429": {
            "description": "Limite diario excedido"
          },
          "500": {
            "description": "Error interno del servidor"
          }
        }
      }
    }
  }
}