Skip to main content

liverpool-create-db

1. Descripción general

Según el pom.xml, el proyecto se describe como "Liverpool get orders an save to DB". Es un microservicio batch (runner) que sincroniza pedidos del marketplace mexicano Liverpool (vía su API QAT) con la base de datos de logística, aceptando pedidos pendientes, persistiendo los que están en envío, y generando/convirtiendo las etiquetas de envío a través de la API Labelary.

2. Información técnica

CampoValor
artifactIdliverpool-create-db
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 3 CommandLineRunner, todos activos.

OrdenRunnerPropósito
1LiverpoolCreateDbWatingRunnerPedidos WAITING_ACCEPTANCE con más de 1h → auto-aceptación en Liverpool
2LiverpoolCreateDbRunnerPedidos SHIPPING (tienda 2795) → transformación y persistencia en BD logistics
3LiverpoolProcessLabelRunnerPedidos PENDING_LABEL → descarga de etiquetas (ZIP), conversión vía Labelary, actualización a PENDING_SHIPMENT
  • .configLiverpoolCreateDbConfig (17 beans de servicios de logistics-commons).
  • .utilsLiverpoolCreateDbUtils (transformación de datos y persistencia JPA).
flowchart TD
A["1. LiverpoolCreateDbWatingRunner<br/>WAITING_ACCEPTANCE > 1h"] -->|acepta| B[Liverpool QAT API]
C["2. LiverpoolCreateDbRunner<br/>SHIPPING, tienda 2795"] --> B
C --> D[(logistics · Order/OrderMarketplace)]
E["3. LiverpoolProcessLabelRunner<br/>PENDING_LABEL"] -->|descarga ZIP| B
E -->|convierte a ZPL/PDF| F[Labelary API]
F -->|guarda etiqueta base64| D
E -.->|>48h sin etiqueta| G[Slack]

El runner 3 descarga en un único ZIP las etiquetas de hasta 50 pedidos pendientes, las descomprime, busca por cada pedido el fichero de etiqueta (por número de seguimiento en formato PDF/GIF/ZPL, o por palabra clave alternativa "delivery"), lo convierte a ZPL mediante Labelary (con un método alternativo de conversión si el primero falla), guarda el PDF resultante en Base64 en OrderMarketplace y cambia el estado del pedido a PENDING_SHIPMENT; si un pedido lleva más de 48 horas sin etiqueta disponible, se marca como ERROR_LABEL y se notifica a un canal de Slack específico de ATC México.

4. Dependencias principales

DependenciaPropósito
spring-boot-starterNúcleo de Spring Boot (sin web, es un runner CLI)
com.itextpdf:itextpdfManipulación de PDF (etiquetas de envío)
com.hawkersco:qat-clientCliente @HttpExchange para la API QAT de Liverpool
com.hawkersco:labelary-clientCliente @HttpExchange para la API Labelary (conversión de etiquetas)
com.hawkersco:logistics-commonsEntidades JPA (Order, OrderMarketplace, Customer, Shipment, etc.) y servicios
com.hawkersco:slack-clientNotificaciones de error
com.hawkersco:pi-function-commonsDateUtils, DirectoryUtils, ZipUtils

5. API / Endpoints

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

6. Integraciones externas

SistemaProtocoloDirecciónDetalle
Liverpool QAT API (pro-api.liverpool.com.mx)HTTP REST (QatClient)Entrante/SalienteLectura de pedidos por estado, aceptación, descarga de documentos/etiquetas
Labelary APIHTTP (LabelaryClient)SalienteConversión de etiquetas de envío a ZPL/PDF
SlackHTTP (SlackClient)SalienteAlertas de aceptación fallida y de pedidos sin etiqueta tras 48h
PostgreSQL (logistics)JDBCSalientePersistencia de pedidos, líneas, envíos y etiquetas

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
qat.credentials.url / .keyCredenciales de la API QAT de Liverpool
labelary.client.urlURL de la API Labelary (pública, sin credenciales)
slack.client.url / .auth.token / .channel.id / .channel-atc-mx.idConfiguración de Slack (canal general y canal específico de ATC México)

⚠️ 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), la clave de la API QAT de Liverpool, y el token de bot de Slack. Ninguno de estos valores se ha reproducido en este documento. Se recomienda:

  1. Rotar la contraseña de BD, la clave de la API QAT 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 (esquema externo, spring.jpa.hibernate.ddl-auto=none). Entidades relevantes: Order, OrderMarketplace, Customer, OrderLine, Shipment, OrderShipmentStatus. 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, activeDeadlineSeconds: 43200 — 12 horas, para dar margen al procesamiento secuencial con esperas de 60s por pedido en el runner de etiquetas). Se ejecutan en orden los 3 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 QAT de Liverpool.

# Compilar sin tests
mvn -B -DskipTests clean install

# Ejecutar el JAR
java -jar target/liverpool-create-db.jar

# Alternativa con Maven Wrapper
./mvnw -DskipTests clean package

No existe suite de tests en este repositorio. 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/liverpool-create-db:<tag>.
  • Orquestación: Kubernetes CronJob en el clúster GKE pi-cluster-hw, namespace pi, contenedor no privilegiado, ejecutándose cada 15 minutos con un plazo de actividad de 12 horas.
  • CI/CD (Jenkins): pipeline real de 3 etapas — CheckoutBuild & PushDeploy to GKE. El CLAUDE.md describe un pipeline con KICS Security Scan, SonarQube y Test que no existen en el Jenkinsfile actual (mismo patrón detectado en varios proyectos hermanos de este lote).

Job de Jenkins: https://jenkins-pi.hawkersco.net/job/liverpool-create-db/

12. Manejo de errores y logging

No hay una estrategia de excepciones centralizada (no hay @ControllerAdvice, es un runner). El runner de etiquetas captura IOException al leer un fichero de etiqueta individual y Exception genérica en la conversión Labelary (con reintento vía un método de conversión alternativo antes de registrar el fallo definitivo). Los pedidos sin etiqueta tras 48 horas se marcan con estado de error y se notifican a Slack, sin interrumpir el procesamiento del resto de pedidos. Logging mediante java.util.logging.Logger estándar (consola).

13. Notas y consideraciones

  • El estado final tras generar la etiqueta no coincide con el nombre descrito en CLAUDE.md: el documento afirma que el runner de etiquetas "updates status to GENERATED_LABEL", pero el código real (saveLabelAndUpdateOrder) actualiza el pedido al estado PENDING_SHIPMENT (constante STATUS_PENDING_SHIPMENT) — no existe ningún estado GENERATED_LABEL en el código de este proyecto.
  • CLAUDE.md verificado y consistente en el resto de aspectos: la secuencia de los 3 runners, sus responsabilidades, el patrón de reintento de conversión de etiquetas (Labelary con método alternativo), el umbral de 48 horas para marcar error, y el resto de la arquitectura coinciden con el código real, verificado directamente en LiverpoolProcessLabelRunner.
  • Ver alerta de seguridad en la sección 7 sobre credenciales reales expuestas en application.properties.