Skip to main content

pickup-point-api

1. Descripción general

Según el pom.xml, el proyecto se describe como "pickup point api". Es una fachada REST muy fina sobre la librería logistics-commons: expone un único endpoint de consulta de puntos de recogida, permitiendo buscar por código de punto + transportista, por proximidad geográfica (latitud/longitud + radio) o por código postal. No contiene entidades, repositorios ni lógica de negocio propia — toda la lógica vive en PickupPointService de logistics-commons.

2. Información técnica

CampoValor
artifactIdpickup-point-api
groupIdcom.hawkersco
version1.0.25
Java25
Spring Boot4.0.6
Tipo de artefactojar (ejecutable, API web de larga duración)
MódulosNo aplica (proyecto de módulo único)

3. Arquitectura y diseño

API REST mínima, protegida con HTTP Basic, documentada con Swagger/OpenAPI.

  • com.hawkersco.pickuppointapi — clase principal (PickupPointApiApplication).
  • .controllerPickupPointApiController (único controlador).
  • .request / .response — DTOs (PickupPointRequest, PickupPointResponse).
  • .configBasicAuthSecurity, LogisticsDbConfig, PasswordEncoderConfig, SwaggerConfig, RestAuthenticationEntryPoint, CorsConfig.
flowchart TD
A["POST /info<br/>(Basic Auth)"] --> B{Criterio de búsqueda}
B -- code + carrier --> C[PickupPointService.getPickupPointsByDsCodeAndCarrier]
B -- lat + lon --> D[PickupPointService.findNearby]
B -- postalCode --> E[PickupPointService.findByZipCode]
C --> F[Filtra isVisible != false]
D --> F
E --> F
F --> G[200 con lista de PickupPointResponse, o 404 si vacía]

PickupPointApiApplication desactiva la decodificación de URL (UrlPathHelper.setUrlDecode(false)) para permitir %2F en parámetros de ruta — ver hallazgo en la sección 13, ya que el endpoint actual no usa parámetros de ruta.

4. Dependencias principales

DependenciaPropósito
spring-boot-starter-webExposición del endpoint REST
spring-boot-starter-securityAutenticación HTTP Basic
org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.3Documentación Swagger/OpenAPI
com.hawkersco:logistics-commons:1.0.25-SNAPSHOTPickupPoint (entidad), PickupPointService
lombokGeneración de código boilerplate
spring-boot-devtools (runtime, opcional)Recarga en caliente en desarrollo
spring-boot-starter-test (test)JUnit 5 + Spring Test

5. API / Endpoints

MétodoRutaDescripciónAutenticación
GET/check-domainHealth checkPública (permitAll)
POST/infoConsulta puntos de recogida por código+carrier, coordenadas o código postalHTTP Basic

Ejemplo de body de /info (por coordenadas):

{
"latitude": 40.4168,
"longitude": -3.7038,
"radius": 2
}

Respuesta (200 OK):

[
{
"carrier": "CORREOS",
"code": "ES123456",
"latitude": 40.4168,
"longitude": -3.7038,
"name": "OFICINA CENTRAL",
"address": "CALLE MAYOR 1",
"city": "MADRID",
"zipCode": "28001",
"province": "MADRID",
"provinceCode": "M",
"country": "ES"
}
]

