박세원 86ae038a31 Event Service API 통합 및 AI 추천 조회 로직 개선
- eventApi에 getAiRecommendations 메서드 추가
- Job COMPLETED 시 Event Service의 공개 API로 추천 결과 조회
- AI Service Internal API 대신 Event Service API 사용
- 타입 정의 통합 및 중복 제거
- 환경변수 포트 설정 수정 (AI_HOST: 8083)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 20:03:42 +09:00

110 lines
3.0 KiB
TypeScript

import axios, { AxiosInstance } from 'axios';
// AI Service API 클라이언트
const AI_API_BASE_URL = process.env.NEXT_PUBLIC_AI_HOST || 'http://localhost:8083';
const API_VERSION = process.env.NEXT_PUBLIC_API_VERSION || 'v1';
export const aiApiClient: AxiosInstance = axios.create({
baseURL: `${AI_API_BASE_URL}/api/${API_VERSION}`,
timeout: 300000, // AI 생성은 최대 5분
headers: {
'Content-Type': 'application/json',
},
withCredentials: false, // CORS 설정
});
// Request interceptor
aiApiClient.interceptors.request.use(
(config) => {
console.log('🤖 AI API Request:', {
method: config.method?.toUpperCase(),
url: config.url,
baseURL: config.baseURL,
data: config.data,
});
const token = localStorage.getItem('accessToken');
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
console.error('❌ AI API Request Error:', error);
return Promise.reject(error);
}
);
// Response interceptor
aiApiClient.interceptors.response.use(
(response) => {
console.log('✅ AI API Response:', {
status: response.status,
url: response.config.url,
data: response.data,
});
return response;
},
(error) => {
console.error('❌ AI API Error:', {
message: error.message,
status: error.response?.status,
url: error.config?.url,
data: error.response?.data,
});
return Promise.reject(error);
}
);
// Types (eventApi.ts로 이동됨 - import해서 사용)
export interface JobStatusResponse {
jobId: string;
status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED';
progress: number;
message: string;
eventId?: string;
createdAt: string;
startedAt?: string;
completedAt?: string;
failedAt?: string;
errorMessage?: string;
retryCount?: number;
processingTimeMs?: number;
}
export interface HealthCheckResponse {
status: 'UP' | 'DOWN' | 'DEGRADED';
timestamp: string;
services: {
kafka: 'UP' | 'DOWN';
redis: 'UP' | 'DOWN';
claude_api: 'UP' | 'DOWN' | 'CIRCUIT_OPEN';
gpt4_api?: 'UP' | 'DOWN' | 'CIRCUIT_OPEN';
circuit_breaker: 'CLOSED' | 'OPEN' | 'HALF_OPEN';
};
}
// API Functions
export const aiApi = {
// 헬스체크
healthCheck: async (): Promise<HealthCheckResponse> => {
const response = await aiApiClient.get<HealthCheckResponse>('/health');
return response.data;
},
// Job 상태 조회 (Internal API)
getJobStatus: async (jobId: string): Promise<JobStatusResponse> => {
const response = await aiApiClient.get<JobStatusResponse>(`/internal/jobs/${jobId}/status`);
return response.data;
},
// AI 추천 결과 조회 (Internal API) - Deprecated: eventApi.getAiRecommendations 사용
// getRecommendations: async (eventId: string): Promise<AiRecommendationResult> => {
// const response = await aiApiClient.get<AiRecommendationResult>(`/internal/recommendations/${eventId}`);
// return response.data;
// },
};
export default aiApi;