openapi: 3.0.0
info:
  title: "Estándar Para Las APIs De Exportación De Datos De Lotería"
  description: |
    Especificación para las APIs de exportación de datos de lotería, diseñada para ser implementada por sistemas heterogéneos, soportando formatos JSON y XML. 
    
    El objetivo es homogeneizar la forma en que los datos son expuestos.
    
    ## Características principales:
    - Soporte dual para JSON y XML
    - Autenticación Bearer Token
    - Filtrado flexible por entidad, moneda, fechas y tipo de lotería
    - Validación robusta de parámetros
    
    ## Límites importantes:
    - Solo se pueden consultar datos hasta el día anterior (fecha actual -1)
    - fechaDesde debe ser menor o igual a fechaHasta
    - Token de acceso válido por 7 días (604800 segundos)
  contact:
    name: "Ing. Ben Gonzalez"
    email: "ben.gonzalez@example.com"
  version: "1.2"
  license:
    name: "MIT"
    url: "https://opensource.org/licenses/MIT"

servers:
  - url: "https://{ip}:{puerto}/api/v1"
    description: "Servidor de producción"
    variables:
      ip:
        default: "localhost"
        description: "Dirección IP o dominio del servidor"
      puerto:
        default: "8080"
        description: "Puerto del servidor"

tags:
  - name: "Autenticación"
    description: "Endpoints para gestión de tokens de acceso"
  - name: "Catálogos"
    description: "Endpoints para obtener listas de tipos de lotería y juegos"
  - name: "Exportaciones"
    description: "Endpoints para exportación de datos de contabilidad"

