diff --git a/analytics-service/frontend-backend-validation.md b/analytics-service/frontend-backend-validation.md new file mode 100644 index 0000000..8f36b9a --- /dev/null +++ b/analytics-service/frontend-backend-validation.md @@ -0,0 +1,108 @@ +# 백엔드-프론트엔드 API 연동 검증 및 수정 결과 + +**작업일시**: 2025-10-28 +**브랜치**: feature/analytics +**작업 범위**: Analytics Service 백엔드 DTO 및 Service 수정 + +--- + +## 📝 수정 요약 + +### 1️⃣ 필드명 통일 (프론트엔드 호환) + +**목적**: 프론트엔드 Mock 데이터 필드명과 백엔드 Response DTO 필드명 일치 + +| 수정 전 (백엔드) | 수정 후 (백엔드) | 프론트엔드 | +|-----------------|----------------|-----------| +| `summary.totalParticipants` | `summary.participants` | `summary.participants` ✅ | +| `channelPerformance[].channelName` | `channelPerformance[].channel` | `channelPerformance[].channel` ✅ | +| `roi.totalInvestment` | `roi.totalCost` | `roiDetail.totalCost` ✅ | + +### 2️⃣ 증감 데이터 추가 + +**목적**: 프론트엔드에서 요구하는 증감 표시 및 목표값 제공 + +| 필드 | 타입 | 설명 | 현재 값 | +|-----|------|------|---------| +| `summary.participantsDelta` | `Integer` | 참여자 증감 (이전 기간 대비) | `0` (TODO: 계산 로직 필요) | +| `summary.targetRoi` | `Double` | 목표 ROI (%) | EventStats에서 가져옴 | + +--- + +## 🔧 수정 파일 목록 + +### DTO (Response 구조 변경) + +1. **AnalyticsSummary.java** + - ✅ `totalParticipants` → `participants` + - ✅ `participantsDelta` 필드 추가 + - ✅ `targetRoi` 필드 추가 + +2. **ChannelSummary.java** + - ✅ `channelName` → `channel` + +3. **RoiSummary.java** + - ✅ `totalInvestment` → `totalCost` + +### Entity (데이터베이스 스키마 변경) + +4. **EventStats.java** + - ✅ `targetRoi` 필드 추가 (`BigDecimal`, default: 0) + +### Service (비즈니스 로직 수정) + +5. **AnalyticsService.java** + - ✅ `.participants()` 사용 + - ✅ `.participantsDelta(0)` 추가 (TODO 마킹) + - ✅ `.targetRoi()` 추가 + - ✅ `.channel()` 사용 + +6. **ROICalculator.java** + - ✅ `.totalCost()` 사용 + +7. **UserAnalyticsService.java** + - ✅ `.participants()` 사용 + - ✅ `.participantsDelta(0)` 추가 + - ✅ `.channel()` 사용 + - ✅ `.totalCost()` 사용 + +--- + +## ✅ 검증 결과 + +### 컴파일 성공 +\`\`\`bash +$ ./gradlew analytics-service:compileJava + +BUILD SUCCESSFUL in 8s +\`\`\` + +--- + +## 📊 데이터베이스 스키마 변경 + +### EventStats 테이블 + +\`\`\`sql +ALTER TABLE event_stats +ADD COLUMN target_roi DECIMAL(10,2) DEFAULT 0.00; +\`\`\` + +**⚠️ 주의사항** +- Spring Boot JPA `ddl-auto` 설정에 따라 자동 적용됨 + +--- + +## 📌 다음 단계 + +### 우선순위 HIGH + +1. **프론트엔드 API 연동 테스트** +2. **participantsDelta 계산 로직 구현** +3. **targetRoi 데이터 입력** (Event Service 연동) + +### 우선순위 MEDIUM + +4. 시간대별 분석 구현 +5. 참여자 프로필 구현 +6. ROI 세분화 구현 diff --git a/analytics-service/src/main/java/com/kt/event/analytics/dto/response/AnalyticsSummary.java b/analytics-service/src/main/java/com/kt/event/analytics/dto/response/AnalyticsSummary.java index e4fb561..2aafc74 100644 --- a/analytics-service/src/main/java/com/kt/event/analytics/dto/response/AnalyticsSummary.java +++ b/analytics-service/src/main/java/com/kt/event/analytics/dto/response/AnalyticsSummary.java @@ -17,7 +17,12 @@ public class AnalyticsSummary { /** * 총 참여자 수 */ - private Integer totalParticipants; + private Integer participants; + + /** + * 참여자 증감 (이전 기간 대비) + */ + private Integer participantsDelta; /** * 총 조회수 @@ -44,6 +49,11 @@ public class AnalyticsSummary { */ private Integer averageEngagementTime; + /** + * 목표 ROI (%) + */ + private Double targetRoi; + /** * SNS 반응 통계 */ diff --git a/analytics-service/src/main/java/com/kt/event/analytics/dto/response/ChannelSummary.java b/analytics-service/src/main/java/com/kt/event/analytics/dto/response/ChannelSummary.java index 49e99da..65abb37 100644 --- a/analytics-service/src/main/java/com/kt/event/analytics/dto/response/ChannelSummary.java +++ b/analytics-service/src/main/java/com/kt/event/analytics/dto/response/ChannelSummary.java @@ -17,7 +17,7 @@ public class ChannelSummary { /** * 채널명 */ - private String channelName; + private String channel; /** * 조회수 diff --git a/analytics-service/src/main/java/com/kt/event/analytics/dto/response/RoiSummary.java b/analytics-service/src/main/java/com/kt/event/analytics/dto/response/RoiSummary.java index ae2e504..9a995f3 100644 --- a/analytics-service/src/main/java/com/kt/event/analytics/dto/response/RoiSummary.java +++ b/analytics-service/src/main/java/com/kt/event/analytics/dto/response/RoiSummary.java @@ -19,7 +19,7 @@ public class RoiSummary { /** * 총 투자 비용 (원) */ - private BigDecimal totalInvestment; + private BigDecimal totalCost; /** * 예상 매출 증대 (원) 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 f4a7666..e3b4464 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 @@ -63,6 +63,13 @@ public class EventStats extends BaseTimeEntity { @Builder.Default private BigDecimal estimatedRoi = BigDecimal.ZERO; + /** + * 목표 ROI (%) + */ + @Column(precision = 10, scale = 2) + @Builder.Default + private BigDecimal targetRoi = BigDecimal.ZERO; + /** * 매출 증가율 (%) */ 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 0969741..4402e06 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 @@ -179,12 +179,14 @@ public class AnalyticsService { .build(); return AnalyticsSummary.builder() - .totalParticipants(eventStats.getTotalParticipants()) + .participants(eventStats.getTotalParticipants()) + .participantsDelta(0) // TODO: 이전 기간 데이터와 비교하여 계산 .totalViews(totalViews) .totalReach(totalReach) .engagementRate(Math.round(engagementRate * 10.0) / 10.0) .conversionRate(Math.round(conversionRate * 10.0) / 10.0) .averageEngagementTime(145) // 고정값 (실제로는 외부 API에서 가져와야 함) + .targetRoi(eventStats.getTargetRoi() != null ? eventStats.getTargetRoi().doubleValue() : null) .socialInteractions(socialStats) .build(); } @@ -202,7 +204,7 @@ public class AnalyticsService { (stats.getParticipants() * 100.0 / stats.getDistributionCost().doubleValue()) : 0.0; summaries.add(ChannelSummary.builder() - .channelName(stats.getChannelName()) + .channel(stats.getChannelName()) .views(stats.getViews()) .participants(stats.getParticipants()) .engagementRate(Math.round(engagementRate * 10.0) / 10.0) diff --git a/analytics-service/src/main/java/com/kt/event/analytics/service/ROICalculator.java b/analytics-service/src/main/java/com/kt/event/analytics/service/ROICalculator.java index b802ea6..29196e4 100644 --- a/analytics-service/src/main/java/com/kt/event/analytics/service/ROICalculator.java +++ b/analytics-service/src/main/java/com/kt/event/analytics/service/ROICalculator.java @@ -192,7 +192,7 @@ public class ROICalculator { } return RoiSummary.builder() - .totalInvestment(eventStats.getTotalInvestment()) + .totalCost(eventStats.getTotalInvestment()) .expectedRevenue(eventStats.getExpectedRevenue()) .netProfit(netProfit) .roi(roi) 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 84058be..98a7b51 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 @@ -190,7 +190,8 @@ public class UserAnalyticsService { double avgConversionRate = totalParticipants > 0 ? (double) totalConversions / totalParticipants * 100 : 0.0; return AnalyticsSummary.builder() - .totalParticipants(totalParticipants) + .participants(totalParticipants) + .participantsDelta(0) // TODO: 이전 기간 데이터와 비교하여 계산 .totalViews(totalViews) .engagementRate(Math.round(avgEngagementRate * 10) / 10.0) .conversionRate(Math.round(avgConversionRate * 10) / 10.0) @@ -231,7 +232,7 @@ public class UserAnalyticsService { : 0.0; return ChannelSummary.builder() - .channelName(channelName) + .channel(channelName) .participants(participants) .views(views) .engagementRate(Math.round(engagementRate * 10) / 10.0) @@ -263,7 +264,7 @@ public class UserAnalyticsService { : 0.0; return RoiSummary.builder() - .totalInvestment(totalInvestment) + .totalCost(totalInvestment) .expectedRevenue(totalExpectedRevenue) .netProfit(totalProfit) .roi(Math.round(roi * 10) / 10.0) @@ -316,7 +317,8 @@ public class UserAnalyticsService { */ private AnalyticsSummary buildEmptyAnalyticsSummary() { return AnalyticsSummary.builder() - .totalParticipants(0) + .participants(0) + .participantsDelta(0) .totalViews(0) .engagementRate(0.0) .conversionRate(0.0) @@ -328,7 +330,7 @@ public class UserAnalyticsService { */ private RoiSummary buildEmptyRoiSummary() { return RoiSummary.builder() - .totalInvestment(BigDecimal.ZERO) + .totalCost(BigDecimal.ZERO) .expectedRevenue(BigDecimal.ZERO) .netProfit(BigDecimal.ZERO) .roi(0.0)