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
| Campo | Valor |
|---|---|
artifactId | pickup-point-api |
groupId | com.hawkersco |
version | 1.0.25 |
| Java | 25 |
| Spring Boot | 4.0.6 |
| Tipo de artefacto | jar (ejecutable, API web de larga duración) |
| Módulos | No 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)..controller—PickupPointApiController(único controlador)..request/.response— DTOs (PickupPointRequest,PickupPointResponse)..config—BasicAuthSecurity,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
| Dependencia | Propósito |
|---|---|
spring-boot-starter-web | Exposición del endpoint REST |
spring-boot-starter-security | Autenticación HTTP Basic |
org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.3 | Documentación Swagger/OpenAPI |
com.hawkersco:logistics-commons:1.0.25-SNAPSHOT | PickupPoint (entidad), PickupPointService |
lombok | Generació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étodo | Ruta | Descripción | Autenticación |
|---|---|---|---|
GET | /check-domain | Health check | Pública (permitAll) |
POST | /info | Consulta puntos de recogida por código+carrier, coordenadas o código postal | HTTP 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).
| Clave | Descripción | Ejemplo (producción) |
|---|---|---|
auth.username / auth.password | Credenciales HTTP Basic del único usuario (pickup-point) | pickup-point / ${userPassword} |
spring.datasource.jdbc-url / .username / .password | Credenciales de la BD logistics | ${dbLogisitcsUrl}, etc. |
springdoc.swagger-ui.try-it-out-enabled | Habilita "try it out" en Swagger UI | true |
⚠️ 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:
- Rotar la contraseña HTTP Basic y la contraseña de BD expuestas.
- 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), 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(baseeclipse-temurin:25-jre,containerizingMode=packaged), publicada eneurope-west3-docker.pkg.dev/pi-saldum/pi-repo/pickup-point-api:<tag>. - Orquestación: Kubernetes
Deployment(noCronJob) en el clúster GKEpi-cluster-hw, namespacepi,restartPolicy: Always. - CI/CD (Jenkins): pipeline con
Build & Push(sustituyeapplication-pro.propertiesporapplication.propertiesmediantejenkins/scripts/mvn.sh, no activado por perfil de Spring) →Deploy to GKE. - Las variables sensibles se inyectan en el pod mediante un
Secretde 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:PickupPointApiApplicationdesactiva la decodificación de URL para permitir%2Fen parámetros de ruta, según el propio comentario del código y elCLAUDE.md. Sin embargo, el único endpoint de negocio (POST /info) recibe todos sus criterios de búsqueda (incluidocarrier) en el cuerpo de la petición JSON, no en la URL — no hay ningún@PathVariableen el controlador actual. Es probable que esta configuración sea un vestigio de un diseño anterior (quizá un endpointGET /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:
getPickupPointsfiltra los puntos con!Boolean.FALSE.equals(pp.getIsVisible()), lo que significa que un punto conisVisible = nullse considera visible (solo se excluyen los marcados explícitamente comofalse). 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.