@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