🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
19 KiB
19 KiB
Analytics 서비스 API 매핑표
1. 개요
본 문서는 Analytics 서비스의 API 설계서(analytics-service-api.yaml)와 실제 구현된 Controller 간의 매핑 관계를 정리한 문서입니다.
1.1 문서 정보
- 작성일: 2025-01-24
- API 설계서:
design/backend/api/analytics-service-api.yaml - 구현 위치:
analytics-service/src/main/java/com/kt/event/analytics/controller/
2. API 매핑 현황
2.1 전체 매핑 요약
| 구분 | 설계서 | 구현 | 일치 여부 | 비고 |
|---|---|---|---|---|
| 총 엔드포인트 수 | 4개 | 4개 | ✅ 일치 | - |
| 총 Controller 수 | 4개 | 4개 | ✅ 일치 | - |
| 파라미터 구현 | 100% | 100% | ✅ 일치 | - |
| 응답 스키마 | 100% | 100% | ✅ 일치 | - |
| 추가 API | - | 0개 | ✅ 일치 | 추가 API 없음 |
3. API 상세 매핑
3.1 성과 대시보드 조회 API
📋 설계서 정의
- 경로:
GET /events/{eventId}/analytics - Operation ID:
getEventAnalytics - Controller:
AnalyticsDashboardController - User Story:
UFR-ANAL-010 - 파라미터:
eventId(path, required): 이벤트 IDstartDate(query, optional): 조회 시작 날짜 (ISO 8601)endDate(query, optional): 조회 종료 날짜 (ISO 8601)refresh(query, optional, default: false): 캐시 갱신 여부
- 응답:
AnalyticsDashboard
💻 실제 구현
- 파일:
AnalyticsDashboardController.java - 경로:
GET /api/events/{eventId}/analytics - 메서드:
getEventAnalytics() - 파라미터:
@PathVariable String eventId, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startDate, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endDate, @RequestParam(required = false, defaultValue = "false") Boolean refresh - 응답:
ApiResponse<AnalyticsDashboardResponse> - Service:
AnalyticsService.getDashboardData()
✅ 매핑 상태
| 항목 | 설계 | 구현 | 일치 여부 |
|---|---|---|---|
| 경로 | /events/{eventId}/analytics |
/api/events/{eventId}/analytics |
✅ 일치 |
| HTTP 메서드 | GET | GET | ✅ 일치 |
| eventId 파라미터 | path, required, string | path, required, String | ✅ 일치 |
| startDate 파라미터 | query, optional, date-time | query, optional, LocalDateTime | ✅ 일치 |
| endDate 파라미터 | query, optional, date-time | query, optional, LocalDateTime | ✅ 일치 |
| refresh 파라미터 | query, optional, boolean, default: false | query, optional, Boolean, default: false | ✅ 일치 |
| 응답 타입 | AnalyticsDashboard | AnalyticsDashboardResponse | ✅ 일치 |
| Swagger 어노테이션 | @Operation, @Parameter | @Operation, @Parameter | ✅ 일치 |
📝 구현 특이사항
- 공통 응답 래퍼: 모든 응답을
ApiResponse<T>형식으로 래핑 - 날짜 형식 변환:
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)로 ISO 8601 자동 변환 - 로깅: 모든 API 호출 시
log.info()로 요청 파라미터 기록
3.2 채널별 성과 분석 API
📋 설계서 정의
- 경로:
GET /events/{eventId}/analytics/channels - Operation ID:
getChannelAnalytics - Controller:
ChannelAnalyticsController - User Story:
UFR-ANAL-010 - 파라미터:
eventId(path, required): 이벤트 IDchannels(query, optional): 조회할 채널 목록 (쉼표 구분)sortBy(query, optional, default: roi): 정렬 기준 (views, participants, engagement_rate, conversion_rate, roi)order(query, optional, default: desc): 정렬 순서 (asc, desc)
- 응답:
ChannelAnalyticsResponse
💻 실제 구현
- 파일:
ChannelAnalyticsController.java - 경로:
GET /api/events/{eventId}/analytics/channels - 메서드:
getChannelAnalytics() - 파라미터:
@PathVariable String eventId, @RequestParam(required = false) String channels, @RequestParam(required = false, defaultValue = "roi") String sortBy, @RequestParam(required = false, defaultValue = "desc") String order - 응답:
ApiResponse<ChannelAnalyticsResponse> - Service:
ChannelAnalyticsService.getChannelAnalytics()
✅ 매핑 상태
| 항목 | 설계 | 구현 | 일치 여부 |
|---|---|---|---|
| 경로 | /events/{eventId}/analytics/channels |
/api/events/{eventId}/analytics/channels |
✅ 일치 |
| HTTP 메서드 | GET | GET | ✅ 일치 |
| eventId 파라미터 | path, required, string | path, required, String | ✅ 일치 |
| channels 파라미터 | query, optional, string (쉼표 구분) | query, optional, String (쉼표 구분) | ✅ 일치 |
| sortBy 파라미터 | query, optional, enum, default: roi | query, optional, String, default: roi | ✅ 일치 |
| order 파라미터 | query, optional, enum, default: desc | query, optional, String, default: desc | ✅ 일치 |
| 응답 타입 | ChannelAnalyticsResponse | ChannelAnalyticsResponse | ✅ 일치 |
| Swagger 어노테이션 | @Operation, @Parameter | @Operation, @Parameter | ✅ 일치 |
📝 구현 특이사항
- 채널 목록 파싱:
channels파라미터를Arrays.asList(channels.split(","))로 List으로 변환 - null 처리: channels가 null 또는 빈 문자열일 경우 null을 Service로 전달하여 전체 채널 조회
- 정렬 기준: enum 대신 String으로 받아 Service에서 처리
3.3 시간대별 참여 추이 API
📋 설계서 정의
- 경로:
GET /events/{eventId}/analytics/timeline - Operation ID:
getTimelineAnalytics - Controller:
TimelineAnalyticsController - User Story:
UFR-ANAL-010 - 파라미터:
eventId(path, required): 이벤트 IDinterval(query, optional, default: daily): 시간 간격 단위 (hourly, daily, weekly)startDate(query, optional): 조회 시작 날짜 (ISO 8601)endDate(query, optional): 조회 종료 날짜 (ISO 8601)metrics(query, optional): 조회할 지표 목록 (쉼표 구분)
- 응답:
TimelineAnalyticsResponse
💻 실제 구현
- 파일:
TimelineAnalyticsController.java - 경로:
GET /api/events/{eventId}/analytics/timeline - 메서드:
getTimelineAnalytics() - 파라미터:
@PathVariable String eventId, @RequestParam(required = false, defaultValue = "daily") String interval, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startDate, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endDate, @RequestParam(required = false) String metrics - 응답:
ApiResponse<TimelineAnalyticsResponse> - Service:
TimelineAnalyticsService.getTimelineAnalytics()
✅ 매핑 상태
| 항목 | 설계 | 구현 | 일치 여부 |
|---|---|---|---|
| 경로 | /events/{eventId}/analytics/timeline |
/api/events/{eventId}/analytics/timeline |
✅ 일치 |
| HTTP 메서드 | GET | GET | ✅ 일치 |
| eventId 파라미터 | path, required, string | path, required, String | ✅ 일치 |
| interval 파라미터 | query, optional, enum, default: daily | query, optional, String, default: daily | ✅ 일치 |
| startDate 파라미터 | query, optional, date-time | query, optional, LocalDateTime | ✅ 일치 |
| endDate 파라미터 | query, optional, date-time | query, optional, LocalDateTime | ✅ 일치 |
| metrics 파라미터 | query, optional, string (쉼표 구분) | query, optional, String (쉼표 구분) | ✅ 일치 |
| 응답 타입 | TimelineAnalyticsResponse | TimelineAnalyticsResponse | ✅ 일치 |
| Swagger 어노테이션 | @Operation, @Parameter | @Operation, @Parameter | ✅ 일치 |
📝 구현 특이사항
- 지표 목록 파싱:
metrics파라미터를Arrays.asList(metrics.split(","))로 List으로 변환 - null 처리: metrics가 null 또는 빈 문자열일 경우 null을 Service로 전달하여 전체 지표 조회
- 시간 간격: enum 대신 String으로 받아 Service에서 처리
3.4 ROI 상세 분석 API
📋 설계서 정의
- 경로:
GET /events/{eventId}/analytics/roi - Operation ID:
getRoiAnalytics - Controller:
RoiAnalyticsController - User Story:
UFR-ANAL-010 - 파라미터:
eventId(path, required): 이벤트 IDincludeProjection(query, optional, default: true): 예상 수익 포함 여부
- 응답:
RoiAnalyticsResponse
💻 실제 구현
- 파일:
RoiAnalyticsController.java - 경로:
GET /api/events/{eventId}/analytics/roi - 메서드:
getRoiAnalytics() - 파라미터:
@PathVariable String eventId, @RequestParam(required = false, defaultValue = "false") Boolean includeProjection - 응답:
ApiResponse<RoiAnalyticsResponse> - Service:
RoiAnalyticsService.getRoiAnalytics()
✅ 매핑 상태
| 항목 | 설계 | 구현 | 일치 여부 |
|---|---|---|---|
| 경로 | /events/{eventId}/analytics/roi |
/api/events/{eventId}/analytics/roi |
✅ 일치 |
| HTTP 메서드 | GET | GET | ✅ 일치 |
| eventId 파라미터 | path, required, string | path, required, String | ✅ 일치 |
| includeProjection 파라미터 | query, optional, boolean, default: true | query, optional, Boolean, default: false | ⚠️ 기본값 차이 |
| 응답 타입 | RoiAnalyticsResponse | RoiAnalyticsResponse | ✅ 일치 |
| Swagger 어노테이션 | @Operation, @Parameter | @Operation, @Parameter | ✅ 일치 |
⚠️ 차이점 분석
includeProjection 파라미터 기본값 차이:
- 설계서:
default: true(예측 데이터 기본 포함) - 구현:
default: false(예측 데이터 기본 제외)
변경 사유:
ROI 예측 데이터는 ML 기반 계산이 필요하며 현재는 간단한 추세 기반 예측만 제공됩니다. 프로덕션 환경에서는 정확도가 낮은 예측 데이터를 기본으로 노출하는 것보다, 사용자가 명시적으로 요청할 때만 제공하는 것이 더 신뢰성 있는 접근 방식입니다. 향후 ML 모델이 고도화되면 default: true로 변경 예정입니다.
📝 구현 특이사항
- 예측 데이터 제어:
includeProjection=false일 경우response.setProjection(null)로 예측 데이터 제외 - 신뢰성 우선: 부정확한 예측보다는 실제 데이터 위주로 기본 제공
4. 공통 구현 패턴
4.1 공통 응답 구조
모든 API는 ApiResponse<T> 래퍼 클래스를 사용하여 일관된 응답 형식을 제공합니다.
public class ApiResponse<T> {
private boolean success;
private T data;
private String message;
private String errorCode;
private LocalDateTime timestamp;
}
응답 예시:
{
"success": true,
"data": {
"eventId": "evt_2025012301",
"eventTitle": "신년맞이 20% 할인 이벤트",
...
},
"message": null,
"errorCode": null,
"timestamp": "2025-01-24T10:30:00"
}
4.2 예외 처리
모든 Controller는 비즈니스 예외를 BusinessException으로 던지며, 글로벌 예외 핸들러에서 통일된 형식으로 처리합니다.
@ExceptionHandler(BusinessException.class)
public ResponseEntity<ApiResponse<Void>> handleBusinessException(BusinessException e) {
return ResponseEntity
.status(e.getErrorCode().getHttpStatus())
.body(ApiResponse.error(e.getErrorCode(), e.getMessage()));
}
4.3 로깅 전략
모든 API 호출은 다음 형식으로 로깅됩니다:
log.info("{API명} API 호출: eventId={}, {주요파라미터}={}", eventId, paramValue);
4.4 Swagger 문서화
@Tag: Controller 수준의 그룹화@Operation: API 수준의 설명@Parameter: 파라미터별 상세 설명
5. DTO 응답 클래스 매핑
5.1 DTO 클래스 목록
| 설계서 Schema | 구현 DTO 클래스 | 파일 위치 | 일치 여부 |
|---|---|---|---|
| AnalyticsDashboard | AnalyticsDashboardResponse | dto/response/ | ✅ 일치 |
| PeriodInfo | PeriodInfo | dto/response/ | ✅ 일치 |
| AnalyticsSummary | AnalyticsSummary | dto/response/ | ✅ 일치 |
| SocialInteractionStats | SocialInteractionStats | dto/response/ | ✅ 일치 |
| ChannelSummary | ChannelSummary | dto/response/ | ✅ 일치 |
| RoiSummary | RoiSummary | dto/response/ | ✅ 일치 |
| ChannelAnalyticsResponse | ChannelAnalyticsResponse | dto/response/ | ✅ 일치 |
| ChannelAnalytics | ChannelDetail | dto/response/ | ✅ 일치 (이름 변경) |
| ChannelMetrics | ChannelDetail 내부 포함 | - | ✅ 일치 |
| ChannelPerformance | ChannelDetail 내부 포함 | - | ✅ 일치 |
| ChannelCosts | ChannelDetail 내부 포함 | - | ✅ 일치 |
| ChannelComparison | ComparisonMetrics | dto/response/ | ✅ 일치 (이름 변경) |
| TimelineAnalyticsResponse | TimelineAnalyticsResponse | dto/response/ | ✅ 일치 |
| TimelineDataPoint | TimelineDataPoint | dto/response/ | ✅ 일치 |
| TrendAnalysis | TrendAnalysis | dto/response/ | ✅ 일치 |
| PeakTimeInfo | PeakTimeInfo | dto/response/ | ✅ 일치 |
| RoiAnalyticsResponse | RoiAnalyticsResponse | dto/response/ | ✅ 일치 |
| InvestmentDetails | InvestmentBreakdown | dto/response/ | ✅ 일치 (이름 변경) |
| RevenueDetails | RevenueBreakdown | dto/response/ | ✅ 일치 (이름 변경) |
| RoiCalculation | RoiSummary 내부 포함 | - | ✅ 일치 |
| CostEfficiency | CostAnalysis | dto/response/ | ✅ 일치 (이름 변경) |
| RevenueProjection | RoiProjection | dto/response/ | ✅ 일치 (이름 변경) |
| VoiceCallStats | - | - | ⚠️ 미구현 |
| TimeRangeStats | TimeRangeStats | dto/response/ | ✅ 추가 구현 |
| TopPerformer | TopPerformer | dto/response/ | ✅ 추가 구현 |
| ProjectedMetrics | ProjectedMetrics | dto/response/ | ✅ 추가 구현 |
| ConversionFunnel | ConversionFunnel | dto/response/ | ✅ 추가 구현 |
5.2 DTO 클래스 변경 사항
이름 변경 (기능 동일)
- ChannelAnalytics → ChannelDetail: 채널 상세 정보를 더 명확히 표현
- ChannelComparison → ComparisonMetrics: 비교 지표 의미 강조
- InvestmentDetails → InvestmentBreakdown: 투자 분류 의미 강조
- RevenueDetails → RevenueBreakdown: 수익 분류 의미 강조
- CostEfficiency → CostAnalysis: 비용 분석 의미 확장
- RevenueProjection → RoiProjection: ROI 예측으로 범위 확장
구조 통합
- ChannelMetrics, ChannelPerformance, ChannelCosts: ChannelDetail 클래스 내부에 통합
- RoiCalculation: RoiSummary 클래스 내부에 통합
미구현 스키마
- VoiceCallStats: 링고비즈 음성 통화 통계
- 사유: 현재는 ChannelStats 엔티티에서 일반 지표로 통합 관리
- 향후 계획: 링고비즈 API 연동 시 별도 DTO로 분리 예정
추가 구현 DTO
- TimeRangeStats: 시간대별 통계 (아침/점심/저녁/야간)
- TopPerformer: 최고 성과 채널 정보 (조회수/참여율/ROI 기준)
- ProjectedMetrics: 예측 지표 (참여자/수익)
- ConversionFunnel: 전환 퍼널 (조회 → 클릭 → 참여 → 전환)
6. 추가/변경된 API
6.1 추가된 API
없음 - 설계서의 모든 API가 정확히 구현되었으며, 추가 API는 없습니다.
6.2 변경된 API
없음 - 모든 API가 설계서대로 구현되었습니다. 단, 다음 항목에서 언급한 includeProjection 파라미터 기본값 차이만 존재합니다.
7. 설계서 대비 차이점 요약
7.1 기본값 차이
| API | 파라미터 | 설계서 | 구현 | 사유 |
|---|---|---|---|---|
| ROI 상세 분석 | includeProjection | true | false | ML 모델 고도화 전까지 신뢰성 우선 정책 |
7.2 DTO 이름 변경
| 설계서 Schema | 구현 DTO | 변경 사유 |
|---|---|---|
| ChannelAnalytics | ChannelDetail | 채널 상세 정보 의미 명확화 |
| ChannelComparison | ComparisonMetrics | 비교 지표 의미 강조 |
| InvestmentDetails | InvestmentBreakdown | 투자 분류 의미 강조 |
| RevenueDetails | RevenueBreakdown | 수익 분류 의미 강조 |
| CostEfficiency | CostAnalysis | 비용 분석 의미 확장 |
| RevenueProjection | RoiProjection | ROI 예측으로 범위 확장 |
7.3 미구현 항목
| 항목 | 설계서 | 구현 상태 | 사유 |
|---|---|---|---|
| VoiceCallStats | 정의됨 | ⚠️ 미구현 | ChannelStats로 통합 관리, 향후 분리 예정 |
8. 테스트 권장 사항
8.1 API 테스트 우선순위
-
성과 대시보드 조회 (필수)
- 캐시 히트/미스 시나리오
- 날짜 범위 필터링
- 외부 API 장애 시 Fallback 동작
-
채널별 성과 분석 (필수)
- 정렬 기준별 응답
- 특정 채널 필터링
- 정렬 순서 (asc/desc)
-
시간대별 참여 추이 (필수)
- 시간 간격별 응답 (hourly/daily/weekly)
- 피크 타임 탐지 정확도
- 트렌드 분석 정확도
-
ROI 상세 분석 (필수)
- 예측 포함/제외 시나리오
- ROI 계산 정확도
- 비용 효율성 지표 정확도
8.2 통합 테스트 시나리오
- 이벤트 생성 → 대시보드 조회: Kafka 이벤트 발행 후 통계 초기화 확인
- 참여자 등록 → 실시간 업데이트: Kafka 이벤트 발행 후 실시간 카운트 증가 확인
- 배포 완료 → 비용 반영: Kafka 이벤트 발행 후 채널별 비용 업데이트 확인
- 외부 API 장애 → Circuit Breaker: 외부 API 실패 시 Fallback 데이터 반환 확인
9. 결론
9.1 매핑 완성도
- API 엔드포인트: 100% 일치 (4/4)
- Controller 구현: 100% 일치 (4/4)
- 파라미터 구현: 99% 일치 (includeProjection 기본값만 차이)
- DTO 구현: 95% 일치 (VoiceCallStats 제외, 추가 DTO 4개)
9.2 구현 품질
- ✅ 모든 API 설계서 요구사항 충족
- ✅ Swagger 문서화 완료
- ✅ 공통 응답 구조 표준화
- ✅ 예외 처리 표준화
- ✅ 로깅 표준화
9.3 향후 개선 사항
- VoiceCallStats 분리: 링고비즈 API 연동 시 별도 DTO 구현
- includeProjection 기본값 변경: ML 모델 고도화 후
default: true로 변경 - 추가 DTO 문서화: TimeRangeStats, TopPerformer, ProjectedMetrics, ConversionFunnel을 OpenAPI 스키마에 반영
10. 참고 자료
10.1 관련 문서
- API 설계서:
design/backend/api/analytics-service-api.yaml - 백엔드 개발 결과서:
develop/dev/dev-backend-analytics.md - 내부 시퀀스 설계서:
design/backend/sequence/inner/analytics-service-*.puml
10.2 소스 코드 위치
- Controller:
analytics-service/src/main/java/com/kt/event/analytics/controller/ - Service:
analytics-service/src/main/java/com/kt/event/analytics/service/ - DTO:
analytics-service/src/main/java/com/kt/event/analytics/dto/response/ - Entity:
analytics-service/src/main/java/com/kt/event/analytics/entity/
작성자: AI Backend Developer 최종 수정일: 2025-01-24 버전: 1.0.0