@startuml event-목적선택 !theme mono title Event Service - 이벤트 목적 선택 및 저장 (UFR-EVENT-020) participant "EventController" as Controller <> participant "EventService" as Service <> participant "EventRepository" as Repo <> participant "Redis Cache" as Cache <> database "Event DB" as DB <> participant "Kafka Producer" as Kafka <> actor Client note over Controller, DB **UFR-EVENT-020: 이벤트 목적 선택 및 저장** - 목적 선택: 신규 고객 유치, 재방문 유도, 매출 증대, 인지도 향상 - Redis 캐시 사용 (TTL: 30분) - Kafka 이벤트 발행 (EventDraftCreated) - 사용자 및 매장 정보는 User Service에서 조회 후 전달됨 end note Client -> Controller: POST /api/events/purposes\n{"userId": 123,\n"objective": "신규 고객 유치",\n"storeName": "맛있는집",\n"industry": "음식점",\n"address": "서울시 강남구"} activate Controller Controller -> Controller: 입력값 검증\n(필수 필드, 목적 유효성 확인) Controller -> Service: createEventDraft(userId, objective, storeInfo) activate Service == 1단계: Redis 캐시 확인 == Service -> Cache: 캐시 조회\nKey: draft:event:{userId}\n(기존 작성 중인 이벤트 확인) activate Cache Cache --> Service: null (캐시 미스) deactivate Cache == 2단계: 목적 유효성 검증 == Service -> Service: 목적 유효성 검증\n- 신규 고객 유치\n- 재방문 유도\n- 매출 증대\n- 인지도 향상 Service -> Service: 매장 정보 유효성 검증\n(매장명, 업종, 주소) == 3단계: 이벤트 초안 저장 == Service -> Repo: save(eventDraft) activate Repo Repo -> DB: 이벤트 초안 저장\n(사용자ID, 목적, 매장명,\n업종, 주소, 상태=DRAFT,\n생성일시)\n저장 후 이벤트초안ID 반환 activate DB DB --> Repo: 생성된 이벤트초안ID deactivate DB Repo --> Service: EventDraft 엔티티\n(eventDraftId 포함) deactivate Repo == 4단계: Redis 캐시 저장 == Service -> Cache: 캐시 저장\nKey: draft:event:{eventDraftId}\nValue: {목적, 매장정보, 상태}\nTTL: 24시간 activate Cache Cache --> Service: 저장 완료 deactivate Cache == 5단계: Kafka 이벤트 발행 == Service -> Kafka: 이벤트 발행\nTopic: event-topic\nEvent: EventDraftCreated\nPayload: {eventDraftId,\nuserId, objective,\ncreatedAt} activate Kafka note right of Kafka **Kafka Event Topic** - Topic: event-topic - Event: EventDraftCreated - 목적 선택 시 발행 **구독자** - Analytics Service (선택적) **참고** - EventCreated는 최종 승인 시 발행 end note Kafka --> Service: ACK (발행 확인) deactivate Kafka == 6단계: 응답 반환 == Service -> Service: 응답 DTO 생성 Service --> Controller: EventDraftResponse\n{eventDraftId, objective,\nstoreName, status=DRAFT} deactivate Service Controller --> Client: 200 OK\n{"eventDraftId": "draft-123",\n"objective": "신규 고객 유치",\n"storeName": "맛있는집",\n"status": "DRAFT"} deactivate Controller note over Controller, Kafka **캐시 전략** - Key: draft:event:{eventDraftId} - TTL: 24시간 - 캐시 히트 시: DB 조회 생략, 즉시 반환 **이벤트 발행 전략** - EventDraftCreated: 목적 선택 시 발행 (Analytics Service 선택적 구독) - EventCreated: 최종 승인 시 발행 (통계 초기화 시작) **성능 목표** - 평균 응답 시간: 0.3초 이내 - P95 응답 시간: 0.5초 이내 - Redis 캐시 조회: 0.05초 이내 **에러 코드** - EVENT_001: 유효하지 않은 목적 - EVENT_002: 매장 정보 누락 end note @enduml