openapi: 3.0.1
info:
  version: 4.2.0
  title: API REST de Backend1n-Service
  description: Solución para la identificación de patrones biométricos 1N, con soporte de base de datos.

servers:
 - url: http://127.0.0.1:6982/

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

  schemas:

    ImageBuffer:
      type: string
      example: /9j/4Rf+RXhpZgAASUkqAAgA...
      description: Buffer de imagen en formato JPEG, PNG o BMP, codificado en base64 RFC4648.

    FacialTemplate:
      type: string
      example: BAEBGgFQqzQ2WO571UW5f4FF...
      description: Patrón biométrico facial, codificado en base64 RFC4648.

    FacialTemplateRaw:
      type: string
      example: QTevT1Lv5jr0rNyzS3u6SAscolMU+bHitq...
      description: Un token extendido que contiene patrones biométricos y metadatos. Se recomienda su almacenamiento en bases de datos por ser persistente. Puede actualizarse automáticamente en caso de cambios en la tecnología de extracción. Está codificado en base64 RFC4648.

    UpdatedTemplateRaw:
      type: boolean
      default: false
      example: false
      description: Si es true, significa que el templateRaw se ha actualizado tras una operación de extracción. Esto se puede usar para determinar si el templateRaw debe actualizarse en las bases de datos.

    BinaryImage:
      type: string
      format: binary
      example: FF D8 FF E1 17 FE 45 78 69 66 00 00 49 49 2A 00 ...
      description: Datos binarios de imagen en formato JPEG, PNG o BMP.

    FaceId:
      type: string
      example: 6782225b-1793-4b68-a9de-8fdb3628c7e5
      description: Un identificador de un espécimen (rostro) en la base de datos.

    TenantId:
      type: string
      example: 57fbc814-3f40-402c-9d29-262f99c3b896
      description: Un identificador que permite agrupar distintas imágenes o patrones biométricos en un espacio común.

    MediaId:
      type: string
      example: 9c79c818-b81a-4959-b65a-a2b0c8143528
      description: Un identificador de imagen en la base de datos.

    MimeType:
      type: string
      example: image/png
      description: Identificador del formato del archivo.

    TemplateRawExraction:
      type: boolean
      default: false
      example: false
      description: Si es true, se calculará el templateRaw.

    MaxCandidates:
      type: integer
      default: 1
      example: 5
      description: El número máximo de candidatos que se desean en la respuesta.

    MinSimilarity:
      type: number
      default: 0
      example: 0.65
      description: La similitud mínima requerida para que un candidato se incluya en la respuesta.

    Similarity:
      type: number
      default: 0
      example: 0.65
      description: Un valor entre 0 y 1 que indica el valor de similitud entre dos patrones biométricos.

    GalleryIndex:
      type: integer
      example: 5
      description: La posición que ocupa un elemento en la galería.

    ExtractOptions:
      type: object
      description: Opciones al extraer patrones biométricos.
      properties:
        templateRawExtraction:
          $ref: '#/components/schemas/TemplateRawExraction'

    SearchOptions:
      type: object
      description: Opciones al buscar patrones biométricos.
      properties:
        maxCandidates:
          $ref: '#/components/schemas/MaxCandidates'
        minSimilariry:
          $ref: '#/components/schemas/MinSimilarity'

    FaceDescription:
      type: string
      example: It's a description of the person
      description: Descripción del espécimen (rostro) que se almacena en la base de datos.

    CreateAt:
      type: string
      example: "2024-11-20T15:39:32Z"
      description: Valor de fecha/hora en formato "%Y-%m-%dT%H:%M:%SZ" en el que se creó un espécimen (rostro).

    UpdateAt:
      type: string
      example: "2025-03-18T12:54:02Z"
      description: Valor de fecha/hora en formato "%Y-%m-%dT%H:%M:%SZ" en el que se actualizó un espécimen (rostro).

    TimeStamp:
      type: string
      description: Un valor de fecha/hora en formato "%Y-%m-%dT%H:%M:%SZ".
      example: "2022-01-14T10:42:05.521922Z"

    ExtractBody:
      type: object
      description: Body para la solicitud de extract
      properties:
        image:
          $ref: '#/components/schemas/ImageBuffer'
        options:
          $ref: '#/components/schemas/ExtractOptions'
      required:
        - image

    ExtractTemplateBody:
      type: object
      description: Body para la solicitud de extracción a partir de un template
      properties:
        facialTemplateRaw:
          $ref: '#/components/schemas/FacialTemplateRaw'
        options:
          $ref: '#/components/schemas/ExtractOptions'
      required:
        - facialTemplateRaw

    AssetUploadBody:
      type: object
      description: Body para la solicitud de subida de recursos (asset) en `multipart/form-data`
      properties:
        file:
          $ref: '#/components/schemas/BinaryImage'
        tenantId:
          $ref: '#/components/schemas/TenantId'
        mimeType:
          $ref: '#/components/schemas/MimeType'
      required:
        - file
        - tenantId
        - mimeType

    FaceBody:
      type: object
      description: Body para la solicitud POST de face
      properties:
        mediaId:
          $ref: '#/components/schemas/MediaId'
        tenantId:
          $ref: '#/components/schemas/TenantId'
        description:
          $ref: '#/components/schemas/FaceDescription'
      required:
        - mediaId
        - tenantId
        - description

    SearchImageBody:
      type: object
      description: Body para la solicitud POST de búsqueda por imagen
      properties:
        image:
          $ref: '#/components/schemas/ImageBuffer'
        options:
          $ref: '#/components/schemas/SearchOptions'
      required:
        - image

    SearchTemplateBody:
      type: object
      description: Body para la solicitud POST de búsqueda por template
      properties:
        facialTemplateRaw:
          $ref: '#/components/schemas/FacialTemplateRaw'
        options:
          $ref: '#/components/schemas/SearchOptions'
      required:
        - image

    ConfigBody:
      type: object
      description: Body para la solicitud de config. Este endpoint no acepta parámetros de autenticación JWT.
      properties:
        config_json_string:
          type: string
          description: Cadena JSON con los parámetros de configuración del servicio.
          example: "{\"fake_param\":\"fake\",\"number_of_threads\":\"2\"}"
      required:
        - config_json_string

    ExtractResponse:
      type: object
      description: Respuesta de extracción biométrica
      properties:
        facialTemplate:
          $ref: '#/components/schemas/FacialTemplate'
        facialTemplateRaw:
          $ref: '#/components/schemas/FacialTemplateRaw'
        updatedTemplateRaw:
          $ref: '#/components/schemas/UpdatedTemplateRaw'

    UploadMediaResponse:
      type: object
      description: Respuesta de subida de recursos multimedia
      properties:
        id:
          $ref: '#/components/schemas/MediaId'

    FaceResponse:
      type: object
      description: Campos de datos del espécimen en la base de datos
      properties:
        createAt:
          $ref: '#/components/schemas/CreateAt'
        description:
          $ref: '#/components/schemas/FaceDescription'
        facialTemplateRaw:
          $ref: '#/components/schemas/FacialTemplateRaw'
        id:
          $ref: '#/components/schemas/FaceId'
        mediaId:
          $ref: '#/components/schemas/MediaId'
        tenantId:
          $ref: '#/components/schemas/TenantId'
        updateAt:
          $ref: '#/components/schemas/UpdateAt'

    FacesResponse:
      type: array
      description: Campos de datos de varios especímenes en la base de datos
      items:
          $ref: '#/components/schemas/FaceResponse'

    SearchItem:
      type: object
      description: Espécimen encontrado en la base de datos
      properties:
        galleryIndex:
          $ref: '#/components/schemas/GalleryIndex'
        similarity:
          $ref: '#/components/schemas/Similarity'
        templateId:
          $ref: '#/components/schemas/FaceId'

    SearchResponse:
      type: array
      description: Una lista de especímenes (rostros) encontrados en la base de datos
      items:
          $ref: '#/components/schemas/SearchItem'

    ConfigResult:
      type: object
      description: Objeto JSON con los parámetros de configuración del servicio expuestos por el endpoint de gestión. Los parámetros de autenticación JWT se omiten intencionadamente.
      example: {
        "port": 6982,
        "number_of_threads": 1,
        "connection_timeout": 0,
        "keep_alive_request_number": 0,
        "client_max_body_size": 100,
        "logger_path": "",
        "logger_level": "off",
        "logger_rotation": "daily",
        "logger_max_files": 7
      }

    BadRequestResult:
      type: object
      description: Resultado cuando llegan parámetros incorrectos en la solicitud.
      properties:
        status:
          type: number
          example: 400
        error:
          type: string
          example: "BadRequest"
        timeStamp:
          $ref: '#/components/schemas/TimeStamp'

    ExceptionResult:
      type: object
      description: Se ha producido un error en la llamada a los servicios del backend.
      properties:
        status:
          type: number
          example: 500
        error:
          type: string
          example: "SelphID-SDK Exception"
        exception:
          type: string
          example: "Bad format"
        timeStamp:
          $ref: '#/components/schemas/TimeStamp'

    HealthStatus:
      type: string
      description: Resultado del servicio de salud (indica si el SDK está activo o no).
      example: "Healthy"
      enum:
        - Healthy
        - Unhealthy

    HealthResult:
      type: object
      description: El resultado de una comprobación de salud.
      properties:
        message:
          $ref: '#/components/schemas/HealthStatus'

    VersionResult:
      type: object
      description: El resultado de una comprobación de versión.
      properties:
        message:
          type: string
          example: "4.2.0 Copyright @ 2026 FacePhi. All rights reserved."

