Skip to main content

order-pi-dynamics

1. Descripción general

Según el pom.xml, el proyecto se describe como "Send orders pi to dynamics". Es el microservicio orquestador central que envía pedidos desde numerosas plataformas de e-commerce/marketplace (SFCC en sus variantes ES/MX/CO/NW/EU2013, Mercado Libre, Mercado Libre Colombia, Miravia, Decathlon, El Corte Inglés, Falabella, Privalia, Privalia Marketplace, Coppel, Liverpool, Showroom, Showroom Flash, TheBradery) hacia Microsoft Dynamics 365, además de sincronizar estados de pedido de vuelta y realizar actualizaciones de datos y pagos.

2. Información técnica

CampoValor
artifactIdorder-pi-dynamics
groupIdcom.hawkersco
version1.0.25
Java25
Spring Boot4.0.6
Tipo de artefactojar (ejecutable, Spring Boot batch/CLI)
MódulosNo aplica (proyecto de módulo único)

3. Arquitectura y diseño

No es una API REST: es una aplicación Spring Boot CLI con 24 CommandLineRunner, cada uno activado por un perfil de Spring (@Profile("NombreDelRunner")) con el mismo nombre que la clase, salvo una excepción notable (ver hallazgo en la sección 13). En producción se activan todos los perfiles simultáneamente; en desarrollo solo se activa uno.

RunnerPerfil (@Profile)Ámbito
OrderMeliPiDynamicsRunnerActivoMercado Libre
OrderMeliCoPiDynamicsRunnerActivoMercado Libre Colombia
OrderSfccPiDynamicsRunner, OrderSfccMxPiDynamicsRunner, OrderSfccCoPiDynamicsRunner, OrderSfccNwPiDynamicsRunner, OrderSfccEu2013PiDynamicsRunnerActivosVariantes de Salesforce Commerce Cloud
OrderSfccMxPaidZeroPiDynamicsRunner, OrderSfccCoPaidZeroPiDynamicsRunnerActivosPedidos SFCC con importe pagado cero (MX/CO)
OrderMiraviaPiDynamicsRunnerActivoMiravia
OrderDecathlonPiDynamicsRunnerActivoDecathlon
OrderECIPiDynamicsRunnerActivoEl Corte Inglés
OrderFalabellaPiDynamicsRunnerActivoFalabella
OrderPrivaliaPiDynamicsRunner, OrderPrivaliaMarketplacePiDynamicsRunnerActivosPrivalia (directo y marketplace)
OrderCoppelPiDynamicsRunnerActivoCoppel
OrderLiverpoolPiDynamicsRunnerActivoLiverpool
OrderShowroomPiDynamicsRunnerActivoShowroom Privé
OrderShowroomFlashPiDynamicsRunner@Profile comentado — sin restricción de perfil (ver hallazgo crítico en la sección 13)Showroom Flash
OrderTheBraderyPiDynamicsRunnerActivoTheBradery
OrderBrandingPiDynamicsRunnerActivoPedidos de branding/personalización
StatusOrderPiDynamicsRunnerActivoSincronización de estados de pedido de vuelta a Dynamics
OrderDetectorLimboRunnerActivoDetección de pedidos atascados/en limbo
UpdateDataDynamicsRunnerActivoActualizaciones masivas de datos
UpdatePaymentDynamicsRunnerActivoActualizaciones de pago
  • .configDynamicsDbConfig (@Primary, BD dynamics-pro), LogisticsDbConfig (BD logistics).
  • .utilsOrderPiDynamicsUtils (transformación compartida), OrderPiDynamicsCons (constantes: SKUs, tipos de tender, DATA_AREA_ID por país), OrderVerifyPiDynamicsUtils (validación previa al envío), OrderPiDynamicsErrorUtils (formato de error + Slack), OrderSfccPiDynamicsUtils/OrderSfccMxPiDynamicsUtils/OrderSfccCoPiDynamicsUtils (lógica específica por canal SFCC), StatusOrderPiDynamicsUtils, UpdateDataDynamicsUtils.
