@startuml meeting-회의시작
!theme mono

title Meeting Service - 회의시작 내부 시퀀스

participant "MeetingController" as Controller
participant "MeetingService" as Service
participant "SessionService" as SessionService
participant "MeetingRepository" as MeetingRepo
participant "SessionRepository" as SessionRepo
database "Meeting DB<<E>>" as DB
database "Redis Cache<<E>>" as Cache
queue "Azure Event Hubs<<E>>" as EventHub

[-> Controller: POST /meetings/{meetingId}/start
activate Controller

note over Controller
경로 변수: meetingId
사용자 정보: userId, userName, email
end note

Controller -> Controller: meetingId 유효성 검증

Controller -> Service: startMeeting(meetingId, userId)
activate Service

' 회의 정보 조회
Service -> Cache: GET meeting:info:{meetingId}
activate Cache
Cache --> Service: 캐시 조회 결과
deactivate Cache

alt Cache Miss
    Service -> MeetingRepo: findById(meetingId)
    activate MeetingRepo
    MeetingRepo -> DB: 회의 정보 조회
    activate DB
    DB --> MeetingRepo: 회의 정보
    deactivate DB
    MeetingRepo --> Service: Meeting
    deactivate MeetingRepo

    Service -> Cache: SET meeting:info:{meetingId}\n(TTL: 10분)
    activate Cache
    note right of Cache
      회의 정보 캐싱:
      - TTL: 10분
      - 자동 만료
    end note
    Cache --> Service: 캐싱 완료
    deactivate Cache
end

note over Service
비즈니스 규칙 검증:
- 회의가 존재하는지 확인
- 회의 시작 권한 확인 (생성자만)
- 회의 상태 확인 (SCHEDULED만 시작 가능)
- 회의 시작 시간 10분 전부터 가능
end note

Service -> Service: 권한 검증\n(생성자 또는 참석자)

Service -> Service: 회의 상태 확인

alt 회의가 이미 진행 중
    Service --> Controller: 409 Conflict\n이미 진행 중인 회의
    note right
      에러 응답 형식:
      {
        "error": {
          "code": "MEETING_ALREADY_IN_PROGRESS",
          "message": "이미 진행 중인 회의입니다",
          "details": "해당 회의는 현재 진행 중 상태입니다",
          "timestamp": "2025-10-23T12:00:00Z",
          "path": "/api/meetings/{meetingId}/start"
        }
      }
    end note
    return 409 Conflict
else 시작 가능
    Service -> Service: 회의 세션 생성

    ' 세션 저장
    Service -> SessionRepo: createSession(meetingId, userId)
    activate SessionRepo

    note over SessionRepo
    세션 정보:
    - sessionId (UUID)
    - meetingId
    - startedBy (userId)
    - startedAt (현재시각)
    - status: ACTIVE
    end note

    SessionRepo -> DB: 회의 세션 생성
    activate DB
    DB --> SessionRepo: 세션 생성 완료
    deactivate DB
    SessionRepo --> Service: Session
    deactivate SessionRepo

    ' 회의 상태 업데이트
    Service -> MeetingRepo: updateStatus(meetingId, "IN_PROGRESS")
    activate MeetingRepo
    MeetingRepo -> DB: 회의 상태를 'IN_PROGRESS'로 변경하고 실제 시작 시간 기록
    activate DB
    DB --> MeetingRepo: 업데이트 완료
    deactivate DB
    MeetingRepo --> Service: 업데이트 성공
    deactivate MeetingRepo

    ' 캐시 무효화
    Service -> Cache: DELETE meeting:info:{meetingId}
    activate Cache
    Cache --> Service: 삭제 완료
    deactivate Cache

    ' 회의록 초안 생성 (빈 회의록)
    Service -> Service: 회의록 초안 생성

    Service -> MeetingRepo: createMinutesDraft(meetingId, sessionId)
    activate MeetingRepo
    MeetingRepo -> DB: 회의록 초안 생성 (상태: DRAFT)
    activate DB
    DB --> MeetingRepo: 회의록 생성 완료
    deactivate DB
    MeetingRepo --> Service: Minutes
    deactivate MeetingRepo

    note over Service
    비동기 이벤트 발행:
    - STT 서비스에 녹음 시작 요청
    - 참석자에게 회의 시작 알림
    - 실시간 협업 WebSocket 준비
    end note

    ' 이벤트 발행
    Service -> EventHub: publish(MeetingStarted)\n{\n  meetingId, sessionId,\n  startedAt, participants\n}
    activate EventHub
    EventHub --> Service: 발행 완료
    deactivate EventHub

    Service --> Controller: SessionResponse
    deactivate Service

    note over Controller
    응답 데이터:
    {
      "sessionId": "uuid",
      "meetingId": "uuid",
      "status": "IN_PROGRESS",
      "startedAt": "2025-01-23T14:00:00",
      "minutesId": "uuid"
    }
    end note

    return 201 Created\nSessionResponse
end

deactivate Controller

@enduml
