Skip to main content

Coppel Client

1. Descripción general

coppel-client (description del pom.xml: Coppel client) es una librería JAR compartida que encapsula la integración con la API del marketplace Coppel. Envuelve todos los endpoints relevantes (pedidos, aceptación de pedidos, tracking, transacciones de pago, ofertas) usando los clientes HTTP declarativos nativos de Spring (@HttpExchange + HttpServiceProxyFactory, Spring Framework 7), sin depender de Spring Cloud OpenFeign.

El proyecto no es un microservicio desplegable de cara a negocio: aunque contiene una clase @SpringBootApplication (CoppelClientApplication), su función real es la de auto-configuración de Spring Boot (@AutoConfiguration, registrada vía META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports) que se activa automáticamente en cualquier microservicio consumidor que declare la dependencia y las propiedades coppel.credentials.*.

Resuelve el problema de que cada microservicio de Hawkers que necesita sincronizar pedidos, tracking, pagos y catálogo con Coppel tenga que reimplementar el cliente HTTP, la autenticación por token y los DTOs de request/response. Dentro del ecosistema de microservicios de Hawkers, actúa como capa de integración transversal para el canal de venta marketplace Coppel, de forma análoga a otros clientes de marketplace del ecosistema (bradery-client, auro-client, etc.).


2. Información técnica

PropiedadValor
artifactIdcoppel-client
groupIdcom.hawkersco
version1.0.25-SNAPSHOT
Java25
Spring Boot4.0.6 (Spring Framework 7)
Tipo de artefactoJAR (librería con auto-configuración Spring Boot; incluye clase @SpringBootApplication de soporte, sin despliegue independiente)
MódulosProyecto mono-módulo
Repositorio MavenGoogle Artifact Registry — europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven

3. Arquitectura y diseño

Paquetes principales

com.hawkersco.coppelclient
├── client/ # CoppelClient — interfaz @HttpExchange con todos los endpoints
├── config/ # CoppelClientConfig — @AutoConfiguration
├── model/ # DTOs de request/response (clases Lombok con anotaciones dobles Jackson/Gson)
└── CoppelClientApplication.java # Clase @SpringBootApplication de soporte

Componentes clave

  • client/CoppelClient — única interfaz @HttpExchange del proyecto; define todos los endpoints de la API de Coppel (pedidos, aceptación, tracking, envío, transacciones de pago, ofertas). La URL base se toma de ${coppel.credentials.url}.
  • config/CoppelClientConfig — clase @AutoConfiguration, condicionada a que existan las propiedades coppel.credentials.url y coppel.credentials.key (@ConditionalOnProperty). Construye un RestClient con el header Authorization: ${coppel.credentials.key} por defecto y crea el proxy CoppelClient vía HttpServiceProxyFactory.
  • model/ — DTOs modelados como clases Lombok (@Getter, @Setter, @NoArgsConstructor, @AllArgsConstructor, @ToString), con anotaciones dobles @SerializedName (Gson) y @JsonProperty (Jackson) en la mayoría de campos — deben mantenerse ambas al modificar los DTOs, según indica CLAUDE.md.

Autenticación

A diferencia de otros clientes del ecosistema (p. ej. auth0-client, que obtiene un token OAuth2 dinámicamente), CoppelClientConfig inyecta el token como header estático configurado directamente en coppel.credentials.key, sin renovación ni interceptor:

RestClient restClient = RestClient.builder()
.baseUrl(baseUrl)
.defaultHeader(AUTHORIZATION_HEADER, coppelKey)
.build();

Flujo principal

sequenceDiagram
participant MS as Microservicio consumidor
participant CC as CoppelClient (proxy HttpExchange)
participant Coppel as API Coppel

MS->>CC: getOrderList(state, startDate, max, offset)
CC->>Coppel: GET /api/orders?order_state_codes=...&start_date=...&max=...&offset=...
Coppel-->>CC: OrdersCoppelResponse
CC-->>MS: ResponseEntity<OrdersCoppelResponse>

MS->>CC: acceptOrder(orderId, AcceptOrderRequest)
CC->>Coppel: PUT /api/orders/{orderId}/accept
Coppel-->>MS: 200 OK

MS->>CC: updateTracking(orderId, TrackingCoppelRequest)
CC->>Coppel: PUT /api/orders/{orderId}/tracking
Coppel-->>MS: 200 OK

MS->>CC: updateShip(orderId)
CC->>Coppel: PUT /api/orders/{orderId}/ship
Coppel-->>MS: 200 OK

4. Dependencias principales