flowchart TD
A[24 runners activados por perfil] -->|pedidos pendientes| B[(logistics · Order)]
A -->|obtiene pedido| C[API de la plataforma correspondiente]
A -->|valida y transforma| D[OrderPiDynamicsUtils]
D -->|envía| E[Dynamics 365 REST API]
A -.->|error| F[Slack]

4. Dependencias principales

DependenciaPropósito
spring-boot-starterNúcleo de Spring Boot (sin web, es un runner CLI)
org.apache.poi:poi / poi-ooxmlSoporte de ficheros Excel
com.hawkersco:dynamics-client / dynamics-commonsCliente y entidades de Dynamics 365
com.hawkersco:sfcc-commonsModelos de pedido de Salesforce Commerce Cloud
com.hawkersco:meli-client, miravia-client, decathlon-client, eci-client, falabella-client, privalia-client, privalia-marketplace-client, coppel-client, qat-client (Liverpool), showroom-client, bradery-clientClientes @HttpExchange por plataforma
com.hawkersco:recharge-clientSuscripciones Recharge (lentillas)
com.hawkersco.posclient:pos-clientPunto de venta
com.hawkersco:stripe-clientPagos Stripe
com.hawkersco:slack-clientNotificaciones de error

No existen dependencias shein-client ni tiktok-client en el pom.xml, pese a que CLAUDE.md las cita explícitamente como integraciones activas, incluyendo un runner OrderSheinPiDynamicsRunner que no existe en el árbol de código actual (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

SistemaProtocoloDirecciónDetalle
Dynamics 365 REST APIHTTP REST, OAuth2 (2 client secrets: login general y picustomersetup)SalienteCreación/actualización de pedidos y datos
Mercado Libre, Mercado Libre Colombia, Miravia, Decathlon, El Corte Inglés, Falabella, Privalia (x2), Coppel, Liverpool, Showroom (x2), TheBraderyHTTP REST (clientes @HttpExchange)EntranteLectura de pedidos por plataforma
RechargeHTTP, con tokens por país (ES/DE/FR/IT/PT/UK)SalienteGestión de suscripciones de lentillas
StripeHTTPSalienteVerificación/gestión de pagos
SprintLogisticsHTTPSalienteDatos logísticos asociados a pedidos
SlackHTTP (SlackClient)SalienteNotificaciones de error
PostgreSQL (dynamics-pro, logistics)JDBC (doble datasource)Entrante/SalienteLectura de pedidos pendientes y escritura en Dynamics

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 una cantidad muy elevada de valores reales hardcodeados (ver alerta de seguridad).

ClaveDescripción
spring.profiles.activeDetermina qué runner se ejecuta en local — actualmente StatusOrderPiDynamicsRunner (ver hallazgo en la sección 13)
spring.datasource.* / logistics.datasource.*Credenciales de las BD dynamics-pro y logistics
dynamics.login.client-secret / dynamics.picustomersetup.login.client-secretDos secretos OAuth distintos de Dynamics 365
slack.auth.tokenToken de bot de Slack
lenses.recharge.tokenTokens de Recharge por país (ES/DE/FR/IT/PT/UK)
sprintlogistics.api.passwordCredencial de SprintLogistics
meli.credentials.clientsecretCredencial OAuth de Mercado Libre
stripe.client.passwordCredencial de Stripe

🛑 Alerta de seguridad — volumen muy elevado de credenciales reales de múltiples sistemas

El fichero src/main/resources/application.properties (perfil local) contiene credenciales reales de al menos 8 sistemas distintos: ambas bases de datos PostgreSQL (contraseña compartida ya señalada como expuesta en múltiples proyectos), dos secretos OAuth de Dynamics 365, el token de bot de Slack, seis tokens de Recharge (uno por país), la contraseña de la API de SprintLogistics, el client secret de Mercado Libre, y la contraseña del cliente de Stripe. Ninguna se ha reproducido en este documento. Dada la centralidad de este proyecto (orquestador de pedidos hacia el ERP), se recomienda rotar todas estas credenciales con prioridad alta y sustituir los valores hardcodeados de application.properties por credenciales de un entorno de desarrollo aislado.

8. Persistencia

Dos bases de datos PostgreSQL independientes: dynamics-pro (@Primary, vía dynamics-commons) y logistics (vía logistics-commons), cada una con su propio EntityManagerFactory/TransactionManager. 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. En producción se activan todos los perfiles de runner simultáneamente (application-pro.properties), ejecutándose los 24 runners en cada invocación.

10. Ejecución en local

Requisitos previos: JDK 25, Maven, acceso a ambas BD y credenciales válidas de la plataforma/runner que se quiera probar.

# Compilar
./mvnw clean package

# Ejecutar (usa el perfil activo en application.properties)
./mvnw spring-boot:run

# Ejecutar tests
./mvnw test

# Ejecutar un test concreto
./mvnw test -Dtest=OrderPiDynamicsApplicationTests

# Build Docker
docker build -t order-pi-dynamics .

Al ser un conjunto de CommandLineRunner, no expone Actuator/health: la verificación se hace revisando el log de consola o el estado de los pedidos en Dynamics/BD.

11. Despliegue

  • Imagen: construida con jib-maven-plugin (base eclipse-temurin:25-jre, containerizingMode=packaged), publicada en europe-west3-docker.pkg.dev/pi-saldum/pi-repo/order-pi-dynamics:<tag>. El CLAUDE.md menciona una imagen base eclipse-temurin:25-jdk con heap -Xmx2G, que no coincide con la configuración real vía Jib.
  • Orquestación: Kubernetes CronJob en el clúster GKE pi-cluster-hw, namespace pi.
  • CI/CD (Jenkins): pipeline real de 3 etapas — CheckoutBuild & PushDeploy to GKE.

Job de Jenkins: https://jenkins-pi.hawkersco.net/job/order-pi-dynamics/

12. Manejo de errores y logging

No hay una estrategia de excepciones centralizada (no hay @ControllerAdvice, es un conjunto de runners). OrderPiDynamicsErrorUtils centraliza el formato de error y la notificación a Slack, usada de forma consistente por los distintos runners de plataforma. Logging mediante java.util.logging.Logger/SLF4J según la clase.

13. Notas y consideraciones

⚠️ Hallazgo: OrderShowroomFlashPiDynamicsRunner no tiene restricción de perfil activa

A diferencia de los otros 23 runners, cuya anotación @Profile("NombreDelRunner") limita su ejecución al perfil correspondiente, OrderShowroomFlashPiDynamicsRunner tiene esta anotación comentada (//@Profile("OrderShowroomFlashPiDynamicsRunner")). Esto significa que este runner en concreto se ejecuta siempre, independientemente del perfil de Spring activo — incluido en el entorno local, donde el perfil activo es actualmente StatusOrderPiDynamicsRunner (ver más abajo), lo que provocaría que ambos runners se ejecuten simultáneamente en desarrollo aunque solo se pretendiera probar uno. En producción, donde todos los perfiles ya están activos a la vez, el efecto práctico es menor, pero conviene restaurar la anotación para mantener el comportamiento consistente y predecible entre entornos.

Otros hallazgos

  • CLAUDE.md cita un runner y clientes de Shein/TikTok que no existen en el código actual: el documento existente menciona OrderSheinPiDynamicsRunner como uno de los "key runners" y lista clientes internos de shein y tiktok entre las integraciones REST — ninguno de los dos existe: no hay ningún fichero OrderSheinPiDynamicsRunner.java en el árbol de código, y el pom.xml no declara ni shein-client ni tiktok-client. Es el mismo patrón de integración ficticia/huérfana de TikTok ya detectado en pi-generate-credentials y logistics-status-process en este ecosistema, y aquí se extiende también a una integración de Shein igualmente inexistente.
  • El perfil activo por defecto en application.properties no coincide con CLAUDE.md: el documento existente afirma que en desarrollo solo OrderMeliPiDynamicsRunner está activo por defecto; el fichero real de configuración tiene spring.profiles.active=StatusOrderPiDynamicsRunner.
  • Imagen base y heap no coinciden con la configuración real: ver hallazgo en la sección 11.
  • El resto de la arquitectura descrita en CLAUDE.md (patrón de runner por perfil, doble datasource, utilidades compartidas) coincide con el código real, verificado mediante inspección de las anotaciones @Profile de los 24 runners.
  • Ver alerta de seguridad en la sección 7 sobre el elevado volumen de credenciales reales expuestas en application.properties.