miravia-update-stock
1. Descripción general
Según el pom.xml, el proyecto se describe como "Miravia update stock". Es un microservicio batch (runner) que sincroniza el stock disponible en Dynamics 365 con las ofertas activas del marketplace Miravia, actualizando la cantidad de cada SKU vía la API de Miravia (firmada con SHA-256).
2. Información técnica
| Campo | Valor |
|---|---|
artifactId | miravia-update-stock |
groupId | com.hawkersco |
version | 1.0.25 |
| Java | 25 |
| Spring Boot | 4.0.6 |
| Tipo de artefacto | jar (ejecutable, Spring Boot batch/CLI) |
| Módulos | No aplica (proyecto de módulo único) |
3. Arquitectura y diseño
No es una API REST: es una aplicación Spring Boot CLI con un único CommandLineRunner (MiraviaUpdateStockRunner).
.config—MiraviaUpdateStockConfig,DynamicsDbConfig(único datasource,dynamics-pro).
flowchart TD
A[MiraviaUpdateStockRunner] -->|token vía pi-generate-credentials| B[Miravia API]
A -->|findProductDynamicsByWharehouseAndDataAreaId<br/>AU03 / dataAreaId 10| C[(dynamics-pro · ProductDynamics)]
A -->|pagina productos, 40/página| B
A -->|"stock = floor(cantidad Dynamics)"| D[updateProductPriceQuantity]
D --> B
A -->|SKU no encontrado| E["cantidad = 0"]
Flujo: obtiene un token OAuth de Miravia vía el servicio interno pi-generate-credentials; carga el stock disponible del almacén AU03/dataAreaId 10 desde Dynamics; pagina el catálogo completo de ofertas de Miravia (40 por página); para cada SKU de Miravia presente en Dynamics, actualiza su cantidad a floor(cantidad disponible en Dynamics) —sin ningún ajuste porcentual—; para los SKUs de Miravia no encontrados en Dynamics, fija la cantidad a 0. Entre llamadas a la API se espera 3 segundos por límite de tasa.
4. Dependencias principales
| Dependencia | Propósito |
|---|---|
spring-boot-starter | Núcleo de Spring Boot (sin web, es un runner CLI) |
spring-web | RestClient/@HttpExchange |
com.hawkersco:miravia-client | Cliente @HttpExchange + utilidades de firma SHA-256 para la API de Miravia |
com.hawkersco:dynamics-commons | ProductDynamicsService, entidad ProductDynamics |
com.hawkersco:pi-generate-credentials-client | Obtención de token OAuth de Miravia |
No existe dependencia marketplaces-commons en el pom.xml, pese a que CLAUDE.md describe un segundo datasource hacia una BD de "Marketplaces" con porcentajes de asignación por SKU (ver hallazgo crítico en la sección 13).
5. API / Endpoints
No aplica a este proyecto. Es un batch/runner sin capa REST.
6. Integraciones externas
| Sistema | Protocolo | Dirección | Detalle |
|---|---|---|---|
Miravia API (api.miravia.es) | HTTP REST firmado SHA-256 (MiraviaClient) | Entrante/Saliente | Lectura paginada del catálogo y actualización de cantidad por SKU |
Servicio interno pi-generate-credentials | HTTP | Entrante | Obtención de token OAuth de Miravia |
PostgreSQL (dynamics-pro) | JDBC | Entrante | Lectura de stock disponible por almacén/dataAreaId |
7. Configuración
En producción (application-pro.properties) las credenciales llegan por variables de entorno inyectadas como Secret de Kubernetes; en local (application.properties) el repositorio contiene actualmente valores reales hardcodeados (ver alerta de seguridad).
| Clave | Descripción |
|---|---|
miravia.client.url / .appkey / .appsecret | Credenciales de la API de Miravia |
spring.datasource.* | Credenciales de la BD dynamics-pro (único datasource) |
credentials-client.api.host | URL del servicio interno pi-generate-credentials |
⚠️ Alerta de seguridad
El fichero src/main/resources/application.properties (perfil local) contiene actualmente credenciales reales en texto plano: la clave/secreto de aplicación de Miravia (la misma ya señalada como expuesta en miravia-create-db y logistics-status-process) y la contraseña de la base de datos PostgreSQL dynamics-pro (la misma ya señalada como expuesta en múltiples proyectos de este ecosistema). Ninguna se ha reproducido en este documento. Se recomienda rotar ambas credenciales y sustituir los valores hardcodeados por credenciales de un entorno de desarrollo aislado.
8. Persistencia
Base de datos PostgreSQL dynamics-pro, único datasource (DynamicsDbConfig), acceso vía dynamics-commons (ddl-auto=none). Entidad relevante: ProductDynamics. No hay Flyway/Liquibase en este repositorio.
9. Procesos programados y mensajería
No hay @Scheduled ni listeners de colas: la periodicidad la impone el CronJob de Kubernetes, que ejecuta el contenedor cada 15 minutos (schedule: "*/15 * * * *"). Único runner, descrito en la sección 3.
10. Ejecución en local
Requisitos previos: JDK 25, Maven, acceso a la BD dynamics-pro y credenciales válidas de Miravia.
# Compilar
./mvnw clean install
# Compilar sin tests (producción)
./mvnw -B -DskipTests clean install
# Ejecutar tests
./mvnw test
# Ejecutar un test concreto
./mvnw test -Dtest=MiraviaUpdateStockApplicationTests
# Ejecutar la aplicación localmente
./mvnw spring-boot:run
Al ser un CommandLineRunner, no expone Actuator/health: la verificación se hace revisando el log de consola o el estado de las ofertas en el panel de Miravia.
11. Despliegue
- Imagen: construida con
jib-maven-plugin(baseeclipse-temurin:25-jre,containerizingMode=packaged), publicada eneurope-west3-docker.pkg.dev/pi-saldum/pi-repo/miravia-update-stock:<tag>. - Orquestación: Kubernetes
CronJoben el clúster GKEpi-cluster-hw, namespacepi, ejecutándose cada 15 minutos. - CI/CD (Jenkins): pipeline real de 3 etapas —
Checkout→Build & Push→Deploy to GKE. ElCLAUDE.mddescribe un pipeline de 5 etapas (Build → Test → Push → Deployment → Clean) que no coincide con elJenkinsfileactual.
Job de Jenkins: https://jenkins-pi.hawkersco.net/job/miravia-update-stock/
12. Manejo de errores y logging
No hay una estrategia de excepciones centralizada (no hay @ControllerAdvice, es un runner). Todo el run() está envuelto en un único try/catch genérico que registra Level.WARNING sin interrumpir la finalización normal del proceso. Un fallo HTTP al actualizar un SKU concreto se registra pero no interrumpe el resto del lote. Logging mediante java.util.logging.Logger estándar (consola).
13. Notas y consideraciones
CLAUDE.mddescribe una arquitectura de doble datasource y ajuste de stock por porcentaje que no existe en el código actual: afirma que el runner consulta un segundo datasource ("Marketplaces DB", vía una claseMarketplacesDbConfigy unMarketplaceStockServicede la libreríamarketplaces-commons) para obtener un porcentaje de asignación por SKU y calcularstock = floor(dynamicsQty * allocation / 100). En el código real solo existe un datasource (dynamics-pro), no hay claseMarketplacesDbConfig, la libreríamarketplaces-commonsni siquiera es una dependencia delpom.xml, y el cálculo de stock es una copia directa del valor de Dynamics redondeado hacia abajo, sin ningún ajuste porcentual. Es exactamente el mismo patrón de desviación ya detectado en el proyecto hermanoshowroom-update-stockde este mismo ecosistema — probablemente ambosCLAUDE.mdse generaron a partir de una plantilla común o se copiaron entre sí sin ajustarse al código real de cada proyecto.- Retardo entre llamadas distinto del documentado:
CLAUDE.mdindica una espera de 10 segundos entre llamadas a la API; el código real usaRATE_LIMIT_DELAY_MS = 3_000L(3 segundos). - Pipeline de Jenkins más simple de lo documentado: ver hallazgo en la sección 11.
- Ver alerta de seguridad en la sección 7 sobre credenciales reales expuestas en
application.properties.