!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