Skip to main content

Privalia Marketplace Client

1. Descripción general

privalia-marketplace-client es una librería cliente reutilizable (JAR) que encapsula la comunicación con la API Pink-Connect v4 de Privalia (canal marketplace, distinto del canal logístico cubierto por privalia-client). El proyecto no expone ningún endpoint REST propio; se publica en el registro de artefactos Maven interno y es consumido por otros microservicios del ecosistema Hawkers que necesiten consultar pedidos del marketplace Privalia y actualizar su estado (envío, cancelación parcial, etc.).

A diferencia de privalia-client, este cliente no gestiona el token internamente: cada método recibe la cabecera Authorization como parámetro explícito, siendo el consumidor responsable de obtener y anteponer el prefijo "Bearer " al token.

2. Información técnica

PropiedadValor
artifactIdprivalia-marketplace-client
groupIdcom.hawkersco
version1.0.25-SNAPSHOT
Java25
Spring Boot4.0.6
Tipo de artefactoJAR (librería, no ejecutable)
MódulosProyecto único (no multi-módulo)

3. Arquitectura y diseño

Estructura del proyecto:

com.hawkersco.privaliamarketplaceclient
├── PrivaliaMarketplaceClientApplication.java # Clase @SpringBootApplication (residual, sin lógica)
├── client/
│ └── PrivaliaMarketplaceClient.java # Interfaz @HttpExchange: getOrders, updateOrderStatus
├── config/
│ ├── PrivaliaMarketplaceClientAutoConfiguration.java # @AutoConfiguration principal (sin interceptor de auth)
│ ├── PrivaliaMarketplaceClientConfig.java # Clase vacía — placeholder heredado de una configuración Feign (ver sección 13)
│ ├── PrivaliaMarketplaceClientConst.java # Constantes de cabeceras y content-types (no referenciadas por el cliente actual)
│ └── CacheStore.java # Cache genérica en memoria (Guava), disponible para quien la necesite
└── models/
├── PrivaliaOrderRequest.java # Modelo de parámetros de consulta (no cableado a ningún método, ver sección 13)
├── PrivaliaOrderResponse.java # Modelo de respuesta de pedido (jerarquía completa)
└── PrivaliaUpdateOrderStatusRequest.java # Request de actualización de estado (contiene una clase anidada duplicada, ver sección 13)

Flujo principal

sequenceDiagram
participant Consumidor as Microservicio consumidor
participant Client as PrivaliaMarketplaceClient
participant API as API Pink-Connect v4 (Privalia)

Consumidor->>Consumidor: obtiene/renueva su propio Bearer token
Consumidor->>Client: getOrders("Bearer <token>") / updateOrderStatus("Bearer <token>", orderId, newStatus, body)
Client->>API: GET /orders | PUT /orders/{orderId}/status/{newStatus} + header Authorization
API-->>Client: ResponseEntity<PrivaliaOrderResponse[]> | ResponseEntity<Void>
Client-->>Consumidor: ResponseEntity<T>

La autoconfiguración (PrivaliaMarketplaceClientAutoConfiguration) se activa condicionalmente con @ConditionalOnProperty(prefix = "privaliacreatedb.v2.url", name = "staging"), registrando el bean PrivaliaMarketplaceClient con un RestClient simple (sin interceptores) apuntando a privaliacreatedb.v2.url.staging.

El registro de la autoconfiguración se realiza mediante el fichero estándar de Spring Boot:

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

4. Dependencias principales

DependenciaVersiónPropósito
spring-boot-starter(gestionada SB4)Base de Spring Boot (contexto, autoconfiguración)
spring-web(gestionada SB4)RestClient + @HttpExchange / HttpServiceProxyFactory
com.google.guava:guava33.4.8-jreImplementación de caché en CacheStore (CacheBuilder); no usada internamente por el cliente actual (ver sección 13)
com.google.code.gson:gson(gestionada SB4)Anotaciones @SerializedName en los modelos (soporte dual con Jackson)
com.fasterxml.jackson.core:jackson-annotations(gestionada SB4)Anotaciones @JsonProperty en los modelos
org.projectlombok:lombok1.18.38 (dependencia; annotationProcessorPath del compilador usa 1.18.46)Generación de boilerplate en los modelos (getters, setters, @Builder)
spring-boot-starter-test(gestionada SB4)Testing (scope test)

5. API / Endpoints

No aplica a este proyecto. privalia-marketplace-client es una librería cliente JAR que no expone endpoints REST propios. Las operaciones que encapsula sobre la API Pink-Connect v4 de Privalia se detallan en la sección 6.

6. Integraciones externas

API Pink-Connect v4 (marketplace Privalia)

