kt-event-marketing/design/backend/sequence/inner/event-AI추천요청.puml
cherry2250 e15b7b42e5 이미지 생성 및 AI 추천 inner sequence 수정
주요 변경사항:
- event-이미지생성요청.puml: Kafka 제거, ContentService 내부 Job 관리로 변경
- event-이미지결과조회.puml: ContentService 패턴으로 업데이트
- event-AI추천요청.puml: Gateway 패턴 추가, 한글화

아키텍처 구분:
- AI 추천: Kafka 사용 (ai-job-topic)
- 이미지 생성: 내부 Job 관리 (Kafka 사용 안 함)

모든 파일:
- Gateway 패턴 적용
- 레이어 아키텍처 (<<API Layer>>, <<Business Layer>>)
- 한글 요청/응답
- Redis 키 패턴 표준화

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 16:31:36 +09:00

127 lines
3.8 KiB
Plaintext

@startuml event-AI추천요청
!theme mono
title Event Service - AI 추천 요청 (Kafka Job 발행) (UFR-EVENT-030)
actor Client
participant "API Gateway" as Gateway
participant "EventController" as Controller <<API Layer>>
participant "EventService" as Service <<Business Layer>>
participant "JobService" as JobSvc <<Business Layer>>
participant "EventRepository" as Repo <<Data Layer>>
participant "Redis Cache" as Cache <<E>>
database "Event DB" as DB <<E>>
participant "Kafka Producer" as Kafka <<E>>
note over Controller, Kafka
**UFR-EVENT-030: AI 이벤트 추천 요청**
- Kafka 비동기 Job 발행
- AI Service가 Kafka 구독하여 처리
- 트렌드 분석 + 3가지 추천안 생성
- 처리 시간: 평균 2분 이내
end note
Client -> Gateway: POST /api/events/{eventDraftId}/ai-recommendations\n{"objective": "신규 고객 유치",\n"industry": "음식점",\n"region": "서울 강남구"}
activate Gateway
Gateway -> Controller: POST /api/events/{eventDraftId}/ai-recommendations
activate Controller
Controller -> Controller: 요청 검증\n(필수 필드, 목적 유효성)
Controller -> Service: requestAIRecommendation(eventDraftId, userId)
activate Service
== 1단계: 이벤트 초안 조회 및 검증 ==
Service -> Repo: findById(eventDraftId)
activate Repo
Repo -> DB: 이벤트 초안 조회\n(초안ID로 이벤트 목적,\n매장 정보 조회)
activate DB
DB --> Repo: EventDraft 엔티티\n{목적, 매장명, 업종, 주소}
deactivate DB
Repo --> Service: EventDraft entity
deactivate Repo
Service -> Service: 소유권 검증\nvalidateOwnership(userId, eventDraft)
alt 소유권 없음
Service --> Controller: throw ForbiddenException\n("권한이 없습니다")
Controller --> Gateway: 403 Forbidden\n{"code": "EVENT_003",\n"message": "권한이 없습니다"}
deactivate Service
deactivate Controller
Gateway --> Client: 403 Forbidden
deactivate Gateway
else 소유권 확인
== 2단계: Kafka Job 생성 ==
Service -> JobSvc: createAIJob(eventDraft)
activate JobSvc
JobSvc -> JobSvc: Job ID 생성 (UUID)
JobSvc -> Cache: Job 상태 저장\nKey: job:{jobId}\nValue: {status: PENDING,\neventDraftId, type: AI_RECOMMEND,\ncreatedAt}\nTTL: 1시간
activate Cache
Cache --> JobSvc: 저장 완료
deactivate Cache
== 3단계: Kafka 이벤트 발행 ==
JobSvc -> Kafka: 이벤트 발행\nTopic: ai-job-topic\nPayload: {jobId, eventDraftId,\nobjective, industry,\nregion, storeInfo}
activate Kafka
note right of Kafka
**Kafka Topic**
- Topic: ai-job-topic
- Consumer: AI Service
- Consumer Group: ai-service-group
**Payload**
{
"jobId": "UUID",
"eventDraftId": "UUID",
"objective": "신규 고객 유치",
"industry": "음식점",
"region": "서울 강남구",
"storeInfo": {...}
}
end note
Kafka --> JobSvc: ACK (발행 확인)
deactivate Kafka
JobSvc --> Service: JobResponse\n{jobId, status: PENDING}
deactivate JobSvc
== 4단계: 응답 반환 ==
Service --> Controller: JobResponse\n{jobId, status: PENDING}
deactivate Service
Controller --> Gateway: 202 Accepted\n{"jobId": "job-uuid-123",\n"status": "PENDING",\n"message": "AI가 분석 중입니다"}
deactivate Controller
Gateway --> Client: 202 Accepted\nAI 분석 시작
deactivate Gateway
note over Service, Kafka
**AI Service 비동기 처리**
- Kafka 구독: ai-job-topic
- 트렌드 분석 (업종, 지역 기반)
- 3가지 추천안 생성 (저/중/고 비용)
- 결과: Redis에 저장 (TTL: 24시간)
- 상세: ai-트렌드분석및추천.puml 참조
**처리 시간**
- 평균: 2분 이내
- P95: 4분 이내
- Timeout: 5분
**결과 조회**
- 폴링 방식: GET /api/jobs/{jobId}/status
- 간격: 2초, 최대 30초
end note
end
@enduml