@startuml participation-이벤트참여
!theme mono

title Participation Service - 이벤트 참여 내부 시퀀스

actor "고객" as Customer
participant "API Gateway" as Gateway
participant "ParticipationController" as Controller
participant "ParticipationService" as Service
participant "ParticipantRepository" as Repo
database "Participation DB" as DB
participant "KafkaProducer" as Kafka
database "Redis Cache<<E>>" as Cache

== UFR-PART-010: 이벤트 참여 ==

Customer -> Gateway: POST /api/v1/participations\n{name, phone, eventId, entryPath, consent}
activate Gateway

note right of Gateway
    비회원 참여 가능
    JWT 검증 불필요
end note

Gateway -> Controller: POST /participations/register\n{name, phone, eventId, entryPath, consent}
activate Controller

Controller -> Controller: 요청 데이터 유효성 검증\n- 이름 2자 이상\n- 전화번호 형식 (정규식)\n- 개인정보 동의 필수

alt 유효성 검증 실패
    Controller --> Gateway: 400 Bad Request\n{message: "유효성 오류"}
    Gateway --> Customer: 400 Bad Request
    deactivate Controller
    deactivate Gateway
else 유효성 검증 성공

    Controller -> Service: registerParticipant(request)
    activate Service

    Service -> Cache: GET duplicate_check:{eventId}:{phone}
    activate Cache
    Cache --> Service: 캐시 확인 결과
    deactivate Cache

    alt 캐시 HIT: 중복 참여
        Service --> Controller: DuplicateParticipationException
        Controller --> Gateway: 409 Conflict\n{message: "이미 참여하신 이벤트입니다"}
        Gateway --> Customer: 409 Conflict
        deactivate Service
        deactivate Controller
        deactivate Gateway
    else 캐시 MISS: DB 조회

        Service -> Repo: findByEventIdAndPhoneNumber(eventId, phone)
        activate Repo
        Repo -> DB: 참여자 중복 확인\n(이벤트ID, 전화번호로 조회)
        activate DB
        DB --> Repo: 조회 결과
        deactivate DB
        Repo --> Service: Optional<Participant>
        deactivate Repo

        alt DB에 중복 참여 존재
            Service -> Cache: SET duplicate_check:{eventId}:{phone} = true\nTTL: 7일
            activate Cache
            Cache --> Service: 캐시 저장 완료
            deactivate Cache

            Service --> Controller: DuplicateParticipationException
            Controller --> Gateway: 409 Conflict\n{message: "이미 참여하신 이벤트입니다"}
            Gateway --> Customer: 409 Conflict
            deactivate Service
            deactivate Controller
            deactivate Gateway
        else 신규 참여: 저장 진행

            Service -> Service: 응모 번호 생성\n- UUID 기반\n- 형식: EVT-{timestamp}-{random}

            Service -> Service: Participant 엔티티 생성\n- participantId (UUID)\n- eventId\n- name, phoneNumber\n- entryPath\n- applicationNumber (응모번호)\n- participatedAt (현재시각)

            Service -> Repo: save(participant)
            activate Repo
            Repo -> DB: 참여자 정보 저장\n(참여자ID, 이벤트ID, 이름, 전화번호,\n참여경로, 응모번호, 참여일시,\n마케팅동의여부)
            activate DB
            DB --> Repo: 저장 완료
            deactivate DB
            Repo --> Service: Participant 엔티티 반환
            deactivate Repo

            note right of Service
                참여자 등록 완료 후
                캐싱 및 이벤트 발행
            end note

            Service -> Cache: SET duplicate_check:{eventId}:{phone} = true\nTTL: 7일
            activate Cache
            Cache --> Service: 캐시 저장 완료
            deactivate Cache

            Service -> Kafka: Publish Event\n"ParticipantRegistered"\nTopic: participant-events
            activate Kafka
            note right of Kafka
                Event Payload:
                {
                  "participantId": "UUID",
                  "eventId": "UUID",
                  "phoneNumber": "010-1234-5678",
                  "entryPath": "SNS",
                  "registeredAt": "2025-10-22T10:30:00Z"
                }
            end note
            Kafka --> Service: 이벤트 발행 완료
            deactivate Kafka

            Service -> Service: 당첨 발표일 계산\n- 이벤트 종료일 + 3일

            Service --> Controller: ParticipationResponse\n{응모번호, 당첨발표일, 참여완료메시지}
            deactivate Service

            Controller --> Gateway: 201 Created\n{applicationNumber, drawDate, message}
            deactivate Controller

            Gateway --> Customer: 201 Created\n참여 완료 화면 표시
            deactivate Gateway
        end
    end
end

@enduml
