mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 12:36:23 +00:00
- 외부 시퀀스 설계 가이드 다운로드 (claude/sequence-outer-design.md) - 외부 시퀀스 설계 디렉토리 생성 (design/backend/sequence/) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
195 lines
4.7 KiB
Plaintext
195 lines
4.7 KiB
Plaintext
@startuml 회의종료및Todo추출
|
|
!theme mono
|
|
|
|
title 회의 종료 및 Todo 추출 플로우 (UFR-MEET-040/050, UFR-AI-020, UFR-TODO-010)
|
|
|
|
actor "사용자" as User
|
|
participant "Frontend" as FE
|
|
participant "API Gateway" as GW
|
|
participant "Meeting Service" as MS
|
|
participant "AI Service" as AI
|
|
participant "Todo Service" as TS
|
|
participant "Notification Service" as NS
|
|
participant "Redis" as Cache
|
|
database "Meeting DB" as MDB
|
|
database "AI DB" as AIDB
|
|
database "Todo DB" as TODB
|
|
queue "RabbitMQ" as MQ
|
|
participant "LLM Server" as LLM
|
|
|
|
== 회의 종료 ==
|
|
User -> FE: 회의 종료 버튼 클릭
|
|
activate FE
|
|
|
|
FE -> GW: POST /api/meetings/{meetingId}/end
|
|
activate GW
|
|
|
|
GW -> MS: 회의 종료 요청
|
|
activate MS
|
|
|
|
MS -> MDB: UPDATE meetings\nSET end_time = NOW(), status = 'completed'\n통계 생성 (duration, 참석자 수, 발언 수)
|
|
activate MDB
|
|
MDB --> MS: 회의 종료 시간 기록 및 통계 생성 완료
|
|
deactivate MDB
|
|
|
|
MS ->> MQ: MeetingEnded 이벤트 발행\n{meetingId, sessionId, endTime, statistics}
|
|
activate MQ
|
|
note right of MQ
|
|
이벤트: MeetingEnded
|
|
Routing Key: meeting.ended
|
|
end note
|
|
MQ -->> MS: ACK
|
|
deactivate MQ
|
|
|
|
MS --> GW: 200 OK\n{status: "completed", statistics}
|
|
deactivate MS
|
|
|
|
GW --> FE: 회의 종료 확인
|
|
deactivate GW
|
|
|
|
FE --> User: 회의 종료 화면 표시
|
|
deactivate FE
|
|
|
|
== AI Todo 자동 추출 (비동기) ==
|
|
MQ ->> AI: MeetingEnded 이벤트 전달
|
|
activate AI
|
|
note right of AI
|
|
구독: meeting.ended
|
|
큐: ai.meeting.ended
|
|
end note
|
|
|
|
AI -> AIDB: SELECT transcript, summary\nFROM minutes_draft\nWHERE session_id = {sessionId}
|
|
activate AIDB
|
|
AIDB --> AI: 회의록 전체 내용 반환
|
|
deactivate AIDB
|
|
|
|
AI -> AI: 액션 아이템 식별\n(동사 패턴, 시간 표현, 담당자 언급)
|
|
AI -> LLM: Todo 추출 요청\n{transcript, context, attendees}
|
|
activate LLM
|
|
LLM --> AI: Todo 목록 반환\n{tasks: [{description, assignee, dueDate, priority, linkedSection}]}
|
|
deactivate LLM
|
|
|
|
AI -> AIDB: UPDATE minutes_draft\nSET todos_extracted = TRUE\n(Todo 추출 완료 표시)
|
|
activate AIDB
|
|
AIDB --> AI: OK
|
|
deactivate AIDB
|
|
|
|
AI ->> MQ: TodoExtracted 이벤트 발행\n{meetingId, todos: [{description, assignee, dueDate, priority, linkedSection}]}
|
|
activate MQ
|
|
note right of MQ
|
|
이벤트: TodoExtracted
|
|
Routing Key: todo.extracted
|
|
end note
|
|
MQ -->> AI: ACK
|
|
deactivate MQ
|
|
|
|
AI -->> MQ: ACK (MeetingEnded)
|
|
deactivate AI
|
|
|
|
== Todo 생성 및 할당 (비동기) ==
|
|
MQ ->> TS: TodoExtracted 이벤트 전달
|
|
activate TS
|
|
note right of TS
|
|
구독: todo.extracted
|
|
큐: todo.extracted
|
|
end note
|
|
|
|
loop 각 Todo
|
|
TS -> TODB: INSERT INTO todos\n(Todo 생성, 담당자 할당, 회의록 섹션 링크)
|
|
activate TODB
|
|
TODB --> TS: Todo ID 반환
|
|
deactivate TODB
|
|
|
|
TS -> Cache: SET todo:list:{userId}\n(사용자별 Todo 목록 캐싱, TTL: 5분)
|
|
activate Cache
|
|
Cache --> TS: OK
|
|
deactivate Cache
|
|
|
|
TS ->> MQ: TodoCreated 이벤트 발행\n{todoId, assignee, description, dueDate, linkedSection}
|
|
activate MQ
|
|
note right of MQ
|
|
이벤트: TodoCreated
|
|
Routing Key: todo.created
|
|
end note
|
|
MQ -->> TS: ACK
|
|
deactivate MQ
|
|
end
|
|
|
|
TS -->> MQ: ACK (TodoExtracted)
|
|
deactivate TS
|
|
|
|
== Todo 할당 알림 (비동기) ==
|
|
MQ ->> NS: TodoCreated 이벤트 전달
|
|
activate NS
|
|
note right of NS
|
|
구독: todo.created
|
|
큐: notification.todo.created
|
|
end note
|
|
|
|
NS -> NS: 알림 템플릿 생성\n(Todo 설명, 기한, 회의록 링크)
|
|
NS -> NS: 담당자에게 알림 발송\n(이메일, 푸시 알림)
|
|
|
|
NS -->> MQ: ACK
|
|
deactivate NS
|
|
|
|
== 회의 통계 및 Todo 목록 조회 ==
|
|
User -> FE: 회의 상세 화면 조회
|
|
activate FE
|
|
|
|
FE -> GW: GET /api/meetings/{meetingId}/summary
|
|
activate GW
|
|
|
|
GW -> MS: 회의 통계 및 Todo 목록 조회
|
|
activate MS
|
|
|
|
MS -> Cache: GET meeting:info:{meetingId}
|
|
activate Cache
|
|
|
|
alt Cache Hit
|
|
Cache --> MS: 회의 정보 반환
|
|
else Cache Miss
|
|
Cache --> MS: null
|
|
MS -> MDB: SELECT * FROM meetings\nWHERE meeting_id = {meetingId}
|
|
activate MDB
|
|
MDB --> MS: 회의 정보 반환
|
|
deactivate MDB
|
|
|
|
MS -> Cache: SET meeting:info:{meetingId}\n(TTL: 10분)
|
|
Cache --> MS: OK
|
|
end
|
|
deactivate Cache
|
|
|
|
MS -> TS: GET /api/todos?meetingId={meetingId}
|
|
activate TS
|
|
|
|
TS -> Cache: GET todo:list:meeting:{meetingId}
|
|
activate Cache
|
|
|
|
alt Cache Hit
|
|
Cache --> TS: Todo 목록 반환
|
|
else Cache Miss
|
|
Cache --> TS: null
|
|
TS -> TODB: SELECT * FROM todos\nWHERE meeting_id = {meetingId}
|
|
activate TODB
|
|
TODB --> TS: Todo 목록 반환
|
|
deactivate TODB
|
|
|
|
TS -> Cache: SET todo:list:meeting:{meetingId}\n(TTL: 5분)
|
|
Cache --> TS: OK
|
|
end
|
|
deactivate Cache
|
|
|
|
TS --> MS: Todo 목록 반환
|
|
deactivate TS
|
|
|
|
MS --> GW: 회의 통계 및 Todo 목록 반환\n{statistics, todos}
|
|
deactivate MS
|
|
|
|
GW --> FE: 200 OK
|
|
deactivate GW
|
|
|
|
FE --> User: 회의 통계 및 Todo 목록 표시
|
|
deactivate FE
|
|
|
|
@enduml
|