Hyowon Yang ea4aa5d072 Analytics Service storeId → userId 변환 및 User 통합 분석 API 개발 완료
주요 변경사항:
- EventStats 엔티티 storeId → userId 필드 변경
- EventStatsRepository 메소드명 변경 (findAllByStoreId → findAllByUserId)
- MVP 환경 1:1 관계 적용 (1 user = 1 store)
- EventCreatedConsumer에서 storeId → userId 매핑 처리

User 통합 분석 API 4개 신규 개발:
1. GET /api/v1/users/{userId}/analytics - 사용자 전체 성과 대시보드
2. GET /api/v1/users/{userId}/analytics/channels - 채널별 성과 분석
3. GET /api/v1/users/{userId}/analytics/roi - ROI 상세 분석
4. GET /api/v1/users/{userId}/analytics/timeline - 시간대별 참여 추이

기술 스택:
- Spring Boot 3.3.0, Java 21
- JPA/Hibernate, Redis 캐싱 (TTL 30분)
- Kafka Event-Driven 아키텍처

문서:
- test-backend.md: 백엔드 테스트 결과서 작성 완료

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 15:19:43 +09:00

18 KiB

Analytics Service 백엔드 테스트 결과서

1. 개요

1.1 테스트 목적

  • userId 기반 통합 성과 분석 API 개발 및 검증
  • 사용자 전체 이벤트를 통합하여 분석하는 4개 API 개발
  • 기존 eventId 기반 API와 독립적으로 동작하는 구조 검증
  • MVP 환경: 1:1 관계 (1 user = 1 store)

1.2 테스트 환경

  • 프로젝트: kt-event-marketing
  • 서비스: analytics-service
  • 브랜치: feature/analytics
  • 빌드 도구: Gradle 8.10
  • 프레임워크: Spring Boot 3.3.0
  • 언어: Java 21

1.3 테스트 일시

  • 작성일: 2025-10-28
  • 컴파일 테스트: 2025-10-28

2. 개발 범위

2.1 Repository 수정

파일: 3개 Repository 인터페이스

EventStatsRepository

// 추가된 메소드
List<EventStats> findAllByUserId(String userId);
  • 목적: 특정 사용자의 모든 이벤트 통계 조회
  • 위치: analytics-service/src/main/java/com/kt/event/analytics/repository/EventStatsRepository.java

ChannelStatsRepository

// 추가된 메소드
List<ChannelStats> findByEventIdIn(List<String> eventIds);
  • 목적: 여러 이벤트의 채널 통계 일괄 조회
  • 위치: analytics-service/src/main/java/com/kt/event/analytics/repository/ChannelStatsRepository.java

TimelineDataRepository

// 추가된 메소드
List<TimelineData> findByEventIdInOrderByTimestampAsc(List<String> eventIds);

@Query("SELECT t FROM TimelineData t WHERE t.eventId IN :eventIds " +
       "AND t.timestamp BETWEEN :startDate AND :endDate " +
       "ORDER BY t.timestamp ASC")
List<TimelineData> findByEventIdInAndTimestampBetween(
    @Param("eventIds") List<String> eventIds,
    @Param("startDate") LocalDateTime startDate,
    @Param("endDate") LocalDateTime endDate
);
  • 목적: 여러 이벤트의 타임라인 데이터 조회
  • 위치: analytics-service/src/main/java/com/kt/event/analytics/repository/TimelineDataRepository.java

2.2 Response DTO 작성

파일: 4개 Response DTO

UserAnalyticsDashboardResponse

  • 경로: com.kt.event.analytics.dto.response.UserAnalyticsDashboardResponse
  • 역할: 사용자 전체 통합 성과 대시보드 응답
  • 주요 필드:
    • userId: 사용자 ID
    • totalEvents: 총 이벤트 수
    • activeEvents: 활성 이벤트 수
    • overallSummary: 전체 성과 요약 (AnalyticsSummary)
    • channelPerformance: 채널별 성과 (List)
    • overallRoi: 전체 ROI 요약 (RoiSummary)
    • eventPerformances: 이벤트별 성과 목록 (EventPerformanceSummary)
    • period: 조회 기간 (PeriodInfo)

UserChannelAnalyticsResponse

  • 경로: com.kt.event.analytics.dto.response.UserChannelAnalyticsResponse
  • 역할: 사용자 전체 채널별 성과 분석 응답
  • 주요 필드:
    • userId: 사용자 ID
    • totalEvents: 총 이벤트 수
    • channels: 채널별 상세 분석 (List)
    • comparison: 채널 간 비교 (ChannelComparison)
    • period: 조회 기간 (PeriodInfo)

