@startuml
!theme mono

title AI Service 내부 시퀀스 - 결정사항제안

participant "SuggestionController" as Controller
participant "DecisionSuggestionService" 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: suggestDecisions(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 -> Cache: GET decisions:{meetingId}
activate Cache
note right
  이전에 감지한 결정사항 조회
  (중복 제거용)
end note

Cache --> Service: previousDecisions
deactivate Cache

== LLM 기반 결정사항 패턴 감지 ==

Service -> Service: 결정사항 감지 프롬프트 생성
note right
  시스템 프롬프트:
  - 역할: 결정사항 추출 전문가
  - 목표: 대화에서 결정 패턴 감지

  결정 패턴 예시:
  - "~하기로 했습니다"
  - "~로 결정했습니다"
  - "~하는 것으로 합의했습니다"
  - "~로 진행하겠습니다"
  - "~은 이렇게 처리하겠습니다"

  사용자 프롬프트:
  - 회의 참석자: {participants}
  - 이미 감지한 결정: {previousDecisions}
  - 현재 대화 내용: {transcriptText}

  지시사항:
  - 위 패턴이 포함된 문장 찾기
  - 결정 내용 구조화
  - 결정자/참여자 식별
  - 결정 카테고리 분류
  - 신뢰도 점수 계산

  응답 형식:
  {
    "decisions": [
      {
        "content": "결정 내용",
        "category": "기술|일정|리소스|정책|기타",
        "decisionMaker": "결정자 이름",
        "participants": ["참여자1", "참여자2"],
        "confidence": 0.0-1.0,
        "extractedFrom": "원문 발췌",
        "context": "결정 배경"
      }
    ]
  }
end note

Service -> LLM: detectDecisionPatterns(prompt)
activate LLM

LLM -> OpenAI: POST /chat/completions
activate OpenAI
note right
  요청 파라미터:
  - model: gpt-4o
  - temperature: 0.2
    (정확한 패턴 감지 위해 낮은 값)
  - response_format: json_object
  - max_tokens: 1500
end note

OpenAI -> OpenAI: 대화 텍스트 분석
note right
  처리 단계:
  1. 문장별로 결정 패턴 검사
  2. "하기로 함" 등 키워드 탐지
  3. 결정 내용 추출 및 정리
  4. 발언자 식별 (누가 결정했나)
  5. 결정 맥락 파악
  6. 신뢰도 계산
     - 명확한 결정 표현: 0.9-1.0
     - 암묵적 합의: 0.7-0.9
     - 추정: 0.5-0.7
  7. 카테고리 분류
     - 기술: 기술 스택, 아키텍처
     - 일정: 마감일, 일정 조정
     - 리소스: 인력, 예산
     - 정책: 프로세스, 규칙
end note

OpenAI --> LLM: 결정사항 제안 목록 (JSON)
deactivate OpenAI

LLM --> Service: decisionSuggestions
deactivate LLM

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

Service -> Service: 결정사항 검증
note right
  검증 기준:
  - 신뢰도 70% 이상만 선택
  - 중복 제거 (이미 감지한 결정)
  - 명확성 검증
    * 주어, 목적어가 명확한가?
    * 결정 내용이 구체적인가?
  - 카테고리별 정렬
  - 신뢰도 높은 순 정렬
end note

loop 각 제안마다

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

end

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

Service -> Cache: APPEND decisions:{meetingId}
activate Cache
note right
  Redis에 임시 저장:
  - Key: decisions:{meetingId}
  - Value: JSON array (제안 목록)
  - TTL: 2시간 (회의 시간)
  - APPEND로 기존 목록에 추가

  목적:
  - 중복 감지용
  - 재접속 시 복원용
end note

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

== 응답 반환 ==

Service -> Service: 응답 데이터 구성
note right
  프론트엔드 전달 형식:
  {
    "suggestions": [
      {
        "id": "suggestion-uuid",
        "content": "결정 내용",
        "category": "기술",
        "decisionMaker": "김철수",
        "confidence": 0.85,
        "extractedFrom": "원문 발췌",
        "context": "결정 배경 설명"
      }
    ],
    "totalCount": 제안 개수,
    "timestamp": "생성 시각"
  }
end note

Service --> Controller: 결정사항 제안 목록
deactivate Service

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

  프론트엔드 처리:
  - 오른쪽 "추천" 탭의 "결정사항" 섹션 표시
  - "적용" 버튼 활성화
  - 신뢰도 표시 (%)
  - 카테고리별 아이콘 표시
  - 원문 보기 링크 제공
end note

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

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

  PUT /api/meetings/{meetingId}/transcript
  Body: {
    "addDecisionSection": {
      "content": "결정 내용",
      "category": "기술",
      "decisionMaker": "김철수"
    }
  }

  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
