@startuml
!theme mono

title AI Service 내부 시퀀스 - 논의사항제안

participant "SuggestionController" as Controller
participant "DiscussionSuggestionService" as Service
participant "LLMClient" as LLM
participant "TranscriptRepository" as TranscriptRepo
database "Azure OpenAI<<E>>" as OpenAI
database "Redis Cache<<E>>" as Cache
database "PostgreSQL<<E>>" as DB

== 실시간 논의사항 제안 요청 ==

note over Controller
  TranscriptService로부터 호출
  (회의록 자동작성 프로세스 내부)
end note

Controller -> Service: suggestDiscussionTopics(meetingId, transcriptText)
activate Service

== 회의 맥락 정보 조회 ==

Service -> TranscriptRepo: getMeetingContext(meetingId)
activate TranscriptRepo

TranscriptRepo -> DB: 회의 맥락 정보 조회\n(회의정보, 안건, 참석자)
activate DB

DB --> TranscriptRepo: 회의 정보
deactivate DB

TranscriptRepo --> Service: meetingContext
deactivate TranscriptRepo

Service -> TranscriptRepo: getPreviousDiscussions(meetingId)
activate TranscriptRepo

TranscriptRepo -> DB: 이미 논의한 주제 조회\n(회의ID 기준)
activate DB

DB --> TranscriptRepo: 이미 논의한 주제 목록
deactivate DB

TranscriptRepo --> Service: discussedTopics
deactivate TranscriptRepo

== LLM 기반 논의사항 제안 생성 ==

Service -> Service: 제안 프롬프트 생성
note right
  시스템 프롬프트:
  - 역할: 회의 퍼실리테이터
  - 목표: 회의 안건 대비 빠진 논의 찾기

  사용자 프롬프트:
  - 회의 안건: {agenda}
  - 이미 논의한 주제: {discussedTopics}
  - 현재 대화 내용: {transcriptText}
  - 참석자 정보: {participants}

  지시사항:
  - 안건에 있지만 아직 안 다룬 항목 찾기
  - 대화 흐름상 빠진 중요 논의 식별
  - 추가하면 좋을 주제 제안
  - 우선순위 부여

  응답 형식:
  {
    "suggestions": [
      {
        "topic": "논의 주제",
        "reason": "제안 이유",
        "priority": "HIGH|MEDIUM|LOW",
        "relatedAgenda": "관련 안건 항목",
        "estimatedTime": 분 단위 예상 시간
      }
    ]
  }
end note

Service -> LLM: generateDiscussionSuggestions(prompt)
activate LLM

LLM -> OpenAI: POST /chat/completions
activate OpenAI
note right
  요청 파라미터:
  - model: gpt-4o
  - temperature: 0.4
  - response_format: json_object
  - max_tokens: 1500
end note

OpenAI -> OpenAI: 회의 맥락 분석
note right
  분석 단계:
  1. 안건 항목별 진행 상황 체크
  2. 이미 논의한 주제와 비교
  3. 현재 대화 맥락 이해
  4. 빠진 중요 논의 식별
  5. 추가 제안 생성
  6. 우선순위 결정
     - HIGH: 안건 필수 항목
     - MEDIUM: 중요하지만 선택적
     - LOW: 추가 고려사항
end note

OpenAI --> LLM: 논의사항 제안 목록 (JSON)
deactivate OpenAI

LLM --> Service: discussionSuggestions
deactivate LLM

== 제안 검증 및 필터링 ==

Service -> Service: 제안 품질 검증
note right
  검증 기준:
  - 중복 제거 (이미 논의한 주제)
  - 관련성 검증 (회의 목적과 부합)
  - 우선순위별 정렬
  - 최대 5개까지만 선택
    (너무 많으면 오히려 방해)
end note

loop 각 제안마다

    Service -> Service: 제안 메타데이터 보강
    note right
      추가 정보:
      - 생성 시각
      - 제안 신뢰도 점수
      - 회의 진행 시점 (분)
      - 고유 ID (UUID)
    end note

end

== 임시 캐시 저장 (선택적) ==

Service -> Cache: SET suggestions:discussion:{meetingId}
activate Cache
note right
  Redis에 임시 저장:
  - Key: suggestions:discussion:{meetingId}
  - Value: JSON array (제안 목록)
  - TTL: 2시간 (회의 시간)

  목적:
  - 재접속 시 복원용
  - WebSocket 재연결 대응
end note

Cache --> Service: 저장 완료
deactivate Cache

== 응답 반환 ==

Service -> Service: 응답 데이터 구성
note right
  프론트엔드 전달 형식:
  {
    "suggestions": [
      {
        "id": "suggestion-uuid",
        "topic": "논의 주제",
        "reason": "제안 이유",
        "priority": "HIGH",
        "relatedAgenda": "관련 안건",
        "estimatedTime": 10
      }
    ],
    "totalCount": 제안 개수,
    "timestamp": "생성 시각"
  }
end note

Service --> Controller: 논의사항 제안 목록
deactivate Service

Controller --> Controller: 이벤트 데이터에 포함하여 반환
note right
  TranscriptSummaryCreated 이벤트에
  discussionSuggestions 필드로 포함

  프론트엔드 처리:
  - 오른쪽 "추천" 탭에 표시
  - "적용" 버튼 활성화
  - 우선순위별 색상 표시
    * HIGH: 빨강
    * MEDIUM: 주황
    * LOW: 초록
end note

== 사용자가 제안 적용 시 ==

note over Controller
  사용자가 "적용" 버튼 클릭 시:
  프론트엔드에서 직접 Meeting Service 호출

  PUT /api/meetings/{meetingId}/transcript
  Body: {
    "addDiscussionSection": {
      "topic": "논의 주제",
      "content": ""
    }
  }

  Meeting Service에서 회의록에
  새로운 논의 섹션 추가
end note

note over Controller, DB
처리 시간:
- 맥락 정보 조회: 100-200ms
- LLM 제안 생성: 2-3초
- 검증 및 필터링: 100-200ms
- 캐시 저장: 50-100ms
총 처리 시간: 약 2.5-3.5초

특징:
- DB 영구 저장 없음 (임시 데이터)
- Redis 캐시만 활용 (재접속 복원용)
- 프론트엔드 메모리에서 관리
- "적용" 시에만 회의록에 반영
end note

@enduml
