@startuml
!theme mono

title Event Service ERD (Entity Relationship Diagram)

' ==============================
' 엔티티 정의
' ==============================

entity "events" as events {
  * event_id : UUID <<PK>>
  --
  * user_id : UUID <<INDEX>>
  * store_id : UUID <<INDEX>>
    event_name : VARCHAR(200)
    description : TEXT
  * objective : VARCHAR(100)
    start_date : DATE
    end_date : DATE
  * status : VARCHAR(20) <<DEFAULT 'DRAFT'>>
    selected_image_id : UUID
    selected_image_url : VARCHAR(500)
    channels : TEXT
  * created_at : TIMESTAMP
  * updated_at : TIMESTAMP
}

entity "ai_recommendations" as ai_recommendations {
  * recommendation_id : UUID <<PK>>
  --
  * event_id : UUID <<FK>>
  * event_name : VARCHAR(200)
  * description : TEXT
  * promotion_type : VARCHAR(50)
  * target_audience : VARCHAR(100)
  * is_selected : BOOLEAN <<DEFAULT FALSE>>
  * created_at : TIMESTAMP
  * updated_at : TIMESTAMP
}

entity "generated_images" as generated_images {
  * image_id : UUID <<PK>>
  --
  * event_id : UUID <<FK>>
  * image_url : VARCHAR(500)
  * style : VARCHAR(50)
  * platform : VARCHAR(50)
  * is_selected : BOOLEAN <<DEFAULT FALSE>>
  * created_at : TIMESTAMP
  * updated_at : TIMESTAMP
}

entity "jobs" as jobs {
  * job_id : UUID <<PK>>
  --
  * event_id : UUID
  * job_type : VARCHAR(50)
  * status : VARCHAR(20) <<DEFAULT 'PENDING'>>
  * progress : INT <<DEFAULT 0>>
    result_key : VARCHAR(200)
    error_message : TEXT
    completed_at : TIMESTAMP
  * created_at : TIMESTAMP
  * updated_at : TIMESTAMP
}

' ==============================
' 관계 정의
' ==============================

events ||--o{ ai_recommendations : "has many"
events ||--o{ generated_images : "has many"
events ||--o{ jobs : "tracks"

' ==============================
' 제약조건 노트
' ==============================

note right of events
  **핵심 도메인 엔티티**
  - 상태 머신: DRAFT → PUBLISHED → ENDED
  - DRAFT에서만 수정 가능
  - PUBLISHED에서 END만 가능
  - channels: JSON 배열 (["SMS", "EMAIL"])

  **인덱스**:
  - IDX_events_user_id (user_id)
  - IDX_events_store_id (store_id)
  - IDX_events_status (status)
  - IDX_events_user_status (user_id, status)

  **체크 제약조건**:
  - status IN ('DRAFT', 'PUBLISHED', 'ENDED')
  - start_date <= end_date
end note

note right of ai_recommendations
  **AI 추천 결과**
  - 이벤트당 최대 3개 생성
  - is_selected=true는 이벤트당 1개만

  **인덱스**:
  - IDX_recommendations_event_id (event_id)
  - IDX_recommendations_selected (event_id, is_selected)

  **외래 키**:
  - FK_recommendations_event (event_id)
    → events(event_id) ON DELETE CASCADE
end note

note right of generated_images
  **생성 이미지 정보**
  - 여러 스타일/플랫폼 조합 가능
  - is_selected=true는 이벤트당 1개만

  **인덱스**:
  - IDX_images_event_id (event_id)
  - IDX_images_selected (event_id, is_selected)

  **외래 키**:
  - FK_images_event (event_id)
    → events(event_id) ON DELETE CASCADE
end note

note right of jobs
  **비동기 작업 추적**
  - job_type: AI_RECOMMENDATION, IMAGE_GENERATION
  - status: PENDING → PROCESSING → COMPLETED/FAILED
  - progress: 0-100

  **인덱스**:
  - IDX_jobs_event_id (event_id)
  - IDX_jobs_type_status (job_type, status)
  - IDX_jobs_status (status)

  **체크 제약조건**:
  - status IN ('PENDING', 'PROCESSING', 'COMPLETED', 'FAILED')
  - job_type IN ('AI_RECOMMENDATION', 'IMAGE_GENERATION')
  - progress BETWEEN 0 AND 100

  **외래 키 없음**: 이벤트 삭제 후에도 작업 이력 보존
end note

' ==============================
' Redis 캐시 노트
' ==============================

note top of events
  **Redis 캐시 전략**

  1. event:session:{userId} (TTL: 3600s)
     - 이벤트 생성 세션 정보
     - Hash: eventId, objective, storeId, createdAt

  2. event:draft:{eventId} (TTL: 1800s)
     - DRAFT 상태 이벤트 캐시
     - Hash: eventName, description, objective, status, userId, storeId

  3. job:status:{jobId} (TTL: 600s)
     - 작업 상태 실시간 조회
     - Hash: jobType, status, progress, eventId
end note

@enduml
