diff --git a/design/backend/api/distribution-service-api.yaml b/design/backend/api/distribution-service-api.yaml index 938b3a8..d47ecb3 100644 --- a/design/backend/api/distribution-service-api.yaml +++ b/design/backend/api/distribution-service-api.yaml @@ -11,10 +11,10 @@ info: - Retry 패턴 및 Fallback 처리 ## 배포 채널 - - **우리동네TV**: 영상 콘텐츠 업로드 - - **링고비즈**: 연결음 업데이트 - - **지니TV**: 광고 등록 - - **SNS**: Instagram, Naver Blog, Kakao Channel + - **우리동네TV** (URIDONGNETV): 영상 콘텐츠 업로드 + - **링고비즈** (RINGOBIZ): 연결음 업데이트 + - **지니TV** (GINITV): 광고 등록 + - **SNS**: Instagram (INSTAGRAM), Naver Blog (NAVER), Kakao Channel (KAKAO) ## Resilience 패턴 - Circuit Breaker: 채널별 독립적 장애 격리 @@ -79,23 +79,21 @@ paths: summary: 다중 채널 배포 예시 value: eventId: "evt-12345" + title: "신규 고객 환영 이벤트" + description: "신규 고객님을 위한 특별 할인 이벤트" + imageUrl: "https://cdn.example.com/images/event-main.jpg" channels: - - type: "WOORIDONGNE_TV" - config: - radius: "1km" - timeSlots: - - "weekday_evening" - - "weekend_lunch" - - type: "INSTAGRAM" - config: - scheduledTime: "2025-11-01T10:00:00Z" - - type: "NAVER_BLOG" - config: - scheduledTime: "2025-11-01T10:30:00Z" - contentUrls: - instagram: "https://cdn.example.com/images/event-instagram.jpg" - naverBlog: "https://cdn.example.com/images/event-naver.jpg" - kakaoChannel: "https://cdn.example.com/images/event-kakao.jpg" + - "URIDONGNETV" + - "INSTAGRAM" + - "NAVER" + channelSettings: + URIDONGNETV: + radius: "1km" + timeSlot: "evening" + INSTAGRAM: + scheduledTime: "2025-11-01T10:00:00" + NAVER: + scheduledTime: "2025-11-01T10:30:00" responses: '200': description: 배포 완료 @@ -107,25 +105,29 @@ paths: allSuccess: summary: 모든 채널 배포 성공 value: - distributionId: "dist-12345" eventId: "evt-12345" - status: "COMPLETED" - completedAt: "2025-11-01T09:00:00Z" - results: - - channel: "WOORIDONGNE_TV" - status: "SUCCESS" + success: true + channelResults: + - channel: "URIDONGNETV" + success: true distributionId: "wtv-uuid-12345" - estimatedViews: 1000 - message: "배포 완료" + estimatedReach: 1000 + executionTimeMs: 234 - channel: "INSTAGRAM" - status: "SUCCESS" - postUrl: "https://instagram.com/p/generated-post-id" - postId: "ig-post-12345" - message: "게시 완료" - - channel: "NAVER_BLOG" - status: "SUCCESS" - postUrl: "https://blog.naver.com/store123/generated-post" - message: "게시 완료" + success: true + distributionId: "ig-uuid-12345" + estimatedReach: 500 + executionTimeMs: 456 + - channel: "NAVER" + success: true + distributionId: "naver-uuid-12345" + estimatedReach: 300 + executionTimeMs: 123 + successCount: 3 + failureCount: 0 + completedAt: "2025-11-01T09:00:00" + totalExecutionTimeMs: 1234 + message: "배포가 성공적으로 완료되었습니다" '400': description: 잘못된 요청 content: @@ -217,67 +219,77 @@ paths: value: eventId: "evt-12345" overallStatus: "COMPLETED" - completedAt: "2025-11-01T09:00:00Z" + startedAt: "2025-11-01T08:58:00" + completedAt: "2025-11-01T09:00:00" channels: - - channel: "WOORIDONGNE_TV" + - channel: "URIDONGNETV" status: "COMPLETED" distributionId: "wtv-uuid-12345" estimatedViews: 1500 - completedAt: "2025-11-01T09:00:00Z" - - channel: "RINGO_BIZ" + completedAt: "2025-11-01T09:00:00" + - channel: "RINGOBIZ" status: "COMPLETED" - updateTimestamp: "2025-11-01T09:00:00Z" - - channel: "GENIE_TV" + updateTimestamp: "2025-11-01T09:00:00" + completedAt: "2025-11-01T09:00:00" + - channel: "GINITV" status: "COMPLETED" adId: "gtv-uuid-12345" impressionSchedule: - "2025-11-01 18:00-20:00" - "2025-11-02 12:00-14:00" + completedAt: "2025-11-01T09:00:00" - channel: "INSTAGRAM" status: "COMPLETED" postUrl: "https://instagram.com/p/generated-post-id" postId: "ig-post-12345" - - channel: "NAVER_BLOG" + completedAt: "2025-11-01T09:00:00" + - channel: "NAVER" status: "COMPLETED" postUrl: "https://blog.naver.com/store123/generated-post" - - channel: "KAKAO_CHANNEL" + completedAt: "2025-11-01T09:00:00" + - channel: "KAKAO" status: "COMPLETED" messageId: "kakao-msg-12345" + completedAt: "2025-11-01T09:00:00" inProgress: summary: 배포 진행중 상태 value: eventId: "evt-12345" overallStatus: "IN_PROGRESS" - startedAt: "2025-11-01T08:58:00Z" + startedAt: "2025-11-01T08:58:00" channels: - - channel: "WOORIDONGNE_TV" + - channel: "URIDONGNETV" status: "COMPLETED" distributionId: "wtv-uuid-12345" estimatedViews: 1500 + completedAt: "2025-11-01T08:59:00" - channel: "INSTAGRAM" status: "IN_PROGRESS" progress: 50 - - channel: "NAVER_BLOG" + - channel: "NAVER" status: "PENDING" partialFailure: summary: 일부 채널 실패 상태 value: eventId: "evt-12345" overallStatus: "PARTIAL_FAILURE" - completedAt: "2025-11-01T09:00:00Z" + startedAt: "2025-11-01T08:58:00" + completedAt: "2025-11-01T09:00:00" channels: - - channel: "WOORIDONGNE_TV" + - channel: "URIDONGNETV" status: "COMPLETED" distributionId: "wtv-uuid-12345" estimatedViews: 1500 + completedAt: "2025-11-01T08:59:00" - channel: "INSTAGRAM" status: "FAILED" errorMessage: "Instagram API 타임아웃" retries: 3 - lastRetryAt: "2025-11-01T08:59:30Z" - - channel: "NAVER_BLOG" + lastRetryAt: "2025-11-01T08:59:30" + - channel: "NAVER" status: "COMPLETED" postUrl: "https://blog.naver.com/store123/generated-post" + completedAt: "2025-11-01T09:00:00" '404': description: 배포 이력을 찾을 수 없음 content: @@ -305,196 +317,133 @@ components: required: - eventId - channels - - contentUrls properties: eventId: type: string description: 이벤트 ID example: "evt-12345" + title: + type: string + description: 이벤트 제목 + example: "신규 고객 환영 이벤트" + description: + type: string + description: 이벤트 설명 + example: "신규 고객님을 위한 특별 할인 이벤트" + imageUrl: + type: string + description: 이미지 URL (CDN) + example: "https://cdn.example.com/images/event-main.jpg" channels: type: array description: 배포할 채널 목록 minItems: 1 items: - $ref: '#/components/schemas/ChannelConfig' - contentUrls: + type: string + enum: + - URIDONGNETV + - RINGOBIZ + - GINITV + - INSTAGRAM + - NAVER + - KAKAO + example: ["URIDONGNETV", "INSTAGRAM", "NAVER"] + channelSettings: type: object - description: 플랫폼별 콘텐츠 URL - properties: - wooridongneTV: - type: string - description: 우리동네TV 영상 URL (15초) - example: "https://cdn.example.com/videos/event-15s.mp4" - ringoBiz: - type: string - description: 링고비즈 연결음 파일 URL - example: "https://cdn.example.com/audio/ringtone.mp3" - genieTV: - type: string - description: 지니TV 광고 영상 URL - example: "https://cdn.example.com/videos/event-ad.mp4" - instagram: - type: string - description: Instagram 이미지 URL (1080x1080) - example: "https://cdn.example.com/images/event-instagram.jpg" - naverBlog: - type: string - description: Naver Blog 이미지 URL (800x600) - example: "https://cdn.example.com/images/event-naver.jpg" - kakaoChannel: - type: string - description: Kakao Channel 이미지 URL (800x800) - example: "https://cdn.example.com/images/event-kakao.jpg" - - ChannelConfig: - type: object - required: - - type - properties: - type: - type: string - description: 채널 타입 - enum: - - WOORIDONGNE_TV - - RINGO_BIZ - - GENIE_TV - - INSTAGRAM - - NAVER_BLOG - - KAKAO_CHANNEL - example: "INSTAGRAM" - config: - type: object - description: 채널별 설정 (채널에 따라 다름) - additionalProperties: true + description: 채널별 추가 설정 (Optional) + additionalProperties: + type: object + additionalProperties: true example: - scheduledTime: "2025-11-01T10:00:00Z" - caption: "이벤트 안내" - hashtags: - - "이벤트" - - "할인" + URIDONGNETV: + radius: "1km" + timeSlot: "evening" + INSTAGRAM: + scheduledTime: "2025-11-01T10:00:00" DistributionResponse: type: object required: - - distributionId - eventId - - status - - results + - success + - channelResults + - successCount + - failureCount properties: - distributionId: - type: string - description: 배포 ID - example: "dist-12345" eventId: type: string description: 이벤트 ID example: "evt-12345" - status: - type: string - description: 전체 배포 상태 - enum: - - PENDING - - IN_PROGRESS - - COMPLETED - - PARTIAL_FAILURE - - FAILED - example: "COMPLETED" - startedAt: - type: string - format: date-time - description: 배포 시작 시각 - example: "2025-11-01T08:59:00Z" + success: + type: boolean + description: 배포 성공 여부 (모든 채널 또는 일부 채널 성공) + example: true + channelResults: + type: array + description: 채널별 배포 결과 + items: + $ref: '#/components/schemas/ChannelDistributionResult' + successCount: + type: integer + description: 성공한 채널 수 + example: 3 + failureCount: + type: integer + description: 실패한 채널 수 + example: 0 completedAt: type: string format: date-time description: 배포 완료 시각 - example: "2025-11-01T09:00:00Z" - results: - type: array - description: 채널별 배포 결과 - items: - $ref: '#/components/schemas/ChannelResult' + example: "2025-11-01T09:00:00" + totalExecutionTimeMs: + type: integer + format: int64 + description: 전체 배포 소요 시간 (ms) + example: 1234 + message: + type: string + description: 메시지 + example: "배포가 성공적으로 완료되었습니다" - ChannelResult: + ChannelDistributionResult: type: object required: - channel - - status + - success properties: channel: type: string description: 채널 타입 enum: - - WOORIDONGNE_TV - - RINGO_BIZ - - GENIE_TV + - URIDONGNETV + - RINGOBIZ + - GINITV - INSTAGRAM - - NAVER_BLOG - - KAKAO_CHANNEL + - NAVER + - KAKAO example: "INSTAGRAM" - status: - type: string - description: 채널별 배포 상태 - enum: - - PENDING - - IN_PROGRESS - - SUCCESS - - FAILED - example: "SUCCESS" + success: + type: boolean + description: 배포 성공 여부 + example: true distributionId: type: string - description: 채널별 배포 ID (우리동네TV, 지니TV) - example: "wtv-uuid-12345" - estimatedViews: + description: 배포 ID (성공 시) + example: "dist-uuid-12345" + estimatedReach: type: integer - description: 예상 노출 수 (우리동네TV, 지니TV) + description: 예상 노출 수 (성공 시) example: 1500 - updateTimestamp: - type: string - format: date-time - description: 업데이트 완료 시각 (링고비즈) - example: "2025-11-01T09:00:00Z" - adId: - type: string - description: 광고 ID (지니TV) - example: "gtv-uuid-12345" - impressionSchedule: - type: array - description: 노출 스케줄 (지니TV) - items: - type: string - example: - - "2025-11-01 18:00-20:00" - - "2025-11-02 12:00-14:00" - postUrl: - type: string - description: 게시물 URL (Instagram, Naver Blog) - example: "https://instagram.com/p/generated-post-id" - postId: - type: string - description: 게시물 ID (Instagram) - example: "ig-post-12345" - messageId: - type: string - description: 메시지 ID (Kakao Channel) - example: "kakao-msg-12345" - message: - type: string - description: 결과 메시지 - example: "배포 완료" errorMessage: type: string - description: 오류 메시지 (실패 시) + description: 에러 메시지 (실패 시) example: "Instagram API 타임아웃" - retries: + executionTimeMs: type: integer - description: 재시도 횟수 - example: 0 - lastRetryAt: - type: string - format: date-time - description: 마지막 재시도 시각 - example: "2025-11-01T08:59:30Z" + format: int64 + description: 배포 소요 시간 (ms) + example: 234 DistributionStatusResponse: type: object @@ -544,12 +493,12 @@ components: type: string description: 채널 타입 enum: - - WOORIDONGNE_TV - - RINGO_BIZ - - GENIE_TV + - URIDONGNETV + - RINGOBIZ + - GINITV - INSTAGRAM - - NAVER_BLOG - - KAKAO_CHANNEL + - NAVER + - KAKAO example: "INSTAGRAM" status: type: string @@ -569,7 +518,7 @@ components: distributionId: type: string description: 채널별 배포 ID - example: "wtv-uuid-12345" + example: "dist-uuid-12345" estimatedViews: type: integer description: 예상 노출 수 @@ -578,35 +527,35 @@ components: type: string format: date-time description: 업데이트 완료 시각 - example: "2025-11-01T09:00:00Z" + example: "2025-11-01T09:00:00" adId: type: string - description: 광고 ID + description: 광고 ID (지니TV) example: "gtv-uuid-12345" impressionSchedule: type: array - description: 노출 스케줄 + description: 노출 스케줄 (지니TV) items: type: string example: - "2025-11-01 18:00-20:00" postUrl: type: string - description: 게시물 URL + description: 게시물 URL (Instagram, Naver Blog) example: "https://instagram.com/p/generated-post-id" postId: type: string - description: 게시물 ID + description: 게시물 ID (Instagram) example: "ig-post-12345" messageId: type: string - description: 메시지 ID + description: 메시지 ID (Kakao Channel) example: "kakao-msg-12345" completedAt: type: string format: date-time description: 완료 시각 - example: "2025-11-01T09:00:00Z" + example: "2025-11-01T09:00:00" errorMessage: type: string description: 오류 메시지 @@ -619,7 +568,7 @@ components: type: string format: date-time description: 마지막 재시도 시각 - example: "2025-11-01T08:59:30Z" + example: "2025-11-01T08:59:30" ErrorResponse: type: object