distribution-completed Kafka 이벤트 형식 변경

- DistributedChannelInfo DTO 추가 (channel, channelType, status, expectedViews)
- ChannelType enum에 category 필드 추가 (TV, CALL, SNS 구분)
- DistributionCompletedEvent 구조 변경 (distributedChannels를 상세 정보 리스트로 변경)
- completedAt 필드에 @JsonFormat 추가하여 ISO 8601 문자열 형식으로 직렬화
- publishDistributionCompletedEvent 메서드 수정하여 새로운 형식으로 이벤트 발행

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
sunmingLee 2025-10-29 09:56:32 +09:00
parent 828a76b630
commit 64aec0fda5
5 changed files with 67 additions and 30 deletions

View File

@ -7,20 +7,26 @@ package com.kt.distribution.dto;
* @since 2025-10-23
*/
public enum ChannelType {
URIDONGNETV("우리동네TV"),
RINGOBIZ("링고비즈"),
GINITV("지니TV"),
INSTAGRAM("Instagram"),
NAVER("Naver Blog"),
KAKAO("Kakao Channel");
URIDONGNETV("우리동네TV", "TV"),
RINGOBIZ("링고비즈", "CALL"),
GINITV("지니TV", "TV"),
INSTAGRAM("Instagram", "SNS"),
NAVER("Naver Blog", "SNS"),
KAKAO("Kakao Channel", "SNS");
private final String displayName;
private final String category;
ChannelType(String displayName) {
ChannelType(String displayName, String category) {
this.displayName = displayName;
this.category = category;
}
public String getDisplayName() {
return displayName;
}
public String getCategory() {
return category;
}
}

View File

@ -0,0 +1,40 @@
package com.kt.distribution.event;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 배포된 채널 정보
* Kafka 이벤트에 포함되는 채널별 상세 정보
*
* @author System Architect
* @since 2025-10-29
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DistributedChannelInfo {
/**
* 채널명 (: "우리동네TV", "지니TV", "링고비즈")
*/
private String channel;
/**
* 채널 타입 (: "TV", "CALL", "SNS")
*/
private String channelType;
/**
* 배포 상태 (SUCCESS, FAILED)
*/
private String status;
/**
* 예상 조회수
*/
private Integer expectedViews;
}

View File

@ -1,5 +1,6 @@
package com.kt.distribution.event;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -27,22 +28,13 @@ public class DistributionCompletedEvent {
private String eventId;
/**
* 배포 완료된 채널 목록
* 배포 완료된 채널 상세 정보 목록
*/
private List<String> distributedChannels;
private List<DistributedChannelInfo> distributedChannels;
/**
* 배포 완료 시각
*/
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS")
private LocalDateTime completedAt;
/**
* 성공한 채널
*/
private int successCount;
/**
* 실패한 채널
*/
private int failureCount;
}

View File

@ -116,7 +116,7 @@ public class DistributionService {
saveCompletedStatus(request.getEventId(), results, startedAt, completedAt, successCount, failureCount);
// Kafka Event 발행
// publishDistributionCompletedEvent(request.getEventId(), results);
publishDistributionCompletedEvent(request.getEventId(), results);
// 응답 생성
return DistributionResponse.builder()
@ -244,20 +244,19 @@ public class DistributionService {
return;
}
List<String> distributedChannels = results.stream()
.filter(ChannelDistributionResult::isSuccess)
.map(result -> result.getChannel().name())
List<com.kt.distribution.event.DistributedChannelInfo> distributedChannels = results.stream()
.map(result -> com.kt.distribution.event.DistributedChannelInfo.builder()
.channel(result.getChannel().getDisplayName())
.channelType(result.getChannel().getCategory())
.status(result.isSuccess() ? "SUCCESS" : "FAILED")
.expectedViews(result.getEstimatedReach())
.build())
.collect(Collectors.toList());
long successCount = results.stream().filter(ChannelDistributionResult::isSuccess).count();
long failureCount = results.size() - successCount;
DistributionCompletedEvent event = DistributionCompletedEvent.builder()
.eventId(eventId)
.distributedChannels(distributedChannels)
.completedAt(LocalDateTime.now())
.successCount((int) successCount)
.failureCount((int) failureCount)
.build();
kafkaEventPublisher.get().publishDistributionCompleted(event);

View File

@ -36,8 +36,8 @@ public class KafkaEventPublisher {
*/
public void publishDistributionCompleted(DistributionCompletedEvent event) {
try {
log.info("Publishing DistributionCompletedEvent: eventId={}, successCount={}, failureCount={}",
event.getEventId(), event.getSuccessCount(), event.getFailureCount());
log.info("Publishing DistributionCompletedEvent: eventId={}, channels={}",
event.getEventId(), event.getDistributedChannels().size());
CompletableFuture<SendResult<String, Object>> future =
kafkaTemplate.send(distributionCompletedTopic, event.getEventId(), event);