Skip to main content

logistic-mx

1. Descripción general

Según el pom.xml, el proyecto se describe como "Logistic from Mexico". Es un microservicio batch (runner) que procesa pedidos pendientes con destino México (estándar y de marketplace) y los envía al operador logístico Cubbo, validando disponibilidad de stock e inventario de marketplace antes del envío.

2. Información técnica

CampoValor
artifactIdlogistic-mx
groupIdcom.hawkersco
version1.0.25
Java25
Spring Boot4.0.6
Tipo de artefactojar (ejecutable, Spring Boot batch/CLI, spring.main.web-application-type=none)
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 2 CommandLineRunner, ambos activos.

OrdenRunnerPropósito
1LogisticMxRunnerProcesa pedidos estándar (no marketplace): construye OrderCubboRequest y los envía a Cubbo
2LogisticMxMpRunnerProcesa pedidos de marketplace: además valida stock/inventario en Cubbo antes de enviar; llama a System.exit() al terminar
  • .clientGroupLogisticsClient (@HttpExchange hacia un endpoint de pruebas de "Group Logistics", ver hallazgo en la sección 13 — no invocado desde ningún punto del código actual).
  • .configGroupLogisticsAutoConfiguration (wiring del cliente anterior), LogisticMxConfiguration (beans de logistics-commons), LogisticMxUtils.
  • .utilsLogisticMxConst (constantes: mapas de código postal por transportista, IDs de transportista).
flowchart TD
A["1. LogisticMxRunner<br/>pedidos estándar"] -->|OrderCubboRequest| B[Cubbo API]
C["2. LogisticMxMpRunner<br/>pedidos marketplace"] -->|valida stock/inventario| B
C -->|envía| B
B -->|éxito/error| D[GCS pi-logistics-segment]
A -.->|≥4 fallos| E[Slack]
C -.->|≥4 fallos, stock, duplicados| E
C -->|System.exit al terminar| F[Fin del proceso]

Ambos runners incrementan un contador de reintentos (nmSendLogistic) por pedido tras un fallo HTTP (RestClientResponseException), archivan cada petición/respuesta en GCS, y notifican a Slack tras 4 fallos, ante escasez de stock, o ante pedidos duplicados.

4. Dependencias principales

DependenciaPropósito
spring-boot-starterNúcleo de Spring Boot (sin web, es un runner CLI)
spring-webRestClient/@HttpExchange
com.hawkersco:cubbo-clientCliente @HttpExchange para la API de Cubbo
com.hawkersco:logistics-commonsEntidades JPA (Order, OrderLine, Shipment) y servicios
com.hawkersco:slack-clientNotificaciones de error
com.hawkersco:pi-function-commonsDateUtils y utilidades compartidas

No existe dependencia logisfashion-client en el pom.xml, pese a que CLAUDE.md la cita como dependencia interna y application.properties contiene credenciales de LogisFashion sin ningún uso en el código (ver hallazgo 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
Cubbo APIHTTP REST (CubboClient)SalienteEnvío de pedidos estándar y de marketplace, consulta de stock/inventario
Google Cloud Storage (bucket pi-logistics-segment)API de GCSSalienteArchivado de peticiones/respuestas
SlackHTTP (SlackClient)SalienteAlertas de stock, duplicados y fallos repetidos
PostgreSQL (logistics)JDBCEntrante/SalienteLectura de pedidos pendientes y actualización de estado

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).

ClaveDescripción
spring.datasource.*Credenciales de la BD logistics
gcs.bucket.nameBucket de GCS para archivado
cubbo.client.url / .clientid.prod / .clientsecret.prod / .storeid.prodCredenciales OAuth de la API de Cubbo (con un bloque de credenciales de test comentado adicional)
logisfashion.api.url / .key / .passwordCredenciales de LogisFashion — sin ningún uso en el código actual (ver hallazgo en la sección 13)
logisticmx.carrier*.cpExtensos listados de códigos postales por transportista para enrutamiento
logisticmx.shipping.country / .iso2 / .iso3 / .isoidDatos fijos de país (México)
slack.client.url / .auth.token / .channel.id / .channel-atc-mx.idConfiguración de Slack

⚠️ Alerta de seguridad