Si ninguno de los tres criterios de búsqueda se aporta, o no hay resultados, la respuesta es 404 Not Found. También se documenta Swagger UI (/swagger-ui/**) como ruta pública.

6. Integraciones externas

No aplica más allá de la propia BD. No hay clientes HTTP salientes a sistemas externos; toda la información se sirve desde PostgreSQL vía logistics-commons.

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ónEjemplo (producción)
auth.username / auth.passwordCredenciales HTTP Basic del único usuario (pickup-point)pickup-point / ${userPassword}
spring.datasource.jdbc-url / .username / .passwordCredenciales de la BD logistics${dbLogisitcsUrl}, etc.
springdoc.swagger-ui.try-it-out-enabledHabilita "try it out" en Swagger UItrue

⚠️ Alerta de seguridad

El fichero src/main/resources/application.properties (perfil local) contiene actualmente credenciales reales en texto plano: la contraseña HTTP Basic del usuario pickup-point y la contraseña de la base de datos PostgreSQL. Ninguno de estos valores se ha reproducido en este documento. Se recomienda:

  1. Rotar la contraseña HTTP Basic y la contraseña de BD expuestas.
  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), acceso vía JPA a través de la librería logistics-commons. spring.jpa.hibernate.ddl-auto=none. Entidad relevante: PickupPoint (con campo geométrico ptCoordinates, usado para las búsquedas por proximidad). No hay Flyway/Liquibase en este repositorio.

9. Procesos programados y mensajería

No aplica a este proyecto. Es puramente reactivo a las peticiones HTTP entrantes; no hay @Scheduled ni listeners de colas.

10. Ejecución en local

Requisitos previos: JDK 25, Maven, acceso a la BD logistics.

# Compilar
mvn clean install

# Ejecutar la aplicación localmente (perfil dev, puerto 80)
mvn spring-boot:run

# Ejecutar tests
mvn test
mvn test -Dtest=PickupPointApiApplicationTests
mvn test -Dtest=PickupPointApiApplicationTests::contextLoads

# Build Docker
docker build -t pickup-point-api .

Verificación de que el servicio está operativo: GET /check-domain devuelve 200 OK. Documentación interactiva disponible en /swagger-ui/index.html.

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/pickup-point-api:<tag>.
  • Orquestación: Kubernetes Deployment (no CronJob) en el clúster GKE pi-cluster-hw, namespace pi, restartPolicy: Always.
  • CI/CD (Jenkins): pipeline con Build & Push (sustituye application-pro.properties por application.properties mediante jenkins/scripts/mvn.sh, no activado por perfil de Spring) → Deploy to GKE.
  • Las variables sensibles se inyectan en el pod mediante un Secret de Kubernetes llamado igual que la app (pickup-point-api).

Job de Jenkins: https://jenkins-pi.hawkersco.net/job/pickup-point-api/

12. Manejo de errores y logging

No se ha localizado un @RestControllerAdvice en este proyecto; el único caso de error gestionado explícitamente en el controlador es la ausencia de resultados (404 Not Found). Fallos de autenticación se gestionan vía RestAuthenticationEntryPoint (Spring Security estándar, 401 Unauthorized). Se ha desactivado explícitamente el log de UserDetailsServiceAutoConfiguration para evitar que Spring Boot imprima la contraseña generada automáticamente (relevante solo si el usuario en memoria no estuviera ya configurado explícitamente, como es el caso). No hay integración con Slack ni otro canal de alertas.

13. Notas y consideraciones

  • UrlPathHelper.setUrlDecode(false) sin uso aparente en el endpoint actual: PickupPointApiApplication desactiva la decodificación de URL para permitir %2F en parámetros de ruta, según el propio comentario del código y el CLAUDE.md. Sin embargo, el único endpoint de negocio (POST /info) recibe todos sus criterios de búsqueda (incluido carrier) en el cuerpo de la petición JSON, no en la URL — no hay ningún @PathVariable en el controlador actual. Es probable que esta configuración sea un vestigio de un diseño anterior (quizá un endpoint GET /info/{carrier}/{code}) que ya no está en uso; no causa ningún problema funcional, pero es configuración muerta que convendría documentar o eliminar.
  • Filtro de visibilidad permisivo con valores nulos: getPickupPoints filtra los puntos con !Boolean.FALSE.equals(pp.getIsVisible()), lo que significa que un punto con isVisible = null se considera visible (solo se excluyen los marcados explícitamente como false). Es un comportamiento razonable pero implícito, que conviene tener presente si se añaden nuevos puntos sin poblar ese campo.
  • Ver alerta de seguridad en la sección 7 sobre credenciales reales expuestas en application.properties.