DependenciaPropósito
org.springframework.boot:spring-boot-starterNúcleo de Spring Boot (auto-configuración, contexto).
org.springframework:spring-webRestClient, HttpServiceProxyFactory y soporte @HttpExchange.
com.fasterxml.jackson.core:jackson-annotationsAnotaciones @JsonProperty en los DTOs.
com.google.code.gson:gson (2.10.1)Anotaciones @SerializedName en los DTOs (uso dual junto a Jackson).
org.projectlombok:lombok (1.18.42)Generación de getters/setters/constructores/toString en los DTOs.
org.springframework.boot:spring-boot-starter-test (test)Soporte de test de Spring Boot.

Extensión de build relevante: com.google.cloud.artifactregistry:artifactregistry-maven-wagon (2.2.1) — necesaria para publicar/resolver contra el Google Artifact Registry corporativo.


5. API / Endpoints

No expone API REST propia (no hay @RestController). En su lugar, define un cliente HTTP declarativo que consume la API de Coppel:

Método HTTPRutaDescripciónRequestResponse
GET/api/ordersLista paginada de pedidos filtrada por order_state_codes y start_date (getOrderList).Query: order_state_codes, start_date, max, offsetOrdersCoppelResponse
GET/api/ordersIdéntico al anterior (getOrderListByStateCode) — método duplicado.Query: order_state_codes, start_date, max, offsetOrdersCoppelResponse
GET/api/ordersLista paginada de pedidos desde una fecha, sin filtrar por estado (getOrderListAlt).Query: start_date, max, offsetOrdersCoppelResponse
PUT/api/orders/{orderId}/acceptAcepta un pedido, indicando aceptación por línea.Path orderId + AcceptOrderRequestString (respuesta cruda de Coppel)
GET/api/sellerpayment/transactions_logsHistorial de transacciones de pago de un pedido.Query order_idTransactionsCoppelResponse
GET/api/orders/documents/downloadDescarga documentos de envío/factura para una lista de pedidos.Query order_ids (IDs separados por coma)byte[]
PUT/api/orders/{orderId}/trackingActualiza la información de tracking del transportista.Path orderId + TrackingCoppelRequestString (respuesta cruda de Coppel)
PUT/api/orders/{orderId}/shipMarca el pedido como enviado.Path orderIdString (respuesta cruda de Coppel)
GET/api/offersLista paginada de ofertas del vendedor.Query max, offsetOffersCoppelResponse
GET/api/offers/{offerId}Obtiene una oferta concreta por ID.Path offerIdString (respuesta cruda de Coppel)
POST/api/offersCrea o actualiza ofertas en bloque.OffersCoppelResponse (JSON)String (respuesta cruda de Coppel)

Ejemplo de payload de TrackingCoppelRequest:

{
"carrier_code": "DHL",
"carrier_name": "DHL Express",
"carrier_url": "https://www.dhl.com/tracking",
"tracking_number": "1234567890"
}

Ejemplo de payload de AcceptOrderRequest:

{
"order_lines": [
{ "id": "order-line-1", "accepted": true },
{ "id": "order-line-2", "accepted": false }
]
}

OrdersCoppelResponse.OrderCoppel es el DTO de mayor complejidad del proyecto (más de 40 campos y varios objetos anidados: Channel, Customer, Fulfillment, entre otros), reflejando la estructura completa del pedido devuelta por Coppel.


6. Integraciones externas

SistemaProtocolo / MecanismoDirección del flujo
Coppel (marketplace)HTTP/REST vía RestClient + @HttpExchange (application/json), autenticación por header Authorization estáticoSaliente: el microservicio consumidor llama a Coppel para leer pedidos/ofertas y escribir aceptaciones, tracking y ofertas.
Microservicios Hawkers consumidoresDependencia Maven (com.hawkersco:coppel-client) + auto-configuración Spring BootEntrante como librería: se activa automáticamente al declarar la dependencia y configurar coppel.credentials.*.

7. Configuración

El proyecto no incluye application.properties/application.yml propio de servicio (es una librería auto-configurable). Los microservicios consumidores deben declarar las siguientes propiedades para que CoppelClientConfig se active (@ConditionalOnProperty exige ambas):

ClaveDescripciónEjemplo de valor
coppel.credentials.urlURL base de la API de Coppel.https://${COPPEL_API_HOST}
coppel.credentials.keyToken de autorización enviado en el header Authorization.${COPPEL_API_KEY}

Nunca deben commitearse valores reales de coppel.credentials.key; se recomienda inyectarlos vía variables de entorno o gestor de secretos del entorno de despliegue.


8. Persistencia

No aplica. La librería no accede a ninguna base de datos; todo el estado relevante de pedidos/ofertas reside en Coppel.


9. Procesos programados y mensajería

