@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