UserRoiAnalyticsResponse

  • 경로: com.kt.event.analytics.dto.response.UserRoiAnalyticsResponse
  • 역할: 사용자 전체 ROI 상세 분석 응답
  • 주요 필드:
    • userId: 사용자 ID
    • totalEvents: 총 이벤트 수
    • overallInvestment: 전체 투자 내역 (InvestmentDetails)
    • overallRevenue: 전체 수익 내역 (RevenueDetails)
    • overallRoi: ROI 계산 (RoiCalculation)
    • costEfficiency: 비용 효율성 (CostEfficiency)
    • projection: 수익 예측 (RevenueProjection)
    • eventRois: 이벤트별 ROI (EventRoiSummary)
    • period: 조회 기간 (PeriodInfo)

UserTimelineAnalyticsResponse

  • 경로: com.kt.event.analytics.dto.response.UserTimelineAnalyticsResponse
  • 역할: 사용자 전체 시간대별 참여 추이 분석 응답
  • 주요 필드:
    • userId: 사용자 ID
    • totalEvents: 총 이벤트 수
    • interval: 시간 간격 단위 (hourly, daily, weekly, monthly)
    • dataPoints: 시간대별 데이터 포인트 (List)
    • trend: 추세 분석 (TrendAnalysis)
    • peakTime: 피크 시간대 정보 (PeakTimeInfo)
    • period: 조회 기간 (PeriodInfo)

2.3 Service 개발

파일: 4개 Service 클래스

UserAnalyticsService

  • 경로: com.kt.event.analytics.service.UserAnalyticsService
  • 역할: 사용자 전체 이벤트 통합 성과 대시보드 서비스
  • 주요 기능:
    • getUserDashboardData(): 사용자 전체 대시보드 데이터 조회
    • Redis 캐싱 (TTL: 30분)
    • 전체 성과 요약 계산 (참여자, 조회수, 참여율, 전환율)
    • 채널별 성과 통합 집계
    • 전체 ROI 계산
    • 이벤트별 성과 목록 생성
  • 특징:
    • 모든 이벤트의 메트릭을 합산하여 통합 분석
    • 채널명 기준으로 그룹화하여 채널 성과 집계
    • BigDecimal 타입으로 금액 정확도 보장

UserChannelAnalyticsService

  • 경로: com.kt.event.analytics.service.UserChannelAnalyticsService
  • 역할: 사용자 전체 이벤트의 채널별 성과 통합 서비스
  • 주요 기능:
    • getUserChannelAnalytics(): 사용자 전체 채널 분석 데이터 조회
    • Redis 캐싱 (TTL: 30분)
    • 채널별 메트릭 집계 (조회수, 참여자, 클릭, 전환)
    • 채널 성과 지표 계산 (참여율, 전환율, CTR, ROI)
    • 채널 비용 분석 (조회당/클릭당/획득당 비용)
    • 채널 간 비교 분석 (최고 성과, 평균 지표)
  • 특징:
    • 채널명 기준으로 그룹화하여 통합 집계
    • 다양한 정렬 옵션 지원 (participants, views, engagement_rate, conversion_rate, roi)
    • 채널 필터링 기능

UserRoiAnalyticsService

  • 경로: com.kt.event.analytics.service.UserRoiAnalyticsService
  • 역할: 사용자 전체 이벤트의 ROI 통합 분석 서비스
  • 주요 기능:
    • getUserRoiAnalytics(): 사용자 전체 ROI 분석 데이터 조회
    • Redis 캐싱 (TTL: 30분)
    • 전체 투자 금액 집계 (콘텐츠 제작, 운영, 배포 비용)
    • 전체 수익 집계 (직접 판매, 예상 판매)
    • ROI 계산 (순이익, ROI %)
    • 비용 효율성 분석 (참여자당 비용/수익)
    • 수익 예측 (현재 수익 기반 최종 수익 예측)
  • 특징:
    • BigDecimal로 금액 정밀 계산
    • 이벤트별 ROI 순위 제공
    • 선택적 수익 예측 기능

