Web Product Catalog Commons
1. Descripción general
webproductcatalog-commons es una librería compartida (no un microservicio desplegable de forma independiente) que centraliza el acceso a la base de datos del catálogo de productos web de Hawkers. Se publica como artefacto Maven en Google Cloud Artifact Registry y es consumida como dependencia por los microservicios que necesitan leer o escribir datos del catálogo.
Proporciona tres capas listas para usar:
- Entidades JPA (
dao/) mapeadas sobre PostgreSQL. - Repositorios Spring Data (
repository/) con métodos de consulta derivados y queries nativas. - Servicios (
service/) que encapsulan el acceso a los repositorios y son los puntos de entrada recomendados para los consumidores.
El microservicio consumidor es responsable de aportar la configuración de conexión a la base de datos (datasource, JPA dialect, etc.) en su propio application.yml.
2. Información técnica
| Propiedad | Valor |
|---|---|
artifactId | webproductcatalog-commons |
groupId | com.hawkersco |
version | 1.0.25-SNAPSHOT |
| Java | 25 |
| Spring Boot | 4.0.6 |
| Tipo de artefacto | JAR (librería, sin main) |
| Módulos | Proyecto simple (no multi-módulo) |
| Repositorio Maven | GCP Artifact Registry — europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven |
3. Arquitectura y diseño
La librería sigue una arquitectura de tres capas sin controladores REST (es una librería, no una API):
service/ → repository/ → dao/ → PostgreSQL
| Paquete | Contenido |
|---|---|
com.hawkersco.webproductcatalogcommons.dao | 9 entidades JPA con claves compuestas (@IdClass) |
com.hawkersco.webproductcatalogcommons.repository | 9 interfaces PagingAndSortingRepository |
com.hawkersco.webproductcatalogcommons.service | 9 @Service que delegan en los repositorios |
Products es la entidad raíz. Todas las demás entidades se relacionan con ella a través de productId. La entidad Products carga todas sus colecciones relacionadas de forma EAGER (@OneToMany(fetch = FetchType.EAGER)).
erDiagram
Products ||--o{ ProductAttributes : "productId"
Products ||--o{ ProductSiteData : "productId"
Products ||--o{ ProductSiteLocaleAttribute : "productId"
Products ||--o{ ProductSiteDataLocaleUrl : "productId"
Products ||--o{ ProductSiteDataImages : "productId"
Products ||--o{ ProductSiteDataLocalePromotions : "productId"
Products ||--o{ ProductSiteDataLocalePrice : "productId"
Varias entidades llevan anotaciones JAXB (@XmlRootElement, @XmlAccessorType, @XmlAttribute) para permitir serialización XML: ProductSiteData, ProductSiteDataLocaleUrl y ProductSiteDataLocalePromotions.
4. Dependencias principales
| Dependencia | Versión | Propósito |
|---|---|---|
spring-boot-starter-data-jpa | (gestionada por Spring Boot 4.0.6) | ORM con Hibernate 7, Spring Data JPA |
spring-boot-starter | (gestionada por Spring Boot 4.0.6) | Core de Spring Boot, autoconfiguración |
postgresql | 42.7.5 | Driver JDBC para PostgreSQL |
lombok | 1.18.42 | Generación de código: @Data, @NoArgsConstructor, @AllArgsConstructor |
jakarta.xml.bind-api | 4.0.2 | Anotaciones JAXB para serialización XML en algunas entidades |
artifactregistry-maven-wagon | 2.2.1 (build extension) | Publicación del artefacto en GCP Artifact Registry |
5. API / Endpoints
No aplica a este proyecto. Es una librería sin capa HTTP.
6. Integraciones externas
| Sistema | Protocolo | Dirección |
|---|---|---|
| PostgreSQL | JDBC / JPA | Saliente (lectura/escritura) |
GCP Artifact Registry (europe-west3-maven.pkg.dev) | HTTPS / Maven Wagon | Saliente (publicación del JAR) |
La configuración de conexión a PostgreSQL (URL, credenciales, pool) no está definida en esta librería: el microservicio consumidor debe proporcionarla.
7. Configuración
Esta librería no incluye application.yml ni application.properties. El microservicio que la consume debe definir al menos las siguientes propiedades:
| Clave | Descripción | Ejemplo de valor |
|---|---|---|
spring.datasource.url | URL JDBC de PostgreSQL | jdbc:postgresql://host:5432/dbname |
spring.datasource.username | Usuario de base de datos | ${DB_USER} |
spring.datasource.password | Contraseña de base de datos | ${DB_PASSWORD} |
spring.jpa.database-platform | Dialecto Hibernate | org.hibernate.dialect.PostgreSQLDialect |
spring.jpa.hibernate.ddl-auto | Estrategia DDL | none (recomendado en producción) |
Para consumir la librería desde otro proyecto Maven es necesario configurar el repositorio de distribución:
<repositories>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven</url>
</repository>
</repositories>
8. Persistencia
Base de datos
PostgreSQL. El esquema es gestionado externamente; esta librería no incluye migraciones Flyway ni Liquibase.
Entidades y tablas
| Entidad | Tabla | Clave primaria | Descripción |
|---|---|---|---|
Products | products | productid | Entidad raíz. Campos: productType, taxClass, masterProductId, variationGroupId, rawData, systemUpdateDate. Carga EAGER todas las colecciones relacionadas. |
ProductAttributes | productattributes | productid + attributeid | Atributos genéricos del producto. Campos: value, systemUpdateDate. |
ProductSiteData | productsitedata | productid + siteid | Datos de asignación del producto a un site: assignment, ats, instock, onLineFrom, systemUpdateDate. Con anotaciones JAXB. |
ProductSiteAttribute | productsiteattributes | productid + siteid + attributeid | Atributos del producto específicos por site. |
ProductSiteLocaleAttribute | productsitelocaleattribute | productid + siteid + localeid + attributeid | Atributos del producto específicos por site y locale. |
ProductSiteDataLocalePrice | productsitedatalocaleprice | productid + siteid + localeid | Precios de lista y venta por site y locale: listPrice, listPriceCurrency, salePrice, salePriceCurrency. |
ProductSiteDataLocaleUrl | productsitedatalocaleurl | productid + siteid + localeid | URL del producto por site y locale. Con anotaciones JAXB. |
ProductSiteDataLocalePromotions | productsitedatalocalepromotions | productid + siteid + locale + promotion | Promociones aplicables por site y locale. Con anotaciones JAXB. |
ProductSiteDataImages | productsitedataimages | productid + siteid + image | Imágenes del producto por site. |
Métodos de consulta destacados
ProductsRepository
| Método | Tipo | Descripción |
|---|---|---|
findAll() | Derivado | Todos los productos |
findByProductId(productId) | Derivado | Producto por ID |
findBySiteId(siteId) | Query nativa | Productos con assignment = true en el site dado |
findByVariationGroupIdIsNotNull() | Derivado | Productos con grupo de variación |
findByMasterProductIdIsNotNullAndVariationGroupIdIsNull() | Derivado | Productos con masterProduct pero sin grupo de variación (típicamente gafas de sol) |
findSunglassesDistinctMasterProductIdBy() | Query nativa | IDs de master product distintos para gafas de sol |
findByMasterProductIdIsNotNullAndVariationGroupIdIsNullAndProductIdList(list) | Query nativa | Filtro anterior restringido a una lista de IDs |
ProductSiteLocaleAttributeRepository
| Método | Tipo | Descripción |
|---|---|---|
findDistinctLocaleIdBySiteId(siteId) | Query nativa | Locales distintos disponibles para un site (consulta la tabla productsitedatalocaleurl) |
findBySiteIdAndLocaleIdOrderByProductIdAscAttributeIdAsc(siteId, localeId) | Derivado | Atributos ordenados para procesamiento bulk |
9. Procesos programados y mensajería
No aplica a este proyecto. Es una librería sin @Scheduled, listeners de colas ni runners batch.
10. Ejecución en local
Esta librería no tiene main y no se arranca de forma independiente. Se instala en el repositorio Maven local para ser consumida por otros proyectos.
Requisitos previos:
- JDK 25
- Maven 3.x
- Credenciales de GCP configuradas para acceder a Artifact Registry (si se necesita publicar o descargar desde el registro remoto)
Instalar en repositorio local:
./mvnw clean install -DskipTests
Compilar con tests:
./mvnw clean install
Verificar compilación:
./mvnw clean package -DskipTests
Para usar la librería en otro proyecto Maven local, añadir en su pom.xml:
<dependency>
<groupId>com.hawkersco</groupId>
<artifactId>webproductcatalog-commons</artifactId>
<version>1.0.25-SNAPSHOT</version>
</dependency>
11. Despliegue
La librería se publica como JAR en GCP Artifact Registry (europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven). No se despliega en ningún entorno de aplicación.
El pipeline de Jenkins ejecuta mvn deploy -DskipTests con JDK 25 y Maven 3. No hay stages de test ni Docker.
Job de Jenkins:
https://jenkins-pi.hawkersco.net/job/webproductcatalog-commons/
12. Manejo de errores y logging
No existe gestión propia de excepciones ni logging configurado en esta librería. Los errores de JPA (entidades no encontradas, violaciones de constraint, etc.) se propagan como excepciones estándar de Spring Data (DataAccessException y subclases) hacia el microservicio consumidor, que es quien debe decidir la estrategia de manejo.
No hay @ControllerAdvice, @ExceptionHandler ni appenders de logging definidos en la librería.
13. Notas y consideraciones
-
Carga EAGER en
Products: la entidadProductscarga todas sus colecciones relacionadas (7@OneToMany) conFetchType.EAGER. En catálogos con alto número de productos, llamar afindAll()ofindBySiteId()puede generar un número elevado de queries SQL o un producto cartesiano considerable. Los microservicios consumidores deben valorar si necesitan la entidad raíz completa o si es más eficiente consultar repositorios individuales. -
PagingAndSortingRepositorysinCrudRepository: los repositorios extiendenPagingAndSortingRepository(noJpaRepository). En Spring Data 3+ esto implica que métodos comosave(),saveAll(),delete()ofindById()no están disponibles a través de los repositorios directamente, salvo que el consumidor los declare o extiendaJpaRepository. Pendiente de verificar si esto es intencional (librería de solo lectura) o una limitación no detectada. -
Inyección de dependencias por campo: todos los servicios usan
@Autowiredsobre campo. Se recomienda migrar a inyección por constructor para facilitar testing unitario y seguir las buenas prácticas de Spring. -
Query cruzada en
ProductSiteLocaleAttributeRepository: el métodofindDistinctLocaleIdBySiteIdconsulta la tablaproductsitedatalocaleurldesde el repositorio deProductSiteLocaleAttribute. Este acoplamiento implícito puede generar confusión al mantener el código. -
Anotaciones JAXB parciales: solo tres entidades (
ProductSiteData,ProductSiteDataLocaleUrl,ProductSiteDataLocalePromotions) incluyen anotaciones JAXB, mientras que el resto no. La intención de uso XML es parcial y no está documentada en el código. -
Sin migraciones de esquema: el esquema de la base de datos no está gestionado por esta librería. Cualquier cambio en las entidades debe coordinarse con el equipo responsable del esquema PostgreSQL.