Marketplaces Commons
1. Descripción general
marketplaces-commons es una librería de acceso a datos compartida, no una aplicación independiente. Se distribuye como dependencia Maven y es consumida por otros microservicios del ecosistema de Hawkers que necesiten interactuar con la base de datos de marketplaces.
Proporciona la capa completa de persistencia (entidades JPA, repositorios Spring Data y servicios de fachada) para las siguientes áreas:
- TikTok Shop: gestión de productos (
tiktok_product) e imágenes asociadas (tiktok_image). - Stock por marketplace: tabla
marketplace_stockcon nombres de producto normalizados para Decathlon, Miravia, ECI y Showroom, segmentados por SKU y empresa.
Al centralizar estas operaciones en una única librería, se evita la duplicación de entidades y queries entre microservicios, y se garantiza la coherencia del modelo de datos.
2. Información técnica
| Propiedad | Valor |
|---|---|
artifactId | marketplaces-commons |
groupId | com.hawkersco |
version | 1.0.25-SNAPSHOT |
| Java | 25 |
| Spring Boot | 4.0.6 |
| Tipo de artefacto | JAR (librería, sin main class) |
| Módulos | Proyecto mono-módulo |
3. Arquitectura y diseño
El proyecto sigue un patrón de 3 capas bajo el paquete raíz com.hawkersco.marketplacescommons:
com.hawkersco.marketplacescommons
├── dao/ ← Entidades JPA (@Entity). Implementan Serializable.
├── repository/ ← Interfaces Spring Data CrudRepository. Queries nativas y JPQL.
└── service/ ← Fachadas @Service. Delegación directa a repositorios.
No existe capa de controlador REST ni clase @SpringBootApplication. La configuración del datasource (URL, credenciales, dialecto JPA) es responsabilidad exclusiva del microservicio consumidor.
graph LR
MS[Microservicio consumidor] -->|autowire| SVC[Service]
SVC --> REPO[Repository]
REPO -->|JPA / SQL nativo| DB[(PostgreSQL)]
4. Dependencias principales
| Dependencia | Versión | Propósito |
|---|---|---|
spring-boot-starter | 4.0.6 | Core Spring Boot (IoC, autoconfiguración) |
spring-boot-starter-data-jpa | 4.0.6 | Spring Data JPA + Hibernate + Jakarta Persistence |
org.postgresql:postgresql | 42.7.4 | Driver JDBC para PostgreSQL |
org.projectlombok:lombok | 1.18.42 | Generación de getters/setters/constructores en tiempo de compilación |
spring-boot-starter-test | 4.0.6 | Framework de tests (scope test) |
artifactregistry-maven-wagon | 2.2.1 | Plugin para publicar en GCP Artifact Registry |
5. API / Endpoints
No aplica a este proyecto.
Esta librería no expone ninguna API REST. Es un artefacto de librería pura; su API pública son los métodos de los @Service.
API pública de los Services:
MarketplaceStockService
| Método | Parámetros | Retorno | Descripción |
|---|---|---|---|
truncateMarketplacesStock() | — | void | Elimina todos los registros de marketplace_stock (TRUNCATE nativo) |
save(MarketplaceStock) | entidad | MarketplaceStock | Persiste o actualiza un registro |
findByCdSku(String) | cdSku | MarketplaceStock | Busca por SKU |
findByCdSkuAndDsCompany(String, String) | cdSku, dsCompany | MarketplaceStock | Busca por clave compuesta |
updateMarketplaceStock(String, String, String, String, String, String) | nmDecathlon, nmMiravia, nmShowroom, nmEci, cdSku, dsCompany | void | Actualiza nombres de marketplace para un SKU+empresa |
TikTokProductService
| Método | Parámetros | Retorno | Descripción |
|---|---|---|---|
save(TikTokProduct) | entidad | TikTokProduct | Persiste o actualiza |
findByCdSku(String) | cdSku | TikTokProduct | Busca por SKU |
findByTiktokProductId(String) | tiktokProductId | TikTokProduct | Busca por ID de producto TikTok |
findByDsStatus(String) | dsStatus | List<TikTokProduct> | Filtra por estado |
delete(TikTokProduct) | entidad | void | Elimina el registro |
TikTokImageService
| Método | Parámetros | Retorno | Descripción |
|---|---|---|---|
save(TikTokImage) | entidad | TikTokImage | Persiste o actualiza |
findByCdSkuAndImagePos(String, int) | cdSku, imagePos | TikTokImage | Busca imagen por SKU y posición |
findByOrderByCdSkuAscImagePosAsc() | — | List<TikTokImage> | Devuelve todas las imágenes ordenadas por SKU y posición |
findByTiktokUri(String) | tiktokUri | TikTokImage | Busca por URI de TikTok |
delete(TikTokImage) | entidad | void | Elimina el registro |
6. Integraciones externas
| Sistema | Protocolo | Dirección | Descripción |
|---|---|---|---|
| PostgreSQL | JDBC / JPA | Saliente | Base de datos de marketplaces. Datasource configurado por el servicio consumidor. |
GCP Artifact Registry (europe-west3) | HTTPS / Maven Wagon | Saliente | Repositorio Maven donde se publica el JAR compilado. |
7. Configuración
Esta librería no incluye application.properties ni application.yml. Toda la configuración JPA debe ser provista por el microservicio que la consuma.
Propiedades mínimas requeridas en el servicio consumidor:
| Propiedad | Descripción | Ejemplo de valor |
|---|---|---|
spring.datasource.url | URL JDBC de la base de datos de marketplaces | jdbc:postgresql://host:5432/marketplaces_db |
spring.datasource.username | Usuario de base de datos | ${DB_USER} |
spring.datasource.password | Contraseña de base de datos | ${DB_PASSWORD} |
spring.jpa.hibernate.ddl-auto | Estrategia DDL de Hibernate | validate o none |
spring.jpa.database-platform | Dialecto JPA | org.hibernate.dialect.PostgreSQLDialect |
Para publicar en Artifact Registry, el fichero ~/.m2/settings.xml del agente de CI debe incluir las credenciales de la cuenta de servicio GCP (credential id: artifact-registry).
8. Persistencia
Base de datos: PostgreSQL
Entidades y tablas:
TikTokProduct → tiktok_product
| Campo Java | Columna SQL | Tipo | Descripción |
|---|---|---|---|
cdSku | cd_sku | String | PK — Código SKU interno |
tiktokProductId | tiktok_product_id | String | ID del producto en la plataforma TikTok |
dsStatus | ds_status | String | Estado del producto (ej. ACTIVE, INACTIVE) |
TikTokImage → tiktok_image
| Campo Java | Columna SQL | Tipo | Descripción |
|---|---|---|---|
tiktokUri | tiktok_uri | String | PK — URI única de la imagen en TikTok |
tiktokUrl | tiktok_url | String | URL pública de la imagen |
cdSku | cd_sku | String | SKU del producto asociado |
imageType | image_type | String | Tipo de imagen |
imagePos | image_pos | int | Posición/orden de la imagen |
rawData | raw_data | String | Payload JSON crudo devuelto por TikTok |
MarketplaceStock → marketplace_stock
| Campo Java | Columna SQL | Tipo | Descripción |
|---|---|---|---|
cdSku | cd_sku | String | PK (parte 1) — Código SKU |
dsCompany | ds_company | String | PK (parte 2) — Identificador de empresa |
nmDecathlon | nm_decathlon | String | Nombre del producto en Decathlon |
nmMiravia | nm_miravia | String | Nombre del producto en Miravia |
nmEci | nm_eci | String | Nombre del producto en ECI |
nmShowroom | nm_showroom | String | Nombre del producto en Showroom |
La clave primaria compuesta de MarketplaceStock está implementada mediante @IdClass(MarketplaceStockId.class).
Migraciones: No existen scripts Flyway ni Liquibase en este repositorio. La creación y evolución del esquema es responsabilidad del servicio consumidor o de un proceso externo.
9. Procesos programados y mensajería
No aplica a este proyecto.
No hay anotaciones @Scheduled, @KafkaListener, @RabbitListener ni runners batch. Es una librería de acceso a datos pura.
10. Ejecución en local
Esta librería no se ejecuta de forma independiente. Para instalarla en el repositorio Maven local:
# Instalar en ~/.m2 local (sin tests)
./mvnw -B -DskipTests clean install
# Ejecutar tests (actualmente sin tests implementados)
./mvnw test
Para consumirla desde otro proyecto local, añadir la dependencia en el pom.xml del servicio consumidor:
<dependency>
<groupId>com.hawkersco</groupId>
<artifactId>marketplaces-commons</artifactId>
<version>1.0.25-SNAPSHOT</version>
</dependency>
Requisitos: JDK 25, Maven 3.x (o usar el wrapper ./mvnw).
11. Despliegue
Mecanismo: Jenkins publica el JAR en GCP Artifact Registry mediante mvn deploy -DskipTests.
Pipeline Jenkins:
| Etapa | Descripción |
|---|---|
Checkout | Clona el repositorio desde SCM |
Publish to Artifact Registry | Ejecuta mvn deploy -DskipTests y publica el JAR |
Repositorio de distribución: artifactregistry://europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven
Herramientas CI: JDK25, Maven3
Job de Jenkins:
https://jenkins-pi.hawkersco.net/job/marketplaces-commons/
12. Manejo de errores y logging
No hay estrategia de excepciones propia definida en la librería. Los servicios delegan directamente a los repositorios sin captura de excepciones, por lo que las excepciones de Spring Data / JPA (p.ej. DataAccessException, EntityNotFoundException) se propagan al servicio consumidor, que es el responsable de manejarlas.
No existe configuración de logging específica (logback-spring.xml, log4j2.xml). El logging heredará la configuración del servicio consumidor.
13. Notas y consideraciones
-
truncateMarketplaceStock()es destructivo e irreversible: elimina toda la tablamarketplace_stocksin condición. Los servicios consumidores deben invocar este método con extrema cautela y siempre antes de una carga masiva de datos. -
Ausencia de tests:
src/test/java/está vacío. No existe cobertura de ninguna query ni comportamiento de servicio. Recomendable añadir tests de integración con base de datos embebida (H2) o Testcontainers para validar las queries nativas. -
@Autowireden fields: los servicios usan inyección por campo en lugar de inyección por constructor. Esto dificulta los tests unitarios. Pendiente de valorar migración a inyección por constructor. -
MarketplaceStockRepositoryextiendeCrudRepository<MarketplaceStock, String>: el tipo de la PK declarado esString, pero la entidad usa clave compuesta (@IdClass). El tipo correcto seríaMarketplaceStockId. Pendiente de verificar si esto genera algún comportamiento inesperado en operaciones comofindById. -
rawDataenTikTokImage: almacena el payload JSON crudo de TikTok comoString. Si los payloads son grandes, puede impactar en el rendimiento de las consultas que devuelven listados completos (p.ej.findByOrderByCdSkuAscImagePosAsc()). -
Sin
@SpringBootApplication: la librería no auto-registra sus beans. El servicio consumidor debe incluir un@ComponentScansobre el paquetecom.hawkersco.marketplacescommonso confiar en la autoconfiguración de Spring Boot si el paquete está dentro del scan por defecto.