UserTimelineAnalyticsService

  • 경로: com.kt.event.analytics.service.UserTimelineAnalyticsService
  • 역할: 사용자 전체 이벤트의 시간대별 추이 통합 서비스
  • 주요 기능:
    • getUserTimelineAnalytics(): 사용자 전체 타임라인 분석 데이터 조회
    • Redis 캐싱 (TTL: 30분)
    • 시간 간격별 데이터 집계 (hourly, daily, weekly, monthly)
    • 추세 분석 (증가/감소/안정)
    • 피크 시간대 식별 (최대 참여자 시점)
  • 특징:
    • 시간대별로 정규화하여 데이터 집계
    • 전반부/후반부 비교를 통한 성장률 계산
    • 메트릭별 필터링 지원

2.4 Controller 개발

파일: 4개 Controller 클래스

UserAnalyticsDashboardController

  • 경로: com.kt.event.analytics.controller.UserAnalyticsDashboardController
  • 엔드포인트: GET /api/v1/users/{userId}/analytics
  • 역할: 사용자 전체 성과 대시보드 API
  • Request Parameters:
    • userId (Path): 사용자 ID (필수)
    • startDate (Query): 조회 시작 날짜 (선택, ISO 8601 format)
    • endDate (Query): 조회 종료 날짜 (선택, ISO 8601 format)
    • refresh (Query): 캐시 갱신 여부 (선택, default: false)
  • Response: ApiResponse<UserAnalyticsDashboardResponse>

UserChannelAnalyticsController

  • 경로: com.kt.event.analytics.controller.UserChannelAnalyticsController
  • 엔드포인트: GET /api/v1/users/{userId}/analytics/channels
  • 역할: 사용자 전체 채널별 성과 분석 API
  • Request Parameters:
    • userId (Path): 사용자 ID (필수)
    • channels (Query): 조회할 채널 목록 (쉼표 구분, 선택)
    • sortBy (Query): 정렬 기준 (선택, default: participants)
    • order (Query): 정렬 순서 (선택, default: desc)
    • startDate (Query): 조회 시작 날짜 (선택)
    • endDate (Query): 조회 종료 날짜 (선택)
    • refresh (Query): 캐시 갱신 여부 (선택, default: false)
  • Response: ApiResponse<UserChannelAnalyticsResponse>

UserRoiAnalyticsController

  • 경로: com.kt.event.analytics.controller.UserRoiAnalyticsController
  • 엔드포인트: GET /api/v1/users/{userId}/analytics/roi
  • 역할: 사용자 전체 ROI 상세 분석 API
  • Request Parameters:
    • userId (Path): 사용자 ID (필수)
    • includeProjection (Query): 예상 수익 포함 여부 (선택, default: true)
    • startDate (Query): 조회 시작 날짜 (선택)
    • endDate (Query): 조회 종료 날짜 (선택)
    • refresh (Query): 캐시 갱신 여부 (선택, default: false)
  • Response: ApiResponse<UserRoiAnalyticsResponse>

UserTimelineAnalyticsController

  • 경로: com.kt.event.analytics.controller.UserTimelineAnalyticsController
  • 엔드포인트: GET /api/v1/users/{userId}/analytics/timeline
  • 역할: 사용자 전체 시간대별 참여 추이 분석 API
  • Request Parameters:
    • userId (Path): 사용자 ID (필수)
    • interval (Query): 시간 간격 단위 (선택, default: daily)
      • 값: hourly, daily, weekly, monthly
    • startDate (Query): 조회 시작 날짜 (선택)
    • endDate (Query): 조회 종료 날짜 (선택)
    • metrics (Query): 조회할 지표 목록 (쉼표 구분, 선택)
    • refresh (Query): 캐시 갱신 여부 (선택, default: false)
  • Response: ApiResponse<UserTimelineAnalyticsResponse>

3. 컴파일 테스트

3.1 테스트 명령

./gradlew.bat analytics-service:compileJava

3.2 테스트 결과

상태: 성공 (BUILD SUCCESSFUL)

출력:

> Task :common:generateEffectiveLombokConfig UP-TO-DATE
> Task :common:compileJava UP-TO-DATE
> Task :analytics-service:generateEffectiveLombokConfig
> Task :analytics-service:compileJava

BUILD SUCCESSFUL in 8s
4 actionable tasks: 2 executed, 2 up-to-date

3.3 오류 해결 과정

3.3.1 초기 컴파일 오류 (19개)

문제: 기존 DTO 구조와 Service 코드 간 필드명/타입 불일치

