@startuml !theme mono title 충돌 해결 내부 시퀀스 participant "WebSocket<>" as WebSocket participant "CollaborationController" as Controller participant "CollaborationService" as Service participant "ConflictResolver" as Resolver participant "TranscriptService" as TranscriptService database "Redis Cache<>" as Cache queue "Event Hub<>" as EventHub WebSocket -> Controller: onConflict(conflictData) activate Controller Controller -> Service: resolveConflict(meetingId, conflictData) activate Service Service -> Cache: get(meeting:{id}:conflicts) activate Cache note right of Cache 충돌 목록 조회: - 발생 시간 - 관련 사용자 - 충돌 영역 end note Cache --> Service: conflictList deactivate Cache Service -> Resolver: analyzeConflict(conflictData) activate Resolver Resolver -> Resolver: detectConflictType() note right of Resolver 충돌 유형 분석: - 동일 위치 수정 - 삭제-수정 충돌 - 순서 변경 충돌 end note Resolver -> Resolver: applyStrategy() note right of Resolver 해결 전략: - 자동 병합 (단순 충돌) - 최신 우선 (시간 기반) - 수동 해결 필요 (복잡) end note Resolver --> Service: resolutionResult deactivate Resolver alt auto-resolved Service -> TranscriptService: applyResolution(meetingId, resolution) activate TranscriptService TranscriptService --> Service: mergedContent deactivate TranscriptService Service -> Cache: del(meeting:{id}:conflicts) activate Cache Cache --> Service: OK deactivate Cache else manual-required Service -> Cache: SET meeting:{id}:conflicts\n(TTL: 1시간) activate Cache note right of Cache 충돌 정보 캐싱: - TTL: 1시간 - 충돌 정보 저장 - 수동 해결 대기 end note Cache --> Service: OK deactivate Cache end Service ->> EventHub: publish(ConflictResolvedEvent) activate EventHub note right of EventHub 이벤트 발행: - 자동 해결: 동기화 - 수동 필요: 알림 end note deactivate EventHub Service --> Controller: ResolutionResponse deactivate Service Controller --> WebSocket: send(resolution) deactivate Controller @enduml