Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
78ec3fd
chore(shipment): application.yaml redis 설정 추가 (#38)
soo96 Apr 6, 2026
4cc4833
chore(shipment): redis, feign 의존성 추가 (#38)
soo96 Apr 6, 2026
f37b5ca
feat(shipment): 이벤트 구독/발행 인프라 구현 (#38)
soo96 Apr 6, 2026
0e929c8
feat(shipment): 외부 서비스 클라이언트 구현 (#38)
soo96 Apr 6, 2026
3327ed8
feat(shipment): 주문 생성 이벤트 기반 배송 생성 로직 구현 (#38)
soo96 Apr 6, 2026
39db1e6
feat(shipment): HubClient 허브 경로 조회 에러처리 추가 (#38)
soo96 Apr 6, 2026
16c92fb
refactor(shipment): 서비스 레이어의 infra 이벤트 직접 참조 방식 개선 (#38)
soo96 Apr 6, 2026
1a06883
feat(shipment): 배송 완료 처리 API 구현 (#38)
soo96 Apr 6, 2026
e774ed0
feat(shipment): 배송 취소 처리 기능 구현 (#38)
soo96 Apr 6, 2026
430becd
test(shipment): 배송 생성,취소,완료 단위테스트 작성 (#38)
soo96 Apr 6, 2026
b67bb7c
Merge remote-tracking branch 'origin/develop' into feature/#38-shipme…
soo96 Apr 6, 2026
9fae04f
refactor(shipment): 배송 생성 이벤트 - shipmentManagerSlackId 필드 추가 (#38)
soo96 Apr 7, 2026
8b8db81
feat(shipment): Gateway 사용자 헤더를 UserContext로 주입받도록 개선 (#38)
soo96 Apr 7, 2026
db95802
feat(shipment): 배송 담당자 일괄 삭제 내부 API 및 스케줄링 구현 (#38)
soo96 Apr 7, 2026
36f2873
fix(shipment): 배송 담당자 배정 시 삭제 예정 담당자 제외 (#38)
soo96 Apr 7, 2026
ca72fa5
fix(hub): DeliveryClient 업체배송담당자 삭제 요청 URL 수정 (#38)
soo96 Apr 7, 2026
21c3aca
refactor(hub): Shipment의 orderId Unique 설정 (#38)
soo96 Apr 7, 2026
60465da
chore(hub): JacksonConfig setVisibility 옵션 추가 (#38)
soo96 Apr 7, 2026
b534f5c
chore(shipment): application.yaml, build.gradle 설정 수정 (#38)
soo96 Apr 7, 2026
84f4b08
refactor(shipment): markPendingDeletionByUserId 멱등성 보장되도록 개선 (#38)
soo96 Apr 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.shipflow.config.message;

import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
Expand All @@ -17,6 +19,7 @@ public ObjectMapper objectMapper() {
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
return mapper;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
@FeignClient(name = "deliveryservice")
public interface DeliveryClient {

@DeleteMapping("/internal/delivery-managers/{hubId}")
@DeleteMapping("/internal/delivery-managers/hubs/{hubId}")
void deleteCompanyDeliveryManagers(
@RequestHeader("X-Internal-Request") String internalRequest,
@RequestHeader("X-User-Id") String requestUserId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
package com.shipflow.orderservice.infrastructure.messaging.event.consume;

import java.util.UUID;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.shipflow.common.messaging.event.SagaEvent;

import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.UUID;

@Getter
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class ShipmentCompletedEvent extends SagaEvent {

private UUID orderId;
private UUID orderId;

public ShipmentCompletedEvent(UUID orderId) {
super("shipment.completed");
this.orderId = orderId;
}
public ShipmentCompletedEvent(UUID orderId) {
super("shipment.completed");
this.orderId = orderId;
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
package com.shipflow.orderservice.infrastructure.messaging.event.consume;

import java.util.UUID;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.shipflow.common.messaging.event.SagaEvent;
import com.shipflow.orderservice.domain.model.ShipmentStatus;

import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.UUID;

@Getter
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class ShipmentCreatedEvent extends SagaEvent {

private UUID orderId;
private UUID shipmentId;
private ShipmentStatus shipmentStatus;
private UUID departureHubId;
private String departureHubName;
private UUID arrivalHubId;
private String arrivalHubName;
private UUID orderId;
private UUID shipmentId;
private ShipmentStatus shipmentStatus;
private UUID departureHubId;
private String departureHubName;
private UUID arrivalHubId;
private String arrivalHubName;

public ShipmentCreatedEvent(UUID orderId, UUID shipmentId, ShipmentStatus shipmentStatus,
UUID departureHubId, String departureHubName,
UUID arrivalHubId, String arrivalHubName) {
super("shipment.created");
this.orderId = orderId;
this.shipmentId = shipmentId;
this.shipmentStatus = shipmentStatus;
this.departureHubId = departureHubId;
this.departureHubName = departureHubName;
this.arrivalHubId = arrivalHubId;
this.arrivalHubName = arrivalHubName;
}
public ShipmentCreatedEvent(UUID orderId, UUID shipmentId, ShipmentStatus shipmentStatus,
UUID departureHubId, String departureHubName,
UUID arrivalHubId, String arrivalHubName) {
super("shipment.created");
this.orderId = orderId;
this.shipmentId = shipmentId;
this.shipmentStatus = shipmentStatus;
this.departureHubId = departureHubId;
this.departureHubName = departureHubName;
this.arrivalHubId = arrivalHubId;
this.arrivalHubName = arrivalHubName;
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
package com.shipflow.orderservice.infrastructure.messaging.event.publish;

import java.util.UUID;

import com.shipflow.common.messaging.event.SagaEvent;

import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.UUID;

@Getter
@NoArgsConstructor
public class OrderCanceledEvent extends SagaEvent {

private static final String EVENT_TYPE = "order.canceled";
private static final String EVENT_TYPE = "order.canceled";

private UUID orderId;
private UUID productId;
private int quantity;
private UUID orderId;
private UUID productId;
private int quantity;

public OrderCanceledEvent(UUID orderId, UUID productId, int quantity) {
super(EVENT_TYPE);
this.orderId = orderId;
this.productId = productId;
this.quantity = quantity;
}
public OrderCanceledEvent(UUID orderId, UUID productId, int quantity) {
super(EVENT_TYPE);
this.orderId = orderId;
this.productId = productId;
this.quantity = quantity;
}
}
7 changes: 7 additions & 0 deletions shipment-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'

// Service Discovery
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'

// Feign
implementation "org.springframework.cloud:spring-cloud-starter-openfeign"

Expand All @@ -45,6 +49,9 @@ dependencies {
// RabbitMQ
implementation 'org.springframework.boot:spring-boot-starter-amqp'

// Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableFeignClients
@EnableScheduling
@SpringBootApplication
public class ShipmentserviceApplication {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.shipflow.shipmentservice.application;

import com.shipflow.shipmentservice.domain.event.ShipmentCompletedEvent;
import com.shipflow.shipmentservice.domain.event.ShipmentCreatedEvent;
import com.shipflow.shipmentservice.domain.event.ShipmentCreationFailedEvent;

public interface ShipmentEventPublisher {

void publishCreated(ShipmentCreatedEvent event);

void publishCreationFailed(ShipmentCreationFailedEvent event);

void publishCompleted(ShipmentCompletedEvent event);
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
@Transactional(readOnly = true)
public class ShipmentManagerService {

private static final UUID SYSTEM_ID = UUID.fromString("00000000-0000-0000-0000-000000000000");

private final ShipmentManagerRepository shipmentManagerRepository;
private final UserClient userClient;

Expand Down Expand Up @@ -107,4 +109,22 @@ public void deleteShipmentManager(UUID managerId, UUID userId) {

shipmentManager.delete(userId);
}

@Transactional
public void markPendingDeletionByHubId(UUID hubId) {
List<ShipmentManager> managers = shipmentManagerRepository.findAllByHubId(hubId);
managers.forEach(ShipmentManager::markPendingDeletion);
}

@Transactional
public void markPendingDeletionByUserId(UUID userId) {
shipmentManagerRepository.findByUserId(userId)
.ifPresent(ShipmentManager::markPendingDeletion);
}

@Transactional
public void deleteAllPending() {
List<ShipmentManager> pending = shipmentManagerRepository.findAllPendingDeletion();
pending.forEach(m -> m.delete(SYSTEM_ID));
}
}
Loading
Loading