El fichero src/main/resources/application.properties (perfil local) contiene actualmente credenciales reales en texto plano: contraseña de la base de datos PostgreSQL logistics (la misma ya señalada como expuesta en múltiples proyectos de este ecosistema), dos juegos de credenciales OAuth de Cubbo (uno de test comentado, uno de producción activo), las credenciales de LogisFashion (huérfanas, sin uso), y el token de bot de Slack. Adicionalmente, el fichero GroupLogisticsClient.java contiene un token de autenticación hardcodeado directamente en la URL de la anotación @HttpExchange en código fuente Java (ver hallazgo en la sección 13). Ninguna credencial se ha reproducido en este documento. Se recomienda:

  1. Rotar la contraseña de BD, las credenciales de Cubbo y el token de Slack.
  2. Decidir si las credenciales de LogisFashion siguen siendo necesarias; si no, eliminarlas del fichero de configuración.
  3. Eliminar o mover a configuración el token hardcodeado en GroupLogisticsClient, y valorar si esa clase debe eliminarse por completo al no usarse.

8. Persistencia

Base de datos PostgreSQL logistics (spring.jpa.hibernate.ddl-auto=none). Entidades relevantes: Order, OrderLine, Shipment. 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 5 minutos (schedule: "0/5 * * * *", concurrencyPolicy: Forbid). Se ejecutan en orden los 2 runners de la tabla de la sección 3.

10. Ejecución en local

Requisitos previos: JDK 25, Maven, acceso a la BD logistics y credenciales válidas de la API de Cubbo.

# Compilar sin tests
./mvnw clean install -DskipTests

# Compilar con tests
./mvnw clean install

# Ejecutar tests
./mvnw test

# Ejecutar un test concreto
./mvnw test -Dtest=ClassName#methodName

# 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 los pedidos en la BD logistics.

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/logistic-mx:<tag>.
  • Orquestación: Kubernetes CronJob en el clúster GKE pi-cluster-hw, namespace pi, ejecutándose cada 5 minutos.
  • CI/CD (Jenkins): pipeline real de 3 etapas — CheckoutBuild & PushDeploy to GKE. El CLAUDE.md menciona escaneo KICS y análisis SonarQube que no aparecen en el Jenkinsfile actual (mismo patrón detectado en varios proyectos hermanos de este lote).

Job de Jenkins: https://jenkins-pi.hawkersco.net/job/logistic-mx/

12. Manejo de errores y logging

No hay una estrategia de excepciones centralizada (no hay @ControllerAdvice, es un runner). Las llamadas HTTP a Cubbo se envuelven en try/catch sobre RestClientResponseException; ante fallo se incrementa el contador de reintentos del pedido y se archiva el error en GCS. Tras 4 fallos se notifica a Slack. Logging mediante java.util.logging.Logger estándar (consola).

13. Notas y consideraciones

  • GroupLogisticsClient apunta a un endpoint de pruebas con un token hardcodeado, y no se usa en ningún punto del código: la interfaz @HttpExchange declara la URL base https://wms-api-test.grupo-logistics.com (obsérvese "test" en el propio host) y una ruta con un token de autenticación embebido como parámetro de consulta (tokenData=...) directamente en la anotación Java. No hay ninguna referencia a esta clase desde LogisticMxRunner ni LogisticMxMpRunner — es código muerto, aparentemente un cliente experimental o abandonado, con un secreto de entorno de pruebas expuesto en el código fuente. Se recomienda eliminarlo si no tiene uso previsto, o moverlo a configuración si se planea retomar.
  • Credenciales de LogisFashion huérfanas: application.properties define logisfashion.api.url/.key/.password, y CLAUDE.md cita logisfashion-client como dependencia interna, pero el pom.xml no la declara y no hay ninguna referencia a "logisfashion" en el código Java de este proyecto — mismo patrón de credenciales huérfanas (aunque de menor escala) detectado en logistic-lenses con Shopify.
  • Doble juego de credenciales de Cubbo en el mismo fichero: application.properties mantiene un bloque de credenciales de test comentado junto al bloque de producción activo — práctica común en este ecosistema, pero que aumenta la superficie de credenciales a rotar si se limpia el fichero en el futuro.
  • El resto de la arquitectura descrita en CLAUDE.md (dos runners, orden de ejecución, patrón de reintento con contador nmSendLogistic, archivado en GCS, alertas Slack) coincide con el código real, verificado directamente en LogisticMxRunner y LogisticMxMpRunner.
  • Ver alerta de seguridad en la sección 7 sobre credenciales reales expuestas en application.properties y sobre el token hardcodeado en GroupLogisticsClient.