@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