No aplica. No se han encontrado @Scheduled, @KafkaListener ni @RabbitListener en el proyecto.


10. Ejecución en local

Como librería auto-configurable, no se "ejecuta" de forma independiente en producción, aunque incluye una clase @SpringBootApplication (CoppelClientApplication) para pruebas locales del contexto de auto-configuración.

Requisitos previos: JDK 25, Maven (o el wrapper ./mvnw incluido).

Build e instalación en repositorio Maven local (omitiendo tests, como en CI):

mvn -B -DskipTests clean install

Ejecutar tests:

mvn test

Ejecutar una clase de test concreta:

mvn test -Dtest=MyTestClassName

Análisis SonarQube (según CLAUDE.md; no verificado como stage activo en el Jenkinsfile actual del repositorio):

mvn sonar:sonar -Dsonar.projectKey=<projectname> -Dsonar.host.url=https://sonarqube.hawkersco.net

No aplica verificación vía Actuator/health al no ser un servicio desplegable de cara a producción. Los microservicios consumidores deben declarar com.hawkersco:coppel-client:<version> en su pom.xml y configurar las propiedades coppel.credentials.* descritas en la sección 7.


11. Despliegue

El despliegue consiste en la publicación del artefacto Maven al Google Artifact Registry corporativo (no hay despliegue de contenedor/servicio propio).

Pipeline Jenkins (Jenkinsfile, agente any, JDK25 + Maven3):

  1. Checkout del repositorio.
  2. Publish to Artifact Registry: mvn deploy -DskipTests, publicando en artifactregistry://europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven (definido en distributionManagement del pom.xml).

CLAUDE.md documenta un pipeline más amplio (Build → KICS Security Scan → SonarQube Analysis → Cleanup, con jenkins/scripts/clean.sh), pero el Jenkinsfile presente en el repositorio solo define los stages de Checkout y publicación — Pendiente de verificar si los stages adicionales se gestionan en una librería compartida de Jenkins (shared library) no visible en este repositorio.

Job de Jenkins:

https://jenkins-pi.hawkersco.net/job/coppel-client/


12. Manejo de errores y logging

No se ha encontrado estrategia de excepciones propia (no hay @ControllerAdvice, excepciones custom ni códigos de error definidos en el proyecto). Las respuestas de error de la API de Coppel se propagan como RestClientResponseException estándar de Spring en las llamadas a CoppelClient; el consumidor es responsable de capturarlas.

No se ha encontrado configuración de logging propia (logback.xml/log4j2.xml); el logging queda delegado a la configuración del microservicio que integra la librería.


13. Notas y consideraciones

  • Sin renovación de token: a diferencia de auth0-client (que obtiene un token dinámico vía client_credentials en cada petición), aquí el token se inyecta como header estático en tiempo de arranque del bean (@Value("${coppel.credentials.key}")). Si el token de Coppel expira o rota, requiere reiniciar el microservicio consumidor tras actualizar la propiedad — no hay mecanismo de refresco en caliente.
  • Métodos duplicados en CoppelClient: getOrderList(...) y getOrderListByStateCode(...) tienen exactamente la misma firma de parámetros y llaman al mismo endpoint (GET /api/orders) — parece deuda técnica o un método renombrado sin eliminar el original. Revisar con el equipo antes de eliminar alguno, por posible uso en consumidores existentes.
  • Respuestas tipadas como String crudo: varios endpoints de escritura (acceptOrder, updateTracking, updateShip, getOffer, updateOffers) devuelven ResponseEntity<String> en lugar de un DTO tipado, lo que traslada al consumidor la responsabilidad de parsear la respuesta si necesita inspeccionar su contenido.
  • DTOs con doble anotación Jackson/Gson: todos los modelos anotan los mismos campos con @JsonProperty y @SerializedName simultáneamente, aunque el cliente HTTP interno solo usa RestClient/Jackson en tiempo de ejecución — las anotaciones Gson parecen destinadas a un uso adicional por parte de proyectos consumidores que deserialicen estos DTOs con Gson.
  • Campos Object en DTOs anidados: campos como deliveryDate (OrdersCoppelResponse.OrderCoppel) y channelCode/discountEndDate/discountStartDate (OffersCoppelResponse.Offer.ApplicablePricing) están tipados como Object en lugar de un tipo concreto (String, LocalDate, etc.) — probablemente porque la API de Coppel puede devolver null o distintos formatos, pero obliga al consumidor a hacer casting/inspección manual.
  • Sin tests: no se ha localizado src/test/java en el proyecto pese a que CLAUDE.md documenta comandos de test (mvn test, mvn test -Dtest=...) — Pendiente de verificar si los tests existen en una rama distinta o si la documentación está desactualizada.