mirror of
https://github.com/ktds-dg0501/kt-event-marketing-fe.git
synced 2025-12-06 10:16:25 +00:00
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>
This commit is contained in:
parent
e3f1e2e3c7
commit
86ae038a31
@ -19,7 +19,8 @@ import {
|
|||||||
Alert,
|
Alert,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { ArrowBack, Edit, Insights } from '@mui/icons-material';
|
import { ArrowBack, Edit, Insights } from '@mui/icons-material';
|
||||||
import { aiApi, eventApi, AIRecommendationResult, EventRecommendation } from '@/shared/api';
|
import { eventApi } from '@/shared/api';
|
||||||
|
import type { AiRecommendationResult, EventRecommendation } from '@/shared/api/eventApi';
|
||||||
|
|
||||||
// 디자인 시스템 색상
|
// 디자인 시스템 색상
|
||||||
const colors = {
|
const colors = {
|
||||||
@ -82,7 +83,7 @@ export default function RecommendationStep({
|
|||||||
const [polling, setPolling] = useState(false);
|
const [polling, setPolling] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
const [aiResult, setAiResult] = useState<AIRecommendationResult | null>(null);
|
const [aiResult, setAiResult] = useState<AiRecommendationResult | null>(null);
|
||||||
const [selected, setSelected] = useState<number | null>(null);
|
const [selected, setSelected] = useState<number | null>(null);
|
||||||
const [editedData, setEditedData] = useState<Record<number, { title: string; description: string }>>({});
|
const [editedData, setEditedData] = useState<Record<number, { title: string; description: string }>>({});
|
||||||
|
|
||||||
@ -206,8 +207,8 @@ export default function RecommendationStep({
|
|||||||
console.log('✅ Job 상태:', status);
|
console.log('✅ Job 상태:', status);
|
||||||
|
|
||||||
if (status.status === 'COMPLETED') {
|
if (status.status === 'COMPLETED') {
|
||||||
// AI 추천 결과 조회
|
// AI 추천 결과 조회 (Event Service API 사용)
|
||||||
const recommendations = await aiApi.getRecommendations(evtId);
|
const recommendations = await eventApi.getAiRecommendations(evtId);
|
||||||
setAiResult(recommendations);
|
setAiResult(recommendations);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setPolling(false);
|
setPolling(false);
|
||||||
|
|||||||
@ -56,78 +56,7 @@ aiApiClient.interceptors.response.use(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Types
|
// Types (eventApi.ts로 이동됨 - import해서 사용)
|
||||||
export interface TrendKeyword {
|
|
||||||
keyword: string;
|
|
||||||
relevance: number;
|
|
||||||
description: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TrendAnalysis {
|
|
||||||
industryTrends: TrendKeyword[];
|
|
||||||
regionalTrends: TrendKeyword[];
|
|
||||||
seasonalTrends: TrendKeyword[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ExpectedMetrics {
|
|
||||||
newCustomers: {
|
|
||||||
min: number;
|
|
||||||
max: number;
|
|
||||||
};
|
|
||||||
repeatVisits?: {
|
|
||||||
min: number;
|
|
||||||
max: number;
|
|
||||||
};
|
|
||||||
revenueIncrease: {
|
|
||||||
min: number;
|
|
||||||
max: number;
|
|
||||||
};
|
|
||||||
roi: {
|
|
||||||
min: number;
|
|
||||||
max: number;
|
|
||||||
};
|
|
||||||
socialEngagement?: {
|
|
||||||
estimatedPosts: number;
|
|
||||||
estimatedReach: number;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EventRecommendation {
|
|
||||||
optionNumber: number;
|
|
||||||
concept: string;
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
targetAudience: string;
|
|
||||||
duration: {
|
|
||||||
recommendedDays: number;
|
|
||||||
recommendedPeriod?: string;
|
|
||||||
};
|
|
||||||
mechanics: {
|
|
||||||
type: 'DISCOUNT' | 'GIFT' | 'STAMP' | 'EXPERIENCE' | 'LOTTERY' | 'COMBO';
|
|
||||||
details: string;
|
|
||||||
};
|
|
||||||
promotionChannels: string[];
|
|
||||||
estimatedCost: {
|
|
||||||
min: number;
|
|
||||||
max: number;
|
|
||||||
breakdown?: {
|
|
||||||
material?: number;
|
|
||||||
promotion?: number;
|
|
||||||
discount?: number;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
expectedMetrics: ExpectedMetrics;
|
|
||||||
differentiator: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AIRecommendationResult {
|
|
||||||
eventId: string;
|
|
||||||
trendAnalysis: TrendAnalysis;
|
|
||||||
recommendations: EventRecommendation[];
|
|
||||||
generatedAt: string;
|
|
||||||
expiresAt: string;
|
|
||||||
aiProvider: 'CLAUDE' | 'GPT4';
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface JobStatusResponse {
|
export interface JobStatusResponse {
|
||||||
jobId: string;
|
jobId: string;
|
||||||
@ -170,11 +99,11 @@ export const aiApi = {
|
|||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
// AI 추천 결과 조회 (Internal API)
|
// AI 추천 결과 조회 (Internal API) - Deprecated: eventApi.getAiRecommendations 사용
|
||||||
getRecommendations: async (eventId: string): Promise<AIRecommendationResult> => {
|
// getRecommendations: async (eventId: string): Promise<AiRecommendationResult> => {
|
||||||
const response = await aiApiClient.get<AIRecommendationResult>(`/internal/recommendations/${eventId}`);
|
// const response = await aiApiClient.get<AiRecommendationResult>(`/internal/recommendations/${eventId}`);
|
||||||
return response.data;
|
// return response.data;
|
||||||
},
|
// },
|
||||||
};
|
};
|
||||||
|
|
||||||
export default aiApi;
|
export default aiApi;
|
||||||
|
|||||||
@ -111,6 +111,78 @@ export interface EventJobStatusResponse {
|
|||||||
completedAt?: string;
|
completedAt?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TrendKeyword {
|
||||||
|
keyword: string;
|
||||||
|
relevance: number;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TrendAnalysis {
|
||||||
|
industryTrends: TrendKeyword[];
|
||||||
|
regionalTrends: TrendKeyword[];
|
||||||
|
seasonalTrends: TrendKeyword[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExpectedMetrics {
|
||||||
|
newCustomers: {
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
};
|
||||||
|
repeatVisits?: {
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
};
|
||||||
|
revenueIncrease: {
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
};
|
||||||
|
roi: {
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
};
|
||||||
|
socialEngagement?: {
|
||||||
|
estimatedPosts: number;
|
||||||
|
estimatedReach: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EventRecommendation {
|
||||||
|
optionNumber: number;
|
||||||
|
concept: string;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
targetAudience: string;
|
||||||
|
duration: {
|
||||||
|
recommendedDays: number;
|
||||||
|
recommendedPeriod?: string;
|
||||||
|
};
|
||||||
|
mechanics: {
|
||||||
|
type: 'DISCOUNT' | 'GIFT' | 'STAMP' | 'EXPERIENCE' | 'LOTTERY' | 'COMBO';
|
||||||
|
details: string;
|
||||||
|
};
|
||||||
|
promotionChannels: string[];
|
||||||
|
estimatedCost: {
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
breakdown?: {
|
||||||
|
material?: number;
|
||||||
|
promotion?: number;
|
||||||
|
discount?: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
expectedMetrics: ExpectedMetrics;
|
||||||
|
differentiator: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AiRecommendationResult {
|
||||||
|
eventId: string;
|
||||||
|
trendAnalysis: TrendAnalysis;
|
||||||
|
recommendations: EventRecommendation[];
|
||||||
|
generatedAt: string;
|
||||||
|
expiresAt?: string;
|
||||||
|
aiProvider: 'CLAUDE' | 'GPT4';
|
||||||
|
}
|
||||||
|
|
||||||
export interface SelectRecommendationRequest {
|
export interface SelectRecommendationRequest {
|
||||||
recommendationId: string;
|
recommendationId: string;
|
||||||
customizations?: {
|
customizations?: {
|
||||||
@ -262,6 +334,15 @@ export const eventApi = {
|
|||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// AI 추천 결과 조회 (Job COMPLETED 후)
|
||||||
|
getAiRecommendations: async (eventId: string): Promise<AiRecommendationResult> => {
|
||||||
|
const response = await eventApiClient.get<AiRecommendationResult>(
|
||||||
|
`/events/${eventId}/ai-recommendations`
|
||||||
|
);
|
||||||
|
console.log('✅ AI 추천 결과 조회:', response.data);
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
|
|
||||||
// AI 추천 선택
|
// AI 추천 선택
|
||||||
selectRecommendation: async (
|
selectRecommendation: async (
|
||||||
eventId: string,
|
eventId: string,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user