security:
  - BearerAuth: []
  - ApiKeyAuth: []

paths:
  /extract:
    post:
      description: Este endpoint extrae el `facialTemplate` a partir de una imagen en bruto. Es únicamente informativo y no modifica la base de datos.

      tags:
        - Extract

      requestBody:
        description: Json con la imagen de entrada codificada en formato base64 RFC4648.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExtractBody'

      responses:
        '200':
          description: El resultado de la extracción.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExtractResponse'

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

  /extract/template:
    post:
      description: Este endpoint extrae el `facialTemplate` a partir de un templateRaw en bruto. Es únicamente informativo y no modifica la base de datos.

      tags:
        - Extract

      requestBody:
        description: Json con el template raw de entrada codificado en formato base64 RFC4648.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExtractTemplateBody'

      responses:
        '200':
          description: El resultado de la extracción.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExtractResponse'

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

  /assets/upload:
    post:
      description: Guarda una imagen en la base de datos.

      tags:
        - Media

      requestBody:
        description: Datos de imagen en multipart/form-data.
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AssetUploadBody'

      responses:
        '200':
          description: El resultado de la subida.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadMediaResponse'

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

  /assets/media/{mediaId}:
    get:
      description: Recupera y descarga una imagen de la base de datos.

      tags:
        - Media

      parameters:
      - in: path
        name: mediaId
        schema:
          $ref: '#/components/schemas/MediaId'
        required: true

      responses:
        '200':
          description: El archivo.
          content:
            image/png:
              schema:
                $ref: '#/components/schemas/BinaryImage'
            image/jpg:
              schema:
                $ref: '#/components/schemas/BinaryImage'

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'


  /faces:
    post:
      description: Añade un nuevo espécimen (rostro) a la base de datos. Primero, se busca la imagen referenciada en la base de datos y se extrae su patrón biométrico.

      tags:
        - Faces

      requestBody:
        description: Datos necesarios para añadir un nuevo espécimen (rostro) a la base de datos.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FaceBody'

      responses:
        '200':
          description: Todos los campos de datos del espécimen (rostro) almacenado en la base de datos.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FaceResponse'

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

    get:
      description: Recupera todos los especímenes (rostros) de la base de datos que coinciden con el tenantId. Si se omite, se devolverán todos los elementos.

      tags:
        - Faces

      parameters:
      - in: query
        name: tenantId
        schema:
          $ref: '#/components/schemas/TenantId'
        required: true

      responses:
        '200':
          description: Todos los especímenes (rostros) almacenados en la base de datos con el mismo tenantId.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FacesResponse'

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

  /faces/{Id}:
    get:
      description: Recupera el espécimen (rostro) con el mismo Id.

      tags:
        - Faces

      parameters:
      - in: path
        name: Id
        schema:
          $ref: '#/components/schemas/FaceId'
        required: true

      responses:
        '200':
          description: El espécimen (rostro) almacenado en la base de datos con el mismo Id.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FaceResponse'

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

    put:
      description: Actualiza el espécimen (rostro) con el mismo Id en la base de datos.

      tags:
        - Faces

      parameters:
      - in: path
        name: Id
        schema:
          $ref: '#/components/schemas/FaceId'
        required: true

      requestBody:
        description: Datos necesarios para actualizar el espécimen (rostro) en la base de datos.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FaceBody'

      responses:
        '200':
          description: Los datos actualizados del espécimen almacenados en la base de datos.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FaceResponse'

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

    delete:
      description: Elimina el espécimen (rostro) con el mismo Id de la base de datos.

      tags:
        - Faces

      parameters:
      - in: path
        name: Id
        schema:
          $ref: '#/components/schemas/FaceId'
        required: true

      responses:
        '200':
          description: Los datos actualizados del espécimen almacenados en la base de datos.
          content:
            application/json:
              schema:
                type: boolean
                example: true
                description: true si el espécimen fue eliminado

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

  /search/image/{tenantId}:
    post:
      description: Busca un patrón biométrico, extraído de una imagen en bruto, entre los especímenes (rostros) almacenados en la base de datos, bajo el mismo tenantId.

      tags:
        - Search

      parameters:
      - in: path
        name: tenantId
        schema:
          $ref: '#/components/schemas/TenantId'
        required: true

      requestBody:
        description: Json con la imagen de entrada codificada en formato base64 RFC4648 y las opciones de búsqueda.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchImageBody'

      responses:
        '200':
          description: El resultado de la búsqueda, una lista de ids de template.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend de Voice-SDK.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

  /search/template/{tenantId}:
    post:
      description: Busca un patrón biométrico, extraído de un template raw, entre los especímenes (rostros) almacenados en la base de datos, bajo el mismo tenantId.

      tags:
        - Search

      parameters:
      - in: path
        name: tenantId
        schema:
          $ref: '#/components/schemas/TenantId'
        required: true

      requestBody:
        description: Json con el template raw de entrada codificado en formato base64 RFC4648 y las opciones de búsqueda.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchTemplateBody'

      responses:
        '200':
          description: El resultado de la búsqueda, una lista de ids de template.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend de Voice-SDK.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

  /health:
    get:
      description: Comprueba si el servicio está activo.
      security: []

      tags:
        - Management

      responses:
        '200':
          description: Un mensaje con el estado de salud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResult'
        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'
        '500':
          description: Se ha producido un error en la llamada al backend de Voice-SDK.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

  /version:
    get:
      description: Comprueba la versión del servicio.
      security: []
      tags:
        - Management

      responses:
        '200':
          description: Un mensaje con la versión.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VersionResult'
        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'
        '500':
          description: Se ha producido un error en la llamada al backend de Voice-SDK.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'

  /config:
    get:
      description: Obtiene la configuración del servicio.
      tags:
        - Management

      responses:
        '200':
          description: Objeto JSON con la configuración del servicio.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConfigResult'
        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'
        '500':
          description: Se ha producido un error en la llamada al backend de Voice-SDK.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'
    post:
      description: Actualiza la configuración del servicio. Solo algunos parámetros pueden actualizarse en tiempo de ejecución.
                   Los parámetros relacionados con la red (port, timeouts, tamaño de body...) o el logger (path, level...) no pueden actualizarse en tiempo de ejecución.
      tags:
        - Management

      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConfigBody'
        required: true

      responses:
        '200':
          description: Mensaje con el resultado de la operación.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "Configuration updated successfully"

        '400':
          description: Llegan parámetros incorrectos en la solicitud.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResult'

        '500':
          description: Se ha producido un error en la llamada al backend de Voice-SDK.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExceptionResult'
