@startuml analytics-참여자등록구독
!theme mono

title Analytics Service - ParticipantRegistered 이벤트 구독 처리 내부 시퀀스\n(Kafka Event 구독)

participant "Kafka Consumer" as Consumer
participant "ParticipantRegisteredListener" as Listener
participant "AnalyticsService" as Service
participant "AnalyticsRepository" as Repository
participant "CacheService" as Cache
participant "Redis" as Redis
database "Analytics DB" as DB

note over Consumer
    **Kafka Consumer 설정**
    - Topic: ParticipantRegistered
    - Consumer Group: analytics-service
    - Partition Key: eventId
    - At-Least-Once Delivery 보장
end note

Kafka -> Consumer: ParticipantRegistered 이벤트 수신\n{\n  participantId: "uuid",\n  eventId: "uuid",\n  phoneNumber: "010-1234-5678",\n  registeredAt: "2025-10-22T11:30:00Z"\n}
activate Consumer

Consumer -> Listener: onParticipantRegistered(event)
activate Listener

note right of Listener
    **멱등성 체크**
    - Redis Set에 participantId 존재 여부 확인
    - 중복 처리 방지
end note

Listener -> Redis: SISMEMBER processed_participants {participantId}
activate Redis

alt 이벤트 미처리 (멱등성 보장)
    Redis --> Listener: false (미처리)
    deactivate Redis

    Listener -> Service: updateParticipantCount(eventId)
    activate Service

    note right of Service
        **참여자 수 실시간 증가**
        - DB UPDATE로 참여자 수 증가
        - 캐시 무효화로 다음 조회 시 최신 데이터 반영
    end note

    Service -> Repository: incrementParticipantCount(eventId)
    activate Repository

    Repository -> DB: 참여자 수 증가\n(참여자 수를 1 증가시키고,\n수정일시를 현재 시각으로 업데이트)
    activate DB

    DB --> Repository: 1 row updated
    deactivate DB

    Repository --> Service: UpdateResult (success)
    deactivate Repository

    note right of Service
        **실시간 통계 업데이트 완료**
        - 참여자 수 +1
        - 다음 대시보드 조회 시 최신 통계 반영
    end note

    Service -> Cache: delete("analytics:dashboard:{eventId}")
    activate Cache

    note right of Cache
        **캐시 무효화**
        - 기존 캐시 삭제
        - 다음 조회 시 최신 참여자 수 반영
        - Cache MISS 시 DB 조회로 최신 데이터 확보
    end note

    Cache -> Redis: DEL analytics:dashboard:{eventId}
    activate Redis

    Redis --> Cache: OK
    deactivate Redis

    Cache --> Service: OK
    deactivate Cache

    Service -> Redis: SADD processed_participants {participantId}
    activate Redis

    note right of Redis
        **멱등성 처리 완료 기록**
        - Redis Set에 participantId 추가
        - TTL 설정 (7일)
    end note

    Redis --> Service: OK
    deactivate Redis

    Service --> Listener: 참여자 수 업데이트 완료
    deactivate Service

    Listener -> Consumer: ACK (처리 완료)
    deactivate Listener

else 이벤트 이미 처리됨 (중복)
    Redis --> Listener: true (이미 처리)
    deactivate Redis

    note right of Listener
        **중복 이벤트 스킵**
        - At-Least-Once Delivery로 인한 중복
        - 멱등성 보장으로 중복 처리 방지
    end note

    Listener -> Consumer: ACK (스킵)
    deactivate Listener
end

Consumer --> Kafka: Commit Offset
deactivate Consumer

note over Consumer, DB
    **처리 시간**
    - 이벤트 수신 → 통계 업데이트 완료: 약 0.15초
    - DB UPDATE: 0.05초
    - Redis 캐시 무효화: 0.01초
    - 멱등성 체크: 0.01초

    **실시간 업데이트 효과**
    - 참여자 등록 즉시 통계 반영
    - 다음 대시보드 조회 시 최신 데이터 제공
    - Cache-Aside 패턴으로 성능 유지
end note

@enduml
