openapi: 3.1.0
info:
  title: POI
  description: "Esta API es parte de **Transcend** y corresponde al módulo de Puntos\
    \ de Interés (POI).\n\nProporciona endpoints para buscar Puntos de Interés (POIs),\
    \ con un enfoque principal actual en aparcamientos para camiones. Las búsquedas\
    \ se pueden realizar por:\n- Ubicación (coordenadas)\n- Código postal (para aparcamientos)\n\
    - Provincia (para aparcamientos)\n- Proximidad a una ruta (path)\n- Cercanía a\
    \ una ciudad\n\nLa estructura de la API está diseñada para soportar diversos tipos\
    \ de POIs (ej. aparcamientos, gasolineras, restaurantes), aunque la implementación\
    \ actual se centra en aparcamientos para varias rutas.\n\n**Nota**: \n- Todos\
    \ los endpoints excepto /test y /health requieren autenticación mediante token\
    \ JWT.\n"
  version: 1.07.071447
  contact:
    email: support@cargoffer.com
  license:
    name: API Privada - Acceso solo por acuerdo
servers:
- url: https://api.pro.cargoffer.com
  description: Producción
components:
  parameters:
    LangParam:
      in: query
      name: lang
      schema:
        type: string
        enum:
        - es
        - en
        - fr
        - de
        - pt
        default: es
      description: 'Idioma de respuesta. Valores soportados: es, en, fr, de, pt. Por
        defecto: es'
      example: es
  schemas:
    Parking:
      type: object
      properties:
        id:
          type: string
          description: ID del aparcamiento
        name:
          type: string
          description: Nombre del aparcamiento
        location:
          type: object
          properties:
            type:
              type: string
              enum:
              - Point
            coordinates:
              type: array
              items:
                type: number
              minItems: 2
              maxItems: 2
              description: Coordenadas como [longitud, latitud]
              example:
              - -3.70379
              - 40.416775
        address:
          type: string
          description: Dirección completa
        zipcode:
          type: string
          description: Código postal
        city:
          type: string
          description: Nombre de la ciudad
        province:
          type: string
          description: Provincia/estado
        country:
          type: string
          description: Código de país (ISO 3166-1 alpha-2)
          example: ES
        features:
          type: array
          items:
            type: string
          description: Lista de características disponibles
      description: Representa una ubicación de aparcamiento de camiones
    ParkingsResponse:
      type: object
      properties:
        parkings:
          type: array
          items:
            $ref: '#/components/schemas/Parking'
      description: Array de ubicaciones de aparcamiento
    POI:
      type: object
      description: Representa un Punto de Interés genérico
      properties:
        id:
          type: string
          description: ID del POI
          example: poi-12345
        name:
          type: string
          description: Nombre del POI
          example: Restaurante El Buen Sabor
        type:
          type: string
          enum:
          - parking
          - workshop
          - restaurant
          - shower
          description: Tipo de POI
          example: restaurant
        location:
          type: object
          properties:
            type:
              type: string
              enum:
              - Point
              example: Point
            coordinates:
              type: array
              items:
                type: number
                format: double
              minItems: 2
              maxItems: 2
              description: Coordenadas como [longitud, latitud]
              example:
              - -3.70379
              - 40.416775
        address:
          type: string
          description: Dirección completa
          example: Calle Mayor, 1, 28013 Madrid
        zipcode:
          type: string
          description: Código postalal
          example: '28013'
        city:
          type: string
          description: Nombre de la ciudad
          example: Madrid
        province:
          type: string
          description: Provincia/estado
          example: Madrid
        country:
          type: string
          description: Código de país (ISO 3166-1 alpha-2)
          example: ES
        details:
          type: object
          additionalProperties: true
          description: Detalles adicionales específicos del tipo de POI
          example:
            cuisine: Spanish
            rating: 4.5
            fuel_types:
            - diesel
            - gasoline
    POIsResponse:
      type: object
      description: Array de Puntos de Interés
      properties:
        pois:
          type: array
          items:
            oneOf:
            - $ref: '#/components/schemas/Parking'
            - $ref: '#/components/schemas/Workshop'
            - $ref: '#/components/schemas/Restaurant'
            - $ref: '#/components/schemas/Shower'
    Workshop:
      type: object
      description: Representa una ubicación de taller de camiones
      properties:
        id:
          type: string
          description: ID del taller
        name:
          type: string
          description: Nombre del taller
        location:
          $ref: '#/components/schemas/POI/properties/location'
        address:
          type: string
          description: Dirección completa
        services:
          type: array
          items:
            type: string
          description: Lista de servicios disponibles
        openingHours:
          type: string
          description: Información de horarios de apertura
        emergencyService:
          type: boolean
          description: Si proporciona servicio de emergencia
    Restaurant:
      type: object
      description: Representa un restaurante para camioneros
      properties:
        id:
          type: string
          description: ID del restaurante
        name:
          type: string
          description: Nombre del restaurante
        location:
          $ref: '#/components/schemas/POI/properties/location'
        cuisine:
          type: string
          description: Tipo de cocina
        rating:
          type: number
          format: float
          minimum: 0
          maximum: 5
          description: Valoración promedio
        priceRange:
          type: string
          enum:
          - low
          - medium
          - high
          description: Indicador de rango de precios
    Shower:
      type: object
      description: Representa una instalación de duchas para camioneros
      properties:
        id:
          type: string
          description: ID de la ducha
        name:
          type: string
          description: Nombre de la instalación de duchas
        location:
          $ref: '#/components/schemas/POI/properties/location'
        price:
          type: number
          format: float
          description: Precio por uso
        genderSeparated:
          type: boolean
          description: Si tiene instalaciones separadas por género
    CityResponse:
      type: object
      description: Información de la ciudad más cercana
      properties:
        name:
          type: string
          description: Nombre de la ciudad
        country:
          type: string
          description: Código de país (ISO 3166-1 alpha-2)
        adminCode:
          type: string
          description: Código administrativo
        location:
          $ref: '#/components/schemas/POI/properties/location'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Token JWT para autenticación
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: Clave API para autenticación de servicios externos
  responses:
    200Parkings:
      description: Operación exitosa
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ParkingsResponse'
    200POIs:
      description: Operación exitosa, devuelve una lista de POIs
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/POIsResponse'
    200City:
      description: Operación exitosa, devuelve información de la ciudad más cercana
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CityResponse'
paths:
  /parking/location:
    get:
      tags:
      - parkings
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find parkings by location
      description: Devuelve aparcamientos dentro de un radio dado de coordenadas.
        Los resultados son procesados con el método .parse()
      parameters:
      - name: lat
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -90
          maximum: 90
        description: Latitude coordinate
        example: 40.416775
      - name: lng
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -180
          maximum: 180
        description: Longitude coordinate
        example: -3.70379
      - name: radius
        in: query
        required: true
        schema:
          type: number
          format: float
          minimum: 1000
          maximum: 250000
        description: Radio de búsqueda en metros. Mín 1000m, Máx 250000m. Requerido.
        example: 25000
      responses:
        '200':
          description: Operación exitosa
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Parking'
        '400':
          description: Parámetros inválidos
        '500':
          description: Error del servidor
  /parking/zipcode:
    get:
      tags:
      - parkings
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find parkings by zipcode
      description: Devuelve aparcamientos que coinciden con el código postal y país.
        Los resultados son procesados con el método .parse()
      parameters:
      - name: zipcode
        in: query
        required: true
        schema:
          type: string
        description: Código postal
        example: '28013'
      - name: country
        in: query
        required: true
        schema:
          type: string
          enum:
          - es
          - fr
          - de
          - pt
        description: 'Código de país (2 letras). Soportados: es, fr, de, pt. Requerido.'
        example: es
      responses:
        '200':
          description: Operación exitosa
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Parking'
        '400':
          description: Parámetros inválidos
        '500':
          description: Error del servidor
  /parking/province:
    get:
      tags:
      - parkings
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find parkings by province
      description: Devuelve aparcamientos en la provincia especificada. Los resultados
        son procesados con el método .parse()
      parameters:
      - name: province
        in: query
        required: true
        schema:
          type: string
        description: Nombre de provincia/estado
        example: Madrid
      responses:
        '200':
          description: Operación exitosa
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Parking'
        '400':
          description: Parámetros inválidos
        '500':
          description: Error del servidor
  /parking/nearby:
    get:
      tags:
      - parkings
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find parkings nearby a location
      description: Devuelve aparcamientos dentro de un radio especificado de coordenadas
        dadas. Por defecto 250km.
      parameters:
      - name: lat
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -90
          maximum: 90
        description: Latitude coordinate
        example: 40.416775
      - name: lng
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -180
          maximum: 180
        description: Longitude coordinate
        example: -3.70379
      - name: radius
        in: query
        schema:
          type: number
          format: float
          minimum: 1000
          maximum: 250000
          default: 250000
        description: Radio de búsqueda en metros. Mín 1000m, Máx 250000m. Por defecto
          250000m (250km).
        example: 10000
      responses:
        '200':
          description: Operación exitosa
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Parking'
        '400':
          description: Parámetros inválidos
        '500':
          description: Error del servidor
  /parking/getAlongPath:
    post:
      tags:
      - parkings
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find parkings along a path
      description: Devuelve aparcamientos cerca de una ruta especificada, definida
        por una serie de coordenadas.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                path:
                  type: array
                  items:
                    type: array
                    items:
                      type: number
                      format: double
                    minItems: 2
                    maxItems: 2
                  description: Array de puntos [longitud, latitud] que definen la
                    ruta. El sistema filtra automáticamente los puntos redundantes
                    manteniendo 25km de distancia mínima entre ellos.
                  example:
                  - - -3.70379
                    - 40.416775
                  - - -3.70123
                    - 40.41789
                  - - -3.69876
                    - 40.41901
                radius:
                  type: number
                  format: float
                  default: 25000
                  minimum: 1000
                  maximum: 150000
                  description: Radio de búsqueda en metros desde la ruta. Mín 1000m,
                    Máx 150000m. Por defecto 25000m (25km).
                  example: 25000
                category:
                  type: string
                  enum:
                  - LOW_SIDE
                  - SECURE
                  - FREE
                  - OTHER
                  - all
                  default: all
                  description: Categoría del aparcamiento para filtrar resultados
                  example: SECURE
                features:
                  type: array
                  items:
                    type: string
                  description: Array de características específicas para filtrar
                  example:
                  - vigilancia
                  - iluminacion
              required:
              - path
      responses:
        '200':
          description: Operación exitosa
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Parking'
        '400':
          description: Cuerpo de petición o parámetros inválidos (ej., ruta faltante,
            puntos inválidos, radio fuera de rango)
        '500':
          description: Error del servidor
  /city/getNear:
    get:
      tags:
      - city
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find nearest city to coordinates
      description: Devuelve información sobre la ciudad más cercana a las coordenadas
        proporcionadas, incluyendo nombre, código de país y ubicación.
      parameters:
      - name: lat
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -90
          maximum: 90
        description: Coordenada de latitud del punto para el cual buscar la ciudad
          más cercana.
        example: 40.416775
      - name: lng
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -180
          maximum: 180
        description: Coordenada de longitud del punto para el cual buscar la ciudad
          más cercana.
        example: -3.70379
      responses:
        '200':
          $ref: '#/components/responses/200City'
        '400':
          description: Parámetros requeridos faltantes o inválidos. `lat` y/o `lng`
            deben ser proporcionados y ser coordenadas geográficas válidas.
        '500':
          description: Error del servidor
  /city/getByName:
    get:
      tags:
      - city
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Search cities by name
      description: Devuelve hasta 5 ciudades que coinciden con el término de búsqueda,
        incluyendo nombre, código de país y ubicación. La búsqueda no distingue mayúsculas
        y coincide con nombres parciales.
      parameters:
      - name: search
        in: query
        required: true
        schema:
          type: string
        description: Nombre de ciudad o nombre parcial a buscar
        example: Madrid
      responses:
        '200':
          $ref: '#/components/responses/200City'
        '400':
          description: Falta el parámetro requerido 'search'
        '500':
          description: Error del servidor
  /restaurant/nearby:
    get:
      tags:
      - restaurant
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find restaurants nearby
      description: Devuelve restaurantes dentro de un radio dado de coordenadas. Por
        defecto 250km.
      parameters:
      - name: lat
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -90
          maximum: 90
        description: Latitude coordinate
        example: 40.416775
      - name: lng
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -180
          maximum: 180
        description: Longitude coordinate
        example: -3.70379
      - name: radius
        in: query
        schema:
          type: number
          format: float
          minimum: 1000
          maximum: 250000
          default: 250000
        description: Radio de búsqueda en metros. Mín 1000m, Máx 250000m. Por defecto
          250000m (250km).
        example: 10000
      responses:
        '200':
          description: Operación exitosa
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Restaurant'
        '400':
          description: Parámetros inválidos
        '500':
          description: Error del servidor
  /restaurant/getAlongPath:
    post:
      tags:
      - restaurant
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find restaurants along a path
      description: Devuelve restaurantes cerca de una ruta especificada
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                path:
                  type: array
                  items:
                    type: array
                    items:
                      type: number
                      format: double
                    minItems: 2
                    maxItems: 2
                  description: Array de puntos [longitud, latitud] que definen la
                    ruta
                  example:
                  - - -3.70379
                    - 40.416775
                  - - -3.70123
                    - 40.41789
                  - - -3.69876
                    - 40.41901
                radius:
                  type: number
                  format: float
                  default: 5000
                  minimum: 1000
                  maximum: 25000
                  description: Radio de búsqueda en metros desde la ruta. Mín 1000m,
                    Máx 25000m. Por defecto 5000m (5km).
              required:
              - path
      responses:
        '200':
          description: Operación exitosa
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Restaurant'
        '400':
          description: Cuerpo de petición o parámetros inválidos
        '500':
          description: Error del servidor
  /workshop/nearby:
    get:
      tags:
      - workshop
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find workshops nearby
      description: Devuelve talleres dentro de un radio dado de coordenadas
      parameters:
      - name: lat
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -90
          maximum: 90
        description: Latitude coordinate
        example: 40.416775
      - name: lng
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -180
          maximum: 180
        description: Longitude coordinate
        example: -3.70379
      - name: radius
        in: query
        schema:
          type: number
          format: float
          minimum: 1000
          maximum: 250000
          default: 250000
        description: Radio de búsqueda en metros. Mín 1000m, Máx 250000m. Por defecto
          250000m (250km).
      responses:
        '200':
          description: Operación exitosa
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Workshop'
        '400':
          description: Parámetros inválidos
        '500':
          description: Error del servidor
  /workshop/getAlongPath:
    post:
      tags:
      - workshop
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find workshops along a path
      description: Devuelve talleres cerca de una ruta especificada
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                path:
                  type: array
                  items:
                    type: array
                    items:
                      type: number
                      format: double
                    minItems: 2
                    maxItems: 2
                  description: Array de puntos [longitud, latitud] que definen la
                    ruta
                  example:
                  - - -3.70379
                    - 40.416775
                  - - -3.70123
                    - 40.41789
                  - - -3.69876
                    - 40.41901
                radius:
                  type: number
                  format: float
                  default: 10000
                  minimum: 1000
                  maximum: 50000
                  description: Radio de búsqueda en metros desde la ruta. Mín 1000m,
                    Máx 50000m. Por defecto 10000m (10km).
              required:
              - path
      responses:
        '200':
          description: Operación exitosa
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Workshop'
        '400':
          description: Cuerpo de petición o parámetros inválidos
        '500':
          description: Error del servidor
  /shower/nearby:
    get:
      tags:
      - shower
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find showers nearby
      description: Devuelve duchas dentro de un radio dado de coordenadas
      parameters:
      - name: lat
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -90
          maximum: 90
        description: Latitude coordinate
        example: 40.416775
      - name: lng
        in: query
        required: true
        schema:
          type: number
          format: double
          minimum: -180
          maximum: 180
        description: Longitude coordinate
        example: -3.70379
      - name: radius
        in: query
        schema:
          type: number
          format: float
          minimum: 1000
          maximum: 25000
          default: 5000
        description: Radio de búsqueda en metros. Mín 1000m, Máx 25000m. Por defecto
          5000m (5km).
      - name: type
        in: query
        schema:
          type: string
        description: Tipo de ducha a buscar
        example: PARKING
      responses:
        '200':
          description: Operación exitosa
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Shower'
        '400':
          description: Parámetros inválidos
        '500':
          description: Error del servidor
  /shower/getAlongPath:
    post:
      tags:
      - shower
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Find showers along a path
      description: Devuelve duchas cerca de una ruta especificada
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                path:
                  type: array
                  items:
                    type: array
                    items:
                      type: number
                      format: double
                    minItems: 2
                    maxItems: 2
                  description: Array de puntos [longitud, latitud] que definen la
                    ruta
                  example:
                  - - -3.70379
                    - 40.416775
                  - - -3.70123
                    - 40.41789
                  - - -3.69876
                    - 40.41901
                radius:
                  type: number
                  format: float
                  default: 5000
                  minimum: 1000
                  maximum: 25000
                  description: Radio de búsqueda en metros desde la ruta. Mín 1000m,
                    Máx 25000m. Por defecto 5000m (5km).
                type:
                  type: string
                  description: Tipo de ducha a buscar
                  example: PARKING
              required:
              - path
      responses:
        '200':
          description: Operación exitosa
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Shower'
        '400':
          description: Cuerpo de petición o parámetros inválidos
        '500':
          description: Error del servidor
  /shower/types:
    get:
      tags:
      - shower
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      summary: Get shower types
      description: Returns all available shower types/categories
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
        '500':
          description: Server error
