@startuml event-콘텐츠생성완료구독 !theme mono title Event Service - 콘텐츠 생성 완료 이벤트 구독 (Kafka Consumer) participant "Kafka\nevent-topic\nConsumer" as Consumer participant "EventHandler" as Handler participant "EventRepository" as Repo database "Event DB" as DB participant "Redis Cache" as Cache note over Consumer: Kafka 구독\nevent-topic\n이벤트 타입: ContentCreated == ContentCreated 이벤트 수신 == Consumer -> Handler: ContentCreated 이벤트 수신\n{jobId, eventDraftId, imageUrls} activate Handler Handler -> Handler: 이벤트 검증\n- eventDraftId 유효성\n- imageUrls 존재 여부 note right: 3가지 스타일 확인\n(simple, fancy, trendy) == Event DB에 이미지 URL 저장 == Handler -> Repo: updateContentImages(eventDraftId, imageUrls) activate Repo Repo -> DB: 이벤트 초안 업데이트\nUPDATE event_drafts\nSET content_images = ?,\n updated_at = NOW()\nWHERE event_draft_id = ? activate DB note over DB 저장 데이터: { "simple": "https://cdn.../simple.png", "fancy": "https://cdn.../fancy.png", "trendy": "https://cdn.../trendy.png" } end note DB --> Repo: 업데이트 완료 deactivate DB Repo --> Handler: 저장 완료 deactivate Repo == 캐시 무효화 == Handler -> Cache: 이벤트 초안 캐시 무효화\nDEL event:draft:{eventDraftId} activate Cache Cache --> Handler: 삭제 완료 deactivate Cache note over Handler: 캐시 무효화로\n다음 조회 시 최신 데이터 반영 Handler --> Consumer: 처리 완료 deactivate Handler note over Consumer, DB **처리 전략** - At-Least-Once 전달 보장 - 멱등성 처리 (중복 이벤트 무시) - 실패 시 자동 재시도 (최대 3회) - Dead Letter Queue로 실패 이벤트 이동 **저장 위치** - Event DB: 영구 저장 (이벤트 초안 테이블) - Redis Cache: 임시 저장 (7일 TTL) **데이터 정합성** - DB 저장 후 캐시 무효화 - 다음 조회 시 DB에서 최신 데이터 로드 end note @enduml