허브, 허브 재고, 허브 간 이동 경로를 관리하는 서비스입니다.
MSA 환경에서 동작하며, Config Server / Eureka / PostgreSQL / Keycloak / Gateway 와 함께 사용됩니다.
hub-service는 다음 3가지 도메인을 담당합니다.
-
🏢 Hub
- 허브 생성 / 조회 / 수정 / 삭제
- 허브 위치 정보(주소, 위도, 경도) 관리
-
📦 Hub Inventory
- 허브 재고 생성 / 조회 / 수정 / 삭제
- 주문 생성용 재고 차감 / 복원
hubInventoryId기반 차감/복원 처리
-
🛣️ Hub Route
- 허브 간 이동 경로 생성 / 조회 / 수정 / 삭제
- 거리/시간을 직접 입력받지 않고 카카오 길찾기 계산 결과로 저장
- 직행 / 릴레이 경로 조회 지원
- 200km 기준 정책으로 최종 배송 경로를 계산
src/main/java/com/fhsh/daitda
├─ common
│ ├─ config.security
│ ├─ enums
│ ├─ exception
│ ├─ model
│ └─ util
└─ hubservice
├─ hub
│ ├─ application
│ ├─ domain
│ └─ presentation
├─ hubinventory
│ ├─ application
│ ├─ domain
│ └─ presentation
├─ hubroute
│ ├─ application
│ ├─ domain
│ └─ presentation
├─ infrastructure.kakao
│ ├─ client
│ ├─ config
│ ├─ dto
│ └─ exception
└─ HubServiceApplication
허브 정보, 허브 재고, 허브 간 이동 경로를 관리하는 서비스입니다.
또한 카카오 길찾기 API를 활용해 허브 간 거리/시간을 계산하고, 200km 정책 기반 최종 배송 경로를 조회합니다.
- Java 17
- Spring Boot 3.5.13
- Spring Cloud 2025.0.1
- Spring Data JPA
- PostgreSQL
- Eureka Client
- Spring Cloud Config Client
- Kakao Mobility Directions API
허브의 기본 정보를 관리합니다.
- 허브명
- 허브 주소
- 위도 / 경도
- 중앙 허브 여부 (
isCentral)
- 허브 생성
- 전체 허브 조회
- 허브 단건 조회
- 허브 수정
- 허브 논리 삭제
허브별 재고를 관리합니다.
hubIdcompanyIdproductId
- 허브 재고 생성
- 전체 허브 재고 조회
- 허브 재고 단건 조회
hubId + companyId + productId기준 재고 조회- 허브 재고 수정
- 허브 재고 논리 삭제
- 주문 생성용 재고 차감
- 재고 복원
- 실제 주문 차감/복원 흐름에서는 실제로 차감된
hubInventoryId를 기준으로 복원할 수 있도록 설계했습니다. - 주문 생성용 차감 API는
supplierCompanyId + productId기준으로 재고 row를 찾습니다. - 실제로 차감된
hubInventoryId목록을 반환합니다.
허브 간 이동 경로를 관리합니다.
- 허브 경로 생성
- 허브 경로 전체 조회
- 허브 경로 단건 조회
srcHubId + destHubId기준 경로 조회- 허브 경로 수정
- 허브 경로 논리 삭제
- 최종 배송 경로(
path) 조회
허브 경로의 거리(distance)와 시간(durationTime)은 요청으로 직접 받지 않습니다.
대신 아래 정보를 사용합니다.
- 출발 허브의 좌표
- 도착 허브의 좌표
이 좌표를 기반으로 Kakao Directions API를 호출하고, 계산 결과를 기준으로 저장 및 재계산합니다.
HubRouteQueryService는 최종 배송 경로를 아래 정책으로 계산합니다.
- 출발 허브와 도착 허브의 직행 거리를 먼저 계산
- 직행 거리가 200km 미만이면
- 직행 1건만 반환
- 직행 거리가 200km 이상이면
- 중간 경유 허브 1개를 선택
- 2개 구간으로 나누어 반환
- 활성 허브 중 출발/도착 허브를 제외한 후보를 순회
[출발 → 후보],[후보 → 도착]두 구간 모두 200km 미만이어야 함- 유효 후보 중 총 거리 합이 가장 짧은 허브를 릴레이 허브로 선택
외부 API는 Gateway를 통해 진입하며, 아래 인증 헤더를 사용합니다.
X-User-IdX-User-EmailX-User-Role
ADMINHUB_ADMINDELIVERYCOMPANY
- 현재 인증 시스템에서는
ADMIN으로 검증
- 인증된 사용자 역할이면 모두 허용
Base Path: /api/v1/hubs
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/hubs |
허브 생성 |
| GET | /api/v1/hubs |
전체 허브 조회 |
| GET | /api/v1/hubs/{hubId} |
허브 단건 조회 |
| PATCH | /api/v1/hubs/{hubId} |
허브 수정 |
| DELETE | /api/v1/hubs/{hubId} |
허브 논리 삭제 |
Base Path: /api/v1/hub-inventories
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/hub-inventories |
허브 재고 생성 |
| GET | /api/v1/hub-inventories |
전체 허브 재고 조회 |
| GET | /api/v1/hub-inventories/search?hubId={hubId}&companyId={companyId}&productId={productId} |
조건 조회 |
| GET | /api/v1/hub-inventories/{hubInventoryId} |
허브 재고 단건 조회 |
| PATCH | /api/v1/hub-inventories/{hubInventoryId} |
허브 재고 수정 |
| DELETE | /api/v1/hub-inventories/{hubInventoryId} |
허브 재고 논리 삭제 |
Base Path: /api/v1/hub-routes
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/hub-routes |
허브 경로 생성 |
| GET | /api/v1/hub-routes |
전체 허브 경로 조회 |
| GET | /api/v1/hub-routes/{hubRouteId} |
허브 경로 단건 조회 |
| GET | /api/v1/hub-routes/search?srcHubId={srcHubId}&destHubId={destHubId} |
출발/도착 허브 기준 조회 |
| PATCH | /api/v1/hub-routes/{hubRouteId} |
허브 경로 재계산 |
| DELETE | /api/v1/hub-routes/{hubRouteId} |
허브 경로 논리 삭제 |
Base Path: /internal/v1/hubs
| Method | Path | Description |
|---|---|---|
| GET | /internal/v1/hubs/{hubId} |
허브 단건 조회 |
Base Path: /internal/v1/hub-inventories
| Method | Path | Description |
|---|---|---|
| PATCH | /internal/v1/hub-inventories/decrease |
재고 차감 |
| PATCH | /internal/v1/hub-inventories/decrease-by-product |
주문 생성용 재고 차감 |
| PATCH | /internal/v1/hub-inventories/restoration |
재고 복원 |
Base Path: /internal/v1/hub-routes
| Method | Path | Description |
|---|---|---|
| GET | /internal/v1/hub-routes?srcHubId={srcHubId}&destHubId={destHubId} |
허브 경로 조회 |
| GET | /internal/v1/hub-routes/path?srcHubId={srcHubId}&destHubId={destHubId} |
최종 배송 경로(path) 조회 |
허브 경로 계산은 Kakao Directions API를 사용합니다.
- 허브 경로 생성 시 거리/시간 계산
- 허브 경로 수정 시 거리/시간 재계산
- 최종 배송 경로(
path) 조회 시 직행/릴레이 여부 판단
kakao.mobility 설정을 통해 주입받습니다.
kakao:
mobility:
rest-api-key: ${KAKAO_MOBILITY_REST_API_KEY}
directions-base-url: https://apis-navi.kakaomobility.comAuthorization: KakaoAK {REST_API_KEY}테스트는 아래 영역을 포함합니다.
- ✅
HubInventoryCommandServiceTest - ✅
HubRouteServiceTest - ✅
HubRouteQueryServiceTest - ✅
HubServiceApplicationTests
./gradlew clean test아래 서비스가 먼저 실행되어 있어야 합니다.
- Config Server
- Eureka Server
- PostgreSQL
- Gateway Server
- Keycloak
- Zipkin (선택)
.env.example 기준으로 필요한 값입니다.
SPRING_PROFILES_ACTIVE=local
DB_PASSWORD=
POSTGRES_HOST=localhost
EUREKA_HOST=localhost
ZIPKIN_HOST=localhost
GITHUB_USERNAME=
GITHUB_TOKEN=
KAKAO_MOBILITY_REST_API_KEY=your_kakao_mobility_rest_api_key| 변수명 | 설명 |
|---|---|
DB_PASSWORD |
PostgreSQL 비밀번호 |
POSTGRES_HOST |
PostgreSQL 호스트 |
EUREKA_HOST |
Eureka Server 호스트 |
ZIPKIN_HOST |
Zipkin 호스트 |
GITHUB_USERNAME |
GitHub Packages 인증용 사용자명 |
GITHUB_TOKEN |
GitHub Packages 인증용 토큰 |
KAKAO_MOBILITY_REST_API_KEY |
카카오 길찾기 API 호출용 REST API Key |
- 서비스명:
hub-service - 기본 profile:
local - Config Server 사용
- Config Server import는 optional
- 로컬 DB 비밀번호 주입
- Hibernate SQL 로그 출력
- 애플리케이션 DEBUG 로그 출력
./gradlew bootRun또는 IntelliJ에서 HubServiceApplication을 실행합니다.
주요 의존성은 아래와 같습니다.
spring-boot-starter-data-jpaspring-boot-starter-webspring-boot-starter-actuatorspring-cloud-starter-netflix-eureka-clientspring-cloud-starter-openfeignspring-cloud-starter-configspring-cloud-starter-circuitbreaker-reactor-resilience4jresilience4j-spring-boot3spring-boot-starter-validationcommon:0.1.4-SNAPSHOTpostgresqlh2 (test)
모든 주요 엔티티는 논리 삭제를 사용합니다.
deletedAtdeletedBy
조회는 기본적으로 deletedAt is null 기준입니다.
허브 경로는 아래 조합이 유일해야 합니다.
srcHubIddestHubId
중복 생성 시 HUB_ROUTE_CONFLICT 예외를 반환합니다.
최종 배송 경로(path) 조회는 단순히 저장된 경로 조회만 의미하지 않습니다.
정책 기반으로 계산된 배송 구간도 응답에 포함할 수 있습니다.
- 저장된 구간이면
hubRouteId포함 - 계산만 된 구간이면
hubRouteId = null
즉, hubRouteId == null 은 오류가 아니라,
계산은 되었지만 DB에 저장된 허브 경로 row는 없는 상태를 의미합니다.
.
├─ build.gradle
├─ settings.gradle
├─ .env.example
├─ src
│ ├─ main
│ │ ├─ java
│ │ └─ resources
│ └─ test
│ ├─ java
│ └─ resources
└─ gradle
이 서비스는 다음을 책임집니다.
- 🏢 허브 관리
- 📦 허브 재고 관리
- 🛣️ 허브 간 이동 경로 관리
- 📍 카카오 길찾기 기반 거리/시간 계산
- 🚚 200km 정책 기반 직행/릴레이 최종 배송 경로 조회