learnflow / lib /api.ts
muhammad naveed
Upload folder using huggingface_hub
1291157 verified
// 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<T>(
url: string,
options: RequestInit = {}
): Promise<T> {
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<AuthResponse> => {
return apiFetch<AuthResponse>(`${API_BASE_URL}/auth/login`, {
method: 'POST',
body: JSON.stringify(data),
});
},
register: async (data: RegisterRequest): Promise<AuthResponse> => {
return apiFetch<AuthResponse>(`${API_BASE_URL}/auth/register`, {
method: 'POST',
body: JSON.stringify(data),
});
},
me: async (): Promise<AuthResponse['user']> => {
return apiFetch<AuthResponse['user']>(`${API_BASE_URL}/auth/me`);
},
};
// ==================== TRIAGE API ====================
export interface QueryRequest {
query: string;
user_id: string;
}
export interface RoutingResponse {
agent: string;
message: string;
params: Record<string, any>;
}
export const triageAPI = {
routeQuery: async (data: QueryRequest): Promise<RoutingResponse> => {
return apiFetch<RoutingResponse>(`${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<string, any>;
}
export interface ExplanationResponse {
topic: string;
explanation: string;
examples: string[];
level: string;
}
export const conceptsAPI = {
explain: async (data: ExplainRequest): Promise<ExplanationResponse> => {
return apiFetch<ExplanationResponse>(`${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<ExerciseResponse> => {
return apiFetch<ExerciseResponse>(`${SERVICES.exercise}/generate`, {
method: 'POST',
body: JSON.stringify(data),
});
},
grade: async (data: SubmissionRequest): Promise<GradeResponse> => {
return apiFetch<GradeResponse>(`${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<ReviewResponse> => {
return apiFetch<ReviewResponse>(`${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<DebugResponse> => {
return apiFetch<DebugResponse>(`${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<string, Record<string, { mastery_score: number }>>;
}
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<ProgressData> => {
return apiFetch<ProgressData>(`${SERVICES.progress}/progress/${userId}`);
},
updateProgress: async (data: UpdateProgressRequest): Promise<ProgressData> => {
return apiFetch<ProgressData>(`${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<ChatResponse> => {
// 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<Record<string, boolean>> => {
const services = ['triage', 'concepts', 'codeReview', 'debug', 'exercise', 'progress'] as const;
const results: Record<string, boolean> = {};
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;
};