@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