paths:
  /auth/token:
    post:
      tags: ["Autenticación"]
      summary: "Obtiene un token de autenticación"
      description: "Valida las credenciales de usuario y retorna un token de acceso Bearer válido por 7 días."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AuthRequest"
            example:
              username: "admin-user"
              password: "secure-password-123"
          application/xml:
            schema:
              $ref: "#/components/schemas/AuthRequest"
            example: |
              <AuthRequest>
                <username>admin-user</username>
                <password>secure-password-123</password>
              </AuthRequest>
      responses:
        "200":
          description: "Autenticación exitosa. Retorna el token de acceso."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthResponse"
              example:
                tokenType: "Bearer"
                expiresIn: 604800
                accessToken: "lksUJKdfGJKuJYiw78we3gkjkkjhjkdsJHHJJHJFDDD"
            application/xml:
              schema:
                $ref: "#/components/schemas/AuthResponse"
              example: |
                <AuthResponse>
                  <tokenType>Bearer</tokenType>
                  <expiresIn>604800</expiresIn>
                  <accessToken>lksUJKdfGJKuJYiw78we3gkjkkjhjkdsJHHJJHJFDDD</accessToken>
                </AuthResponse>
        "401":
          description: "No autorizado. Credenciales inválidas."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error:
                  codigo: "INVALID-CREDENTIALS"
                  mensaje: "El usuario o la contraseña son incorrectos."
            application/xml:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /tipo-loteria:
    get:
      tags: ["Catálogos"]
      summary: "Obtiene la lista de tipos de lotería"
      description: "Retorna una lista de todos los tipos de lotería disponibles para consulta."
      security:
        - bearerAuth: []
      responses:
        "200":
          description: "Lista de tipos de lotería."
          content:
            application/json:
              schema:
                type: object
                properties:
                  tipoLoteria:
                    type: array
                    items:
                      type: string
                      enum: [triple, terminal, recargas, multijuego, juego-electronico, animalito]
              example:
                tipoLoteria: ["triple", "terminal", "recargas", "multijuego", "juego-electronico", "animalito"]
            application/xml:
              schema:
                $ref: "#/components/schemas/TiposLoteriaResponse"
        "401":
          $ref: "#/components/responses/UnauthorizedError"

  /juegos:
    get:
      tags: ["Catálogos"]
      summary: "Obtiene la lista de todos los juegos"
      description: "Retorna una lista de todos los juegos disponibles en el sistema."
      security:
        - bearerAuth: []
      responses:
        "200":
          description: "Lista de todos los juegos."
          content:
            application/json:
              schema:
                type: object
                properties:
                  juegos:
                    type: array
                    items:
                      type: string
              example:
                juegos: ["activo", "bomba", "caliente", "granjita", "lotto-activo", "ruleta-activa", "uneloton", "zulia"]
            application/xml:
              schema:
                $ref: "#/components/schemas/JuegosResponse"
        "401":
          $ref: "#/components/responses/UnauthorizedError"

  /tipos-loteria/{tipoLoteriaId}/juegos:
    get:
      tags: ["Catálogos"]
      summary: "Obtiene los juegos por tipo de lotería"
      description: "Retorna una lista de juegos asociados a un tipo de lotería específico."
      security:
        - bearerAuth: []
      parameters:
        - name: "tipoLoteriaId"
          in: "path"
          required: true
          description: "El identificador del tipo de lotería."
          schema:
            type: string
            enum: [triple, terminal, recargas, multijuego, juego-electronico, animalito]
          example: "triple"
      responses:
        "200":
          description: "Lista de juegos para el tipo de lotería especificado."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TipoLoteriaJuegosResponse"
              example:
                tipoLoteria: "triple"
                juegos: ["trio-activo", "chance", "terminaltrio"]
            application/xml:
              schema:
                $ref: "#/components/schemas/TipoLoteriaJuegosResponse"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          description: "Tipo de lotería no encontrado."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /exportaciones:
    get:
      tags: ["Exportaciones"]
      summary: "Realiza una exportación de datos"
      description: |
        Obtiene datos de contabilidad filtrados según los parámetros proporcionados.
        
        **Limitaciones importantes:**
        - Solo se pueden consultar datos hasta el día anterior (fecha actual -1)
        - fechaDesde debe ser menor o igual a fechaHasta
        - Para tipoLoteria=multijuego, el parámetro juego será ignorado
      security:
        - bearerAuth: []
      parameters:
        - name: "entidad"
          in: "query"
          required: true
          description: "Filtra por agencias ('ag') o distribuidores ('rc')."
          schema:
            type: string
            enum: [ag, rc]
          example: "rc"
        - name: "moneda"
          in: "query"
          required: false
          description: "Filtra por moneda. Por defecto es 'ved' (bolívares digitales)."
          schema:
            type: string
            enum: [ved, usd]
            default: "ved"
          example: "ved"
        - name: "fechaDesde"
          in: "query"
          required: true
          description: "Fecha inicial de la consulta en formato YYYY-MM-DD. Debe ser anterior a la fecha actual."
          schema:
            type: string
            format: date
          example: "2025-07-01"
        - name: "fechaHasta"
          in: "query"
          required: false
          description: "Fecha final de la consulta en formato YYYY-MM-DD. Si no se especifica, se usa la fecha anterior a la consulta."
          schema:
            type: string
            format: date
          example: "2025-07-03"
        - name: "tipoLoteria"
          in: "query"
          required: false
          description: "Define el tipo de lotería. Por defecto es 'multijuego'."
          schema:
            type: string
            enum: [triple, terminal, recargas, multijuego, juego-electronico, animalito]
            default: "multijuego"
          example: "triple"
        - name: "juego"
          in: "query"
          required: false
          description: "Define un juego específico. Se ignora si tipoLoteria es 'multijuego'."
          schema:
            type: string
          example: "trio-activo"
      responses:
        "200":
          description: "Exportación de datos exitosa."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExportResponse"
              examples:
                consulta_especifica:
                  summary: "Consulta específica por juego"
                  value:
                    metadata:
                      entidad: "rc"
                      moneda: "ved"
                      fechaDesde: "2025-07-01"
                      fechaHasta: "2025-07-03"
                      tipoLoteria: "triple"
                      juego: "trio-activo"
                    salidaConsulta:
                      - nombre: "distribuidor-1"
                        venta: 12865
                        premio: 4500
                        porcentajeVenta: 1801.1
                        total: 6563.9
                        tipoLoteria: "triple"
                        juego: "trio-activo"
                consulta_multijuego:
                  summary: "Consulta multijuego"
                  value:
                    metadata:
                      entidad: "ag"
                      moneda: "usd"
                      fechaDesde: "2025-07-01"
                      fechaHasta: "2025-07-03"
                      tipoLoteria: "multijuego"
                      juego: null
                    salidaConsulta:
                      - nombre: "agencia-1"
                        venta: 12865
                        premio: 4500
                        porcentajeVenta: 1801.1
                        total: 6563.9
                        tipoLoteria: "triple"
                        juego: "trio-activo"
            application/xml:
              schema:
                $ref: "#/components/schemas/ExportResponse"
        "400":
          description: "Petición incorrecta."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                invalid_date_range:
                  summary: "Rango de fechas inválido"
                  value:
                    error:
                      codigo: "INVALID-DATE-RANGE"
                      mensaje: "La fechaDesde no puede ser mayor que la fechaHasta."
                future_date:
                  summary: "Consulta fecha futura"
                  value:
                    error:
                      codigo: "FUTURE-DATE-QUERY"
                      mensaje: "No se pueden consultar datos de la fecha actual; los datos se actualizan hasta el día anterior."
        "401":
          $ref: "#/components/responses/UnauthorizedError"

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: "Token de acceso obtenido desde el endpoint /auth/token. Válido por 7 días."

  responses:
    UnauthorizedError:
      description: "No autorizado. El token es inválido o ha expirado."
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            error:
              codigo: "TOKEN-INVALID"
              mensaje: "Token de autenticación inválido o expirado."
        application/xml:
          schema:
            $ref: "#/components/schemas/ErrorResponse"

  schemas:
    AuthRequest:
      type: object
      required:
        - username
        - password
      xml:
        name: "AuthRequest"
      properties:
        username:
          type: string
          description: "Nombre de usuario para autenticación"
          minLength: 3
          maxLength: 50
          example: "admin-user"
        password:
          type: string
          description: "Contraseña del usuario"
          minLength: 8
          maxLength: 100
          format: password
          example: "secure-password-123"
    
    AuthResponse:
      type: object
      xml:
        name: "AuthResponse"
      properties:
        tokenType:
          type: string
          description: "Tipo de token (siempre 'Bearer')"
          example: "Bearer"
        expiresIn:
          type: integer
          format: int64
          description: "Tiempo de expiración del token en segundos"
          example: 604800
        accessToken:
          type: string
          description: "Token de acceso JWT"
          example: "lksUJKdfGJKuJYiw78we3gkjkkjhjkdsJHHJJHJFDDD"
    
    TiposLoteriaResponse:
      type: object
      xml:
        name: "TiposLoteriaResponse"
      properties:
        tipoLoteria:
          type: array
          description: "Lista de tipos de lotería disponibles"
          xml:
            wrapped: false
          items:
            type: string
            xml:
              name: "tipoLoteria"
            enum: [triple, terminal, recargas, multijuego, juego-electronico, animalito]
    
    JuegosResponse:
      type: object
      xml:
        name: "JuegosResponse"
      properties:
        juegos:
          type: array
          description: "Lista de todos los juegos disponibles"
          xml:
            wrapped: false
          items:
            type: string
            xml:
              name: "juego"
    
    TipoLoteriaJuegosResponse:
      type: object
      xml:
        name: "TipoLoteriaJuegosResponse"
      properties:
        tipoLoteria:
          type: string
          description: "Tipo de lotería consultado"
          example: "triple"
        juegos:
          type: array
          description: "Lista de juegos asociados al tipo de lotería"
          xml:
            name: "juegos"
            wrapped: true
          items:
            type: string
            xml:
              name: "juego"
    
    ExportResponse:
      type: object
      xml:
        name: "ExportResponse"
      properties:
        metadata:
          $ref: "#/components/schemas/Metadata"
        salidaConsulta:
          type: array
          description: "Resultados de la consulta"
          xml:
            name: "salidaConsulta"
            wrapped: true
          items:
            $ref: "#/components/schemas/ItemConsulta"
    
    Metadata:
      type: object
      xml:
        name: "metadata"
      properties:
        entidad:
          type: string
          description: "Tipo de entidad consultada"
          enum: [ag, rc]
          example: "rc"
        moneda:
          type: string
          description: "Moneda de los valores"
          enum: [ved, usd]
          example: "ved"
        fechaDesde:
          type: string
          format: date
          description: "Fecha inicial de la consulta"
          example: "2025-07-01"
        fechaHasta:
          type: string
          format: date
          description: "Fecha final de la consulta"
          example: "2025-07-03"
        tipoLoteria:
          type: string
          description: "Tipo de lotería consultado"
          example: "triple"
        juego:
          type: string
          nullable: true
          description: "Juego específico consultado (null para multijuego)"
          example: "trio-activo"
    
    ItemConsulta:
      type: object
      xml:
        name: "item"
      properties:
        nombre:
          type: string
          description: "Nombre del distribuidor o agencia"
          example: "distribuidor-1"
        venta:
          type: number
          format: double
          description: "Monto total de ventas"
          minimum: 0
          example: 12865.0
        premio:
          type: number
          format: double
          description: "Monto total de premios pagados"
          minimum: 0
          example: 4500.0
        porcentajeVenta:
          type: number
          format: double
          description: "Porcentaje de comisión sobre ventas"
          minimum: 0
          example: 1801.1
        total:
          type: number
          format: double
          description: "Balance total (venta - premio - porcentajeVenta)"
          example: 6563.9
        tipoLoteria:
          type: string
          description: "Tipo de lotería del registro"
          example: "triple"
        juego:
          type: string
          description: "Juego específico del registro"
          example: "trio-activo"
    
    ErrorResponse:
      type: object
      xml:
        name: "ErrorResponse"
      properties:
        error:
          type: object
          xml:
            name: "error"
          properties:
            codigo:
              type: string
              description: "Código de error identificador"
              example: "TOKEN-INVALID"
            mensaje:
              type: string
              description: "Mensaje descriptivo del error"
              example: "Token de autenticación inválido o expirado."