해결:

  1. AnalyticsSummary: totalInvestment, expectedRevenue 필드 제거
  2. ChannelSummary: cost 필드 제거
  3. RoiSummary: BigDecimal 타입 사용
  4. InvestmentDetails: totalAmount → total 변경, 필드명 수정 (contentCreation, operation, distribution)
  5. RevenueDetails: totalRevenue → total 변경, 필드명 수정 (directSales, expectedSales)
  6. RoiCalculation: totalInvestment, totalRevenue 필드 제거
  7. TrendAnalysis: direction → overallTrend 변경
  8. PeakTimeInfo: participants → value 변경, metric, description 추가
  9. ChannelPerformance: participationRate 필드 제거
  10. ChannelCosts: totalCost → distributionCost 변경, costPerParticipant → costPerAcquisition 변경
  11. ChannelComparison: mostEfficient, highestEngagement → averageMetrics로 통합
  12. RevenueProjection: projectedRevenue → projectedFinalRevenue 변경, basedOn 필드 추가

3.3.2 수정된 파일

  • UserAnalyticsService.java: DTO 필드명 수정 (5곳)
  • UserChannelAnalyticsService.java: DTO 필드명 수정, HashMap import 추가 (3곳)
  • UserRoiAnalyticsService.java: DTO 필드명 수정, BigDecimal 타입 사용 (4곳)
  • UserTimelineAnalyticsService.java: DTO 필드명 수정 (3곳)

4. API 설계 요약

4.1 API 엔드포인트 구조

/api/v1/users/{userId}/analytics
├─ GET /                     # 전체 통합 대시보드
├─ GET /channels             # 채널별 성과 분석
├─ GET /roi                  # ROI 상세 분석
└─ GET /timeline             # 시간대별 참여 추이

4.2 기존 API와의 비교

구분 기존 API 신규 API
기준 eventId (개별 이벤트) userId (사용자 전체)
범위 단일 이벤트 사용자의 모든 이벤트 통합
엔드포인트 /api/v1/events/{eventId}/... /api/v1/users/{userId}/...
캐시 TTL 3600초 (60분) 1800초 (30분)
데이터 집계 개별 이벤트 데이터 여러 이벤트 합산/평균

4.3 캐싱 전략

  • 캐시 키 형식: analytics:user:{category}:{userId}
  • TTL: 30분 (1800초)
    • 여러 이벤트 통합으로 데이터 변동성이 높아 기존보다 짧게 설정
  • 갱신 방식: refresh=true 파라미터로 강제 갱신 가능
  • 구현: RedisTemplate + Jackson ObjectMapper

5. 주요 기능

5.1 데이터 집계 로직

5.1.1 통합 성과 계산

  • 참여자 수: 모든 이벤트의 totalParticipants 합산
  • 조회수: 모든 이벤트의 totalViews 합산
  • 참여율: 전체 참여자 / 전체 조회수 * 100
  • 전환율: 전체 전환 / 전체 참여자 * 100

5.1.2 채널 성과 집계

  • 그룹화: 채널명(channelName) 기준
  • 메트릭 합산: views, participants, clicks, conversions
  • 비용 집계: distributionCost 합산
  • ROI 계산: (참여자 - 비용) / 비용 * 100

5.1.3 ROI 계산

  • 투자 금액: 모든 이벤트의 totalInvestment 합산
  • 수익: 모든 이벤트의 expectedRevenue 합산
  • 순이익: 수익 - 투자
  • ROI: (순이익 / 투자) * 100

5.1.4 시간대별 집계

  • 정규화: interval에 따라 timestamp 정규화
    • hourly: 시간 단위로 truncate
    • daily: 일 단위로 truncate
    • weekly: 주 시작일로 정규화
    • monthly: 월 시작일로 정규화
  • 데이터 포인트 합산: 동일 시간대의 participants, views, engagement, conversions 합산

5.2 추세 분석

  • 전반부/후반부 비교: 데이터 포인트를 반으로 나누어 성장률 계산
  • 추세 결정:
    • 성장률 > 5%: "increasing"
    • 성장률 < -5%: "decreasing"
    • -5% ≤ 성장률 ≤ 5%: "stable"

5.3 피크 시간 식별

  • 기준: 참여자 수(participants) 최대 시점
  • 정보: timestamp, metric, value, description

6. 아키텍처 특징

6.1 계층 구조

Controller
    ↓
Service (비즈니스 로직)
    ↓
Repository (데이터 접근)
    ↓
Entity (JPA)

