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
| Campo | Valor |
|---|---|
artifactId | logistic-sea |
groupId | com.hawkersco |
version | 1.0.25 |
| Java | 25 |
| Spring Boot | 4.0.6 |
| Tipo de artefacto | jar (ejecutable, Spring Boot batch/CLI, spring.main.web-application-type=none) |
| 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 (LogisticSeaRunner).
.config—LogisticSeaConfiguraton(wiring de beans),CustomsProperties(umbrales de aduanas por país)..utils—LogisticSeaConst,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 (INIT → CREATED en éxito, o estados de error) y tras 4 reintentos fallidos se notifica a Slack.
4. Dependencias principales
| Dependencia | Propósito |
|---|---|
spring-boot-starter | Núcleo de Spring Boot (sin web, es un runner CLI) |
com.hawkersco:hk-timeslogistics-client | Cliente @HttpExchange para la API de HK Times Logistics |
com.hawkersco:logistics-commons | Entidades JPA (Order, Shipment) y servicios |
com.hawkersco:sfcc-commons | Utilidades de Salesforce Commerce Cloud |
com.hawkersco:slack-client | Notificaciones de error |
com.hawkersco:pi-function-commons | DateUtils, StorageUtils |
5. API / Endpoints
No aplica a este proyecto. Es un batch/runner sin capa REST.
6. Integraciones externas
| Sistema | Protocolo | Dirección | Detalle |
|---|---|---|---|
HK Times Logistics API (foms-api.kec-app.com) | HTTP REST (hk-timeslogistics-client) | Saliente | Envío de pedidos/envíos de Malasia y Singapur |
Google Cloud Storage (bucket pi-logistics-segment) | API de GCS | Saliente | Archivado de peticiones/respuestas |
| Slack | HTTP (SlackClient) | Saliente | Alertas tras 4 intentos fallidos |
PostgreSQL (logistics) | JDBC | Entrante/Saliente | Lectura 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).
| Clave | Descripción |
|---|---|
spring.datasource.* | Credenciales de la BD logistics |
hktl.url / .id / .pass | Credenciales de la API de HK Times Logistics (con un bloque de credenciales de test comentado adicional) |
hktl.provinces.my | Lista de provincias de Malasia en formato completo requerido por HKTL |
logisticsea.customs.my / .sg | Umbrales 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.id | Configuració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:
- Rotar la contraseña de BD, las credenciales de HKTL y el token de Slack.
- Sustituir los valores hardcodeados de
application.propertiespor credenciales de un entorno de desarrollo aislado. - 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(baseeclipse-temurin:25-jre,containerizingMode=packaged), publicada eneurope-west3-docker.pkg.dev/pi-saldum/pi-repo/logistic-sea:<tag>. - Orquestación: Kubernetes
CronJoben el clúster GKEpi-cluster-hw, namespacepi, con credenciales de cuenta de servicio de GCP montadas por volumen, ejecutándose cada 15 minutos. - CI/CD (Jenkins): pipeline real de 3 etapas —
Checkout→Build & Push→Deploy to GKE. ElCLAUDE.mddescribe un pipeline de 7 etapas (Build → KICS Scan → SonarQube → Test → Docker Push → K8s Deploy → Clean) que no coincide con elJenkinsfileactual (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 pedidoINIT/CREATED/TEST/COUNTRY_ERROR/NO_PROVINCE_ERROR/ERROR, límite de 4 reintentos) coincide con el código real, verificado directamente enLogisticSeaRunneryLogisticSeaUtils. - Ver alerta de seguridad en la sección 7 sobre credenciales reales expuestas en
application.properties.