Skip to main content

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

PropiedadValor
artifactIdwebproductcatalog-commons
groupIdcom.hawkersco
version1.0.25-SNAPSHOT
Java25
Spring Boot4.0.6
Tipo de artefactoJAR (librería, sin main)
MódulosProyecto simple (no multi-módulo)
Repositorio MavenGCP 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
PaqueteContenido
com.hawkersco.webproductcatalogcommons.dao9 entidades JPA con claves compuestas (@IdClass)
com.hawkersco.webproductcatalogcommons.repository9 interfaces PagingAndSortingRepository
com.hawkersco.webproductcatalogcommons.service9 @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

DependenciaVersiónPropó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
postgresql42.7.5Driver JDBC para PostgreSQL
lombok1.18.42Generación de código: @Data, @NoArgsConstructor, @AllArgsConstructor
jakarta.xml.bind-api4.0.2Anotaciones JAXB para serialización XML en algunas entidades
artifactregistry-maven-wagon2.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

SistemaProtocoloDirección
PostgreSQLJDBC / JPASaliente (lectura/escritura)
GCP Artifact Registry (europe-west3-maven.pkg.dev)HTTPS / Maven WagonSaliente (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:

ClaveDescripciónEjemplo de valor
spring.datasource.urlURL JDBC de PostgreSQLjdbc:postgresql://host:5432/dbname
spring.datasource.usernameUsuario de base de datos${DB_USER}
spring.datasource.passwordContraseña de base de datos${DB_PASSWORD}
spring.jpa.database-platformDialecto Hibernateorg.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-autoEstrategia DDLnone (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

EntidadTablaClave primariaDescripción
ProductsproductsproductidEntidad raíz. Campos: productType, taxClass, masterProductId, variationGroupId, rawData, systemUpdateDate. Carga EAGER todas las colecciones relacionadas.
ProductAttributesproductattributesproductid + attributeidAtributos genéricos del producto. Campos: value, systemUpdateDate.
ProductSiteDataproductsitedataproductid + siteidDatos de asignación del producto a un site: assignment, ats, instock, onLineFrom, systemUpdateDate. Con anotaciones JAXB.
ProductSiteAttributeproductsiteattributesproductid + siteid + attributeidAtributos del producto específicos por site.
ProductSiteLocaleAttributeproductsitelocaleattributeproductid + siteid + localeid + attributeidAtributos del producto específicos por site y locale.
ProductSiteDataLocalePriceproductsitedatalocalepriceproductid + siteid + localeidPrecios de lista y venta por site y locale: listPrice, listPriceCurrency, salePrice, salePriceCurrency.
ProductSiteDataLocaleUrlproductsitedatalocaleurlproductid + siteid + localeidURL del producto por site y locale. Con anotaciones JAXB.
ProductSiteDataLocalePromotionsproductsitedatalocalepromotionsproductid + siteid + locale + promotionPromociones aplicables por site y locale. Con anotaciones JAXB.
ProductSiteDataImagesproductsitedataimagesproductid + siteid + imageImágenes del producto por site.

Métodos de consulta destacados

ProductsRepository

MétodoTipoDescripción
findAll()DerivadoTodos los productos
findByProductId(productId)DerivadoProducto por ID
findBySiteId(siteId)Query nativaProductos con assignment = true en el site dado
findByVariationGroupIdIsNotNull()DerivadoProductos con grupo de variación
findByMasterProductIdIsNotNullAndVariationGroupIdIsNull()DerivadoProductos con masterProduct pero sin grupo de variación (típicamente gafas de sol)
findSunglassesDistinctMasterProductIdBy()Query nativaIDs de master product distintos para gafas de sol
findByMasterProductIdIsNotNullAndVariationGroupIdIsNullAndProductIdList(list)Query nativaFiltro anterior restringido a una lista de IDs

ProductSiteLocaleAttributeRepository

MétodoTipoDescripción
findDistinctLocaleIdBySiteId(siteId)Query nativaLocales distintos disponibles para un site (consulta la tabla productsitedatalocaleurl)
findBySiteIdAndLocaleIdOrderByProductIdAscAttributeIdAsc(siteId, localeId)DerivadoAtributos 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 entidad Products carga todas sus colecciones relacionadas (7 @OneToMany) con FetchType.EAGER. En catálogos con alto número de productos, llamar a findAll() o findBySiteId() 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.

  • PagingAndSortingRepository sin CrudRepository: los repositorios extienden PagingAndSortingRepository (no JpaRepository). En Spring Data 3+ esto implica que métodos como save(), saveAll(), delete() o findById() no están disponibles a través de los repositorios directamente, salvo que el consumidor los declare o extienda JpaRepository. 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 @Autowired sobre 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étodo findDistinctLocaleIdBySiteId consulta la tabla productsitedatalocaleurl desde el repositorio de ProductSiteLocaleAttribute. 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.