6.2 독립성 보장

  • 기존 eventId 기반 API와 독립적 구조
  • 별도의 Controller, Service 클래스
  • 공통 Repository 재사용
  • 기존 DTO 구조 준수

6.3 확장성

  • 새로운 메트릭 추가 용이: Service 레이어에서 계산 로직 추가
  • 캐싱 전략 개별 조정 가능: 각 Service마다 독립적인 캐시 키
  • 채널/이벤트 필터링 지원: 동적 쿼리 지원

7. 검증 결과

7.1 컴파일 검증

  • Service 계층: 4개 클래스 컴파일 성공
  • Controller 계층: 4개 클래스 컴파일 성공
  • Repository 계층: 3개 인터페이스 컴파일 성공
  • DTO 계층: 4개 Response 클래스 컴파일 성공

7.2 코드 품질

  • Lombok 활용: Builder 패턴, Data 클래스
  • 로깅: Slf4j 적용
  • 트랜잭션: @Transactional(readOnly = true)
  • 예외 처리: try-catch로 캐시 오류 대응
  • 타입 안정성: BigDecimal로 금액 처리

7.3 Swagger 문서화

  • @Tag: API 그룹 정의
  • @Operation: 엔드포인트 설명
  • @Parameter: 파라미터 설명

8. 다음 단계

8.1 백엔드 개발 완료 항목

  • Repository 쿼리 메소드 추가
  • Response DTO 작성
  • Service 로직 구현
  • Controller API 개발
  • 컴파일 검증

8.2 향후 작업

  1. 백엔드 서버 실행 테스트 (Phase 1 완료 후)

    • 애플리케이션 실행 확인
    • API 엔드포인트 접근 테스트
    • Swagger UI 확인
  2. API 통합 테스트 (Phase 1 완료 후)

    • Postman/curl로 API 호출 테스트
    • 실제 데이터로 응답 검증
    • 에러 핸들링 확인
  3. 프론트엔드 연동 (Phase 2)

    • 프론트엔드에서 4개 API 호출
    • 응답 데이터 바인딩
    • UI 렌더링 검증

9. 결론

9.1 성과

  • userId 기반 통합 분석 API 4개 개발 완료
  • 컴파일 성공
  • 기존 구조와 독립적인 설계
  • 확장 가능한 아키텍처
  • MVP 환경 1:1 관계 (1 user = 1 store) 적용

9.2 특이사항

  • 기존 DTO 구조 재사용: 새로운 DTO 생성 최소화
  • BigDecimal 타입 사용: 금액 정확도 보장
  • 캐싱 전략: Redis 캐싱으로 성능 최적화 (TTL: 30분)

9.3 개발 시간

  • 예상 개발 기간: 3~4일
  • 실제 개발 완료: 1일 (컴파일 테스트까지)

10. 첨부

10.1 주요 파일 목록

analytics-service/src/main/java/com/kt/event/analytics/
├── repository/
│   ├── EventStatsRepository.java (수정)
│   ├── ChannelStatsRepository.java (수정)
│   └── TimelineDataRepository.java (수정)
├── dto/response/
│   ├── UserAnalyticsDashboardResponse.java (신규)
│   ├── UserChannelAnalyticsResponse.java (신규)
│   ├── UserRoiAnalyticsResponse.java (신규)
│   └── UserTimelineAnalyticsResponse.java (신규)
├── service/
│   ├── UserAnalyticsService.java (신규)
│   ├── UserChannelAnalyticsService.java (신규)
│   ├── UserRoiAnalyticsService.java (신규)
│   └── UserTimelineAnalyticsService.java (신규)
└── controller/
    ├── UserAnalyticsDashboardController.java (신규)
    ├── UserChannelAnalyticsController.java (신규)
    ├── UserRoiAnalyticsController.java (신규)
    └── UserTimelineAnalyticsController.java (신규)

10.2 API 목록

No HTTP Method Endpoint 설명
1 GET /api/v1/users/{userId}/analytics 사용자 전체 성과 대시보드
2 GET /api/v1/users/{userId}/analytics/channels 사용자 전체 채널별 성과 분석
3 GET /api/v1/users/{userId}/analytics/roi 사용자 전체 ROI 상세 분석
4 GET /api/v1/users/{userId}/analytics/timeline 사용자 전체 시간대별 참여 추이

작성자: AI Backend Developer 검토자: - 승인자: - 버전: 1.0 최종 수정일: 2025-10-28