Skip to main content

logistic-sea

1. Descripción general

Según el pom.xml, el proyecto se describe como "Logistic South Eastern Asia API". Es un microservicio batch (runner) que procesa pedidos pendientes con destino al sudeste asiático (Malasia y Singapur) y los envía al operador logístico HK Times Logistics (HKTL), dividiendo en múltiples envíos los pedidos que superan el umbral de aduanas de cada país.

2. Información técnica

CampoValor
artifactIdlogistic-sea
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 un único CommandLineRunner (LogisticSeaRunner).

  • .configLogisticSeaConfiguraton (wiring de beans), CustomsProperties (umbrales de aduanas por país).
  • .utilsLogisticSeaConst, LogisticSeaUtils (división de pedidos por umbral de aduanas, mapa de provincias de Malasia a nombre completo requerido por HKTL).
flowchart TD
A[LogisticSeaRunner] -->|pedidos pendientes SEA| B[(logistics · Order)]
B --> C{supera umbral aduanas?<br/>MY 500 MYR / SG 400 SGD}
C -->|sí| D[división en varios envíos]
C -->|no| E[envío único]
D --> F[HK Times Logistics API]
E --> F
F -->|éxito/error| G[GCS pi-logistics-segment]
F -.->|error, ≥4 reintentos| H[Slack]

Flujo: obtiene los pedidos pendientes de logística SEA; los pedidos de Malasia superiores a 500 MYR y de Singapur superiores a 400 SGD se dividen en varios envíos (LogisticSeaUtils); cada pedido/envío se transforma y se envía a la API de HKTL; la petición y la respuesta se archivan en GCS; el estado del pedido se actualiza (INITCREATED en éxito, o estados de error) y tras 4 reintentos fallidos se notifica a Slack.

4. Dependencias principales

DependenciaPropósito
spring-boot-starterNúcleo de Spring Boot (sin web, es un runner CLI)
com.hawkersco:hk-timeslogistics-clientCliente @HttpExchange para la API de HK Times Logistics
com.hawkersco:logistics-commonsEntidades JPA (Order, Shipment) y servicios
com.hawkersco:sfcc-commonsUtilidades de Salesforce Commerce Cloud
com.hawkersco:slack-clientNotificaciones de error
com.hawkersco:pi-function-commonsDateUtils, StorageUtils

5. API / Endpoints

No aplica a este proyecto. Es un batch/runner sin capa REST.

6. Integraciones externas

SistemaProtocoloDirecciónDetalle
HK Times Logistics API (foms-api.kec-app.com)HTTP REST (hk-timeslogistics-client)SalienteEnvío de pedidos/envíos de Malasia y Singapur
Google Cloud Storage (bucket pi-logistics-segment)API de GCSSalienteArchivado de peticiones/respuestas
SlackHTTP (SlackClient)SalienteAlertas tras 4 intentos fallidos
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
hktl.url / .id / .passCredenciales de la API de HK Times Logistics (con un bloque de credenciales de test comentado adicional)
hktl.provinces.myLista de provincias de Malasia en formato completo requerido por HKTL
logisticsea.customs.my / .sgUmbrales de valor de aduanas por país (500 MYR / 400 SGD) que disparan la división en varios envíos
slack.client.url / .auth.token / .channel.id / .channel-atc.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), las credenciales de producción de la API HKTL, y el token de bot de Slack. Ninguna credencial se ha reproducido en este documento. Se recomienda:

  1. Rotar la contraseña de BD, las credenciales de HKTL y el token de Slack.
  2. Sustituir los valores hardcodeados de application.properties por credenciales de un entorno de desarrollo aislado.
  3. Revisar el historial de control de versiones, ya que estas credenciales pueden seguir expuestas en commits anteriores.

8. Persistencia

Base de datos PostgreSQL logistics (spring.jpa.hibernate.ddl-auto=none). Entidades relevantes: Order, 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 (k8s/cronjob.yaml), que ejecuta el contenedor cada 15 minutos (schedule: "0/15 * * * *", concurrencyPolicy: Forbid). Único runner, descrito en 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 HKTL.

# Compilar sin tests
./mvnw clean install -DskipTests

# Compilar con tests
./mvnw clean install

# Ejecutar la aplicación localmente
./mvnw spring-boot:run

# Ejecutar con perfil de producción
./mvnw spring-boot:run -Dspring-boot.run.profiles=pro

# Docker
docker build -t logistic-sea:local .

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-sea:<tag>.
  • Orquestación: Kubernetes CronJob en el clúster GKE pi-cluster-hw, namespace pi, con credenciales de cuenta de servicio de GCP montadas por volumen, ejecutándose cada 15 minutos.
  • CI/CD (Jenkins): pipeline real de 3 etapas — CheckoutBuild & PushDeploy to GKE. El CLAUDE.md describe un pipeline de 7 etapas (Build → KICS Scan → SonarQube → Test → Docker Push → K8s Deploy → Clean) que no coincide con el Jenkinsfile actual (mismo patrón detectado en varios proyectos hermanos de este lote).

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

12. Manejo de errores y logging

No hay una estrategia de excepciones centralizada (no hay @ControllerAdvice, es un runner). El procesamiento de cada pedido captura sus propios errores HTTP, incrementando el contador de reintentos y archivando en GCS; tras 4 fallos se notifica a Slack. Logging mediante java.util.logging.Logger estándar (consola).

13. Notas y consideraciones

  • Pipeline de Jenkins más simple de lo documentado: ver hallazgo en la sección 11.
  • El resto de la arquitectura descrita en CLAUDE.md (umbrales de aduanas de 500 MYR/400 SGD, división de envíos, mapa de provincias de Malasia, estados de pedido INIT/CREATED/TEST/COUNTRY_ERROR/NO_PROVINCE_ERROR/ERROR, límite de 4 reintentos) coincide con el código real, verificado directamente en LogisticSeaRunner y LogisticSeaUtils.
  • Ver alerta de seguridad en la sección 7 sobre credenciales reales expuestas en application.properties.