Método clienteHTTPRuta remotaDescripción
getOrdersGET/ordersLista los pedidos del marketplace (sin parámetros de consulta cableados, ver sección 13)
updateOrderStatusPUT/orders/{orderId}/status/{newStatus}Actualiza el estado de un pedido (envío, cancelación, envío parcial, etc.)

Ejemplo de payload updateOrderStatus (PrivaliaUpdateOrderStatusRequest):

{
"trackingNumber": "1234567890",
"trackingUrl": "https://carrier.example/tracking/1234567890",
"carrierId": 12345,
"reason": null,
"order_line_ids": [111, 222]
}

order_line_ids solo es obligatorio cuando newStatus=PARTIALLY_SHIPPED; en cualquier otro caso se ignora (según comentario en el propio código).

Ejemplo de respuesta getOrders (PrivaliaOrderResponse[], un elemento resumido):

[
{
"orderId": 987654,
"marketplaceName": "Privalia",
"marketplaceCode": "PRV",
"marketplaceOrderCode": "PRV-000123",
"status": "PENDING",
"totalPrice": 59.90,
"currency": "EUR",
"shippingInformation": { "name": "Cliente Final", "city": "Madrid", "countryIsoCode": "ES" },
"orderLines": [
{
"id": 1,
"sku": "SKU-001",
"name": "Camiseta básica",
"quantity": 2,
"totalPrice": 39.98,
"status": { "In Stock": true, "Shipped": 0, "Pending": 2 }
}
]
}
]

Según el Javadoc del modelo PrivaliaOrderRequest (no cableado actualmente a ningún parámetro real del método getOrders, ver sección 13), el endpoint GET /orders del contrato de la API Pink-Connect v4 admitiría los siguientes parámetros de consulta: offset (paginación, >= 0), limit (<= 50), orderStatusCodes (lista de WAITING_ACCEPTANCE, PENDING, PROCESSING, SHIPPED, CANCELLED, PARTIALLY_SHIPPED), shopChannelId, marketplaceCode y marketplaceOrderCode.

Protocolo: HTTPS REST (JSON). Autenticación: Bearer token pasado explícitamente como cabecera Authorization en cada llamada (@RequestHeader); el cliente no obtiene ni renueva el token por sí mismo.

7. Configuración

No se incluye ningún application.properties/application.yml en la librería. La única propiedad requerida debe ser suministrada por la aplicación consumidora:

PropiedadDescripciónEjemplo de valor
privaliacreatedb.v2.url.stagingURL base de la API Pink-Connect v4 (activa la autoconfiguración)${PRIVALIA_MARKETPLACE_URL}

El token OAuth/Bearer no se configura como propiedad Spring: el consumidor debe obtenerlo por su cuenta y pasarlo explícitamente (con el prefijo "Bearer ") en cada llamada.

Variables de entorno recomendadas

VariablePropiedad mapeada
PRIVALIA_MARKETPLACE_URLprivaliacreatedb.v2.url.staging

Importante: Si privaliacreatedb.v2.url.staging no está definida, el bean PrivaliaMarketplaceClient no se registra (condición @ConditionalOnProperty).

