diff --git a/analytics-service/.run/analytics-service.run.xml b/analytics-service/.run/analytics-service.run.xml
index de874e9..931ba8c 100644
--- a/analytics-service/.run/analytics-service.run.xml
+++ b/analytics-service/.run/analytics-service.run.xml
@@ -24,7 +24,7 @@
-
+
diff --git a/analytics-service/src/main/java/com/kt/event/analytics/config/KafkaConsumerConfig.java b/analytics-service/src/main/java/com/kt/event/analytics/config/KafkaConsumerConfig.java
index e3c413b..1d71d31 100644
--- a/analytics-service/src/main/java/com/kt/event/analytics/config/KafkaConsumerConfig.java
+++ b/analytics-service/src/main/java/com/kt/event/analytics/config/KafkaConsumerConfig.java
@@ -23,7 +23,7 @@ public class KafkaConsumerConfig {
@Value("${spring.kafka.bootstrap-servers}")
private String bootstrapServers;
- @Value("${spring.kafka.consumer.group-id:analytics-service}")
+ @Value("${spring.kafka.consumer.group-id:analytics-service-consumers-v3}")
private String groupId;
@Bean
diff --git a/analytics-service/src/main/java/com/kt/event/analytics/config/SampleDataLoader.java b/analytics-service/src/main/java/com/kt/event/analytics/config/SampleDataLoader.java
index 092c1d7..36c1cea 100644
--- a/analytics-service/src/main/java/com/kt/event/analytics/config/SampleDataLoader.java
+++ b/analytics-service/src/main/java/com/kt/event/analytics/config/SampleDataLoader.java
@@ -19,6 +19,7 @@ import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaAdmin;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
@@ -60,7 +61,8 @@ public class SampleDataLoader implements ApplicationRunner {
private final Random random = new Random();
- private static final String CONSUMER_GROUP_ID = "analytics-service-consumers-v3";
+ @Value("${spring.kafka.consumer.group-id}")
+ private String consumerGroupId;
// Kafka Topic Names (MVP용 샘플 토픽)
private static final String EVENT_CREATED_TOPIC = "sample.event.created";
@@ -181,7 +183,7 @@ public class SampleDataLoader implements ApplicationRunner {
*/
private void resetConsumerOffsets() {
try (AdminClient adminClient = AdminClient.create(kafkaAdmin.getConfigurationProperties())) {
- log.info("🔄 Kafka Consumer Offset 리셋 시작: group={}", CONSUMER_GROUP_ID);
+ log.info("🔄 Kafka Consumer Offset 리셋 시작: group={}", consumerGroupId);
// 모든 토픽의 offset 삭제
Set partitions = new HashSet<>();
@@ -195,7 +197,7 @@ public class SampleDataLoader implements ApplicationRunner {
// Consumer Group Offset 삭제
DeleteConsumerGroupOffsetsResult result = adminClient.deleteConsumerGroupOffsets(
- CONSUMER_GROUP_ID,
+ consumerGroupId,
partitions
);
@@ -224,6 +226,8 @@ public class SampleDataLoader implements ApplicationRunner {
.totalInvestment(new BigDecimal("5000000"))
.expectedRevenue(new BigDecimal("15000000")) // 투자 대비 3배 수익
.status("ACTIVE")
+ .startDate(java.time.LocalDateTime.of(2025, 1, 23, 0, 0)) // 2025-01-23 시작
+ .endDate(null) // 진행중
.build();
publishEvent(EVENT_CREATED_TOPIC, event1);
@@ -235,6 +239,8 @@ public class SampleDataLoader implements ApplicationRunner {
.totalInvestment(new BigDecimal("3500000"))
.expectedRevenue(new BigDecimal("7000000")) // 투자 대비 2배 수익
.status("ACTIVE")
+ .startDate(java.time.LocalDateTime.of(2025, 2, 1, 0, 0)) // 2025-02-01 시작
+ .endDate(null) // 진행중
.build();
publishEvent(EVENT_CREATED_TOPIC, event2);
@@ -246,6 +252,8 @@ public class SampleDataLoader implements ApplicationRunner {
.totalInvestment(new BigDecimal("2000000"))
.expectedRevenue(new BigDecimal("3000000")) // 투자 대비 1.5배 수익
.status("COMPLETED")
+ .startDate(java.time.LocalDateTime.of(2025, 1, 15, 0, 0)) // 2025-01-15 시작
+ .endDate(java.time.LocalDateTime.of(2025, 1, 31, 23, 59)) // 2025-01-31 종료
.build();
publishEvent(EVENT_CREATED_TOPIC, event3);
diff --git a/analytics-service/src/main/java/com/kt/event/analytics/entity/EventStats.java b/analytics-service/src/main/java/com/kt/event/analytics/entity/EventStats.java
index e3b4464..f19a282 100644
--- a/analytics-service/src/main/java/com/kt/event/analytics/entity/EventStats.java
+++ b/analytics-service/src/main/java/com/kt/event/analytics/entity/EventStats.java
@@ -97,6 +97,18 @@ public class EventStats extends BaseTimeEntity {
@Column(length = 20)
private String status;
+ /**
+ * 이벤트 시작일
+ */
+ @Column(name = "start_date")
+ private java.time.LocalDateTime startDate;
+
+ /**
+ * 이벤트 종료일 (null이면 진행중)
+ */
+ @Column(name = "end_date")
+ private java.time.LocalDateTime endDate;
+
/**
* 참여자 수 증가
*/
diff --git a/analytics-service/src/main/java/com/kt/event/analytics/messaging/consumer/EventCreatedConsumer.java b/analytics-service/src/main/java/com/kt/event/analytics/messaging/consumer/EventCreatedConsumer.java
index 3f86256..ef3c530 100644
--- a/analytics-service/src/main/java/com/kt/event/analytics/messaging/consumer/EventCreatedConsumer.java
+++ b/analytics-service/src/main/java/com/kt/event/analytics/messaging/consumer/EventCreatedConsumer.java
@@ -64,11 +64,13 @@ public class EventCreatedConsumer {
.totalInvestment(event.getTotalInvestment())
.expectedRevenue(event.getExpectedRevenue() != null ? event.getExpectedRevenue() : BigDecimal.ZERO)
.status(event.getStatus())
+ .startDate(event.getStartDate())
+ .endDate(event.getEndDate())
.build();
eventStatsRepository.save(eventStats);
- log.info("✅ 이벤트 통계 초기화 완료: eventId={}, userId={}, expectedRevenue={}",
- eventId, eventStats.getUserId(), event.getExpectedRevenue());
+ log.info("✅ 이벤트 통계 초기화 완료: eventId={}, userId={}, startDate={}, endDate={}",
+ eventId, eventStats.getUserId(), event.getStartDate(), event.getEndDate());
// 3. 캐시 무효화 (다음 조회 시 최신 데이터 반영)
String cacheKey = CACHE_KEY_PREFIX + eventId;
diff --git a/analytics-service/src/main/java/com/kt/event/analytics/messaging/event/EventCreatedEvent.java b/analytics-service/src/main/java/com/kt/event/analytics/messaging/event/EventCreatedEvent.java
index a044a28..771f9a0 100644
--- a/analytics-service/src/main/java/com/kt/event/analytics/messaging/event/EventCreatedEvent.java
+++ b/analytics-service/src/main/java/com/kt/event/analytics/messaging/event/EventCreatedEvent.java
@@ -6,6 +6,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
+import java.time.LocalDateTime;
/**
* 이벤트 생성 이벤트
@@ -45,4 +46,14 @@ public class EventCreatedEvent {
* 이벤트 상태
*/
private String status;
+
+ /**
+ * 이벤트 시작일
+ */
+ private LocalDateTime startDate;
+
+ /**
+ * 이벤트 종료일 (null이면 진행중)
+ */
+ private LocalDateTime endDate;
}
diff --git a/analytics-service/src/main/java/com/kt/event/analytics/service/AnalyticsService.java b/analytics-service/src/main/java/com/kt/event/analytics/service/AnalyticsService.java
index 2830a94..8d781df 100644
--- a/analytics-service/src/main/java/com/kt/event/analytics/service/AnalyticsService.java
+++ b/analytics-service/src/main/java/com/kt/event/analytics/service/AnalyticsService.java
@@ -146,11 +146,12 @@ public class AnalyticsService {
}
/**
- * 기간 정보 구성 (이벤트 생성일 ~ 현재)
+ * 기간 정보 구성 (이벤트 시작일 ~ 종료일 또는 현재)
*/
private PeriodInfo buildPeriodInfo(EventStats eventStats) {
- LocalDateTime start = eventStats.getCreatedAt();
- LocalDateTime end = LocalDateTime.now();
+ LocalDateTime start = eventStats.getStartDate();
+ LocalDateTime end = eventStats.getEndDate() != null ?
+ eventStats.getEndDate() : LocalDateTime.now();
long durationDays = ChronoUnit.DAYS.between(start, end);
diff --git a/analytics-service/src/main/java/com/kt/event/analytics/service/UserAnalyticsService.java b/analytics-service/src/main/java/com/kt/event/analytics/service/UserAnalyticsService.java
index 5b8ed29..fc0cc35 100644
--- a/analytics-service/src/main/java/com/kt/event/analytics/service/UserAnalyticsService.java
+++ b/analytics-service/src/main/java/com/kt/event/analytics/service/UserAnalyticsService.java
@@ -301,20 +301,17 @@ public class UserAnalyticsService {
/**
* 기간 정보 구성
- */
- /**
- * 전체 이벤트의 생성/수정 시간 기반으로 period 계산
+ *
+ * 전체 이벤트 중 가장 빠른 시작일 ~ 현재까지의 기간 계산
*/
private PeriodInfo buildPeriodFromEvents(List events) {
LocalDateTime start = events.stream()
- .map(EventStats::getCreatedAt)
+ .map(EventStats::getStartDate)
+ .filter(Objects::nonNull)
.min(LocalDateTime::compareTo)
.orElse(LocalDateTime.now());
- LocalDateTime end = events.stream()
- .map(EventStats::getUpdatedAt)
- .max(LocalDateTime::compareTo)
- .orElse(LocalDateTime.now());
+ LocalDateTime end = LocalDateTime.now();
return PeriodInfo.builder()
.startDate(start)
diff --git a/analytics-service/src/main/resources/application.yml b/analytics-service/src/main/resources/application.yml
index e15aaf6..0aa7c70 100644
--- a/analytics-service/src/main/resources/application.yml
+++ b/analytics-service/src/main/resources/application.yml
@@ -80,7 +80,6 @@ server:
charset: UTF-8
enabled: true
force: true
- context-path: /api/v1/analytics
# JWT
jwt: