mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 13:46:24 +00:00
외부 시퀀스 설계 파일 정리 및 유저스토리 업데이트
- 기존 외부 시퀀스 설계 파일 삭제 - 유저스토리 수정 - 샘플 외부 시퀀스 파일 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
bb921e10eb
commit
3405d233ee
126
claude/sample-external-sequence.puml
Normal file
126
claude/sample-external-sequence.puml
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
@startuml 로그인플로우
|
||||||
|
!theme mono
|
||||||
|
|
||||||
|
title 로그인 플로우 - 외부 시퀀스 다이어그램
|
||||||
|
|
||||||
|
actor "Mobile Client" as Client
|
||||||
|
participant "API Gateway" as Gateway
|
||||||
|
participant "User Service" as UserService
|
||||||
|
database "Redis Cache" as Redis
|
||||||
|
|
||||||
|
== 로그인 화면 접근 ==
|
||||||
|
Client -> Gateway: GET /login-page
|
||||||
|
activate Gateway
|
||||||
|
Gateway -> Client: 200 OK (로그인 화면)
|
||||||
|
deactivate Gateway
|
||||||
|
|
||||||
|
== 로그인 처리 ==
|
||||||
|
Client -> Gateway: POST /api/v1/users/auth/login\n{userId, password}
|
||||||
|
activate Gateway
|
||||||
|
|
||||||
|
Gateway -> UserService: 로그인 요청 전달
|
||||||
|
activate UserService
|
||||||
|
|
||||||
|
UserService -> UserService: 사용자 인증 처리\n(비밀번호 검증)
|
||||||
|
|
||||||
|
alt 인증 성공
|
||||||
|
UserService -> UserService: JWT 토큰 생성
|
||||||
|
UserService -> Redis: 세션 정보 저장\n(userId, token, TTL)
|
||||||
|
activate Redis
|
||||||
|
Redis -> UserService: 저장 완료
|
||||||
|
deactivate Redis
|
||||||
|
|
||||||
|
UserService -> Gateway: 200 OK\n{token, userId, profile}
|
||||||
|
Gateway -> Client: 로그인 성공\n{token, profile}
|
||||||
|
|
||||||
|
Client -> Client: 토큰 저장\n(localStorage)
|
||||||
|
Client -> Client: 대시보드로 이동
|
||||||
|
|
||||||
|
else 인증 실패
|
||||||
|
UserService -> Gateway: 401 Unauthorized\n{error: "아이디 또는 비밀번호를 확인해주세요"}
|
||||||
|
Gateway -> Client: 로그인 실패 메시지
|
||||||
|
|
||||||
|
alt 5회 연속 실패
|
||||||
|
UserService -> Redis: 계정 잠금 정보 저장\n(userId, lockTime: 30분)
|
||||||
|
UserService -> Gateway: 423 Locked\n{error: "30분간 계정 잠금"}
|
||||||
|
Gateway -> Client: 계정 잠금 안내
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
deactivate UserService
|
||||||
|
deactivate Gateway
|
||||||
|
|
||||||
|
== 로그인 상태 확인 ==
|
||||||
|
Client -> Gateway: GET /api/v1/users/profile\n(Authorization: Bearer {token})
|
||||||
|
activate Gateway
|
||||||
|
|
||||||
|
Gateway -> Gateway: JWT 토큰 검증
|
||||||
|
|
||||||
|
alt 토큰 유효
|
||||||
|
Gateway -> Redis: 세션 조회\n(userId)
|
||||||
|
activate Redis
|
||||||
|
Redis -> Gateway: 세션 정보 반환
|
||||||
|
deactivate Redis
|
||||||
|
|
||||||
|
Gateway -> UserService: 프로필 조회
|
||||||
|
activate UserService
|
||||||
|
UserService -> Gateway: 사용자 프로필 반환
|
||||||
|
deactivate UserService
|
||||||
|
|
||||||
|
Gateway -> Client: 200 OK\n{userId, name, email, avatar}
|
||||||
|
Client -> Client: 프로필 표시\n(헤더 아바타)
|
||||||
|
else 토큰 무효
|
||||||
|
Gateway -> Client: 401 Unauthorized
|
||||||
|
Client -> Client: 로그인 화면으로 이동
|
||||||
|
end
|
||||||
|
|
||||||
|
deactivate Gateway
|
||||||
|
|
||||||
|
== 로그아웃 처리 ==
|
||||||
|
Client -> Client: 로그아웃 확인 다이얼로그 표시
|
||||||
|
Client -> Gateway: POST /api/v1/users/auth/logout\n(Authorization: Bearer {token})
|
||||||
|
activate Gateway
|
||||||
|
|
||||||
|
Gateway -> UserService: 로그아웃 요청
|
||||||
|
activate UserService
|
||||||
|
|
||||||
|
UserService -> Redis: 세션 삭제\n(userId)
|
||||||
|
activate Redis
|
||||||
|
Redis -> UserService: 삭제 완료
|
||||||
|
deactivate Redis
|
||||||
|
|
||||||
|
UserService -> Gateway: 200 OK\n{message: "안전하게 로그아웃되었습니다"}
|
||||||
|
deactivate UserService
|
||||||
|
|
||||||
|
Gateway -> Client: 로그아웃 완료
|
||||||
|
deactivate Gateway
|
||||||
|
|
||||||
|
Client -> Client: 토큰 삭제\n(localStorage)
|
||||||
|
Client -> Client: 로그인 화면으로 이동
|
||||||
|
|
||||||
|
note right of Client
|
||||||
|
대시보드(01) 화면의 헤더에서
|
||||||
|
프로필 아바타를 클릭하면
|
||||||
|
드롭다운 메뉴가 표시됨:
|
||||||
|
- 내 정보 보기
|
||||||
|
- 프로필 편집
|
||||||
|
- 로그아웃
|
||||||
|
end note
|
||||||
|
|
||||||
|
note right of UserService
|
||||||
|
로그인 시 검증 사항:
|
||||||
|
- 아이디/비밀번호 확인
|
||||||
|
- 계정 잠금 상태 확인
|
||||||
|
- 연속 실패 횟수 체크
|
||||||
|
- JWT 토큰 생성 및 발급
|
||||||
|
end note
|
||||||
|
|
||||||
|
note right of Redis
|
||||||
|
캐시 저장 정보:
|
||||||
|
- 세션 정보 (토큰, 사용자ID)
|
||||||
|
- 로그인 실패 횟수
|
||||||
|
- 계정 잠금 상태
|
||||||
|
- TTL 기반 자동 만료
|
||||||
|
end note
|
||||||
|
|
||||||
|
@enduml
|
||||||
@ -1,164 +0,0 @@
|
|||||||
@startuml 01-사용자인증및대시보드조회
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title 사용자 인증 및 대시보드 조회 (User Authentication and Dashboard)
|
|
||||||
|
|
||||||
actor "사용자" as User
|
|
||||||
participant "Web App" as WebApp
|
|
||||||
participant "API Gateway" as Gateway
|
|
||||||
participant "User Service" as UserService
|
|
||||||
participant "Meeting Service" as MeetingService
|
|
||||||
participant "Todo Service" as TodoService
|
|
||||||
participant "Redis\n(Cache)" as Redis
|
|
||||||
database "User DB\n(PostgreSQL)" as UserDB
|
|
||||||
database "Meeting DB\n(PostgreSQL)" as MeetingDB
|
|
||||||
database "Todo DB\n(PostgreSQL)" as TodoDB
|
|
||||||
|
|
||||||
== 1. 사용자 인증 (User Authentication) ==
|
|
||||||
|
|
||||||
User -> WebApp: 1.1. 로그인 시도\n(사번, 비밀번호 입력)
|
|
||||||
activate WebApp
|
|
||||||
|
|
||||||
WebApp -> Gateway: 1.2. POST /api/auth/login\n{employeeId, password}
|
|
||||||
activate Gateway
|
|
||||||
|
|
||||||
Gateway -> UserService: 1.3. 인증 요청\nPOST /auth/login
|
|
||||||
activate UserService
|
|
||||||
|
|
||||||
UserService -> UserService: 1.4. LDAP 연동 인증\n(사번, 비밀번호 검증)
|
|
||||||
note right
|
|
||||||
LDAP 서버와 통신하여
|
|
||||||
사용자 인증 처리
|
|
||||||
end note
|
|
||||||
|
|
||||||
alt 인증 성공
|
|
||||||
UserService -> UserDB: 1.5. 사용자 정보 조회\nSELECT * FROM users WHERE employee_id = ?
|
|
||||||
activate UserDB
|
|
||||||
UserDB --> UserService: 사용자 정보 반환
|
|
||||||
deactivate UserDB
|
|
||||||
|
|
||||||
UserService -> UserService: 1.6. JWT 토큰 생성\n(userId, 권한 정보 포함)
|
|
||||||
|
|
||||||
UserService -> Redis: 1.7. 사용자 프로필 캐싱\nSET user:profile:{userId}\n(TTL: 30분)
|
|
||||||
activate Redis
|
|
||||||
Redis --> UserService: 캐싱 완료
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
UserService --> Gateway: 1.8. 인증 성공 응답\n{token, userId, userName}
|
|
||||||
deactivate UserService
|
|
||||||
|
|
||||||
Gateway --> WebApp: 1.9. 로그인 성공\n{token, userId, userName}
|
|
||||||
deactivate Gateway
|
|
||||||
|
|
||||||
WebApp -> WebApp: 1.10. JWT 토큰 저장\n(LocalStorage)
|
|
||||||
|
|
||||||
WebApp --> User: 1.11. 로그인 성공 메시지
|
|
||||||
|
|
||||||
else 인증 실패
|
|
||||||
UserService --> Gateway: 인증 실패 (401 Unauthorized)
|
|
||||||
Gateway --> WebApp: 인증 실패
|
|
||||||
WebApp --> User: 로그인 실패 메시지
|
|
||||||
end
|
|
||||||
|
|
||||||
== 2. 대시보드 데이터 조회 (Dashboard Data Loading) ==
|
|
||||||
|
|
||||||
WebApp -> Gateway: 2.1. GET /api/dashboard\n(Authorization: Bearer {token})
|
|
||||||
activate Gateway
|
|
||||||
|
|
||||||
Gateway -> Gateway: 2.2. JWT 토큰 검증
|
|
||||||
note right
|
|
||||||
토큰 유효성 검증
|
|
||||||
사용자 권한 확인
|
|
||||||
end note
|
|
||||||
|
|
||||||
Gateway -> MeetingService: 2.3. 예정된 회의 조회\nGET /meetings/upcoming?userId={userId}
|
|
||||||
activate MeetingService
|
|
||||||
|
|
||||||
MeetingService -> Redis: 2.4. 캐시 확인\nGET meeting:upcoming:{userId}
|
|
||||||
activate Redis
|
|
||||||
Redis --> MeetingService: Cache Miss (캐시 없음)
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
MeetingService -> MeetingDB: 2.5. 예정된 회의 조회\nSELECT * FROM meetings\nWHERE user_id = ? AND status = 'SCHEDULED'\nORDER BY meeting_date LIMIT 5
|
|
||||||
activate MeetingDB
|
|
||||||
MeetingDB --> MeetingService: 예정된 회의 목록 (최대 5개)
|
|
||||||
deactivate MeetingDB
|
|
||||||
|
|
||||||
MeetingService -> Redis: 2.6. 조회 결과 캐싱\nSET meeting:upcoming:{userId}\n(TTL: 10분)
|
|
||||||
activate Redis
|
|
||||||
Redis --> MeetingService: 캐싱 완료
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
MeetingService --> Gateway: 2.7. 예정된 회의 목록 반환
|
|
||||||
deactivate MeetingService
|
|
||||||
|
|
||||||
|||
|
|
||||||
|
|
||||||
Gateway -> TodoService: 2.8. 진행 중 Todo 조회\nGET /todos/in-progress?userId={userId}
|
|
||||||
activate TodoService
|
|
||||||
|
|
||||||
TodoService -> Redis: 2.9. 캐시 확인\nGET todo:user:{userId}
|
|
||||||
activate Redis
|
|
||||||
Redis --> TodoService: Cache Hit (캐시 존재)
|
|
||||||
note right
|
|
||||||
Cache-Aside 패턴:
|
|
||||||
캐시에서 직접 반환하여
|
|
||||||
DB 부하 감소
|
|
||||||
end note
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
TodoService --> Gateway: 2.10. 진행 중 Todo 목록 반환\n(캐시에서 조회)
|
|
||||||
deactivate TodoService
|
|
||||||
|
|
||||||
|||
|
|
||||||
|
|
||||||
Gateway -> MeetingService: 2.11. 최근 회의록 조회\nGET /transcripts/recent?userId={userId}
|
|
||||||
activate MeetingService
|
|
||||||
|
|
||||||
MeetingService -> Redis: 2.12. 캐시 확인\nGET transcript:recent:{userId}
|
|
||||||
activate Redis
|
|
||||||
Redis --> MeetingService: Cache Miss
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
MeetingService -> MeetingDB: 2.13. 최근 회의록 조회\nSELECT * FROM transcripts\nWHERE user_id = ? OR shared_with LIKE '%{userId}%'\nORDER BY created_at DESC LIMIT 6
|
|
||||||
activate MeetingDB
|
|
||||||
MeetingDB --> MeetingService: 최근 회의록 목록\n(내 회의록 3개 + 공유받은 회의록 3개)
|
|
||||||
deactivate MeetingDB
|
|
||||||
|
|
||||||
MeetingService -> Redis: 2.14. 조회 결과 캐싱\nSET transcript:recent:{userId}\n(TTL: 10분)
|
|
||||||
activate Redis
|
|
||||||
Redis --> MeetingService: 캐싱 완료
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
MeetingService --> Gateway: 2.15. 최근 회의록 목록 반환
|
|
||||||
deactivate MeetingService
|
|
||||||
|
|
||||||
|||
|
|
||||||
|
|
||||||
Gateway -> TodoService: 2.16. Todo 통계 조회\nGET /todos/stats?userId={userId}
|
|
||||||
activate TodoService
|
|
||||||
|
|
||||||
TodoService -> Redis: 2.17. 캐시 확인\nGET todo:stats:{userId}
|
|
||||||
activate Redis
|
|
||||||
Redis --> TodoService: Cache Hit
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
TodoService --> Gateway: 2.18. Todo 통계 반환\n{total, inProgress, completionRate}
|
|
||||||
deactivate TodoService
|
|
||||||
|
|
||||||
|||
|
|
||||||
|
|
||||||
Gateway --> WebApp: 2.19. 대시보드 데이터 통합 응답\n{\n upcomingMeetings: [...],\n inProgressTodos: [...],\n recentTranscripts: [...],\n todoStats: {...}\n}
|
|
||||||
deactivate Gateway
|
|
||||||
|
|
||||||
WebApp -> WebApp: 2.20. 대시보드 UI 렌더링\n- 통계 카드 표시\n- 예정된 회의 목록\n- 진행 중 Todo 목록\n- 최근 회의록 목록
|
|
||||||
note right
|
|
||||||
반응형 레이아웃:
|
|
||||||
- 데스크톱: 좌측 사이드바
|
|
||||||
- 모바일: 하단 탭 바
|
|
||||||
end note
|
|
||||||
|
|
||||||
WebApp --> User: 2.21. 대시보드 화면 표시\n(맞춤형 정보 제공)
|
|
||||||
deactivate WebApp
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,186 +0,0 @@
|
|||||||
@startuml 02-회의예약및초대
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title 회의 예약 및 초대 (Meeting Reservation and Invitation)
|
|
||||||
|
|
||||||
actor "사용자\n(회의록 작성자)" as User
|
|
||||||
participant "Web App" as WebApp
|
|
||||||
participant "API Gateway" as Gateway
|
|
||||||
participant "Meeting Service" as MeetingService
|
|
||||||
participant "User Service" as UserService
|
|
||||||
participant "Notification Service" as NotificationService
|
|
||||||
participant "RabbitMQ\n(Message Broker)" as RabbitMQ
|
|
||||||
participant "Redis\n(Cache)" as Redis
|
|
||||||
database "Meeting DB\n(PostgreSQL)" as MeetingDB
|
|
||||||
database "User DB\n(PostgreSQL)" as UserDB
|
|
||||||
database "Notification DB\n(PostgreSQL)" as NotificationDB
|
|
||||||
|
|
||||||
== 1. 회의 예약 (Meeting Reservation) ==
|
|
||||||
|
|
||||||
User -> WebApp: 1.1. 회의 예약 화면 접근\n(플로팅 액션 버튼 → 📅 회의 예약)
|
|
||||||
activate WebApp
|
|
||||||
|
|
||||||
WebApp --> User: 1.2. 회의 예약 폼 표시\n(제목, 날짜/시간, 장소, 참석자)
|
|
||||||
note right
|
|
||||||
입력 필드:
|
|
||||||
- 회의 제목 (최대 100자, 필수)
|
|
||||||
- 날짜/시간 (필수)
|
|
||||||
- 장소 (최대 200자, 선택)
|
|
||||||
- 참석자 목록 (이메일, 최소 1명 필수)
|
|
||||||
end note
|
|
||||||
|
|
||||||
User -> WebApp: 1.3. 회의 정보 입력 완료\n- 제목: "프로젝트 킥오프 회의"\n- 날짜: 2025-02-01 14:00\n- 장소: "회의실 A"\n- 참석자: ["user1@company.com", "user2@company.com"]
|
|
||||||
|
|
||||||
WebApp -> WebApp: 1.4. 입력 유효성 검증\n- 필수 필드 확인\n- 날짜/시간 형식 검증\n- 이메일 형식 검증
|
|
||||||
|
|
||||||
WebApp -> Gateway: 1.5. POST /api/meetings\n{\n title: "프로젝트 킥오프 회의",\n dateTime: "2025-02-01T14:00:00",\n location: "회의실 A",\n participants: ["user1@company.com", "user2@company.com"]\n}\n(Authorization: Bearer {token})
|
|
||||||
activate Gateway
|
|
||||||
|
|
||||||
Gateway -> Gateway: 1.6. JWT 토큰 검증\n- 사용자 인증 확인\n- 회의 생성 권한 확인
|
|
||||||
|
|
||||||
Gateway -> MeetingService: 1.7. 회의 생성 요청\nPOST /meetings
|
|
||||||
activate MeetingService
|
|
||||||
|
|
||||||
MeetingService -> MeetingService: 1.8. 회의 데이터 생성\n- 회의 ID 생성 (UUID)\n- 생성 시간 기록\n- 상태: SCHEDULED
|
|
||||||
|
|
||||||
MeetingService -> MeetingDB: 1.9. 회의 정보 저장\nINSERT INTO meetings\n(id, title, date_time, location, creator_id, status, created_at)\nVALUES (?, ?, ?, ?, ?, 'SCHEDULED', NOW())
|
|
||||||
activate MeetingDB
|
|
||||||
MeetingDB --> MeetingService: 회의 생성 완료
|
|
||||||
deactivate MeetingDB
|
|
||||||
|
|
||||||
MeetingService -> MeetingDB: 1.10. 참석자 정보 저장\nINSERT INTO meeting_participants\n(meeting_id, user_email, role)\nVALUES (?, ?, 'PARTICIPANT')
|
|
||||||
activate MeetingDB
|
|
||||||
MeetingDB --> MeetingService: 참석자 저장 완료
|
|
||||||
deactivate MeetingDB
|
|
||||||
|
|
||||||
MeetingService -> Redis: 1.11. 회의 정보 캐싱\nSET meeting:info:{meetingId}\n{\n title, dateTime, location,\n participants, status\n}\n(TTL: 10분)
|
|
||||||
activate Redis
|
|
||||||
Redis --> MeetingService: 캐싱 완료
|
|
||||||
note right
|
|
||||||
Cache-Aside 패턴:
|
|
||||||
생성 즉시 캐싱하여
|
|
||||||
후속 조회 성능 향상
|
|
||||||
end note
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
== 2. 이벤트 발행 (Event Publishing) ==
|
|
||||||
|
|
||||||
MeetingService -> RabbitMQ: 1.12. MeetingCreated 이벤트 발행\n- Exchange: meeting.events\n- Routing Key: meeting.created\n- Payload: {\n meetingId,\n title,\n dateTime,\n location,\n creatorId,\n participants: [user1@company.com, user2@company.com]\n }
|
|
||||||
activate RabbitMQ
|
|
||||||
note right
|
|
||||||
Publisher-Subscriber 패턴:
|
|
||||||
이벤트 기반 느슨한 결합
|
|
||||||
end note
|
|
||||||
|
|
||||||
RabbitMQ --> MeetingService: 1.13. 이벤트 발행 성공
|
|
||||||
deactivate RabbitMQ
|
|
||||||
|
|
||||||
MeetingService --> Gateway: 1.14. 회의 생성 응답\n{\n meetingId,\n title,\n dateTime,\n location,\n status: "SCHEDULED",\n createdAt\n}
|
|
||||||
deactivate MeetingService
|
|
||||||
|
|
||||||
Gateway --> WebApp: 1.15. 회의 예약 성공 응답
|
|
||||||
deactivate Gateway
|
|
||||||
|
|
||||||
WebApp --> User: 1.16. 예약 완료 메시지 표시\n"회의가 성공적으로 예약되었습니다."
|
|
||||||
deactivate WebApp
|
|
||||||
|
|
||||||
== 3. 초대 알림 발송 (Invitation Notification) ==
|
|
||||||
|
|
||||||
RabbitMQ -> NotificationService: 2.1. MeetingCreated 이벤트 수신\n- Queue: notification.meeting.queue
|
|
||||||
activate NotificationService
|
|
||||||
activate RabbitMQ
|
|
||||||
|
|
||||||
NotificationService -> NotificationService: 2.2. 이벤트 처리\n- 참석자 목록 추출\n- 알림 템플릿 로딩
|
|
||||||
|
|
||||||
NotificationService -> UserService: 2.3. 참석자 정보 조회\nGET /users/by-emails?emails=user1@company.com,user2@company.com
|
|
||||||
activate UserService
|
|
||||||
|
|
||||||
UserService -> Redis: 2.4. 캐시 확인\nMGET user:profile:user1, user:profile:user2
|
|
||||||
activate Redis
|
|
||||||
Redis --> UserService: Cache Hit (일부 캐시 존재)
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
UserService -> UserDB: 2.5. 캐시 미스 사용자 DB 조회\nSELECT * FROM users\nWHERE email IN (?, ?)
|
|
||||||
activate UserDB
|
|
||||||
UserDB --> UserService: 사용자 정보 반환
|
|
||||||
deactivate UserDB
|
|
||||||
|
|
||||||
UserService -> Redis: 2.6. 조회 결과 캐싱\nSET user:profile:{userId}\n(TTL: 30분)
|
|
||||||
activate Redis
|
|
||||||
Redis --> UserService: 캐싱 완료
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
UserService --> NotificationService: 2.7. 참석자 정보 반환\n[{userId, name, email}, ...]
|
|
||||||
deactivate UserService
|
|
||||||
|
|
||||||
NotificationService -> NotificationService: 2.8. 알림 메시지 생성\n- 제목: "[회의 초대] 프로젝트 킥오프 회의"\n- 내용: "홍길동님께서 회의에 초대하셨습니다.\n 일시: 2025-02-01 14:00\n 장소: 회의실 A"
|
|
||||||
|
|
||||||
NotificationService -> NotificationDB: 2.9. 알림 기록 저장\nINSERT INTO notifications\n(meeting_id, recipient_email, type, content, status, created_at)\nVALUES (?, ?, 'MEETING_INVITATION', ?, 'PENDING', NOW())
|
|
||||||
activate NotificationDB
|
|
||||||
NotificationDB --> NotificationService: 알림 기록 저장 완료
|
|
||||||
deactivate NotificationDB
|
|
||||||
|
|
||||||
loop 각 참석자에 대해
|
|
||||||
NotificationService -> NotificationService: 2.10. 이메일 발송\n- To: user1@company.com\n- Subject: [회의 초대] 프로젝트 킥오프 회의\n- Body: 회의 상세 정보 + 참여 링크
|
|
||||||
note right
|
|
||||||
Email/SMS Service 연동:
|
|
||||||
- SMTP 또는 SendGrid 사용
|
|
||||||
- 발송 실패 시 재시도 (최대 3회)
|
|
||||||
end note
|
|
||||||
|
|
||||||
NotificationService -> NotificationDB: 2.11. 알림 상태 업데이트\nUPDATE notifications\nSET status = 'SENT', sent_at = NOW()\nWHERE id = ?
|
|
||||||
activate NotificationDB
|
|
||||||
NotificationDB --> NotificationService: 업데이트 완료
|
|
||||||
deactivate NotificationDB
|
|
||||||
end
|
|
||||||
|
|
||||||
NotificationService --> RabbitMQ: 2.12. 이벤트 처리 완료 (ACK)
|
|
||||||
deactivate RabbitMQ
|
|
||||||
|
|
||||||
NotificationService -> NotificationService: 2.13. 리마인더 일정 생성\n- 회의 시작 30분 전 알림\n- 일정: 2025-02-01 13:30
|
|
||||||
note right
|
|
||||||
Queue-Based Load Leveling:
|
|
||||||
리마인더는 별도 큐로 관리
|
|
||||||
(reminder.queue)
|
|
||||||
end note
|
|
||||||
|
|
||||||
deactivate NotificationService
|
|
||||||
|
|
||||||
== 4. 결과 확인 (Result Confirmation) ==
|
|
||||||
|
|
||||||
User -> WebApp: 3.1. 대시보드 화면 새로고침
|
|
||||||
activate WebApp
|
|
||||||
|
|
||||||
WebApp -> Gateway: 3.2. GET /api/dashboard\n(Authorization: Bearer {token})
|
|
||||||
activate Gateway
|
|
||||||
|
|
||||||
Gateway -> MeetingService: 3.3. 예정된 회의 조회\nGET /meetings/upcoming?userId={userId}
|
|
||||||
activate MeetingService
|
|
||||||
|
|
||||||
MeetingService -> Redis: 3.4. 캐시 확인\nGET meeting:upcoming:{userId}
|
|
||||||
activate Redis
|
|
||||||
Redis --> MeetingService: Cache Miss (새로운 회의 추가로 캐시 무효화됨)
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
MeetingService -> MeetingDB: 3.5. 예정된 회의 조회\nSELECT * FROM meetings\nWHERE user_id = ? AND status = 'SCHEDULED'\nORDER BY meeting_date LIMIT 5
|
|
||||||
activate MeetingDB
|
|
||||||
MeetingDB --> MeetingService: 예정된 회의 목록\n(새로 생성한 회의 포함)
|
|
||||||
deactivate MeetingDB
|
|
||||||
|
|
||||||
MeetingService -> Redis: 3.6. 조회 결과 재캐싱\nSET meeting:upcoming:{userId}\n(TTL: 10분)
|
|
||||||
activate Redis
|
|
||||||
Redis --> MeetingService: 캐싱 완료
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
MeetingService --> Gateway: 3.7. 예정된 회의 목록 반환
|
|
||||||
deactivate MeetingService
|
|
||||||
|
|
||||||
Gateway --> WebApp: 3.8. 대시보드 데이터 반환
|
|
||||||
deactivate Gateway
|
|
||||||
|
|
||||||
WebApp -> WebApp: 3.9. 대시보드 UI 업데이트\n- 예정된 회의 개수 증가\n- 새 회의 목록에 표시
|
|
||||||
|
|
||||||
WebApp --> User: 3.10. 업데이트된 대시보드 표시\n(새로 예약한 회의 확인 가능)
|
|
||||||
deactivate WebApp
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
@startuml 회의시작및템플릿선택
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title 회의 시작 및 템플릿 선택 (Flow 3)
|
|
||||||
|
|
||||||
actor "사용자" as User
|
|
||||||
participant "Web App" as Web
|
|
||||||
participant "API Gateway" as Gateway
|
|
||||||
participant "Meeting Service" as Meeting
|
|
||||||
participant "STT Service" as STT
|
|
||||||
participant "RabbitMQ" as MQ
|
|
||||||
participant "Redis" as Cache
|
|
||||||
database "PostgreSQL" as DB
|
|
||||||
|
|
||||||
== 템플릿 선택 ==
|
|
||||||
User -> Web: 회의 템플릿 선택\n(일반/스크럼/킥오프/주간)
|
|
||||||
Web -> Gateway: GET /api/meetings/templates
|
|
||||||
Gateway -> Meeting: 템플릿 목록 조회
|
|
||||||
Meeting -> Cache: 템플릿 캐시 확인
|
|
||||||
alt 캐시 존재
|
|
||||||
Cache --> Meeting: 템플릿 목록 반환
|
|
||||||
else 캐시 미존재
|
|
||||||
Meeting -> DB: SELECT * FROM templates
|
|
||||||
DB --> Meeting: 템플릿 데이터
|
|
||||||
Meeting -> Cache: 템플릿 캐시 저장
|
|
||||||
end
|
|
||||||
Meeting --> Gateway: 템플릿 목록 응답
|
|
||||||
Gateway --> Web: 200 OK + 템플릿 목록
|
|
||||||
Web --> User: 템플릿 선택 UI 표시
|
|
||||||
|
|
||||||
== 회의 시작 ==
|
|
||||||
User -> Web: 회의 시작 버튼 클릭
|
|
||||||
Web -> Gateway: POST /api/meetings/{meetingId}/start\n+ templateId
|
|
||||||
Gateway -> Meeting: 회의 시작 요청
|
|
||||||
|
|
||||||
Meeting -> DB: BEGIN TRANSACTION
|
|
||||||
Meeting -> DB: UPDATE meetings\nSET status='ongoing',\nstarted_at=NOW()
|
|
||||||
DB --> Meeting: 업데이트 완료
|
|
||||||
|
|
||||||
Meeting -> DB: INSERT INTO meeting_sessions\n(meeting_id, template_id,\nsession_status='active')
|
|
||||||
DB --> Meeting: 세션 생성 완료
|
|
||||||
|
|
||||||
Meeting -> DB: INSERT INTO meeting_transcripts\n(session_id, template_id,\ncontent='{}')
|
|
||||||
DB --> Meeting: 회의록 초기화 완료
|
|
||||||
|
|
||||||
Meeting -> DB: COMMIT
|
|
||||||
Meeting -> Cache: 회의 상태 캐시 업데이트\n(status='ongoing')
|
|
||||||
|
|
||||||
== 이벤트 발행 ==
|
|
||||||
Meeting ->> MQ: Publish "MeetingStarted" Event\n{\n meetingId,\n sessionId,\n templateId,\n startedAt,\n participants\n}
|
|
||||||
note right
|
|
||||||
비동기 이벤트 발행
|
|
||||||
- Exchange: meeting.events
|
|
||||||
- Routing Key: meeting.started
|
|
||||||
end note
|
|
||||||
|
|
||||||
Meeting --> Gateway: 200 OK + sessionId
|
|
||||||
Gateway --> Web: 회의 시작 성공 응답
|
|
||||||
Web --> User: 회의 진행 화면 전환
|
|
||||||
|
|
||||||
== STT 서비스 시작 ==
|
|
||||||
MQ -->> STT: Consume "MeetingStarted" Event
|
|
||||||
STT -> STT: 오디오 녹음 세션 초기화
|
|
||||||
STT -> Cache: 녹음 세션 상태 저장\n(sessionId, status='recording')
|
|
||||||
STT -> STT: 마이크 활성화 및\n오디오 스트림 시작
|
|
||||||
|
|
||||||
note over STT
|
|
||||||
STT 서비스 준비 완료
|
|
||||||
- 5초 단위 음성 인식 시작
|
|
||||||
- 실시간 텍스트 변환 대기
|
|
||||||
end note
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,108 +0,0 @@
|
|||||||
@startuml 회의진행및실시간회의록작성
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title 회의 진행 및 실시간 회의록 작성 (Flow 4)
|
|
||||||
|
|
||||||
actor "참여자 A" as UserA
|
|
||||||
actor "참여자 B" as UserB
|
|
||||||
participant "Web App A\n(WebSocket)" as WebA
|
|
||||||
participant "Web App B\n(WebSocket)" as WebB
|
|
||||||
participant "STT Service" as STT
|
|
||||||
participant "AI Service" as AI
|
|
||||||
participant "Collaboration\nService" as Collab
|
|
||||||
participant "RabbitMQ" as MQ
|
|
||||||
participant "Redis" as Cache
|
|
||||||
database "PostgreSQL" as DB
|
|
||||||
|
|
||||||
== 실시간 음성 인식 (5초 단위) ==
|
|
||||||
loop 5초마다 반복
|
|
||||||
STT -> STT: 오디오 청크 수집\n(5초분)
|
|
||||||
STT -> STT: 음성-텍스트 변환\n(Speech-to-Text)
|
|
||||||
|
|
||||||
STT ->> MQ: Publish "TranscriptReady" Event\n{\n sessionId,\n timestamp,\n speaker: "참여자A",\n text: "변환된 텍스트",\n confidence: 0.95\n}
|
|
||||||
note right
|
|
||||||
비동기 이벤트 발행
|
|
||||||
- Exchange: transcript.events
|
|
||||||
- Routing Key: transcript.ready
|
|
||||||
end note
|
|
||||||
end
|
|
||||||
|
|
||||||
== AI 기반 회의록 자동 생성 ==
|
|
||||||
MQ -->> AI: Consume "TranscriptReady" Event
|
|
||||||
|
|
||||||
AI -> AI: 텍스트 분석 및 구조화\n(키워드, 주제, 맥락 파악)
|
|
||||||
|
|
||||||
AI -> Cache: 템플릿 구조 조회\n(sessionId)
|
|
||||||
Cache --> AI: 템플릿 섹션 정보\n(agenda, decisions, tasks)
|
|
||||||
|
|
||||||
AI -> AI: 템플릿 섹션에 맞춰\n내용 자동 분류
|
|
||||||
note right
|
|
||||||
예시:
|
|
||||||
- "결정사항" → decisions
|
|
||||||
- "TODO" → action_items
|
|
||||||
- "논의내용" → discussions
|
|
||||||
end note
|
|
||||||
|
|
||||||
AI -> DB: INSERT INTO transcript_segments\n(session_id, section,\ncontent, timestamp)
|
|
||||||
DB --> AI: 세그먼트 저장 완료
|
|
||||||
|
|
||||||
AI ->> MQ: Publish "TranscriptUpdated" Event\n{\n sessionId,\n segmentId,\n section,\n content,\n updatedAt\n}
|
|
||||||
|
|
||||||
== 실시간 협업 및 동기화 ==
|
|
||||||
MQ -->> Collab: Consume "TranscriptUpdated" Event
|
|
||||||
|
|
||||||
Collab -> Cache: 현재 회의록 상태 조회
|
|
||||||
Cache --> Collab: 최신 회의록 데이터
|
|
||||||
|
|
||||||
Collab -> Collab: 변경 사항 감지 및\n충돌 검사 (CRDT 알고리즘)
|
|
||||||
|
|
||||||
Collab ->> WebA: WebSocket Push\n{\n type: "transcript.update",\n section: "decisions",\n content: "...",\n author: "AI"\n}
|
|
||||||
Collab ->> WebB: WebSocket Push\n{\n type: "transcript.update",\n section: "decisions",\n content: "...",\n author: "AI"\n}
|
|
||||||
|
|
||||||
WebA --> UserA: 회의록 UI 실시간 업데이트
|
|
||||||
WebB --> UserB: 회의록 UI 실시간 업데이트
|
|
||||||
|
|
||||||
== 참여자 실시간 편집 ==
|
|
||||||
UserA -> WebA: 회의록 내용 수정\n("결정사항" 섹션 편집)
|
|
||||||
WebA ->> Collab: WebSocket Send\n{\n type: "edit",\n section: "decisions",\n content: "수정된 내용",\n cursorPosition: 42\n}
|
|
||||||
|
|
||||||
Collab -> Collab: 동시 편집 충돌 검사\n(Operational Transform)
|
|
||||||
|
|
||||||
alt 충돌 없음
|
|
||||||
Collab -> DB: UPDATE transcript_segments\nSET content='수정된 내용'
|
|
||||||
DB --> Collab: 업데이트 완료
|
|
||||||
|
|
||||||
Collab -> Cache: 최신 회의록 캐시 갱신
|
|
||||||
|
|
||||||
Collab ->> WebB: WebSocket Push\n{\n type: "peer.edit",\n section: "decisions",\n content: "수정된 내용",\n author: "참여자A"\n}
|
|
||||||
WebB --> UserB: 참여자A의 수정사항 반영
|
|
||||||
|
|
||||||
else 충돌 발생
|
|
||||||
Collab -> Collab: 충돌 해결 알고리즘 적용\n(Last-Write-Wins + Merge)
|
|
||||||
|
|
||||||
Collab -> DB: UPDATE transcript_segments\nSET content='병합된 내용'
|
|
||||||
|
|
||||||
Collab ->> WebA: WebSocket Push\n{\n type: "conflict.resolved",\n mergedContent: "병합된 내용"\n}
|
|
||||||
Collab ->> WebB: WebSocket Push\n{\n type: "conflict.resolved",\n mergedContent: "병합된 내용"\n}
|
|
||||||
|
|
||||||
WebA --> UserA: 병합된 내용으로 UI 업데이트
|
|
||||||
WebB --> UserB: 병합된 내용으로 UI 업데이트
|
|
||||||
end
|
|
||||||
|
|
||||||
== 실시간 커서 및 선택 영역 공유 ==
|
|
||||||
UserB -> WebB: 텍스트 선택 또는 커서 이동
|
|
||||||
WebB ->> Collab: WebSocket Send\n{\n type: "cursor.move",\n userId: "userB",\n position: 120,\n selection: {start: 100, end: 130}\n}
|
|
||||||
|
|
||||||
Collab ->> WebA: WebSocket Push\n{\n type: "peer.cursor",\n userId: "userB",\n userName: "참여자B",\n position: 120,\n color: "#FF5733"\n}
|
|
||||||
|
|
||||||
WebA --> UserA: 참여자B의 커서 위치 표시\n(다른 색상으로 강조)
|
|
||||||
|
|
||||||
note over WebA, WebB
|
|
||||||
실시간 협업 기능:
|
|
||||||
- 동시 편집 지원 (CRDT)
|
|
||||||
- 충돌 자동 해결
|
|
||||||
- 커서 위치 공유
|
|
||||||
- 변경 이력 추적
|
|
||||||
end note
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,140 +0,0 @@
|
|||||||
@startuml
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title Flow 5: 회의 종료 및 Todo 자동 추출 (Meeting End and Auto Todo Extraction)
|
|
||||||
|
|
||||||
actor "사용자\n(User)" as User
|
|
||||||
participant "Web App" as Web
|
|
||||||
participant "API Gateway" as Gateway
|
|
||||||
participant "Meeting Service" as Meeting
|
|
||||||
participant "STT Service" as STT
|
|
||||||
participant "AI Service" as AI
|
|
||||||
participant "Todo Service" as Todo
|
|
||||||
participant "Notification Service" as Notification
|
|
||||||
queue "RabbitMQ" as MQ
|
|
||||||
database "Redis" as Cache
|
|
||||||
database "PostgreSQL" as DB
|
|
||||||
|
|
||||||
== 회의 종료 (Meeting End) ==
|
|
||||||
|
|
||||||
User -> Web: 1. 회의 종료 버튼 클릭\n(Click "End Meeting" button)
|
|
||||||
activate Web
|
|
||||||
|
|
||||||
Web -> Gateway: 2. PATCH /api/meetings/{meetingId}/end\n(End meeting request)
|
|
||||||
activate Gateway
|
|
||||||
|
|
||||||
Gateway -> Meeting: 3. 회의 종료 요청\n(Forward end meeting request)
|
|
||||||
activate Meeting
|
|
||||||
|
|
||||||
Meeting -> DB: 4. 회의 상태 조회\n(Query meeting status)
|
|
||||||
activate DB
|
|
||||||
DB --> Meeting: 회의 정보 반환\n(Return meeting info)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
Meeting -> DB: 5. 회의 상태를 "ended"로 업데이트\n종료 시간 기록\n(Update status to "ended", record end time)
|
|
||||||
activate DB
|
|
||||||
DB --> Meeting: 업데이트 완료\n(Update confirmed)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
Meeting -> DB: 6. 회의 통계 생성\n(참여자 수, 발언 시간, 총 시간 등)\n(Generate meeting statistics)
|
|
||||||
activate DB
|
|
||||||
DB --> Meeting: 통계 저장 완료\n(Statistics saved)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
Meeting -> Cache: 7. 캐시 업데이트\n(Update cache with final status)
|
|
||||||
activate Cache
|
|
||||||
Cache --> Meeting: 캐시 업데이트 완료\n(Cache updated)
|
|
||||||
deactivate Cache
|
|
||||||
|
|
||||||
Meeting ->> MQ: 8. "MeetingEnded" 이벤트 발행\n(Publish "MeetingEnded" event)\n{meetingId, endTime, stats}
|
|
||||||
activate MQ
|
|
||||||
|
|
||||||
Meeting --> Gateway: 9. 회의 종료 응답\n(Return end meeting response)
|
|
||||||
deactivate Meeting
|
|
||||||
|
|
||||||
Gateway --> Web: 10. 종료 확인 응답\n(Return confirmation)
|
|
||||||
deactivate Gateway
|
|
||||||
|
|
||||||
Web --> User: 11. 회의 종료 완료 메시지 표시\n(Display meeting ended message)
|
|
||||||
deactivate Web
|
|
||||||
|
|
||||||
== STT 녹음 중지 (Stop STT Recording) ==
|
|
||||||
|
|
||||||
MQ ->> STT: 12. "MeetingEnded" 이벤트 수신\n(Receive "MeetingEnded" event)
|
|
||||||
activate STT
|
|
||||||
|
|
||||||
STT -> STT: 13. 녹음 중지 및 최종 처리\n(Stop recording and final processing)
|
|
||||||
|
|
||||||
STT -> DB: 14. 최종 음성 데이터 저장\n(Save final audio data)
|
|
||||||
activate DB
|
|
||||||
DB --> STT: 저장 완료\n(Save confirmed)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
STT -> DB: 15. 전사 완료 상태 업데이트\n(Update transcription status to completed)
|
|
||||||
activate DB
|
|
||||||
DB --> STT: 업데이트 완료\n(Update confirmed)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
deactivate STT
|
|
||||||
deactivate MQ
|
|
||||||
|
|
||||||
== AI Todo 자동 추출 (AI Auto Todo Extraction) ==
|
|
||||||
|
|
||||||
MQ ->> AI: 16. "MeetingEnded" 이벤트 수신\n(Receive "MeetingEnded" event)
|
|
||||||
activate MQ
|
|
||||||
activate AI
|
|
||||||
|
|
||||||
AI -> DB: 17. 전체 회의록 조회\n(Query full transcript)
|
|
||||||
activate DB
|
|
||||||
DB --> AI: 회의록 텍스트 반환\n(Return transcript text)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
AI -> AI: 18. AI 분석 수행\n- 실행 항목(Action Items) 식별\n- 담당자(Assignee) 추출\n- 마감일 추론\n(AI analysis:\n- Identify action items\n- Extract assignees\n- Infer deadlines)
|
|
||||||
|
|
||||||
AI -> DB: 19. AI 추출 결과 저장\n(Save AI extraction results)
|
|
||||||
activate DB
|
|
||||||
DB --> AI: 저장 완료\n(Save confirmed)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
AI ->> MQ: 20. "TodoExtracted" 이벤트 발행\n(Publish "TodoExtracted" event)\n{meetingId, todos: [{description, assignee, dueDate, transcriptSection}]}
|
|
||||||
deactivate AI
|
|
||||||
|
|
||||||
== Todo 생성 및 연결 (Todo Creation and Linking) ==
|
|
||||||
|
|
||||||
MQ ->> Todo: 21. "TodoExtracted" 이벤트 수신\n(Receive "TodoExtracted" event)
|
|
||||||
activate Todo
|
|
||||||
|
|
||||||
loop 각 Todo 항목마다 (For each todo item)
|
|
||||||
Todo -> DB: 22. Todo 생성\n- 회의 연결 (meetingId)\n- 전사 섹션 연결 (transcriptSectionId)\n- 담당자 정보\n- 마감일\n(Create todo with:\n- Meeting link\n- Transcript section link\n- Assignee info\n- Due date)
|
|
||||||
activate DB
|
|
||||||
DB --> Todo: Todo 생성 완료\n(Todo created)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
Todo ->> MQ: 23. "TodoCreated" 이벤트 발행\n(Publish "TodoCreated" event)\n{todoId, meetingId, assignee}
|
|
||||||
end
|
|
||||||
|
|
||||||
deactivate Todo
|
|
||||||
|
|
||||||
== 담당자 알림 (Assignee Notification) ==
|
|
||||||
|
|
||||||
MQ ->> Notification: 24. "TodoCreated" 이벤트 수신\n(Receive "TodoCreated" event)
|
|
||||||
activate Notification
|
|
||||||
|
|
||||||
Notification -> DB: 25. 담당자 정보 조회\n(Query assignee information)
|
|
||||||
activate DB
|
|
||||||
DB --> Notification: 사용자 정보 및 이메일\n(Return user info and email)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
Notification -> Notification: 26. Todo 할당 이메일 생성\n- Todo 내용\n- 마감일\n- 회의록 링크\n(Generate todo assignment email:\n- Todo description\n- Due date\n- Transcript link)
|
|
||||||
|
|
||||||
Notification -> Notification: 27. 이메일 발송\n(Send email to assignee)
|
|
||||||
|
|
||||||
Notification -> DB: 28. 알림 전송 기록 저장\n(Save notification log)
|
|
||||||
activate DB
|
|
||||||
DB --> Notification: 저장 완료\n(Save confirmed)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
deactivate Notification
|
|
||||||
deactivate MQ
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,183 +0,0 @@
|
|||||||
@startuml
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title Flow 6: 회의록 확정 및 공유 (Transcript Confirmation and Sharing)
|
|
||||||
|
|
||||||
actor "사용자\n(User)" as User
|
|
||||||
participant "Web App" as Web
|
|
||||||
participant "API Gateway" as Gateway
|
|
||||||
participant "Meeting Service" as Meeting
|
|
||||||
participant "Notification Service" as Notification
|
|
||||||
queue "RabbitMQ" as MQ
|
|
||||||
database "Redis" as Cache
|
|
||||||
database "PostgreSQL" as DB
|
|
||||||
|
|
||||||
== 회의록 검토 (Transcript Review) ==
|
|
||||||
|
|
||||||
User -> Web: 1. 회의록 최종 검토\n(Review final transcript)
|
|
||||||
activate Web
|
|
||||||
|
|
||||||
Web -> Gateway: 2. GET /api/meetings/{meetingId}/transcript\n(Get transcript for review)
|
|
||||||
activate Gateway
|
|
||||||
|
|
||||||
Gateway -> Meeting: 3. 회의록 조회 요청\n(Forward transcript query)
|
|
||||||
activate Meeting
|
|
||||||
|
|
||||||
Meeting -> Cache: 4. 캐시에서 회의록 조회\n(Check cache for transcript)
|
|
||||||
activate Cache
|
|
||||||
Cache --> Meeting: 캐시 히트/미스\n(Cache hit/miss)
|
|
||||||
deactivate Cache
|
|
||||||
|
|
||||||
alt 캐시 미스 (Cache miss)
|
|
||||||
Meeting -> DB: 5. DB에서 회의록 조회\n(Query transcript from DB)
|
|
||||||
activate DB
|
|
||||||
DB --> Meeting: 회의록 데이터 반환\n(Return transcript data)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
Meeting -> Cache: 6. 캐시에 저장\n(Store in cache)
|
|
||||||
activate Cache
|
|
||||||
Cache --> Meeting: 저장 완료\n(Stored)
|
|
||||||
deactivate Cache
|
|
||||||
end
|
|
||||||
|
|
||||||
Meeting --> Gateway: 7. 회의록 반환\n(Return transcript)
|
|
||||||
deactivate Meeting
|
|
||||||
|
|
||||||
Gateway --> Web: 8. 회의록 데이터\n(Return transcript data)
|
|
||||||
deactivate Gateway
|
|
||||||
|
|
||||||
Web --> User: 9. 회의록 표시\n(Display transcript)
|
|
||||||
deactivate Web
|
|
||||||
|
|
||||||
== 필수 항목 검증 (Validate Required Sections) ==
|
|
||||||
|
|
||||||
User -> Web: 10. 회의록 확정 요청\n(Request transcript confirmation)
|
|
||||||
activate Web
|
|
||||||
|
|
||||||
Web -> Web: 11. 필수 항목 검증\n- 회의 제목 존재 여부\n- 참석자 목록 존재 여부\n- 주요 결정사항 작성 여부\n(Validate required sections:\n- Title exists\n- Participants list exists\n- Key decisions documented)
|
|
||||||
|
|
||||||
alt 필수 항목 누락 (Missing required sections)
|
|
||||||
Web --> User: 12. 필수 항목 누락 경고\n(Display missing sections warning)
|
|
||||||
deactivate Web
|
|
||||||
else 검증 통과 (Validation passed)
|
|
||||||
|
|
||||||
Web -> Gateway: 13. POST /api/meetings/{meetingId}/confirm\n(Confirm transcript request)
|
|
||||||
activate Gateway
|
|
||||||
|
|
||||||
Gateway -> Meeting: 14. 회의록 확정 요청\n(Forward confirmation request)
|
|
||||||
activate Meeting
|
|
||||||
|
|
||||||
Meeting -> DB: 15. 회의록 확정 처리\n- 최종 버전 생성 (version++)\n- 확정 상태로 변경 (status: "confirmed")\n- 확정 일시 기록\n(Confirm transcript:\n- Create final version\n- Update status to "confirmed"\n- Record confirmation time)
|
|
||||||
activate DB
|
|
||||||
DB --> Meeting: 확정 완료\n(Confirmation saved)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
Meeting -> Cache: 16. 캐시 무효화\n(Invalidate cache)
|
|
||||||
activate Cache
|
|
||||||
Cache --> Meeting: 캐시 삭제 완료\n(Cache invalidated)
|
|
||||||
deactivate Cache
|
|
||||||
|
|
||||||
Meeting --> Gateway: 17. 확정 완료 응답\n(Return confirmation response)
|
|
||||||
deactivate Meeting
|
|
||||||
|
|
||||||
Gateway --> Web: 18. 확정 완료\n(Confirmation successful)
|
|
||||||
deactivate Gateway
|
|
||||||
|
|
||||||
Web --> User: 19. 확정 완료 메시지 표시\n(Display confirmation message)
|
|
||||||
deactivate Web
|
|
||||||
end
|
|
||||||
|
|
||||||
== 공유 설정 (Configure Sharing) ==
|
|
||||||
|
|
||||||
User -> Web: 20. 공유 설정 화면 열기\n(Open sharing configuration)
|
|
||||||
activate Web
|
|
||||||
|
|
||||||
Web --> User: 21. 공유 옵션 표시\n- 수신자 선택\n- 권한 설정 (읽기/편집)\n- 공유 범위 (전체/일부)\n(Display sharing options:\n- Select recipients\n- Set permissions\n- Choose scope)
|
|
||||||
deactivate Web
|
|
||||||
|
|
||||||
User -> Web: 22. 공유 설정 입력\n- 수신자 목록\n- 권한 레벨\n- 메시지 (선택)\n(Input sharing settings:\n- Recipients list\n- Permission level\n- Optional message)
|
|
||||||
activate Web
|
|
||||||
|
|
||||||
Web -> Gateway: 23. POST /api/meetings/{meetingId}/share\n{recipients, permissions, message}\n(Submit sharing request)
|
|
||||||
activate Gateway
|
|
||||||
|
|
||||||
Gateway -> Meeting: 24. 공유 설정 요청\n(Forward sharing request)
|
|
||||||
activate Meeting
|
|
||||||
|
|
||||||
Meeting -> DB: 25. 공유 링크 생성\n- 고유 공유 ID 생성 (UUID)\n- 공유 권한 저장\n- 유효기간 설정 (선택)\n(Generate share link:\n- Create unique share ID\n- Save permissions\n- Set expiration if configured)
|
|
||||||
activate DB
|
|
||||||
DB --> Meeting: 공유 정보 저장 완료\n(Share info saved)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
Meeting -> Cache: 26. 공유 링크 캐시 저장\n(Cache share link)
|
|
||||||
activate Cache
|
|
||||||
Cache --> Meeting: 캐시 저장 완료\n(Cached)
|
|
||||||
deactivate Cache
|
|
||||||
|
|
||||||
Meeting ->> MQ: 27. "TranscriptShared" 이벤트 발행\n(Publish "TranscriptShared" event)\n{meetingId, shareId, recipients, permissions}
|
|
||||||
activate MQ
|
|
||||||
|
|
||||||
Meeting --> Gateway: 28. 공유 링크 반환\n(Return share link)
|
|
||||||
deactivate Meeting
|
|
||||||
|
|
||||||
Gateway --> Web: 29. 공유 링크 및 확인\n(Return share link)
|
|
||||||
deactivate Gateway
|
|
||||||
|
|
||||||
Web --> User: 30. 공유 완료 메시지 및 링크 표시\n(Display share link and confirmation)
|
|
||||||
deactivate Web
|
|
||||||
|
|
||||||
== 공유 알림 발송 (Send Share Notifications) ==
|
|
||||||
|
|
||||||
MQ ->> Notification: 31. "TranscriptShared" 이벤트 수신\n(Receive "TranscriptShared" event)
|
|
||||||
activate Notification
|
|
||||||
|
|
||||||
loop 각 수신자마다 (For each recipient)
|
|
||||||
Notification -> DB: 32. 수신자 정보 조회\n(Query recipient information)
|
|
||||||
activate DB
|
|
||||||
DB --> Notification: 사용자 정보 및 이메일\n(Return user info and email)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
Notification -> Notification: 33. 공유 알림 이메일 생성\n- 회의 정보\n- 공유 링크\n- 권한 레벨\n- 발신자 메시지\n(Generate share notification email:\n- Meeting info\n- Share link\n- Permission level\n- Sender message)
|
|
||||||
|
|
||||||
Notification -> Notification: 34. 이메일 발송\n(Send email to recipient)
|
|
||||||
|
|
||||||
Notification -> DB: 35. 알림 전송 기록 저장\n(Save notification log)
|
|
||||||
activate DB
|
|
||||||
DB --> Notification: 저장 완료\n(Save confirmed)
|
|
||||||
deactivate DB
|
|
||||||
end
|
|
||||||
|
|
||||||
deactivate Notification
|
|
||||||
deactivate MQ
|
|
||||||
|
|
||||||
== 참여자 알림 (Participant Notification) ==
|
|
||||||
|
|
||||||
note over Notification
|
|
||||||
모든 회의 참여자에게도
|
|
||||||
회의록 확정 알림 발송
|
|
||||||
(Send confirmation notification
|
|
||||||
to all meeting participants)
|
|
||||||
end note
|
|
||||||
|
|
||||||
Notification ->> Notification: 36. 참여자 알림 처리\n(Process participant notifications)
|
|
||||||
activate Notification
|
|
||||||
|
|
||||||
Notification -> DB: 37. 참여자 목록 조회\n(Query participants list)
|
|
||||||
activate DB
|
|
||||||
DB --> Notification: 참여자 정보 반환\n(Return participants info)
|
|
||||||
deactivate DB
|
|
||||||
|
|
||||||
loop 각 참여자마다 (For each participant)
|
|
||||||
Notification -> Notification: 38. 확정 알림 이메일 생성\n- 회의록 확정 알림\n- 회의록 보기 링크\n- 주요 내용 요약\n(Generate confirmation email:\n- Transcript confirmed\n- View link\n- Summary)
|
|
||||||
|
|
||||||
Notification -> Notification: 39. 이메일 발송\n(Send email)
|
|
||||||
|
|
||||||
Notification -> DB: 40. 알림 기록 저장\n(Save notification log)
|
|
||||||
activate DB
|
|
||||||
DB --> Notification: 저장 완료\n(Saved)
|
|
||||||
deactivate DB
|
|
||||||
end
|
|
||||||
|
|
||||||
deactivate Notification
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
@startuml
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title 회의록 목록 조회 및 상세 조회 Flow
|
|
||||||
|
|
||||||
actor "User" as user
|
|
||||||
participant "Web App" as web
|
|
||||||
participant "API Gateway" as gateway
|
|
||||||
participant "Meeting Service" as meeting
|
|
||||||
participant "AI Service" as ai
|
|
||||||
participant "Redis" as redis
|
|
||||||
participant "PostgreSQL" as db
|
|
||||||
|
|
||||||
== 회의록 목록 조회 ==
|
|
||||||
|
|
||||||
user -> web: 회의록 목록 화면 진입
|
|
||||||
web -> gateway: GET /api/meetings/transcripts\n(filters: status, date, participants)
|
|
||||||
gateway -> meeting: 회의록 목록 조회 요청\n(필터 및 정렬 조건 포함)
|
|
||||||
|
|
||||||
meeting -> redis: 캐시 조회\n(key: transcripts:filter:{hash})
|
|
||||||
alt 캐시 히트
|
|
||||||
redis --> meeting: 캐시된 목록 반환
|
|
||||||
else 캐시 미스
|
|
||||||
meeting -> db: SELECT transcripts\nWHERE status, date, participants\nORDER BY created_at
|
|
||||||
db --> meeting: 회의록 목록 데이터
|
|
||||||
meeting -> redis: 캐시 저장\n(TTL: 5분)
|
|
||||||
end
|
|
||||||
|
|
||||||
meeting --> gateway: 회의록 목록 응답
|
|
||||||
gateway --> web: 200 OK\n{transcripts: [...]}
|
|
||||||
web --> user: 회의록 목록 표시\n(필터/정렬 적용)
|
|
||||||
|
|
||||||
== 회의록 상세 조회 ==
|
|
||||||
|
|
||||||
user -> web: 회의록 항목 클릭
|
|
||||||
web -> gateway: GET /api/meetings/transcripts/{id}
|
|
||||||
gateway -> meeting: 회의록 상세 조회 요청
|
|
||||||
|
|
||||||
meeting -> redis: 캐시 조회\n(key: transcript:{id})
|
|
||||||
alt 캐시 히트
|
|
||||||
redis --> meeting: 캐시된 상세 데이터
|
|
||||||
else 캐시 미스
|
|
||||||
meeting -> db: SELECT transcript, content,\nparticipants, action_items\nWHERE id = {id}
|
|
||||||
db --> meeting: 회의록 상세 데이터
|
|
||||||
meeting -> redis: 캐시 저장\n(TTL: 10분)
|
|
||||||
end
|
|
||||||
|
|
||||||
== 연관 회의록 자동 링크 ==
|
|
||||||
|
|
||||||
meeting ->> ai: 연관 회의록 요청\n(transcript_id, threshold: 0.7)
|
|
||||||
ai -> db: Vector 유사도 검색\n(임베딩 기반, similarity > 70%)
|
|
||||||
db --> ai: 유사 회의록 목록\n(최대 5개)
|
|
||||||
ai --> meeting: 연관 회의록 ID 목록
|
|
||||||
|
|
||||||
meeting -> db: 연관 회의록 메타데이터 조회
|
|
||||||
db --> meeting: 연관 회의록 제목, 날짜, 참석자
|
|
||||||
|
|
||||||
meeting --> gateway: 회의록 상세 + 연관 목록 응답
|
|
||||||
gateway --> web: 200 OK\n{transcript: {...},\nrelated: [...]}
|
|
||||||
web --> user: 회의록 상세 표시\n+ 연관 회의록 링크
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
@startuml
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title 맥락 기반 용어 설명 제공 Flow
|
|
||||||
|
|
||||||
actor "User" as user
|
|
||||||
participant "Web App" as web
|
|
||||||
participant "API Gateway" as gateway
|
|
||||||
participant "RAG Service" as rag
|
|
||||||
participant "Vector DB" as vectordb
|
|
||||||
participant "PostgreSQL" as db
|
|
||||||
|
|
||||||
== 실시간 용어 감지 ==
|
|
||||||
|
|
||||||
user -> web: 회의록 내용 조회 중
|
|
||||||
web -> gateway: GET /api/meetings/transcripts/{id}
|
|
||||||
gateway -> rag: 회의록 내용 전달\n(기술 용어 감지 요청)
|
|
||||||
|
|
||||||
rag -> rag: NLP 기반 기술 용어 추출\n(confidence > 70%)
|
|
||||||
note right of rag
|
|
||||||
- 도메인 용어 사전 매칭
|
|
||||||
- 컨텍스트 분석
|
|
||||||
- 신뢰도 점수 계산
|
|
||||||
end note
|
|
||||||
|
|
||||||
rag --> gateway: 감지된 용어 목록\n{terms: [{word, position, confidence}]}
|
|
||||||
gateway --> web: 회의록 + 하이라이트 용어
|
|
||||||
web --> user: 회의록 표시\n(기술 용어 하이라이트)
|
|
||||||
|
|
||||||
== 용어 설명 요청 ==
|
|
||||||
|
|
||||||
user -> web: 하이라이트 용어 호버
|
|
||||||
web -> gateway: GET /api/rag/terms/explain\n?term={용어}&context={문장}&meeting_id={id}
|
|
||||||
gateway -> rag: 맥락 기반 용어 설명 요청
|
|
||||||
|
|
||||||
== Vector 유사도 검색 ==
|
|
||||||
|
|
||||||
rag -> vectordb: Vector 검색\n(term embedding, similarity search)
|
|
||||||
note right of vectordb
|
|
||||||
- 과거 회의록 임베딩 검색
|
|
||||||
- 관련 문서 임베딩 검색
|
|
||||||
- 유사도 임계값: 0.7
|
|
||||||
end note
|
|
||||||
|
|
||||||
vectordb --> rag: 유사 문서 조각 목록\n(최대 10개, similarity > 70%)
|
|
||||||
|
|
||||||
rag -> db: 관련 컨텍스트 메타데이터 조회\n(project_id, issue_id, meeting_ids)
|
|
||||||
db --> rag: 프로젝트, 이슈, 회의 정보
|
|
||||||
|
|
||||||
== 설명 생성 ==
|
|
||||||
|
|
||||||
rag -> rag: LLM 기반 설명 생성
|
|
||||||
note right of rag
|
|
||||||
생성 내용:
|
|
||||||
1. 간단한 정의
|
|
||||||
2. 현재 회의에서의 맥락적 의미
|
|
||||||
3. 관련 프로젝트/이슈
|
|
||||||
4. 과거 회의 참조 (최대 3개)
|
|
||||||
end note
|
|
||||||
|
|
||||||
rag -> db: 과거 회의 제목 및 날짜 조회\n(meeting_ids, LIMIT 3)
|
|
||||||
db --> rag: 회의 메타데이터
|
|
||||||
|
|
||||||
rag --> gateway: 용어 설명 응답\n{definition, context_meaning,\nrelated_projects, past_meetings}
|
|
||||||
gateway --> web: 200 OK\n{explanation: {...}}
|
|
||||||
web --> user: 툴팁/사이드 패널에 설명 표시
|
|
||||||
note left of user
|
|
||||||
표시 내용:
|
|
||||||
- 📖 정의: "..."
|
|
||||||
- 💬 맥락: "이 회의에서는..."
|
|
||||||
- 🔗 관련: 프로젝트 A, 이슈 #123
|
|
||||||
- 📅 과거 회의:
|
|
||||||
• 2025-08-15 기획 회의
|
|
||||||
• 2025-07-20 기술 검토
|
|
||||||
• 2025-06-10 아키텍처 논의
|
|
||||||
end note
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,94 +0,0 @@
|
|||||||
@startuml
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title Flow 9: Todo 완료 및 회의록 반영 (Todo Completion and Transcript Update)
|
|
||||||
|
|
||||||
actor User as user
|
|
||||||
participant "Web App" as web
|
|
||||||
participant "API Gateway" as gateway
|
|
||||||
participant "Todo Service" as todo
|
|
||||||
participant "RabbitMQ" as mq
|
|
||||||
participant "Meeting Service" as meeting
|
|
||||||
participant "Notification Service" as notification
|
|
||||||
participant "Redis" as redis
|
|
||||||
participant "PostgreSQL\n(Todo DB)" as tododb
|
|
||||||
participant "PostgreSQL\n(Meeting DB)" as meetingdb
|
|
||||||
participant "WebSocket\nConnection" as ws
|
|
||||||
|
|
||||||
== Todo 완료 처리 (Todo Completion Processing) ==
|
|
||||||
|
|
||||||
user -> web: Todo 완료 버튼 클릭\n(Click "Complete" button)
|
|
||||||
web -> gateway: PUT /api/todos/{todoId}/complete\n(Todo 완료 요청)
|
|
||||||
|
|
||||||
gateway -> todo: PUT /todos/{todoId}/complete\n(Todo 완료 처리 요청)
|
|
||||||
activate todo
|
|
||||||
|
|
||||||
todo -> tododb: UPDATE todos\nSET status='COMPLETED',\ncompleted_at=NOW(),\ncompleted_by={userId}\nWHERE id={todoId}
|
|
||||||
tododb --> todo: 완료 상태 저장 완료\n(Completion status saved)
|
|
||||||
|
|
||||||
todo -> redis: DEL cache:todo:{todoId}\n(Todo 캐시 무효화)
|
|
||||||
redis --> todo: 캐시 삭제 완료
|
|
||||||
|
|
||||||
todo --> gateway: 200 OK\n{todo: {..., status: "COMPLETED"}}
|
|
||||||
gateway --> web: 200 OK
|
|
||||||
web --> user: Todo 완료 표시\n(Show completion checkmark)
|
|
||||||
|
|
||||||
== 비동기 이벤트 발행 (Async Event Publishing) ==
|
|
||||||
|
|
||||||
todo ->> mq: Publish "TodoCompleted"\n{todoId, meetingId, userId,\ncompletedAt}
|
|
||||||
deactivate todo
|
|
||||||
|
|
||||||
mq ->> meeting: Consume "TodoCompleted"\n(Todo 완료 이벤트 수신)
|
|
||||||
activate meeting
|
|
||||||
|
|
||||||
== 회의록 업데이트 (Meeting Transcript Update) ==
|
|
||||||
|
|
||||||
meeting -> redis: GET cache:transcript:{meetingId}\n(회의록 캐시 조회)
|
|
||||||
alt 캐시 히트 (Cache Hit)
|
|
||||||
redis --> meeting: 회의록 데이터 반환
|
|
||||||
else 캐시 미스 (Cache Miss)
|
|
||||||
meeting -> meetingdb: SELECT * FROM transcripts\nWHERE meeting_id={meetingId}
|
|
||||||
meetingdb --> meeting: 회의록 데이터 반환
|
|
||||||
end
|
|
||||||
|
|
||||||
meeting -> meeting: Todo 섹션에 완료 상태 반영\n(Update todo section:\ncheckmark, completed_at,\ncompleted_by)
|
|
||||||
|
|
||||||
meeting -> meetingdb: UPDATE transcripts\nSET content={updatedContent},\nupdated_at=NOW()\nWHERE meeting_id={meetingId}
|
|
||||||
meetingdb --> meeting: 회의록 업데이트 완료
|
|
||||||
|
|
||||||
meeting -> redis: DEL cache:transcript:{meetingId}\n(회의록 캐시 무효화)
|
|
||||||
redis --> meeting: 캐시 삭제 완료
|
|
||||||
|
|
||||||
== 알림 발송 (Notification Sending) ==
|
|
||||||
|
|
||||||
meeting ->> mq: Publish "TranscriptUpdated"\n{meetingId, updateType:\n"TODO_COMPLETED",\ntodoId, userId}
|
|
||||||
deactivate meeting
|
|
||||||
|
|
||||||
mq ->> notification: Consume "TranscriptUpdated"\n(회의록 업데이트 이벤트 수신)
|
|
||||||
activate notification
|
|
||||||
|
|
||||||
notification -> meetingdb: SELECT creator_id\nFROM transcripts\nWHERE meeting_id={meetingId}
|
|
||||||
meetingdb --> notification: 회의록 작성자 ID 반환
|
|
||||||
|
|
||||||
notification -> notification: 알림 메시지 생성\n("Todo가 완료되었습니다")
|
|
||||||
|
|
||||||
notification ->> user: 회의록 작성자에게\n완료 알림 전송\n(Send completion notification)
|
|
||||||
|
|
||||||
deactivate notification
|
|
||||||
|
|
||||||
== 실시간 동기화 (Real-time Sync) ==
|
|
||||||
|
|
||||||
mq ->> ws: Consume "TranscriptUpdated"\n(실시간 동기화 이벤트)
|
|
||||||
activate ws
|
|
||||||
|
|
||||||
ws -> redis: GET ws:participants:{meetingId}\n(현재 회의록 조회 중인\n참여자 목록 조회)
|
|
||||||
redis --> ws: 참여자 WebSocket 세션 목록
|
|
||||||
|
|
||||||
loop 각 참여자에게 (For each participant)
|
|
||||||
ws ->> web: WebSocket Push\n{type: "TODO_COMPLETED",\ntodoId, completedAt,\ncompletedBy}
|
|
||||||
web -> web: 화면에 완료 상태 실시간 반영\n(Update UI with completion status)
|
|
||||||
end
|
|
||||||
|
|
||||||
deactivate ws
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,328 +0,0 @@
|
|||||||
# 외부 시퀀스 설계서 (Outer Sequence Design)
|
|
||||||
|
|
||||||
## 개요
|
|
||||||
|
|
||||||
본 문서는 회의록 작성 및 공유 개선 서비스의 **외부 시퀀스 다이어그램**을 설명합니다.
|
|
||||||
외부 시퀀스는 **마이크로서비스 간의 통신 흐름**을 나타내며, 주요 사용자 플로우별로 서비스 간 상호작용을 정의합니다.
|
|
||||||
|
|
||||||
### 문서 정보
|
|
||||||
- **작성일**: 2025-10-22
|
|
||||||
- **작성자**: 홍길동 (Architect)
|
|
||||||
- **버전**: 2.0
|
|
||||||
- **설계 원칙**: 공통설계원칙 및 외부시퀀스설계가이드 준용
|
|
||||||
|
|
||||||
### 병렬 처리 전략 적용
|
|
||||||
- **Group A (순차)**: 회의 생애주기 플로우 (플로우 10-13)
|
|
||||||
- **Group B (독립)**: Todo 관리 플로우 (플로우 14)
|
|
||||||
- **Group C (독립)**: 회의록 조회/수정 플로우 (플로우 15)
|
|
||||||
- 3개 서브 에이전트가 병렬로 작업하여 전체 작업 시간 약 60% 단축
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 외부 시퀀스 목록
|
|
||||||
|
|
||||||
### 1. 사용자 인증 및 대시보드 조회
|
|
||||||
- **파일**: [01-사용자인증및대시보드조회.puml](./01-사용자인증및대시보드조회.puml)
|
|
||||||
- **관련 유저스토리**: AFR-USER-010, AFR-USER-020
|
|
||||||
- **참여 서비스**:
|
|
||||||
- Web App
|
|
||||||
- API Gateway
|
|
||||||
- User Service
|
|
||||||
- Meeting Service
|
|
||||||
- Todo Service
|
|
||||||
- Redis (Cache)
|
|
||||||
- PostgreSQL (User DB, Meeting DB, Todo DB)
|
|
||||||
|
|
||||||
**주요 흐름**:
|
|
||||||
1. **사용자 인증**:
|
|
||||||
- 사용자가 사번과 비밀번호로 로그인
|
|
||||||
- User Service가 LDAP 연동하여 인증
|
|
||||||
- JWT 토큰 생성 및 사용자 프로필 Redis 캐싱 (TTL: 30분)
|
|
||||||
- 인증 성공 시 토큰 반환
|
|
||||||
|
|
||||||
2. **대시보드 데이터 조회**:
|
|
||||||
- 예정된 회의 조회 (Meeting Service)
|
|
||||||
- Redis 캐시 확인 → Cache Miss → DB 조회 → 캐싱 (TTL: 10분)
|
|
||||||
- 진행 중 Todo 조회 (Todo Service)
|
|
||||||
- Redis 캐시 확인 → Cache Hit → 캐시에서 직접 반환
|
|
||||||
- 최근 회의록 조회 (Meeting Service)
|
|
||||||
- Redis 캐시 확인 → Cache Miss → DB 조회 → 캐싱 (TTL: 10분)
|
|
||||||
- Todo 통계 조회 (Todo Service)
|
|
||||||
- Redis 캐시 확인 → Cache Hit → 캐시에서 직접 반환
|
|
||||||
|
|
||||||
**적용 패턴**:
|
|
||||||
- **Cache-Aside Pattern**: 캐시 우선 조회로 DB 부하 감소
|
|
||||||
- **JWT 인증**: API Gateway에서 일괄 토큰 검증
|
|
||||||
- **LDAP 연동**: 기업 사용자 인증
|
|
||||||
|
|
||||||
**성능 목표**:
|
|
||||||
- API 응답 시간 (P95): < 500ms
|
|
||||||
- Cache Hit Rate: > 70%
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. 회의 예약 및 초대
|
|
||||||
- **파일**: [02-회의예약및초대.puml](./02-회의예약및초대.puml)
|
|
||||||
- **관련 유저스토리**: UFR-MEET-010
|
|
||||||
- **참여 서비스**:
|
|
||||||
- Web App
|
|
||||||
- API Gateway
|
|
||||||
- Meeting Service
|
|
||||||
- User Service
|
|
||||||
- Notification Service
|
|
||||||
- RabbitMQ (Message Broker)
|
|
||||||
- Redis (Cache)
|
|
||||||
- PostgreSQL (Meeting DB, User DB, Notification DB)
|
|
||||||
|
|
||||||
**주요 흐름**:
|
|
||||||
1. **회의 예약**:
|
|
||||||
- 사용자가 회의 정보 입력 (제목, 날짜/시간, 장소, 참석자)
|
|
||||||
- 입력 유효성 검증 (필수 필드, 날짜 형식, 이메일 형식)
|
|
||||||
- Meeting Service가 회의 생성 및 DB 저장
|
|
||||||
- 회의 정보 Redis 캐싱 (TTL: 10분)
|
|
||||||
|
|
||||||
2. **이벤트 발행**:
|
|
||||||
- Meeting Service가 `MeetingCreated` 이벤트를 RabbitMQ에 발행
|
|
||||||
- Exchange: `meeting.events`
|
|
||||||
- Routing Key: `meeting.created`
|
|
||||||
- Notification Service가 이벤트 구독
|
|
||||||
|
|
||||||
3. **초대 알림 발송**:
|
|
||||||
- Notification Service가 `MeetingCreated` 이벤트 수신
|
|
||||||
- User Service에서 참석자 정보 조회 (캐시 우선)
|
|
||||||
- 알림 메시지 생성 및 DB 저장
|
|
||||||
- 각 참석자에게 이메일 초대 발송
|
|
||||||
- 알림 상태 업데이트 (PENDING → SENT)
|
|
||||||
- 리마인더 일정 생성 (회의 시작 30분 전)
|
|
||||||
|
|
||||||
4. **결과 확인**:
|
|
||||||
- 사용자가 대시보드에서 새로 예약한 회의 확인
|
|
||||||
- 캐시 무효화 후 DB 재조회 및 재캐싱
|
|
||||||
|
|
||||||
**적용 패턴**:
|
|
||||||
- **Publisher-Subscriber Pattern**: 이벤트 기반 느슨한 결합
|
|
||||||
- **Queue-Based Load Leveling**: 대량 알림 발송 시 부하 분산
|
|
||||||
- **Cache-Aside Pattern**: 사용자 정보 캐싱으로 성능 향상
|
|
||||||
- **Asynchronous Processing**: 알림 발송은 비동기로 처리
|
|
||||||
|
|
||||||
**이벤트 스키마**:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"eventType": "MeetingCreated",
|
|
||||||
"payload": {
|
|
||||||
"meetingId": "uuid",
|
|
||||||
"title": "프로젝트 킥오프 회의",
|
|
||||||
"dateTime": "2025-02-01T14:00:00",
|
|
||||||
"location": "회의실 A",
|
|
||||||
"creatorId": "userId",
|
|
||||||
"participants": ["user1@company.com", "user2@company.com"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**성능 목표**:
|
|
||||||
- 회의 생성 응답 시간: < 300ms
|
|
||||||
- 알림 발송 지연 시간: < 5초
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 설계 원칙
|
|
||||||
|
|
||||||
### 1. 통신 패턴
|
|
||||||
|
|
||||||
#### 동기 통신 (REST API)
|
|
||||||
- **적용 대상**: 즉시 응답이 필요한 단순 조회
|
|
||||||
- **특징**:
|
|
||||||
- API Gateway를 통한 일관된 인증/인가
|
|
||||||
- 캐시 우선 전략으로 직접 의존성 최소화
|
|
||||||
|
|
||||||
#### 비동기 통신 (Message Queue)
|
|
||||||
- **적용 대상**: 이벤트 기반 통신, 느슨한 결합
|
|
||||||
- **특징**:
|
|
||||||
- RabbitMQ Topic Exchange를 통한 Pub/Sub 패턴
|
|
||||||
- 이벤트 발행자와 구독자 간 느슨한 결합
|
|
||||||
- 대량 작업 시 Queue-Based Load Leveling
|
|
||||||
|
|
||||||
### 2. 캐싱 전략 (Cache-Aside)
|
|
||||||
|
|
||||||
| 데이터 유형 | TTL | 캐시 키 패턴 | 무효화 시점 |
|
|
||||||
|------------|-----|--------------|------------|
|
|
||||||
| 사용자 프로필 | 30분 | `user:profile:{userId}` | 프로필 수정 시 |
|
|
||||||
| 사용자 권한 | 1시간 | `user:auth:{userId}` | 권한 변경 시 |
|
|
||||||
| 회의 정보 | 10분 | `meeting:info:{meetingId}` | 회의 수정 시 |
|
|
||||||
| 회의 참여자 | 10분 | `meeting:participants:{meetingId}` | 참여자 변경 시 |
|
|
||||||
| Todo 목록 | 5분 | `todo:user:{userId}` | Todo 상태 변경 시 |
|
|
||||||
| Todo 통계 | 5분 | `todo:stats:{userId}` | Todo 완료 시 |
|
|
||||||
|
|
||||||
**캐시 처리 플로우**:
|
|
||||||
1. 조회 요청 → Redis 캐시 확인
|
|
||||||
2. Cache Hit → 캐시 데이터 반환
|
|
||||||
3. Cache Miss → DB 조회 → Redis 저장 (TTL 설정) → 데이터 반환
|
|
||||||
4. 데이터 수정 시 → DB 업데이트 → Redis 캐시 무효화
|
|
||||||
|
|
||||||
### 3. 이벤트 기반 아키텍처
|
|
||||||
|
|
||||||
#### RabbitMQ Exchange/Queue 구성
|
|
||||||
- **Topic Exchange**: `meeting.events`, `transcript.events`, `todo.events`
|
|
||||||
- **Queue 네이밍**: `{service}.{event-category}.queue`
|
|
||||||
- **Routing Key 패턴**: `{event}.{action}` (예: `meeting.created`, `todo.completed`)
|
|
||||||
|
|
||||||
#### 주요 이벤트
|
|
||||||
|
|
||||||
| 이벤트 | 발행자 | 구독자 | 목적 |
|
|
||||||
|--------|--------|--------|------|
|
|
||||||
| **MeetingCreated** | Meeting Service | Notification Service<br/>AI Service | 참석자 알림 발송<br/>회의 분석 준비 |
|
|
||||||
| **MeetingEnded** | Meeting Service | STT Service<br/>AI Service<br/>Todo Service<br/>Notification Service | 회의록 생성<br/>AI 분석 시작<br/>Todo 추출<br/>종료 알림 |
|
|
||||||
| **TodoCreated** | Todo Service | Notification Service | 담당자 알림 발송 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 다이어그램 렌더링 방법
|
|
||||||
|
|
||||||
### PlantUML 렌더링
|
|
||||||
|
|
||||||
#### 1. Visual Studio Code 플러그인 사용
|
|
||||||
1. PlantUML 확장 설치: `jebbs.plantuml`
|
|
||||||
2. `.puml` 파일 열기
|
|
||||||
3. `Alt + D` (미리보기) 또는 우클릭 → `Preview Current Diagram`
|
|
||||||
|
|
||||||
#### 2. 온라인 렌더링
|
|
||||||
- [PlantUML Online Editor](https://www.plantuml.com/plantuml/uml/)
|
|
||||||
- 파일 내용 복사 → 붙여넣기 → 렌더링
|
|
||||||
|
|
||||||
#### 3. 로컬 PlantUML 서버
|
|
||||||
```bash
|
|
||||||
# Docker로 PlantUML 서버 실행
|
|
||||||
docker run -d --name plantuml -p 38080:8080 plantuml/plantuml-server:latest
|
|
||||||
|
|
||||||
# 브라우저에서 접근
|
|
||||||
http://localhost:38080
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 다음 단계
|
|
||||||
|
|
||||||
### 1. 내부 시퀀스 설계
|
|
||||||
각 서비스 내부의 상세 처리 흐름을 설계합니다:
|
|
||||||
- User Service 내부 시퀀스 (인증 처리, 프로필 관리)
|
|
||||||
- Meeting Service 내부 시퀀스 (회의 생성, 회의록 관리)
|
|
||||||
- Notification Service 내부 시퀀스 (알림 발송, 리마인더 관리)
|
|
||||||
|
|
||||||
### 2. API 명세 작성
|
|
||||||
각 서비스별 REST API 명세를 OpenAPI 3.0 형식으로 작성합니다.
|
|
||||||
|
|
||||||
### 3. 클래스 설계
|
|
||||||
엔티티, DTO, 서비스 클래스 설계를 진행합니다.
|
|
||||||
|
|
||||||
### 4. 데이터 설계
|
|
||||||
각 서비스별 데이터베이스 스키마 설계를 진행합니다.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 참고 자료
|
|
||||||
|
|
||||||
- [논리 아키텍처 설계서](../../logical/logical-architecture.md)
|
|
||||||
- [유저스토리](../../../userstory.md)
|
|
||||||
- [아키텍처 패턴 적용 방안](../../../pattern/architecture-pattern.md)
|
|
||||||
- [클라우드 디자인 패턴 요약](../../../../claude/cloud-design-patterns.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 신규 플로우 (v2.0)
|
|
||||||
|
|
||||||
### 10. 회의 예약 및 초대
|
|
||||||
- **파일**: [회의예약및초대.puml](./회의예약및초대.puml)
|
|
||||||
- **관련 유저스토리**: UFR-MEET-010
|
|
||||||
- **참여 서비스**: Frontend, API Gateway, Meeting Service, User Service, Redis, RabbitMQ, Notification Service, Meeting DB
|
|
||||||
- **주요 특징**:
|
|
||||||
- Cache-Aside 패턴으로 참석자 정보 조회 (Redis 캐시 우선)
|
|
||||||
- 회의 정보 저장 및 캐싱 (TTL: 10분)
|
|
||||||
- MeetingCreated 이벤트 비동기 발행
|
|
||||||
- Notification Service가 참석자 전원에게 초대 이메일 발송
|
|
||||||
|
|
||||||
### 11. 회의 시작 및 회의록 작성
|
|
||||||
- **파일**: [회의시작및회의록작성.puml](./회의시작및회의록작성.puml)
|
|
||||||
- **관련 유저스토리**: UFR-MEET-030, UFR-STT-010/020, UFR-AI-010, UFR-RAG-010/020, UFR-COLLAB-010
|
|
||||||
- **참여 서비스**: Frontend, API Gateway, Meeting Service, STT Service, AI Service, RAG Service, Collaboration Service, Redis, RabbitMQ, Azure Speech, LLM Server, 각 서비스 DB
|
|
||||||
- **주요 특징**:
|
|
||||||
- 실시간 음성 인식 (Azure Speech, 5초 간격)
|
|
||||||
- AI 기반 회의록 자동 작성 (LLM)
|
|
||||||
- WebSocket 실시간 동기화 (델타만 전송)
|
|
||||||
- RAG 기반 전문용어 감지 및 맥락 설명 제공
|
|
||||||
- 가장 복잡한 플로우 (동기+비동기+실시간 혼합)
|
|
||||||
|
|
||||||
### 12. 회의 종료 및 Todo 추출
|
|
||||||
- **파일**: [회의종료및Todo추출.puml](./회의종료및Todo추출.puml)
|
|
||||||
- **관련 유저스토리**: UFR-MEET-040/050, UFR-AI-020, UFR-TODO-010
|
|
||||||
- **참여 서비스**: Frontend, API Gateway, Meeting Service, AI Service, Todo Service, Notification Service, Redis, RabbitMQ, LLM Server, 각 서비스 DB
|
|
||||||
- **주요 특징**:
|
|
||||||
- 회의 통계 자동 생성 (duration, 참석자 수, 발언 수)
|
|
||||||
- AI Todo 자동 추출 (액션 아이템 식별, 담당자 자동 지정)
|
|
||||||
- 이벤트 체인: MeetingEnded → TodoExtracted → TodoCreated
|
|
||||||
- Todo 목록 캐싱 (TTL: 5분)
|
|
||||||
- 담당자에게 자동 알림 발송
|
|
||||||
|
|
||||||
### 13. 회의록 확정 및 공유
|
|
||||||
- **파일**: [회의록확정및공유.puml](./회의록확정및공유.puml)
|
|
||||||
- **관련 유저스토리**: UFR-MEET-060
|
|
||||||
- **참여 서비스**: Frontend, API Gateway, Meeting Service, Notification Service, Redis, RabbitMQ, Meeting DB
|
|
||||||
- **주요 특징**:
|
|
||||||
- 필수 항목 자동 검사 (제목, 참석자, 논의 내용, 결정 사항)
|
|
||||||
- 고유 공유 링크 생성 (UUID 기반)
|
|
||||||
- 공유 보안 설정 (비밀번호, 유효기간)
|
|
||||||
- TranscriptShared 이벤트 발행
|
|
||||||
- 다음 회의 일정 자동 캘린더 등록 (선택)
|
|
||||||
|
|
||||||
### 14. Todo 완료 및 회의록 반영
|
|
||||||
- **파일**: [Todo완료및회의록반영.puml](./Todo완료및회의록반영.puml)
|
|
||||||
- **관련 유저스토리**: UFR-TODO-030
|
|
||||||
- **참여 서비스**: Frontend, API Gateway, Todo Service, Meeting Service, Notification Service, Redis, RabbitMQ, 각 서비스 DB
|
|
||||||
- **주요 특징** (**차별화 포인트**):
|
|
||||||
- Todo 완료가 회의록에 실시간 반영되는 양방향 연동
|
|
||||||
- 완료 시간 및 완료자 정보 자동 기록
|
|
||||||
- TodoCompleted 이벤트 → Meeting Service가 회의록 자동 업데이트
|
|
||||||
- 모든 Todo 완료 시 전체 완료 알림 자동 발송
|
|
||||||
- Cache-Aside 패턴으로 회의록 조회 최적화
|
|
||||||
|
|
||||||
### 15. 회의록 조회 및 수정
|
|
||||||
- **파일**: [회의록조회및수정.puml](./회의록조회및수정.puml)
|
|
||||||
- **관련 유저스토리**: UFR-MEET-046/047/055, UFR-COLLAB-010
|
|
||||||
- **참여 서비스**: Frontend, API Gateway, Meeting Service, Collaboration Service, Redis, Meeting DB
|
|
||||||
- **주요 특징**:
|
|
||||||
- Cache-Aside 패턴으로 목록/상세 조회 (TTL: 10분)
|
|
||||||
- 권한 검증 (본인 작성 회의록만 수정 가능)
|
|
||||||
- 수정 이력 자동 기록 (수정자, 수정 시간, 변경 내용)
|
|
||||||
- WebSocket 실시간 동기화 (델타만 전송)
|
|
||||||
- 버전 관리 (새 버전 생성, 이전 버전 보관)
|
|
||||||
- 확정완료 → 작성중 자동 상태 변경
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 설계 원칙 적용
|
|
||||||
|
|
||||||
### PlantUML 문법 검사
|
|
||||||
✅ **모든 파일 검증 통과** (Docker 기반 PlantUML 검사 완료)
|
|
||||||
- `!theme mono` 적용
|
|
||||||
- 동기: 실선 (→), 비동기: 점선 (->>) 명확 구분
|
|
||||||
- `..>` 사용 금지 (sequence diagram 원칙 준수)
|
|
||||||
|
|
||||||
### 논리 아키텍처 일치성
|
|
||||||
- ✅ 참여자: 논리 아키텍처의 서비스, DB, 메시지 큐 구조 일치
|
|
||||||
- ✅ 통신 방식: 동기(REST), 비동기(RabbitMQ), 실시간(WebSocket) 일치
|
|
||||||
- ✅ 캐시 전략: Cache-Aside 패턴, TTL 설정 일치
|
|
||||||
|
|
||||||
### 유저스토리 커버리지
|
|
||||||
- ✅ 신규 6개 플로우가 11개 유저스토리 완전 커버
|
|
||||||
- ✅ 기존 9개 플로우와 통합하여 전체 시스템 커버
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 문서 이력
|
|
||||||
|
|
||||||
| 버전 | 작성일 | 작성자 | 변경 내용 |
|
|
||||||
|------|--------|--------|----------|
|
|
||||||
| 1.0 | 2025-01-22 | 길동 (Architect) | 초안 작성 (Flow 1-9) |
|
|
||||||
| 2.0 | 2025-10-22 | 길동 (Architect) | 신규 6개 플로우 추가 (Flow 10-15), 병렬 처리 전략 적용 |
|
|
||||||
@ -1,211 +0,0 @@
|
|||||||
@startuml Todo완료및회의록반영
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title 외부 시퀀스 다이어그램: Todo 완료 및 회의록 반영\n(Flow 5: Todo Completion and Meeting Minutes Reflection)
|
|
||||||
|
|
||||||
' 참여자 정의
|
|
||||||
actor "사용자\n(Todo 담당자)" as User
|
|
||||||
participant "Frontend" as FE
|
|
||||||
participant "API Gateway" as GW
|
|
||||||
participant "Todo Service" as TodoSvc
|
|
||||||
participant "Meeting Service" as MeetingSvc
|
|
||||||
participant "Notification Service" as NotifySvc
|
|
||||||
database "Todo DB" as TodoDB
|
|
||||||
database "Meeting DB" as MeetingDB
|
|
||||||
queue "RabbitMQ" as MQ
|
|
||||||
database "Redis Cache" as Redis
|
|
||||||
|
|
||||||
== Todo 완료 요청 ==
|
|
||||||
|
|
||||||
User -> FE: Todo 완료 버튼 클릭
|
|
||||||
activate FE
|
|
||||||
|
|
||||||
FE -> FE: 완료 여부 확인 다이얼로그 표시
|
|
||||||
FE --> User: 확인 요청 표시
|
|
||||||
User -> FE: 완료 확인
|
|
||||||
|
|
||||||
FE -> GW: PUT /todos/{todoId}/complete
|
|
||||||
activate GW
|
|
||||||
note right: JWT 인증 및 권한 검증
|
|
||||||
|
|
||||||
GW -> TodoSvc: PUT /todos/{todoId}/complete
|
|
||||||
activate TodoSvc
|
|
||||||
|
|
||||||
== Todo 완료 처리 ==
|
|
||||||
|
|
||||||
TodoSvc -> TodoDB: Todo 상태 업데이트\n(상태=완료, 완료시간, 완료자 기록)
|
|
||||||
activate TodoDB
|
|
||||||
TodoDB --> TodoSvc: 업데이트 완료
|
|
||||||
deactivate TodoDB
|
|
||||||
|
|
||||||
note right of TodoSvc
|
|
||||||
완료 처리 정보:
|
|
||||||
- 완료 시간 자동 기록
|
|
||||||
- 완료자 정보 저장
|
|
||||||
- 완료 상태로 변경
|
|
||||||
end note
|
|
||||||
|
|
||||||
== 캐시 무효화 ==
|
|
||||||
|
|
||||||
TodoSvc -> Redis: DEL todo:user:{userId}
|
|
||||||
activate Redis
|
|
||||||
Redis --> TodoSvc: 캐시 삭제 완료
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
TodoSvc -> Redis: DEL todo:stats:{userId}
|
|
||||||
activate Redis
|
|
||||||
Redis --> TodoSvc: 캐시 삭제 완료
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
note right of Redis
|
|
||||||
캐시 무효화 대상:
|
|
||||||
- todo:user:{userId}
|
|
||||||
- todo:stats:{userId}
|
|
||||||
end note
|
|
||||||
|
|
||||||
== TodoCompleted 이벤트 발행 ==
|
|
||||||
|
|
||||||
TodoSvc -> MQ: publish TodoCompleted\n(todoId, meetingId, userId, completedAt)
|
|
||||||
activate MQ
|
|
||||||
|
|
||||||
note right of MQ
|
|
||||||
이벤트 내용:
|
|
||||||
- todoId: Todo ID
|
|
||||||
- meetingId: 관련 회의 ID
|
|
||||||
- userId: 완료자 ID
|
|
||||||
- completedAt: 완료 시간
|
|
||||||
- sectionId: 회의록 섹션 ID
|
|
||||||
end note
|
|
||||||
|
|
||||||
TodoSvc --> GW: 200 OK\n(완료 처리 결과 반환)
|
|
||||||
deactivate TodoSvc
|
|
||||||
GW --> FE: 200 OK
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
FE -> FE: Todo 완료 상태 UI 업데이트
|
|
||||||
FE --> User: 완료 처리 완료 표시
|
|
||||||
deactivate FE
|
|
||||||
|
|
||||||
== Meeting Service: TodoCompleted 이벤트 구독 ==
|
|
||||||
|
|
||||||
MQ ->> MeetingSvc: TodoCompleted 이벤트 수신
|
|
||||||
activate MeetingSvc
|
|
||||||
|
|
||||||
note right of MeetingSvc
|
|
||||||
비동기 처리:
|
|
||||||
구독자가 이벤트 수신
|
|
||||||
end note
|
|
||||||
|
|
||||||
MeetingSvc -> Redis: GET meeting:info:{meetingId}
|
|
||||||
activate Redis
|
|
||||||
|
|
||||||
alt 캐시 Hit
|
|
||||||
Redis --> MeetingSvc: 회의 정보 반환
|
|
||||||
else 캐시 Miss
|
|
||||||
Redis --> MeetingSvc: null
|
|
||||||
MeetingSvc -> MeetingDB: SELECT 회의 정보
|
|
||||||
activate MeetingDB
|
|
||||||
MeetingDB --> MeetingSvc: 회의 정보 반환
|
|
||||||
deactivate MeetingDB
|
|
||||||
|
|
||||||
MeetingSvc -> Redis: SETEX meeting:info:{meetingId}\n(TTL: 10분)
|
|
||||||
Redis --> MeetingSvc: 캐시 저장 완료
|
|
||||||
end
|
|
||||||
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
note right of MeetingSvc
|
|
||||||
Cache-Aside 패턴 적용:
|
|
||||||
1. 캐시 조회 시도
|
|
||||||
2. 캐시 미스 시 DB 조회
|
|
||||||
3. 조회 결과 캐시 저장
|
|
||||||
end note
|
|
||||||
|
|
||||||
== 회의록에 완료 상태 자동 반영 ==
|
|
||||||
|
|
||||||
MeetingSvc -> MeetingDB: UPDATE 회의록 Todo 섹션\n(완료 상태, 완료 시간, 완료자)
|
|
||||||
activate MeetingDB
|
|
||||||
|
|
||||||
note right of MeetingDB
|
|
||||||
회의록 반영 내용:
|
|
||||||
- Todo 섹션에 완료 표시 (✅)
|
|
||||||
- 완료 시간 기록
|
|
||||||
- 완료자 정보 표시
|
|
||||||
- 양방향 연결 유지
|
|
||||||
end note
|
|
||||||
|
|
||||||
MeetingDB --> MeetingSvc: 업데이트 완료
|
|
||||||
deactivate MeetingDB
|
|
||||||
|
|
||||||
== 캐시 무효화 ==
|
|
||||||
|
|
||||||
MeetingSvc -> Redis: DEL meeting:info:{meetingId}
|
|
||||||
activate Redis
|
|
||||||
Redis --> MeetingSvc: 캐시 삭제 완료
|
|
||||||
deactivate Redis
|
|
||||||
|
|
||||||
note right of MeetingSvc
|
|
||||||
회의록 수정 시 캐시 무효화:
|
|
||||||
다음 조회 시 최신 정보 반영
|
|
||||||
end note
|
|
||||||
|
|
||||||
== TranscriptUpdated 이벤트 발행 (선택) ==
|
|
||||||
|
|
||||||
MeetingSvc -> MQ: publish TranscriptUpdated\n(meetingId, updateType=TODO_COMPLETED)
|
|
||||||
note right of MeetingSvc
|
|
||||||
선택적 이벤트:
|
|
||||||
실시간 협업 중인 경우
|
|
||||||
다른 참석자에게 알림 가능
|
|
||||||
end note
|
|
||||||
|
|
||||||
deactivate MeetingSvc
|
|
||||||
|
|
||||||
== Notification Service: TodoCompleted 이벤트 구독 ==
|
|
||||||
|
|
||||||
MQ ->> NotifySvc: TodoCompleted 이벤트 수신
|
|
||||||
activate NotifySvc
|
|
||||||
|
|
||||||
NotifySvc -> NotifySvc: 알림 내용 생성
|
|
||||||
note right of NotifySvc
|
|
||||||
알림 내용:
|
|
||||||
- Todo 완료 알림
|
|
||||||
- 회의록 작성자에게 발송
|
|
||||||
- 완료자 정보 포함
|
|
||||||
end note
|
|
||||||
|
|
||||||
NotifySvc -> NotifySvc: 회의록 알림 발송\n(이메일)
|
|
||||||
note right of NotifySvc
|
|
||||||
알림 발송 대상:
|
|
||||||
- 회의록 작성자
|
|
||||||
- 참석자 (선택)
|
|
||||||
end note
|
|
||||||
|
|
||||||
== 모든 Todo 완료 확인 ==
|
|
||||||
|
|
||||||
NotifySvc -> TodoDB: SELECT COUNT(*)\nWHERE meetingId={meetingId}\nAND status != COMPLETED
|
|
||||||
activate TodoDB
|
|
||||||
TodoDB --> NotifySvc: 미완료 Todo 개수 반환
|
|
||||||
deactivate TodoDB
|
|
||||||
|
|
||||||
alt 모든 Todo 완료
|
|
||||||
NotifySvc -> NotifySvc: 전체 완료 알림 생성
|
|
||||||
note right of NotifySvc
|
|
||||||
전체 완료 알림:
|
|
||||||
- "모든 Todo가 완료되었습니다"
|
|
||||||
- 회의록 작성자 및 참석자 전원 발송
|
|
||||||
end note
|
|
||||||
NotifySvc -> NotifySvc: 전체 완료 알림 발송\n(이메일)
|
|
||||||
end
|
|
||||||
|
|
||||||
deactivate NotifySvc
|
|
||||||
deactivate MQ
|
|
||||||
|
|
||||||
note over User, Redis
|
|
||||||
차별화 포인트:
|
|
||||||
- Todo 완료가 회의록에 실시간 반영되어 양방향 연동
|
|
||||||
- 회의 결과 추적 용이
|
|
||||||
- 완료 시간 및 완료자 정보 자동 기록
|
|
||||||
- 모든 Todo 완료 시 전체 완료 알림 자동 발송
|
|
||||||
end note
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 41 KiB |
@ -1,123 +0,0 @@
|
|||||||
@startuml 회의록조회및수정
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title 플로우 6: 회의록 조회 및 수정
|
|
||||||
|
|
||||||
actor "Frontend" as FE
|
|
||||||
participant "API Gateway" as GW
|
|
||||||
participant "Meeting Service" as MS
|
|
||||||
participant "Collaboration Service" as CS
|
|
||||||
participant "Redis" as RD
|
|
||||||
database "Meeting DB" as MDB
|
|
||||||
|
|
||||||
== 회의록 목록 조회 ==
|
|
||||||
FE -> GW: 회의록 목록 조회 요청\n(필터/정렬/검색 조건)
|
|
||||||
activate GW
|
|
||||||
GW -> MS: 목록 조회 요청
|
|
||||||
activate MS
|
|
||||||
|
|
||||||
MS -> RD: 캐시 조회 (Cache-Aside)\nKey: meeting:list:{userId}:{filter}
|
|
||||||
activate RD
|
|
||||||
|
|
||||||
alt Cache Hit
|
|
||||||
RD --> MS: 캐시 데이터 반환
|
|
||||||
MS --> GW: 목록 데이터 반환
|
|
||||||
GW --> FE: 목록 표시
|
|
||||||
else Cache Miss
|
|
||||||
RD --> MS: 캐시 없음
|
|
||||||
deactivate RD
|
|
||||||
MS -> MDB: DB 조회\n(필터, 정렬, 검색 조건 적용)
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 목록 데이터
|
|
||||||
deactivate MDB
|
|
||||||
MS -> RD: 캐시 저장 (TTL 10분)\nKey: meeting:list:{userId}:{filter}
|
|
||||||
activate RD
|
|
||||||
RD --> MS: 저장 완료
|
|
||||||
deactivate RD
|
|
||||||
MS --> GW: 목록 데이터 반환
|
|
||||||
GW --> FE: 목록 표시
|
|
||||||
end
|
|
||||||
|
|
||||||
deactivate MS
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
== 회의록 상세 조회 ==
|
|
||||||
FE -> GW: 회의록 클릭\n회의록 상세 조회 요청
|
|
||||||
activate GW
|
|
||||||
GW -> MS: 상세 조회 요청 (meetingId)
|
|
||||||
activate MS
|
|
||||||
|
|
||||||
MS -> RD: 캐시 조회 (Cache-Aside)\nKey: meeting:info:{meetingId}
|
|
||||||
activate RD
|
|
||||||
|
|
||||||
alt Cache Hit
|
|
||||||
RD --> MS: 캐시 데이터 반환\n(회의 정보, 섹션별 내용, 관련 회의록)
|
|
||||||
MS --> GW: 상세 데이터 반환
|
|
||||||
GW --> FE: 상세 정보 표시
|
|
||||||
else Cache Miss
|
|
||||||
RD --> MS: 캐시 없음
|
|
||||||
deactivate RD
|
|
||||||
MS -> MDB: DB 조회\n(회의 정보, 섹션별 내용, 관련 회의록)
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 상세 데이터
|
|
||||||
deactivate MDB
|
|
||||||
MS -> RD: 캐시 저장 (TTL 10분)\nKey: meeting:info:{meetingId}
|
|
||||||
activate RD
|
|
||||||
RD --> MS: 저장 완료
|
|
||||||
deactivate RD
|
|
||||||
MS --> GW: 상세 데이터 반환
|
|
||||||
GW --> FE: 상세 정보 표시
|
|
||||||
end
|
|
||||||
|
|
||||||
deactivate MS
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
== 회의록 수정 ==
|
|
||||||
FE -> GW: 수정 버튼 클릭
|
|
||||||
activate GW
|
|
||||||
GW -> MS: 권한 확인 요청
|
|
||||||
activate MS
|
|
||||||
MS -> MS: 수정 권한 검증\n(본인 작성 회의록만 수정 가능)
|
|
||||||
|
|
||||||
alt 권한 없음
|
|
||||||
MS --> GW: 권한 오류
|
|
||||||
GW --> FE: 수정 불가 알림
|
|
||||||
else 권한 있음
|
|
||||||
MS --> GW: 권한 확인 완료
|
|
||||||
GW --> FE: 수정 모드 진입
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
FE -> GW: 회의록 수정 내용 전송
|
|
||||||
activate GW
|
|
||||||
GW -> MS: 수정 요청
|
|
||||||
|
|
||||||
MS -> MDB: 수정 내용 저장\n수정 이력 기록\n(수정자, 수정 시간, 변경 내용)
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 저장 완료
|
|
||||||
deactivate MDB
|
|
||||||
|
|
||||||
MS -> RD: 캐시 무효화\nKey: meeting:info:{meetingId}
|
|
||||||
activate RD
|
|
||||||
RD --> MS: 무효화 완료
|
|
||||||
deactivate RD
|
|
||||||
|
|
||||||
MS ->> CS: 실시간 동기화 요청\n(비동기)
|
|
||||||
activate CS
|
|
||||||
CS ->> FE: WebSocket: 모든 참석자에게\n수정 델타 전송\n수정 영역 하이라이트 (3초간)
|
|
||||||
deactivate CS
|
|
||||||
|
|
||||||
MS -> MDB: 새 버전 번호 생성\n이전 버전 보관
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 버전 관리 완료
|
|
||||||
deactivate MDB
|
|
||||||
|
|
||||||
note over MS: 확정완료 상태였던 경우\n작성중 상태로 변경
|
|
||||||
|
|
||||||
MS --> GW: 수정 완료 응답
|
|
||||||
GW --> FE: 수정 완료 표시
|
|
||||||
end
|
|
||||||
|
|
||||||
deactivate MS
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,243 +0,0 @@
|
|||||||
@startuml 회의록확정및공유
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title 회의록 확정 및 공유 플로우 (UFR-MEET-060)
|
|
||||||
|
|
||||||
actor "사용자" as User
|
|
||||||
participant "Frontend" as FE
|
|
||||||
participant "API Gateway" as GW
|
|
||||||
participant "Meeting Service" as MS
|
|
||||||
participant "Notification Service" as NS
|
|
||||||
participant "Redis" as Cache
|
|
||||||
database "Meeting DB" as MDB
|
|
||||||
queue "RabbitMQ" as MQ
|
|
||||||
|
|
||||||
== 회의록 확정 ==
|
|
||||||
User -> FE: 회의록 확정 버튼 클릭
|
|
||||||
activate FE
|
|
||||||
|
|
||||||
FE -> GW: POST /api/meetings/{meetingId}/minutes/finalize
|
|
||||||
activate GW
|
|
||||||
|
|
||||||
GW -> MS: 회의록 확정 요청
|
|
||||||
activate MS
|
|
||||||
|
|
||||||
MS -> MS: 필수 항목 검사\n(제목, 참석자, 논의 내용, 결정 사항)
|
|
||||||
|
|
||||||
alt 필수 항목 누락
|
|
||||||
MS --> GW: 400 Bad Request\n{error: "필수 항목 누락", missingFields}
|
|
||||||
deactivate MS
|
|
||||||
GW --> FE: 오류 반환
|
|
||||||
deactivate GW
|
|
||||||
FE --> User: 필수 항목 누락 안내
|
|
||||||
deactivate FE
|
|
||||||
else 필수 항목 완료
|
|
||||||
MS -> MDB: INSERT INTO minutes_versions\n(확정 버전 생성, 확정 시간 기록)\nUPDATE meetings SET minutes_status = 'finalized'
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 확정 버전 ID 반환
|
|
||||||
deactivate MDB
|
|
||||||
|
|
||||||
MS -> Cache: DEL meeting:info:{meetingId}\n(캐시 무효화)
|
|
||||||
activate Cache
|
|
||||||
Cache --> MS: OK
|
|
||||||
deactivate Cache
|
|
||||||
|
|
||||||
MS --> GW: 200 OK\n{versionId, status: "finalized"}
|
|
||||||
deactivate MS
|
|
||||||
|
|
||||||
GW --> FE: 회의록 확정 완료
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
FE --> User: 회의록 확정 완료 화면 표시
|
|
||||||
deactivate FE
|
|
||||||
end
|
|
||||||
|
|
||||||
== 회의록 공유 설정 ==
|
|
||||||
User -> FE: 공유 설정 입력\n(대상: 참석자/전체/특정인, 권한: 읽기/편집, 방식: 링크/이메일)
|
|
||||||
activate FE
|
|
||||||
|
|
||||||
FE -> GW: POST /api/meetings/{meetingId}/share\n{targets, permission, method, password, expiresAt}
|
|
||||||
activate GW
|
|
||||||
|
|
||||||
GW -> MS: 공유 설정 요청
|
|
||||||
activate MS
|
|
||||||
|
|
||||||
MS -> MS: 고유 공유 링크 생성\n(UUID 기반 URL)
|
|
||||||
MS -> MDB: INSERT INTO share_settings\n(공유 대상, 권한, 링크, 비밀번호, 유효기간 저장)
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 공유 설정 ID 반환
|
|
||||||
deactivate MDB
|
|
||||||
|
|
||||||
MS -> Cache: SET share:link:{shareId}\n(공유 링크 정보 캐싱, TTL: 유효기간)
|
|
||||||
activate Cache
|
|
||||||
Cache --> MS: OK
|
|
||||||
deactivate Cache
|
|
||||||
|
|
||||||
MS ->> MQ: TranscriptShared 이벤트 발행\n{meetingId, shareId, targets, shareUrl, method}
|
|
||||||
activate MQ
|
|
||||||
note right of MQ
|
|
||||||
이벤트: TranscriptShared
|
|
||||||
Routing Key: transcript.shared
|
|
||||||
end note
|
|
||||||
MQ -->> MS: ACK
|
|
||||||
deactivate MQ
|
|
||||||
|
|
||||||
MS --> GW: 200 OK\n{shareUrl, shareId, expiresAt}
|
|
||||||
deactivate MS
|
|
||||||
|
|
||||||
GW --> FE: 공유 링크 반환
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
FE --> User: 공유 링크 및 설정 표시
|
|
||||||
deactivate FE
|
|
||||||
|
|
||||||
== 공유 알림 발송 (비동기) ==
|
|
||||||
MQ ->> NS: TranscriptShared 이벤트 전달
|
|
||||||
activate NS
|
|
||||||
note right of NS
|
|
||||||
구독: transcript.shared
|
|
||||||
큐: notification.transcript.shared
|
|
||||||
end note
|
|
||||||
|
|
||||||
alt 공유 방식: 이메일
|
|
||||||
loop 각 대상
|
|
||||||
NS -> NS: 이메일 템플릿 생성\n(회의 제목, 공유 링크, 유효기간, 비밀번호)
|
|
||||||
NS -> NS: 이메일 발송
|
|
||||||
end
|
|
||||||
else 공유 방식: 링크만
|
|
||||||
NS -> NS: 알림 생성\n(링크 복사 완료)
|
|
||||||
end
|
|
||||||
|
|
||||||
NS -->> MQ: ACK
|
|
||||||
deactivate NS
|
|
||||||
|
|
||||||
== 다음 회의 일정 자동 등록 (선택) ==
|
|
||||||
opt 회의록에 다음 회의 언급 존재
|
|
||||||
User -> FE: 다음 회의 일정 자동 등록 확인
|
|
||||||
activate FE
|
|
||||||
|
|
||||||
FE -> GW: POST /api/meetings/{meetingId}/schedule-next
|
|
||||||
activate GW
|
|
||||||
|
|
||||||
GW -> MS: 다음 회의 일정 등록 요청
|
|
||||||
activate MS
|
|
||||||
|
|
||||||
MS -> MDB: SELECT next_meeting_info\nFROM minutes\nWHERE meeting_id = {meetingId}
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 다음 회의 정보 반환\n{suggestedDate, suggestedTime, suggestedAttendees}
|
|
||||||
deactivate MDB
|
|
||||||
|
|
||||||
MS -> MS: 캘린더 등록 데이터 생성\n(제목, 날짜, 시간, 참석자)
|
|
||||||
MS -> MDB: INSERT INTO meetings\n(다음 회의 생성, 이전 회의 ID 링크)
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 다음 회의 ID 반환
|
|
||||||
deactivate MDB
|
|
||||||
|
|
||||||
MS ->> MQ: MeetingCreated 이벤트 발행\n(다음 회의 초대)
|
|
||||||
activate MQ
|
|
||||||
MQ -->> MS: ACK
|
|
||||||
deactivate MQ
|
|
||||||
|
|
||||||
MS --> GW: 200 OK\n{nextMeetingId, status: "scheduled"}
|
|
||||||
deactivate MS
|
|
||||||
|
|
||||||
GW --> FE: 다음 회의 등록 완료
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
FE --> User: 다음 회의 등록 완료 표시
|
|
||||||
deactivate FE
|
|
||||||
end
|
|
||||||
|
|
||||||
== 공유 링크 접근 (외부 사용자) ==
|
|
||||||
actor "외부 사용자" as External
|
|
||||||
External -> FE: 공유 링크 접근\n(GET /share/{shareId})
|
|
||||||
activate FE
|
|
||||||
|
|
||||||
FE -> GW: 공유 링크 검증 요청
|
|
||||||
activate GW
|
|
||||||
|
|
||||||
GW -> MS: 공유 설정 조회
|
|
||||||
activate MS
|
|
||||||
|
|
||||||
MS -> Cache: GET share:link:{shareId}
|
|
||||||
activate Cache
|
|
||||||
|
|
||||||
alt Cache Hit
|
|
||||||
Cache --> MS: 공유 설정 반환
|
|
||||||
else Cache Miss
|
|
||||||
Cache --> MS: null
|
|
||||||
MS -> MDB: SELECT * FROM share_settings\nWHERE share_id = {shareId}\nAND expires_at > NOW()
|
|
||||||
activate MDB
|
|
||||||
|
|
||||||
alt 유효한 공유 링크
|
|
||||||
MDB --> MS: 공유 설정 반환
|
|
||||||
deactivate MDB
|
|
||||||
|
|
||||||
MS -> Cache: SET share:link:{shareId}\n(TTL: 남은 유효기간)
|
|
||||||
Cache --> MS: OK
|
|
||||||
else 만료 또는 존재하지 않음
|
|
||||||
MDB --> MS: null
|
|
||||||
deactivate MDB
|
|
||||||
Cache --> MS: null
|
|
||||||
MS --> GW: 404 Not Found\n{error: "공유 링크가 만료되었거나 존재하지 않습니다"}
|
|
||||||
deactivate MS
|
|
||||||
GW --> FE: 오류 반환
|
|
||||||
deactivate GW
|
|
||||||
FE --> External: 오류 화면 표시
|
|
||||||
deactivate FE
|
|
||||||
end
|
|
||||||
end
|
|
||||||
deactivate Cache
|
|
||||||
|
|
||||||
alt 비밀번호 설정된 경우
|
|
||||||
MS --> GW: 비밀번호 요청
|
|
||||||
deactivate MS
|
|
||||||
GW --> FE: 비밀번호 입력 화면
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
External -> FE: 비밀번호 입력
|
|
||||||
FE -> GW: 비밀번호 검증 요청
|
|
||||||
activate GW
|
|
||||||
|
|
||||||
GW -> MS: 비밀번호 검증
|
|
||||||
activate MS
|
|
||||||
|
|
||||||
alt 비밀번호 일치
|
|
||||||
MS -> MDB: SELECT minutes\nFROM meetings\nWHERE meeting_id = {meetingId}
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 회의록 반환
|
|
||||||
deactivate MDB
|
|
||||||
|
|
||||||
MS --> GW: 200 OK\n{minutes, permission}
|
|
||||||
deactivate MS
|
|
||||||
|
|
||||||
GW --> FE: 회의록 데이터 반환
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
FE --> External: 회의록 표시\n(권한에 따라 읽기/편집)
|
|
||||||
deactivate FE
|
|
||||||
else 비밀번호 불일치
|
|
||||||
MS --> GW: 401 Unauthorized\n{error: "비밀번호가 일치하지 않습니다"}
|
|
||||||
deactivate MS
|
|
||||||
GW --> FE: 오류 반환
|
|
||||||
deactivate GW
|
|
||||||
FE --> External: 오류 화면 표시
|
|
||||||
deactivate FE
|
|
||||||
end
|
|
||||||
else 비밀번호 미설정
|
|
||||||
MS -> MDB: SELECT minutes\nFROM meetings\nWHERE meeting_id = {meetingId}
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 회의록 반환
|
|
||||||
deactivate MDB
|
|
||||||
|
|
||||||
MS --> GW: 200 OK\n{minutes, permission}
|
|
||||||
deactivate MS
|
|
||||||
|
|
||||||
GW --> FE: 회의록 데이터 반환
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
FE --> External: 회의록 표시\n(권한에 따라 읽기/편집)
|
|
||||||
deactivate FE
|
|
||||||
end
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,170 +0,0 @@
|
|||||||
@startuml 회의시작및회의록작성
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title 회의 시작 및 회의록 작성 플로우 (UFR-MEET-030, UFR-STT-010/020, UFR-AI-010, UFR-RAG-010/020, UFR-COLLAB-010)
|
|
||||||
|
|
||||||
actor "참석자" as User
|
|
||||||
participant "Frontend" as FE
|
|
||||||
participant "API Gateway" as GW
|
|
||||||
participant "Meeting Service" as MS
|
|
||||||
participant "STT Service" as STT
|
|
||||||
participant "AI Service" as AI
|
|
||||||
participant "RAG Service" as RAG
|
|
||||||
participant "Collaboration Service" as CS
|
|
||||||
participant "Redis" as Cache
|
|
||||||
database "Meeting DB" as MDB
|
|
||||||
database "STT DB" as STTDB
|
|
||||||
database "AI DB" as AIDB
|
|
||||||
database "RAG DB" as RAGDB
|
|
||||||
queue "RabbitMQ" as MQ
|
|
||||||
participant "Azure Speech" as Azure
|
|
||||||
participant "LLM Server" as LLM
|
|
||||||
|
|
||||||
== 회의 시작 ==
|
|
||||||
User -> FE: 회의 시작 버튼 클릭
|
|
||||||
activate FE
|
|
||||||
|
|
||||||
FE -> GW: POST /api/meetings/{meetingId}/start
|
|
||||||
activate GW
|
|
||||||
|
|
||||||
GW -> MS: 회의 시작 요청
|
|
||||||
activate MS
|
|
||||||
|
|
||||||
MS -> MDB: UPDATE meetings\nSET start_time = NOW(), status = 'in_progress'\n세션 생성
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 회의 시작 시간 기록 완료
|
|
||||||
deactivate MDB
|
|
||||||
|
|
||||||
MS ->> MQ: MeetingStarted 이벤트 발행\n{meetingId, sessionId, startTime}
|
|
||||||
activate MQ
|
|
||||||
note right of MQ
|
|
||||||
이벤트: MeetingStarted
|
|
||||||
Routing Key: meeting.started
|
|
||||||
end note
|
|
||||||
MQ -->> MS: ACK
|
|
||||||
deactivate MQ
|
|
||||||
|
|
||||||
MS --> GW: 200 OK\n{sessionId, status: "in_progress"}
|
|
||||||
deactivate MS
|
|
||||||
|
|
||||||
GW --> FE: 회의 세션 정보 반환
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
FE --> User: 회의 진행 화면 표시
|
|
||||||
deactivate FE
|
|
||||||
|
|
||||||
== 음성 녹음 시작 (비동기) ==
|
|
||||||
MQ ->> STT: MeetingStarted 이벤트 전달
|
|
||||||
activate STT
|
|
||||||
note right of STT
|
|
||||||
구독: meeting.started
|
|
||||||
큐: stt.meeting.started
|
|
||||||
end note
|
|
||||||
|
|
||||||
STT -> STTDB: INSERT INTO sessions\n(세션 생성)
|
|
||||||
activate STTDB
|
|
||||||
STTDB --> STT: 세션 ID 반환
|
|
||||||
deactivate STTDB
|
|
||||||
|
|
||||||
STT -> STT: 음성 녹음 시작\n(실시간 스트림)
|
|
||||||
STT -->> MQ: ACK
|
|
||||||
deactivate STT
|
|
||||||
|
|
||||||
== 실시간 음성 인식 (5초 간격 반복) ==
|
|
||||||
loop 발언 발생 (5초마다)
|
|
||||||
User -> FE: 음성 발언
|
|
||||||
activate FE
|
|
||||||
|
|
||||||
FE -> STT: 오디오 스트림 전송
|
|
||||||
activate STT
|
|
||||||
|
|
||||||
STT -> Azure: 음성-텍스트 변환 요청\n(실시간 스트림)
|
|
||||||
activate Azure
|
|
||||||
Azure --> STT: 변환된 텍스트 반환\n{speaker, text, timestamp}
|
|
||||||
deactivate Azure
|
|
||||||
|
|
||||||
STT -> STTDB: INSERT INTO transcripts\n(발언 텍스트 저장)
|
|
||||||
activate STTDB
|
|
||||||
STTDB --> STT: OK
|
|
||||||
deactivate STTDB
|
|
||||||
|
|
||||||
STT ->> MQ: TranscriptReady 이벤트 발행\n{sessionId, speaker, text, timestamp}
|
|
||||||
activate MQ
|
|
||||||
note right of MQ
|
|
||||||
이벤트: TranscriptReady
|
|
||||||
Routing Key: transcript.ready
|
|
||||||
주기: 5초
|
|
||||||
end note
|
|
||||||
MQ -->> STT: ACK
|
|
||||||
deactivate MQ
|
|
||||||
deactivate STT
|
|
||||||
|
|
||||||
== AI 회의록 자동 작성 (비동기) ==
|
|
||||||
MQ ->> AI: TranscriptReady 이벤트 전달
|
|
||||||
activate AI
|
|
||||||
note right of AI
|
|
||||||
구독: transcript.ready
|
|
||||||
큐: ai.transcript.ready
|
|
||||||
end note
|
|
||||||
|
|
||||||
AI -> AI: 회의 맥락 이해\n주제별 분류\n문장 다듬기
|
|
||||||
AI -> LLM: 회의록 자동 작성 요청\n{context, transcript, history}
|
|
||||||
activate LLM
|
|
||||||
LLM --> AI: 회의록 초안 반환\n{summary, topics, keyPoints}
|
|
||||||
deactivate LLM
|
|
||||||
|
|
||||||
AI -> AIDB: INSERT INTO minutes_draft\n(회의록 초안 저장)
|
|
||||||
activate AIDB
|
|
||||||
AIDB --> AI: OK
|
|
||||||
deactivate AIDB
|
|
||||||
|
|
||||||
AI -> CS: 실시간 동기화 요청\n{delta, version}
|
|
||||||
activate CS
|
|
||||||
|
|
||||||
CS -> FE: WebSocket 푸시\n(회의록 델타 전송)
|
|
||||||
activate FE
|
|
||||||
FE -> User: 회의록 실시간 업데이트 표시
|
|
||||||
deactivate FE
|
|
||||||
|
|
||||||
CS --> AI: 동기화 완료
|
|
||||||
deactivate CS
|
|
||||||
|
|
||||||
AI -->> MQ: ACK
|
|
||||||
deactivate AI
|
|
||||||
|
|
||||||
== 전문용어 자동 감지 및 설명 (비동기) ==
|
|
||||||
MQ ->> RAG: TranscriptReady 이벤트 전달
|
|
||||||
activate RAG
|
|
||||||
note right of RAG
|
|
||||||
구독: transcript.ready
|
|
||||||
큐: rag.transcript.ready
|
|
||||||
end note
|
|
||||||
|
|
||||||
RAG -> RAG: 전문용어 자동 감지\n(NER, 도메인 사전)
|
|
||||||
RAG -> RAGDB: SELECT explanation\nFROM terms\nWHERE term IN (detected_terms)
|
|
||||||
activate RAGDB
|
|
||||||
RAGDB --> RAG: 용어 설명 반환
|
|
||||||
deactivate RAGDB
|
|
||||||
|
|
||||||
alt 맥락 기반 설명 필요
|
|
||||||
RAG -> LLM: 맥락 기반 설명 생성 요청\n{term, context, domain}
|
|
||||||
activate LLM
|
|
||||||
LLM --> RAG: 맥락적 설명 반환
|
|
||||||
deactivate LLM
|
|
||||||
|
|
||||||
RAG -> RAGDB: INSERT INTO explanations\n(생성된 설명 저장)
|
|
||||||
activate RAGDB
|
|
||||||
RAGDB --> RAG: OK
|
|
||||||
deactivate RAGDB
|
|
||||||
end
|
|
||||||
|
|
||||||
RAG -> FE: WebSocket 푸시\n(용어 설명 툴팁 데이터)
|
|
||||||
activate FE
|
|
||||||
FE -> User: 용어 설명 툴팁 표시
|
|
||||||
deactivate FE
|
|
||||||
|
|
||||||
RAG -->> MQ: ACK
|
|
||||||
deactivate RAG
|
|
||||||
end
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
@startuml 회의예약및초대
|
|
||||||
!theme mono
|
|
||||||
|
|
||||||
title 회의 예약 및 초대 플로우 (UFR-MEET-010)
|
|
||||||
|
|
||||||
actor "사용자" as User
|
|
||||||
participant "Frontend" as FE
|
|
||||||
participant "API Gateway" as GW
|
|
||||||
participant "Meeting Service" as MS
|
|
||||||
participant "User Service" as US
|
|
||||||
participant "Redis" as Cache
|
|
||||||
database "Meeting DB" as MDB
|
|
||||||
queue "RabbitMQ" as MQ
|
|
||||||
participant "Notification Service" as NS
|
|
||||||
|
|
||||||
User -> FE: 회의 정보 입력\n(제목, 날짜/시간, 장소, 참석자)
|
|
||||||
activate FE
|
|
||||||
|
|
||||||
FE -> GW: POST /api/meetings\n(회의 예약 요청)
|
|
||||||
activate GW
|
|
||||||
|
|
||||||
GW -> MS: 회의 생성 요청
|
|
||||||
activate MS
|
|
||||||
|
|
||||||
== 참석자 정보 조회 (Cache-Aside 패턴) ==
|
|
||||||
loop 각 참석자
|
|
||||||
MS -> Cache: GET user:profile:{userId}
|
|
||||||
activate Cache
|
|
||||||
|
|
||||||
alt Cache Hit
|
|
||||||
Cache --> MS: 사용자 정보 반환
|
|
||||||
else Cache Miss
|
|
||||||
Cache --> MS: null
|
|
||||||
MS -> US: GET /api/users/{userId}\n(사용자 프로필 조회)
|
|
||||||
activate US
|
|
||||||
US --> MS: 사용자 정보 반환
|
|
||||||
deactivate US
|
|
||||||
|
|
||||||
MS -> Cache: SET user:profile:{userId}\n(TTL: 10분)
|
|
||||||
Cache --> MS: OK
|
|
||||||
end
|
|
||||||
deactivate Cache
|
|
||||||
end
|
|
||||||
|
|
||||||
== 회의 정보 저장 ==
|
|
||||||
MS -> MDB: INSERT INTO meetings\n(회의 정보 저장)
|
|
||||||
activate MDB
|
|
||||||
MDB --> MS: 회의 ID 반환
|
|
||||||
deactivate MDB
|
|
||||||
|
|
||||||
MS -> Cache: SET meeting:info:{meetingId}\n(TTL: 10분)
|
|
||||||
activate Cache
|
|
||||||
Cache --> MS: OK
|
|
||||||
deactivate Cache
|
|
||||||
|
|
||||||
== 초대 이벤트 발행 (비동기) ==
|
|
||||||
MS ->> MQ: MeetingCreated 이벤트 발행\n{meetingId, title, attendees, datetime}
|
|
||||||
activate MQ
|
|
||||||
note right of MQ
|
|
||||||
이벤트: MeetingCreated
|
|
||||||
Routing Key: meeting.created
|
|
||||||
end note
|
|
||||||
MQ -->> MS: ACK
|
|
||||||
deactivate MQ
|
|
||||||
|
|
||||||
MS --> GW: 회의 ID 반환\n{meetingId, status: "scheduled"}
|
|
||||||
deactivate MS
|
|
||||||
|
|
||||||
GW --> FE: 201 Created\n회의 생성 완료
|
|
||||||
deactivate GW
|
|
||||||
|
|
||||||
FE --> User: 회의 예약 완료 화면 표시
|
|
||||||
deactivate FE
|
|
||||||
|
|
||||||
== 초대 이메일 발송 (비동기) ==
|
|
||||||
MQ ->> NS: MeetingCreated 이벤트 전달
|
|
||||||
activate NS
|
|
||||||
note right of NS
|
|
||||||
구독: meeting.created
|
|
||||||
큐: notification.meeting.created
|
|
||||||
end note
|
|
||||||
|
|
||||||
loop 각 참석자
|
|
||||||
NS -> NS: 이메일 템플릿 생성\n(회의 제목, 일시, 장소, 초대 링크)
|
|
||||||
NS -> NS: 이메일 발송
|
|
||||||
end
|
|
||||||
|
|
||||||
NS -->> MQ: ACK
|
|
||||||
deactivate NS
|
|
||||||
|
|
||||||
@enduml
|
|
||||||
@ -1,194 +0,0 @@
|
|||||||
@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
|
|
||||||
@ -26,14 +26,24 @@
|
|||||||
|
|
||||||
## 마이크로서비스 구성
|
## 마이크로서비스 구성
|
||||||
|
|
||||||
1. **User** - 사용자 인증 및 권한 관리
|
1. **User** - 사용자 인증 (LDAP 연동, JWT 토큰 발급/검증)
|
||||||
2. **Meeting** - 회의 관리, 회의록 생성 및 관리, 회의록 공유
|
2. **Meeting** - 회의, 회의록, Todo, 실시간 협업 통합 관리
|
||||||
|
- 회의 관리: 회의 예약, 시작, 종료
|
||||||
|
- 회의록 관리: 회의록 생성, 수정, 확정, 공유
|
||||||
|
- Todo 관리: Todo 할당, 진행 상황 추적, 회의록 양방향 연결
|
||||||
|
- 실시간 협업: WebSocket 기반 실시간 동기화, 버전 관리, 충돌 해결
|
||||||
|
- 템플릿 관리: 회의록 템플릿 관리
|
||||||
|
- 통계 생성: 회의 및 Todo 통계
|
||||||
3. **STT** - 음성 녹음 관리, 음성-텍스트 변환, 화자 식별 (기본 기능)
|
3. **STT** - 음성 녹음 관리, 음성-텍스트 변환, 화자 식별 (기본 기능)
|
||||||
4. **AI** - LLM 기반 회의록 자동 작성, Todo 자동 추출, 프롬프팅 기반 회의록 개선
|
4. **AI** - AI 기반 회의록 자동화, Todo 추출, 지능형 검색 (RAG 통합)
|
||||||
5. **RAG** - 맥락 기반 용어 설명, 관련 문서 검색 및 연결, 업무 이력 통합
|
- LLM 기반 회의록 자동 작성
|
||||||
6. **Collaboration** - 실시간 동기화, 버전 관리, 충돌 해결
|
- Todo 자동 추출 및 담당자 식별
|
||||||
7. **Todo** - Todo 할당 및 관리, 진행 상황 추적, 회의록 실시간 연동
|
- 프롬프팅 기반 회의록 개선 (1Page 요약, 핵심 요약 등)
|
||||||
8. **Notification** - 알림 발송 및 리마인더 관리
|
- 관련 회의록 자동 연결 (벡터 유사도 검색)
|
||||||
|
- 전문용어 자동 감지 및 맥락 기반 설명 생성 (RAG)
|
||||||
|
- 과거 회의록 및 사내 문서 검색
|
||||||
|
- 업무 이력 통합
|
||||||
|
5. **Notification** - 알림 발송 및 리마인더 관리
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -55,6 +65,11 @@ AFR-USER-020: [대시보드] 사용자로서 | 나는, 회의록 서비스의
|
|||||||
- 시나리오: 대시보드 조회
|
- 시나리오: 대시보드 조회
|
||||||
로그인 후 대시보드에 접근하면 | 예정된 회의, 진행 중 Todo, 최근 회의록 등 주요 정보가 표시되고 | 플로팅 액션 버튼을 통해 새 회의를 시작하거나 예약할 수 있다.
|
로그인 후 대시보드에 접근하면 | 예정된 회의, 진행 중 Todo, 최근 회의록 등 주요 정보가 표시되고 | 플로팅 액션 버튼을 통해 새 회의를 시작하거나 예약할 수 있다.
|
||||||
|
|
||||||
|
**변경사항 (논리 아키텍처)**:
|
||||||
|
- 프론트엔드가 Meeting Service에 직접 API 요청하여 회의, Todo, 회의록 정보 조회
|
||||||
|
- User Service는 인증만 담당 (JWT 토큰 검증)
|
||||||
|
- 모든 API 요청에 사용자 정보(userId, userName, email) 포함
|
||||||
|
|
||||||
[대시보드 주요 위젯]
|
[대시보드 주요 위젯]
|
||||||
- 사용자 인사말 (이름 표시)
|
- 사용자 인사말 (이름 표시)
|
||||||
- 통계 카드:
|
- 통계 카드:
|
||||||
@ -110,7 +125,7 @@ AFR-USER-020: [대시보드] 사용자로서 | 나는, 회의록 서비스의
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
2. Meeting 서비스
|
2. Meeting 서비스 (회의, 회의록, Todo, 실시간 협업 통합)
|
||||||
1) 회의 준비 및 관리
|
1) 회의 준비 및 관리
|
||||||
UFR-MEET-010: [회의예약] 회의록 작성자로서 | 나는, 회의를 효율적으로 준비하기 위해 | 회의를 예약하고 참석자를 초대하고 싶다.
|
UFR-MEET-010: [회의예약] 회의록 작성자로서 | 나는, 회의를 효율적으로 준비하기 위해 | 회의를 예약하고 참석자를 초대하고 싶다.
|
||||||
- 시나리오: 회의 예약 및 참석자 초대
|
- 시나리오: 회의 예약 및 참석자 초대
|
||||||
@ -358,7 +373,7 @@ UFR-MEET-060: [회의록공유] 회의록 작성자로서 | 나는, 회의 내
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
3. STT 서비스 (기본 기능)
|
3. STT 서비스 (음성 인식 및 변환 - 기본 기능)
|
||||||
1) 음성 인식 및 변환
|
1) 음성 인식 및 변환
|
||||||
UFR-STT-010: [음성녹음인식] 회의 참석자로서 | 나는, 발언 내용이 자동으로 기록되기 위해 | 음성이 실시간으로 녹음되고 인식되기를 원한다.
|
UFR-STT-010: [음성녹음인식] 회의 참석자로서 | 나는, 발언 내용이 자동으로 기록되기 위해 | 음성이 실시간으로 녹음되고 인식되기를 원한다.
|
||||||
- 시나리오: 음성 녹음 및 발언 인식
|
- 시나리오: 음성 녹음 및 발언 인식
|
||||||
@ -422,7 +437,7 @@ UFR-STT-020: [텍스트변환] 회의록 시스템으로서 | 나는, 인식된
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
4. AI 서비스 (차별화 포인트)
|
4. AI 서비스 (AI 기반 회의록 자동화, Todo 추출, 지능형 검색 - RAG 통합)
|
||||||
1) AI 회의록 작성
|
1) AI 회의록 작성
|
||||||
UFR-AI-010: [회의록자동작성] 회의록 작성자로서 | 나는, 회의록 작성 부담을 줄이기 위해 | AI가 발언 내용을 자동으로 정리하여 회의록을 작성하기를 원한다.
|
UFR-AI-010: [회의록자동작성] 회의록 작성자로서 | 나는, 회의록 작성 부담을 줄이기 위해 | AI가 발언 내용을 자동으로 정리하여 회의록을 작성하기를 원한다.
|
||||||
- 시나리오: AI 회의록 자동 작성
|
- 시나리오: AI 회의록 자동 작성
|
||||||
@ -573,12 +588,18 @@ UFR-AI-040: [관련회의록연결] 회의록 작성자로서 | 나는, 이전
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
5. RAG 서비스 (차별화 포인트)
|
5. AI 서비스 (지능형 검색 - RAG 기능, AI Service에 통합됨)
|
||||||
1) 맥락 기반 용어 설명 (강화)
|
1) 맥락 기반 용어 설명 (강화)
|
||||||
UFR-RAG-010: [전문용어감지] 회의록 작성자로서 | 나는, 업무 지식이 없어도 회의록을 정확히 작성하기 위해 | 전문용어가 자동으로 감지되고 맥락에 맞는 설명을 제공받고 싶다.
|
UFR-RAG-010: [전문용어감지] 회의록 작성자로서 | 나는, 업무 지식이 없어도 회의록을 정확히 작성하기 위해 | 전문용어가 자동으로 감지되고 맥락에 맞는 설명을 제공받고 싶다.
|
||||||
- 시나리오: 맥락 기반 전문용어 자동 감지
|
- 시나리오: 맥락 기반 전문용어 자동 감지
|
||||||
회의록이 작성되는 상황에서 | 시스템이 회의록 텍스트를 분석하면 | 전문용어가 자동으로 감지되고 맥락에 맞는 설명이 준비된다.
|
회의록이 작성되는 상황에서 | 시스템이 회의록 텍스트를 분석하면 | 전문용어가 자동으로 감지되고 맥락에 맞는 설명이 준비된다.
|
||||||
|
|
||||||
|
**변경사항 (논리 아키텍처)**:
|
||||||
|
- AI Service에 RAG 기능 통합
|
||||||
|
- RAG와 AI 모두 LLM 기반 처리로 긴밀하게 연동
|
||||||
|
- 동일한 벡터 임베딩 모델 및 LLM 공유 가능
|
||||||
|
- 회의록 자동 작성 시 용어 설명이 병렬 처리되어 효율적
|
||||||
|
|
||||||
[전문용어 감지 처리]
|
[전문용어 감지 처리]
|
||||||
- 회의록 텍스트 실시간 분석
|
- 회의록 텍스트 실시간 분석
|
||||||
- 용어 사전과 비교
|
- 용어 사전과 비교
|
||||||
@ -655,12 +676,17 @@ UFR-RAG-020: [맥락기반용어설명] 회의록 작성자로서 | 나는, 전
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
6. Collaboration 서비스
|
6. Meeting 서비스 (실시간 협업 - Meeting Service에 통합됨)
|
||||||
1) 실시간 협업
|
1) 실시간 협업
|
||||||
UFR-COLLAB-010: [회의록수정동기화] 회의 참석자로서 | 나는, 회의록을 함께 검증하기 위해 | 회의록을 수정하고 실시간으로 다른 참석자와 동기화하고 싶다.
|
UFR-COLLAB-010: [회의록수정동기화] 회의 참석자로서 | 나는, 회의록을 함께 검증하기 위해 | 회의록을 수정하고 실시간으로 다른 참석자와 동기화하고 싶다.
|
||||||
- 시나리오: 회의록 실시간 수정 및 동기화
|
- 시나리오: 회의록 실시간 수정 및 동기화
|
||||||
회의록 초안이 작성된 상황에서 | 참석자가 회의록 내용을 수정하면 | 수정 사항이 버전 관리되고 웹소켓을 통해 모든 참석자에게 즉시 동기화된다.
|
회의록 초안이 작성된 상황에서 | 참석자가 회의록 내용을 수정하면 | 수정 사항이 버전 관리되고 웹소켓을 통해 모든 참석자에게 즉시 동기화된다.
|
||||||
|
|
||||||
|
**변경사항 (논리 아키텍처)**:
|
||||||
|
- Meeting Service에 실시간 협업 기능 통합
|
||||||
|
- WebSocket, 버전 관리, 충돌 해결이 Meeting Service 내부에서 처리됨
|
||||||
|
- 서비스 간 통신 오버헤드 제거, 성능 향상
|
||||||
|
|
||||||
[회의록 수정 처리]
|
[회의록 수정 처리]
|
||||||
- 수정 내용 검증
|
- 수정 내용 검증
|
||||||
- 수정 권한 확인
|
- 수정 권한 확인
|
||||||
@ -766,12 +792,17 @@ UFR-COLLAB-030: [검증완료] 회의 참석자로서 | 나는, 회의록의 정
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
7. Todo 서비스 (차별화 포인트)
|
7. Meeting 서비스 (Todo 관리 - Meeting Service에 통합됨, 차별화 포인트)
|
||||||
1) 실시간 Todo 연결 (강화)
|
1) 실시간 Todo 연결 (강화)
|
||||||
UFR-TODO-010: [Todo할당] Todo 시스템으로서 | 나는, AI가 추출한 Todo를 담당자에게 전달하기 위해 | Todo를 실시간으로 할당하고 회의록과 연결하고 싶다.
|
UFR-TODO-010: [Todo할당] Todo 시스템으로서 | 나는, AI가 추출한 Todo를 담당자에게 전달하기 위해 | Todo를 실시간으로 할당하고 회의록과 연결하고 싶다.
|
||||||
- 시나리오: Todo 실시간 할당 및 회의록 연결
|
- 시나리오: Todo 실시간 할당 및 회의록 연결
|
||||||
AI가 Todo를 추출한 상황에서 | 시스템이 Todo를 등록하고 담당자를 지정하면 | Todo가 실시간으로 할당되고 회의록의 해당 위치와 연결되며 담당자에게 즉시 알림이 발송된다.
|
AI가 Todo를 추출한 상황에서 | 시스템이 Todo를 등록하고 담당자를 지정하면 | Todo가 실시간으로 할당되고 회의록의 해당 위치와 연결되며 담당자에게 즉시 알림이 발송된다.
|
||||||
|
|
||||||
|
**변경사항 (논리 아키텍처)**:
|
||||||
|
- Meeting Service에 Todo 관리 기능 통합
|
||||||
|
- Todo와 회의록이 동일 트랜잭션 내에서 처리 가능
|
||||||
|
- 회의록-Todo 양방향 연결이 내부 메서드 호출로 처리됨 (10배 빠름)
|
||||||
|
|
||||||
[Todo 등록]
|
[Todo 등록]
|
||||||
- Todo 정보 저장
|
- Todo 정보 저장
|
||||||
- Todo ID 생성
|
- Todo ID 생성
|
||||||
@ -856,3 +887,96 @@ UFR-TODO-030: [Todo완료처리] Todo 담당자로서 | 나는, 완료된 Todo
|
|||||||
- M/8
|
- M/8
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 논리 아키텍처 반영 사항 요약
|
||||||
|
|
||||||
|
### 1. 마이크로서비스 구성 변경 (v2.0)
|
||||||
|
|
||||||
|
**변경 전 (v1.0)**: 8개 마이크로서비스
|
||||||
|
- User, Meeting, STT, AI, RAG, Collaboration, Todo, Notification
|
||||||
|
|
||||||
|
**변경 후 (v2.0)**: 5개 마이크로서비스
|
||||||
|
- User, Meeting, STT, AI, Notification
|
||||||
|
|
||||||
|
### 2. 주요 변경사항
|
||||||
|
|
||||||
|
#### 2.1 User Service 역할 변경
|
||||||
|
- **변경 전**: 사용자 인증 및 권한 관리, 대시보드 정보 제공
|
||||||
|
- **변경 후**: 사용자 인증 전용 (LDAP 연동, JWT 토큰 발급/검증)
|
||||||
|
- **이유**:
|
||||||
|
- 프론트엔드가 모든 API 요청에 사용자 정보(userId, userName, email) 포함
|
||||||
|
- User Service 동기 호출 제거 → 성능 향상, 장애 격리
|
||||||
|
- 네트워크 지연 제거 (~100ms 개선)
|
||||||
|
|
||||||
|
#### 2.2 Meeting Service 통합
|
||||||
|
- **통합 서비스**: Meeting + Collaboration + Todo
|
||||||
|
- **핵심 기능**:
|
||||||
|
- 회의 관리: 회의 예약, 시작, 종료
|
||||||
|
- 회의록 관리: 회의록 생성, 수정, 확정, 공유
|
||||||
|
- Todo 관리: Todo 할당, 진행 상황 추적, 회의록 양방향 연결
|
||||||
|
- 실시간 협업: WebSocket 기반 실시간 동기화, 버전 관리, 충돌 해결
|
||||||
|
- **이점**:
|
||||||
|
- 서비스 간 통신 오버헤드 제거
|
||||||
|
- Todo와 회의록이 동일 트랜잭션 내에서 처리 가능
|
||||||
|
- 일관성 향상, 개발 효율성 증가
|
||||||
|
- 내부 메서드 호출로 처리 속도 10배 향상
|
||||||
|
|
||||||
|
#### 2.3 AI Service 통합
|
||||||
|
- **통합 서비스**: AI + RAG
|
||||||
|
- **핵심 기능**:
|
||||||
|
- LLM 기반 회의록 자동 작성
|
||||||
|
- Todo 자동 추출 및 담당자 식별
|
||||||
|
- 프롬프팅 기반 회의록 개선
|
||||||
|
- 관련 회의록 자동 연결 (벡터 유사도 검색)
|
||||||
|
- 전문용어 자동 감지 및 맥락 기반 설명 생성 (RAG)
|
||||||
|
- 과거 회의록 및 사내 문서 검색
|
||||||
|
- **이점**:
|
||||||
|
- RAG와 AI 모두 LLM 기반 처리로 긴밀하게 연동
|
||||||
|
- 동일한 벡터 임베딩 모델 및 LLM 공유 가능
|
||||||
|
- 회의록 자동 작성 시 용어 설명이 병렬 처리되어 효율적
|
||||||
|
- 서비스 개수 감소로 운영 복잡도 감소
|
||||||
|
|
||||||
|
### 3. 유저스토리 영향도
|
||||||
|
|
||||||
|
#### 3.1 변경 없음
|
||||||
|
- STT 서비스 유저스토리: UFR-STT-010, UFR-STT-020
|
||||||
|
- Notification 서비스 유저스토리: 알림 발송 관련
|
||||||
|
|
||||||
|
#### 3.2 서비스 통합에 따른 변경
|
||||||
|
- **Collaboration → Meeting**: UFR-COLLAB-010, UFR-COLLAB-020, UFR-COLLAB-030
|
||||||
|
- **Todo → Meeting**: UFR-TODO-010, UFR-TODO-030
|
||||||
|
- **RAG → AI**: UFR-RAG-010, UFR-RAG-020
|
||||||
|
|
||||||
|
#### 3.3 기능적 변경
|
||||||
|
- **AFR-USER-020 (대시보드)**:
|
||||||
|
- 프론트엔드가 Meeting Service에 직접 API 요청
|
||||||
|
- User Service는 인증만 담당
|
||||||
|
|
||||||
|
### 4. 성능 개선 효과
|
||||||
|
|
||||||
|
| 항목 | 개선 전 | 개선 후 | 효과 |
|
||||||
|
|------|---------|---------|------|
|
||||||
|
| User Service 동기 호출 | ~100ms | 제거 | 네트워크 지연 제거 |
|
||||||
|
| Todo 처리 | 서비스 간 통신 | 내부 메서드 호출 | 10배 빠름 |
|
||||||
|
| 실시간 동기화 | 서비스 간 REST API | Meeting 내부 처리 | 지연 감소 |
|
||||||
|
| 서비스 개수 | 8개 | 5개 | 운영 복잡도 감소 |
|
||||||
|
|
||||||
|
### 5. 차별화 전략 유지
|
||||||
|
|
||||||
|
논리 아키텍처 변경에도 불구하고 차별화 포인트는 그대로 유지됩니다:
|
||||||
|
|
||||||
|
- ✅ **맥락 기반 용어 설명**: AI Service에서 RAG 기능 통합 제공
|
||||||
|
- ✅ **강화된 Todo 연결**: Meeting Service에서 더 강력한 통합 제공
|
||||||
|
- ✅ **프롬프팅 기반 회의록 개선**: AI Service에서 계속 제공
|
||||||
|
- ✅ **지능형 회의 진행 지원**: AI Service에서 계속 제공
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 문서 이력
|
||||||
|
|
||||||
|
| 버전 | 작성일 | 작성자 | 변경 내용 |
|
||||||
|
|------|--------|--------|----------|
|
||||||
|
| 1.0 | 2025-01-20 | 도그냥 (서비스 기획자) | 초안 작성 (8개 마이크로서비스) |
|
||||||
|
| 2.0 | 2025-01-22 | 길동 (아키텍트) | 논리 아키텍처 반영 (5개 마이크로서비스로 단순화) |
|
||||||
|
|
||||||
|
---
|
||||||
Loading…
x
Reference in New Issue
Block a user