Nota sobre el nombre de la propiedad: El nombre privaliacreatedb.v2.url.staging sugiere que fue copiado/heredado de otro proyecto relacionado (posiblemente privalia-create-db) y que originalmente apuntaba a un entorno de staging específico; no sigue el patrón privalia*.credentials.url/*.client.url usado por el resto de clientes del ecosistema. Pendiente de verificar si es intencional o un remanente de copia.

8. Persistencia

No aplica a este proyecto. La librería no accede a ninguna base de datos. CacheStore está disponible como utilidad pero no se usa internamente por ningún componente de este cliente (ver sección 13).

9. Procesos programados y mensajería

No aplica a este proyecto. No existen jobs @Scheduled, listeners de colas/topics ni runners batch.

10. Ejecución en local

privalia-marketplace-client es una librería JAR, no una aplicación ejecutable. No tiene servidor embebido ni endpoint de health.

Requisitos previos

  • Java 25
  • Maven 3.x
  • Acceso al registro de artefactos Maven interno (europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven) para resolver/publicar dependencias.

Compilar e instalar en repositorio local

# Compilar sin tests
mvn clean install -DskipTests

# Compilar con tests
mvn clean install

# Ejecutar un test concreto
mvn test -Dtest=MyTestClass
mvn test -Dtest=MyTestClass#myMethod

Uso como dependencia en un microservicio consumidor

<dependency>
<groupId>com.hawkersco</groupId>
<artifactId>privalia-marketplace-client</artifactId>
<version>1.0.25-SNAPSHOT</version>
</dependency>

La autoconfiguración se activa automáticamente al declarar privaliacreatedb.v2.url.staging en la aplicación consumidora. El consumidor debe gestionar por su cuenta la obtención del token y pasarlo con el prefijo "Bearer " en cada llamada.

11. Despliegue

El pipeline de Jenkins (Jenkinsfile) consta de dos etapas:

  1. Checkout — descarga el código del repositorio.
  2. Publish to Artifact Registry — ejecuta mvn deploy -DskipTests para publicar el JAR en Google Artifact Registry.

CLAUDE.md documenta un pipeline de tres etapas (Build, SonarQube, Clean), que no se corresponde con el Jenkinsfile actual del repositorio (dos etapas: Checkout y Publish to Artifact Registry). Se documenta el Jenkinsfile realmente presente.

ParámetroValor
JDKJDK25 (tool Jenkins)
MavenMaven3 (tool Jenkins)
Repositorioeurope-west3-maven.pkg.dev/pi-saldum/pi-repo-maven (Artifact Registry GCP)

No existe Dockerfile ni despliegue como servicio independiente; el artefacto es un JAR publicado en el registro Maven.

Job de Jenkins:

https://jenkins-pi.hawkersco.net/job/privalia-marketplace-client/

12. Manejo de errores y logging

La librería no implementa ninguna estrategia propia de manejo de excepciones ni logging estructurado. Ningún método de PrivaliaMarketplaceClient declara throws explícito; las excepciones de red o HTTP propagadas por RestClient (como RestClientResponseException) son responsabilidad del servicio consumidor. No hay configuración de logback ni de niveles de log específicos en la librería.

13. Notas y consideraciones

  • PrivaliaMarketplaceClientConfig documentada explícitamente como placeholder muerto: El propio Javadoc de la clase indica que es un "Empty Feign configuration placeholder", conservada únicamente porque una antigua anotación @FeignClient(configuration = ...) la referenciaba, y que puede eliminarse una vez se retire esa referencia. Confirma que el proyecto migró de OpenFeign a @HttpExchange/RestClient (igual que otros clientes del ecosistema) dejando código residual documentado como tal.

  • PrivaliaOrderRequest no cableado a getOrders: El método getOrders de PrivaliaMarketplaceClient solo recibe el token (@RequestHeader("Authorization")), sin ningún @RequestParam para offset, limit, orderStatusCodes, shopChannelId, marketplaceCode ni marketplaceOrderCode — pese a que el modelo PrivaliaOrderRequest documenta extensamente estos parámetros en su Javadoc como parte del contrato de la API. Esto significa que, tal como está implementado hoy, el cliente siempre solicita el conjunto completo de pedidos sin paginación ni filtro, y PrivaliaOrderRequest es un modelo huérfano no utilizado por ningún método. Pendiente de verificar si se trata de una funcionalidad incompleta o de una versión anterior del contrato de la API.

  • Clase anidada PrivaliaOrderResponse duplicada dentro de PrivaliaUpdateOrderStatusRequest: PrivaliaUpdateOrderStatusRequest contiene una clase estática anidada también llamada PrivaliaOrderResponse, con una estructura casi idéntica a la clase de nivel superior com.hawkersco.privaliamarketplaceclient.models.PrivaliaOrderResponse, pero con diferencias sutiles (p. ej. marketplaceOrderCode como long en la anidada vs. String en la de nivel superior; OrderLine.id como String vs. Long; additionalInformation como String vs. Map<String, Object>; ausencia del campo comment en ContactInformation). Esta clase anidada no es utilizada por ningún método de PrivaliaMarketplaceClient — parece ser código copiado y pegado por error o un remanente de una refactorización, generando confusión sobre cuál es el modelo "correcto" de respuesta de pedido.

  • CacheStore y PrivaliaMarketplaceClientConst sin uso interno: Ambas clases están presentes en el paquete config/ pero ningún componente de este proyecto las utiliza — CacheStore no se instancia en ningún punto y las constantes de PrivaliaMarketplaceClientConst (cabeceras, content-types) no se referencian, ya que la autoconfiguración no registra ningún interceptor. Podrían ser remanentes copiados de privalia-client (que sí las usa activamente) durante la creación de este proyecto.

  • Autenticación completamente delegada al consumidor: A diferencia de privalia-client (que cachea el token 30 minutos vía interceptor), aquí el consumidor debe resolver el token en cada llamada; el CacheStore disponible en el paquete podría haber sido pensado para este propósito pero no está integrado en el flujo actual.

  • Nombre de propiedad privaliacreatedb.v2.url.staging inconsistente con el resto del ecosistema: Ver detalle en sección 7.

  • Sin tests implementados: No existe directorio src/test/ en el proyecto.

  • PrivaliaMarketplaceClientApplication.java: Clase principal de Spring Boot en el paquete raíz, sin funcionalidad operativa. Artefacto residual de la generación inicial del proyecto con Spring Initializr, mismo patrón observado en otros clientes del ecosistema.