257 lines
12 KiB
Plaintext
257 lines
12 KiB
Plaintext
!theme mono
|
|
|
|
skinparam sequenceArrowThickness 2
|
|
skinparam sequenceParticipantBorderThickness 2
|
|
skinparam sequenceActorBorderThickness 2
|
|
skinparam sequenceGroupBorderThickness 2
|
|
|
|
title Intelligence Service 내부 시퀀스 다이어그램 (역설계 - Claude AI 기반)
|
|
|
|
participant "AnalysisController" as AnalysisCtrl
|
|
participant "ChatController" as ChatCtrl
|
|
participant "NotificationController" as NotificationCtrl
|
|
participant "BatchController" as BatchCtrl
|
|
participant "HealthAnalysisUseCase" as HealthAnalysisUC
|
|
participant "ChatUseCase" as ChatUC
|
|
participant "NotificationUseCase" as NotificationUC
|
|
participant "BatchUseCase" as BatchUC
|
|
participant "AiAnalysisDomainService" as AiAnalysisDomainSvc
|
|
participant "ChatDomainService" as ChatDomainSvc
|
|
participant "NotificationDomainService" as NotificationDomainSvc
|
|
participant "HealthServiceAdapter" as HealthAdapter
|
|
participant "UserServiceAdapter" as UserAdapter
|
|
participant "GoalServiceAdapter" as GoalAdapter
|
|
participant "ClaudeApiAdapter" as ClaudeAdapter
|
|
participant "CacheAdapter" as CacheAdapter
|
|
participant "ChatHistoryRepository" as ChatRepo
|
|
participant "EventPublisherAdapter" as EventAdapter
|
|
participant "PostgreSQL" as PostgreSQL
|
|
participant "Redis Cache" as Redis
|
|
participant "Claude API" as ClaudeAPI
|
|
participant "Azure Service Bus" as ServiceBus
|
|
|
|
== 1. GET /api/intelligence/health/diagnosis (AI 3줄 요약 진단) ==
|
|
|
|
AnalysisCtrl -> HealthAnalysisUC: generateHealthDiagnosis(userId)
|
|
|
|
HealthAnalysisUC -> CacheAdapter: getCachedDiagnosis(userId)
|
|
CacheAdapter -> Redis: GET diagnosis:{userId}
|
|
Redis -> CacheAdapter: 캐시된 진단 또는 null
|
|
|
|
alt 캐시 미스인 경우
|
|
HealthAnalysisUC -> HealthAdapter: getLatestHealthCheckup(userId)
|
|
HealthAdapter -> HealthAnalysisUC: 최신 건강검진 데이터 (정상치 비교 결과 포함)
|
|
|
|
HealthAnalysisUC -> UserAdapter: getUserProfile(userId)
|
|
UserAdapter -> HealthAnalysisUC: 사용자 프로필 (직업, 나이 등)
|
|
|
|
HealthAnalysisUC -> AiAnalysisDomainSvc: createDiagnosisPrompt(healthData, userProfile)
|
|
AiAnalysisDomainSvc -> AiAnalysisDomainSvc: formatHealthDataForAI(checkupData)
|
|
note right: **AI 프롬프트 생성**\n- 건강검진 수치 및 정상치 비교 결과\n- 사용자 직업군 특성 반영\n- 3줄 요약 요청 형식
|
|
|
|
AiAnalysisDomainSvc -> ClaudeAdapter: requestHealthDiagnosis(prompt)
|
|
ClaudeAdapter -> ClaudeAPI: Claude AI 건강 진단 요청
|
|
ClaudeAPI -> ClaudeAdapter: AI 생성 3줄 요약 진단
|
|
|
|
AiAnalysisDomainSvc -> AiAnalysisDomainSvc: parseAndValidateAIResponse(aiResponse)
|
|
AiAnalysisDomainSvc -> AiAnalysisDomainSvc: calculateConfidenceScore(healthData, aiResponse)
|
|
|
|
HealthAnalysisUC -> CacheAdapter: cacheDiagnosis(userId, diagnosisResult)
|
|
CacheAdapter -> Redis: SETEX diagnosis:{userId} 1800 {data}
|
|
note right: 30분 TTL로 캐싱
|
|
end
|
|
|
|
HealthAnalysisUC -> AnalysisCtrl: HealthDiagnosisResponse 반환
|
|
note right: {threeSentenceSummary, healthScore, riskLevel, occupationConsiderations, analysisTimestamp, confidenceScore}
|
|
|
|
== 2. POST /api/intelligence/missions/recommend (AI 미션 추천) ==
|
|
|
|
AnalysisCtrl -> HealthAnalysisUC: recommendMissions(missionRecommendationRequest)
|
|
note right: {userId, currentHealthStatus, preferences}
|
|
|
|
HealthAnalysisUC -> HealthAdapter: getHealthAnalysisData(userId)
|
|
HealthAdapter -> HealthAnalysisUC: 건강 상태 및 위험 요인
|
|
|
|
HealthAnalysisUC -> UserAdapter: getUserOccupationInfo(userId)
|
|
UserAdapter -> HealthAnalysisUC: 직업군 정보
|
|
|
|
HealthAnalysisUC -> AiAnalysisDomainSvc: generateMissionRecommendations(healthData, occupation, preferences)
|
|
AiAnalysisDomainSvc -> AiAnalysisDomainSvc: createPersonalizedPrompt(data)
|
|
note right: **개인화 미션 추천 프롬프트**\n- 건강 위험 요인 기반\n- 직업군별 특성 고려\n- 사용자 선호도 반영
|
|
|
|
AiAnalysisDomainSvc -> ClaudeAdapter: requestMissionRecommendations(prompt)
|
|
ClaudeAdapter -> ClaudeAPI: Claude AI 미션 추천 요청
|
|
ClaudeAPI -> ClaudeAdapter: AI 생성 개인화 미션 목록
|
|
|
|
AiAnalysisDomainSvc -> AiAnalysisDomainSvc: parseMissionRecommendations(aiResponse)
|
|
AiAnalysisDomainSvc -> AiAnalysisDomainSvc: validateAndEnrichMissions(missions)
|
|
|
|
HealthAnalysisUC -> AnalysisCtrl: MissionRecommendationResponse 반환
|
|
note right: {missions, recommendationReason, totalRecommended}
|
|
|
|
== 3. POST /api/intelligence/chat/consultation (AI 채팅 상담) ==
|
|
|
|
ChatCtrl -> ChatUC: processChat(chatRequest)
|
|
note right: {message, sessionId, context}
|
|
|
|
ChatUC -> ChatDomainService: validateChatSession(sessionId)
|
|
ChatDomainService -> ChatRepo: findChatSession(sessionId)
|
|
ChatRepo -> PostgreSQL: SELECT * FROM chat_sessions WHERE session_id = ?
|
|
|
|
alt 새 세션인 경우
|
|
ChatDomainService -> ChatDomainService: createNewChatSession(userId)
|
|
ChatDomainService -> ChatRepo: saveChatSession(newSession)
|
|
ChatRepo -> PostgreSQL: INSERT INTO chat_sessions
|
|
end
|
|
|
|
ChatUC -> ChatRepo: getChatHistory(sessionId, limit=10)
|
|
ChatRepo -> Redis: LRANGE chat:history:{sessionId} 0 9
|
|
Redis -> ChatRepo: 최근 채팅 히스토리
|
|
|
|
alt 캐시 미스인 경우
|
|
ChatRepo -> PostgreSQL: SELECT * FROM chat_messages WHERE session_id = ? ORDER BY message_order DESC LIMIT 10
|
|
PostgreSQL -> ChatRepo: DB 채팅 히스토리
|
|
ChatRepo -> Redis: LPUSH chat:history:{sessionId} {messages}
|
|
end
|
|
|
|
ChatUC -> ChatDomainService: buildContextualPrompt(userMessage, chatHistory, context)
|
|
ChatDomainService -> ChatDomainService: formatChatContext(history)
|
|
note right: **채팅 컨텍스트 구성**\n- 이전 대화 맥락 유지\n- 건강 상담 톤앤매너 적용\n- 사용자 메시지 전처리
|
|
|
|
ChatDomainService -> ClaudeAdapter: requestChatResponse(contextualPrompt)
|
|
ClaudeAdapter -> ClaudeAPI: Claude AI 채팅 응답 요청
|
|
ClaudeAPI -> ClaudeAdapter: AI 생성 채팅 응답
|
|
|
|
ChatUC -> ChatDomainService: saveChatExchange(sessionId, userMessage, aiResponse)
|
|
ChatDomainService -> ChatRepo: saveChatMessages(sessionId, messages)
|
|
ChatRepo -> PostgreSQL: INSERT INTO chat_messages (batch)
|
|
ChatRepo -> Redis: LPUSH chat:history:{sessionId} {newMessages}
|
|
|
|
ChatUC -> ChatCtrl: ChatResponse 반환
|
|
note right: {response, sessionId, timestamp, suggestedQuestions, responseType}
|
|
|
|
== 4. GET /api/intelligence/chat/history (채팅 히스토리 조회) ==
|
|
|
|
ChatCtrl -> ChatUC: getChatHistory(sessionId, messageLimit)
|
|
|
|
ChatUC -> CacheAdapter: getCachedChatHistory(sessionId)
|
|
CacheAdapter -> Redis: LRANGE chat:history:{sessionId} 0 {limit-1}
|
|
Redis -> CacheAdapter: 캐시된 채팅 히스토리
|
|
|
|
alt 캐시 미스인 경우
|
|
ChatUC -> ChatRepo: findChatHistoryBySession(sessionId, messageLimit)
|
|
ChatRepo -> PostgreSQL: SELECT * FROM chat_messages WHERE session_id = ? ORDER BY message_order DESC LIMIT ?
|
|
PostgreSQL -> ChatRepo: DB 채팅 히스토리
|
|
|
|
ChatUC -> CacheAdapter: cacheChatHistory(sessionId, history)
|
|
CacheAdapter -> Redis: LPUSH chat:history:{sessionId} {messages}
|
|
end
|
|
|
|
ChatUC -> ChatDomainService: formatChatHistory(rawHistory)
|
|
ChatDomainService -> ChatDomainService: maskSensitiveInfo(messages)
|
|
note right: 민감정보 마스킹 처리
|
|
|
|
ChatUC -> ChatCtrl: ChatHistoryResponse 반환
|
|
note right: {sessionId, messages, totalMessageCount, cacheExpiration}
|
|
|
|
== 5. POST /api/intelligence/notifications/celebration (미션 달성 축하) ==
|
|
|
|
NotificationCtrl -> NotificationUC: generateCelebrationMessage(celebrationRequest)
|
|
note right: {userId, missionId, achievementType, consecutiveDays, totalAchievements}
|
|
|
|
NotificationUC -> GoalAdapter: getMissionDetails(missionId)
|
|
GoalAdapter -> NotificationUC: 미션 정보 및 사용자 진행 상황
|
|
|
|
NotificationUC -> NotificationDomainService: createCelebrationMessage(celebrationData)
|
|
NotificationDomainService -> NotificationDomainService: prepareCelebrationPrompt(data)
|
|
note right: **축하 메시지 프롬프트**\n- 달성 미션 정보\n- 연속 달성 일수\n- 동기부여 톤앤매너
|
|
|
|
NotificationDomainService -> ClaudeAdapter: requestCelebrationMessage(prompt)
|
|
ClaudeAdapter -> ClaudeAPI: AI 축하 메시지 요청
|
|
ClaudeAPI -> ClaudeAdapter: AI 생성 축하 메시지
|
|
|
|
NotificationDomainService -> NotificationDomainService: enhanceCelebrationMessage(aiMessage, achievementData)
|
|
note right: **축하 메시지 강화**\n- 달성 배지 정보 추가\n- 건강 효과 설명\n- 다음 마일스톤 안내
|
|
|
|
NotificationUC -> NotificationCtrl: CelebrationResponse 반환
|
|
note right: {congratsMessage, achievementBadge, healthBenefit, nextMilestone, encouragementLevel, visualEffect}
|
|
|
|
== 6. POST /api/intelligence/notifications/encouragement (독려 메시지) ==
|
|
|
|
NotificationCtrl -> NotificationUC: generateEncouragementMessage(encouragementRequest)
|
|
note right: {userId, missionsStatus}
|
|
|
|
NotificationUC -> GoalAdapter: getUserDailyProgress(userId)
|
|
GoalAdapter -> NotificationUC: 일일 진행 상황
|
|
|
|
NotificationUC -> NotificationDomainService: analyzeProgressPattern(userId, missionsStatus, dailyProgress)
|
|
NotificationDomainService -> NotificationDomainService: calculateProgressLevel(data)
|
|
NotificationDomainService -> NotificationDomainService: identifyFailurePoints(missionsStatus)
|
|
|
|
NotificationUC -> CacheAdapter: getCachedEncouragementMessage(userId, progressLevel)
|
|
CacheAdapter -> Redis: GET encouragement:{userId}:{progressLevel}
|
|
Redis -> CacheAdapter: 캐시된 독려 메시지 또는 null
|
|
|
|
alt 캐시 미스인 경우
|
|
NotificationDomainService -> NotificationDomainService: createEncouragementPrompt(progressAnalysis)
|
|
NotificationDomainService -> ClaudeAdapter: requestEncouragementMessage(prompt)
|
|
ClaudeAdapter -> ClaudeAPI: AI 독려 메시지 요청
|
|
ClaudeAPI -> ClaudeAdapter: AI 생성 독려 메시지
|
|
|
|
NotificationUC -> CacheAdapter: cacheEncouragementMessage(userId, progressLevel, message)
|
|
CacheAdapter -> Redis: SETEX encouragement:{userId}:{progressLevel} 1800 {message}
|
|
end
|
|
|
|
NotificationUC -> NotificationCtrl: EncouragementResponse 반환
|
|
note right: {message, motivationType, timing, personalizedTip, priority}
|
|
|
|
== 7. POST /api/intelligence/batch/notifications (배치 알림 처리) ==
|
|
|
|
BatchCtrl -> BatchUC: processBatchNotifications(batchRequest)
|
|
note right: {triggerTime, targetUsers, notificationType}
|
|
|
|
BatchUC -> GoalAdapter: getAllUsersProgress(targetUsers)
|
|
GoalAdapter -> BatchUC: 모든 대상 사용자의 진행 상황
|
|
|
|
loop 사용자별 처리
|
|
BatchUC -> NotificationDomainService: generatePersonalizedNotification(user, progress)
|
|
NotificationDomainService -> ClaudeAdapter: requestBatchNotification(personalizedPrompt)
|
|
ClaudeAdapter -> ClaudeAPI: AI 개인화 알림 요청
|
|
ClaudeAPI -> ClaudeAdapter: AI 생성 개인화 알림
|
|
end
|
|
|
|
BatchUC -> EventAdapter: publishBatchNotificationEvents(processedNotifications)
|
|
EventAdapter -> ServiceBus: 배치 알림 이벤트 발행
|
|
|
|
BatchUC -> BatchCtrl: BatchNotificationResponse 반환
|
|
note right: {processedCount, successCount, failedCount, nextScheduledTime}
|
|
|
|
== 예외 처리 ==
|
|
|
|
alt Claude API 호출 실패
|
|
ClaudeAdapter -> AiAnalysisDomainSvc: ClaudeApiException
|
|
AiAnalysisDomainSvc -> HealthAnalysisUC: 기본 메시지 사용
|
|
note right: Fallback 메시지로 대체
|
|
end
|
|
|
|
alt 캐시 접근 실패
|
|
CacheAdapter -> ChatUC: CacheAccessException
|
|
ChatUC -> ChatRepo: DB에서 직접 조회
|
|
end
|
|
|
|
alt 세션 만료
|
|
ChatDomainService -> ChatUC: SessionExpiredException
|
|
ChatUC -> ChatCtrl: 새 세션 생성 안내
|
|
end
|
|
|
|
== 성능 최적화 및 모니터링 ==
|
|
|
|
note over NotificationUC, CacheAdapter
|
|
**Claude AI 연동 최적화**
|
|
- 응답 캐싱으로 API 호출 최소화
|
|
- Circuit Breaker 패턴 적용
|
|
- Fallback 메시지 준비
|
|
- 배치 처리 시 우선순위 기반
|
|
- API 응답 시간 모니터링
|
|
- 캐시 히트율 추적
|
|
end note |