// API Service Layer for LearnFlow Frontend const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'; // Service URLs const SERVICES = { triage: process.env.NEXT_PUBLIC_TRIAGE_URL || 'http://localhost:8001', concepts: process.env.NEXT_PUBLIC_CONCEPTS_URL || 'http://localhost:8002', codeReview: process.env.NEXT_PUBLIC_CODE_REVIEW_URL || 'http://localhost:8003', debug: process.env.NEXT_PUBLIC_DEBUG_URL || 'http://localhost:8004', exercise: process.env.NEXT_PUBLIC_EXERCISE_URL || 'http://localhost:8005', progress: process.env.NEXT_PUBLIC_PROGRESS_URL || 'http://localhost:8006', }; // Auth token management let authToken: string | null = null; export const setAuthToken = (token: string) => { authToken = token; if (typeof window !== 'undefined') { localStorage.setItem('learnflow_token', token); } }; export const getAuthToken = (): string | null => { if (authToken) return authToken; if (typeof window !== 'undefined') { return localStorage.getItem('learnflow_token'); } return null; }; export const clearAuthToken = () => { authToken = null; if (typeof window !== 'undefined') { localStorage.removeItem('learnflow_token'); } }; // Generic fetch wrapper async function apiFetch( url: string, options: RequestInit = {} ): Promise { const token = getAuthToken(); const headers: HeadersInit = { 'Content-Type': 'application/json', ...(token && { Authorization: `Bearer ${token}` }), ...options.headers, }; const response = await fetch(url, { ...options, headers, }); if (!response.ok) { const error = await response.json().catch(() => ({ message: 'Request failed' })); throw new Error(error.message || `HTTP error! status: ${response.status}`); } return response.json(); } // ==================== AUTH API ==================== export interface LoginRequest { email: string; password: string; } export interface RegisterRequest { name: string; email: string; password: string; role: 'student' | 'teacher'; } export interface AuthResponse { token: string; user: { id: string; name: string; email: string; role: 'student' | 'teacher'; }; } export const authAPI = { login: async (data: LoginRequest): Promise => { return apiFetch(`${API_BASE_URL}/auth/login`, { method: 'POST', body: JSON.stringify(data), }); }, register: async (data: RegisterRequest): Promise => { return apiFetch(`${API_BASE_URL}/auth/register`, { method: 'POST', body: JSON.stringify(data), }); }, me: async (): Promise => { return apiFetch(`${API_BASE_URL}/auth/me`); }, }; // ==================== TRIAGE API ==================== export interface QueryRequest { query: string; user_id: string; } export interface RoutingResponse { agent: string; message: string; params: Record; } export const triageAPI = { routeQuery: async (data: QueryRequest): Promise => { return apiFetch(`${SERVICES.triage}/query`, { method: 'POST', body: JSON.stringify(data), }); }, health: async (): Promise<{ status: string }> => { return apiFetch<{ status: string }>(`${SERVICES.triage}/health`); }, }; // ==================== CONCEPTS API ==================== export interface ExplainRequest { topic: string; level?: 'beginner' | 'intermediate' | 'advanced'; user_context?: Record; } export interface ExplanationResponse { topic: string; explanation: string; examples: string[]; level: string; } export const conceptsAPI = { explain: async (data: ExplainRequest): Promise => { return apiFetch(`${SERVICES.concepts}/explain`, { method: 'POST', body: JSON.stringify(data), }); }, health: async (): Promise<{ status: string }> => { return apiFetch<{ status: string }>(`${SERVICES.concepts}/health`); }, }; // ==================== EXERCISE API ==================== export interface ExerciseRequest { module: string; topic: string; difficulty?: 'beginner' | 'intermediate' | 'advanced'; user_id?: string; } export interface ExerciseResponse { id: string; module: string; topic: string; problem: string; starter_code: string; test_cases: Array<{ input: string; expected_output: string }>; difficulty: string; } export interface SubmissionRequest { quiz_id: string; user_id: string; code: string; } export interface GradeResponse { quiz_id: string; user_id: string; score: number; feedback: string; passed_tests: number; total_tests: number; } export const exerciseAPI = { generate: async (data: ExerciseRequest): Promise => { return apiFetch(`${SERVICES.exercise}/generate`, { method: 'POST', body: JSON.stringify(data), }); }, grade: async (data: SubmissionRequest): Promise => { return apiFetch(`${SERVICES.exercise}/grade`, { method: 'POST', body: JSON.stringify(data), }); }, health: async (): Promise<{ status: string }> => { return apiFetch<{ status: string }>(`${SERVICES.exercise}/health`); }, }; // ==================== CODE REVIEW API ==================== export interface ReviewRequest { code: string; context?: string; user_id?: string; } export interface ReviewResponse { overall_quality: string; issues: Array<{ type: string; line: number; message: string; suggestion: string; }>; suggestions: string[]; score: number; } export const codeReviewAPI = { review: async (data: ReviewRequest): Promise => { return apiFetch(`${SERVICES.codeReview}/review`, { method: 'POST', body: JSON.stringify(data), }); }, health: async (): Promise<{ status: string }> => { return apiFetch<{ status: string }>(`${SERVICES.codeReview}/health`); }, }; // ==================== DEBUG API ==================== export interface DebugRequest { code: string; error_message: string; user_id?: string; } export interface DebugResponse { error_type: string; explanation: string; fix_suggestion: string; corrected_code: string; learning_tip: string; } export const debugAPI = { analyze: async (data: DebugRequest): Promise => { return apiFetch(`${SERVICES.debug}/analyze`, { method: 'POST', body: JSON.stringify(data), }); }, health: async (): Promise<{ status: string }> => { return apiFetch<{ status: string }>(`${SERVICES.debug}/health`); }, }; // ==================== PROGRESS API ==================== export interface ProgressData { user_id: string; overall_mastery: number; modules_completed: number; current_module: string; modules: Record>; } export interface UpdateProgressRequest { user_id: string; module: string; topic: string; score: number; activity_type: 'quiz' | 'exercise' | 'lesson'; } export const progressAPI = { getProgress: async (userId: string): Promise => { return apiFetch(`${SERVICES.progress}/progress/${userId}`); }, updateProgress: async (data: UpdateProgressRequest): Promise => { return apiFetch(`${SERVICES.progress}/progress`, { method: 'POST', body: JSON.stringify(data), }); }, health: async (): Promise<{ status: string }> => { return apiFetch<{ status: string }>(`${SERVICES.progress}/health`); }, }; // ==================== AI CHAT API ==================== export interface ChatMessage { role: 'user' | 'assistant'; content: string; } export interface ChatRequest { messages: ChatMessage[]; user_id: string; context?: string; } export interface ChatResponse { response: string; agent_used: string; } export const chatAPI = { sendMessage: async (data: ChatRequest): Promise => { // First route through triage const routing = await triageAPI.routeQuery({ query: data.messages[data.messages.length - 1].content, user_id: data.user_id, }); // Then call the appropriate agent if (routing.agent === 'concepts-agent') { const response = await conceptsAPI.explain({ topic: data.messages[data.messages.length - 1].content, level: 'intermediate', }); return { response: `${response.explanation}\n\nExamples:\n${response.examples.join('\n')}`, agent_used: routing.agent, }; } // Default response return { response: routing.message, agent_used: routing.agent, }; }, }; // ==================== UTILITY FUNCTIONS ==================== export const checkServicesHealth = async (): Promise> => { const services = ['triage', 'concepts', 'codeReview', 'debug', 'exercise', 'progress'] as const; const results: Record = {}; await Promise.all( services.map(async (service) => { try { const api = { triage: triageAPI, concepts: conceptsAPI, codeReview: codeReviewAPI, debug: debugAPI, exercise: exerciseAPI, progress: progressAPI, }[service]; await api.health(); results[service] = true; } catch { results[service] = false; } }) ); return results; };