mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 19:36:23 +00:00
주요 변경사항:
[Critical]
- API 엔드포인트 통일: POST /api/minutes/{minutesId}/finalize
- 이벤트 이름 표준화: MinutesFinalized
[Warning]
- API Gateway 라우팅 규칙 문서화 (외부 시퀀스 7개 파일)
- 대시보드 API 경로 통일: GET /api/dashboard
- AI 제안 병합 프로세스 상세 문서화
- 회의록 확정 검증 로직 5단계 상세화
[Minor]
- Redis 캐시 TTL 명시 (7개 파일, TTL 정책 표준화)
- 대시보드 페이지네이션 파라미터 추가
- 에러 응답 포맷 표준화 (14개 에러 응답)
총 31개 파일 수정, 34건의 개선 사항 적용
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
232 lines
5.4 KiB
Plaintext
232 lines
5.4 KiB
Plaintext
@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
|