Description
The generateQuiz method in src/modules/quizzes/quiz.service.ts currently returns a hardcoded 3-question Stellar quiz regardless of courseId or module. This is the placeholder at lines 190-225:
private createPlaceholderQuestions(courseId: string, moduleId: string) {
// Placeholder quiz generation — in production, call an LLM or content service
return [
{ id: "q1", text: "What is the primary purpose of the Stellar network?", ... },
{ id: "q2", text: "What language are Soroban smart contracts written in?", ... },
{ id: "q3", text: "What is the minimum account balance on Stellar?", ... },
];
}
This should call the chainlearn-ai service's POST /generate-quiz endpoint.
What the AI service expects
Based on chainlearn-ai/src/routes/quizzes.py:
POST http://localhost:8000/generate-quiz
Request body:
{
"user_id": "string",
"course_id": "string",
"module_id": "string",
"difficulty": "beginner" | "intermediate" | "advanced",
"num_questions": 5
}
Response body:
{
"quiz_id": "string",
"questions": [
{
"prompt": "string",
"options": ["A", "B", "C", "D"],
"correct_index": 2
}
]
}
Implementation steps
1. Add AI_SERVICE_URL to config
In src/config/index.ts, add:
aiServiceUrl: z.string().url().default("http://localhost:8000"),
2. Create AI service client
Create src/modules/quizzes/ai-client.ts:
import { config } from "../../config/index.js";
import { logger } from "../../utils/logger.js";
interface AiQuizQuestion {
prompt: string;
options: string[];
correct_index: number;
}
interface AiQuizResponse {
quiz_id: string;
questions: AiQuizQuestion[];
}
export async function generateQuizFromAI(params: {
userId: string;
courseId: string;
moduleId: string;
difficulty: string;
numQuestions: number;
}): Promise<AiQuizQuestion[]> {
const response = await fetch(`${config.aiServiceUrl}/generate-quiz`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: params.userId,
course_id: params.courseId,
module_id: params.moduleId,
difficulty: params.difficulty,
num_questions: params.numQuestions,
}),
});
if (!response.ok) {
logger.error({ status: response.status }, "AI service quiz generation failed");
throw new Error(`AI service returned ${response.status}`);
}
const data: AiQuizResponse = await response.json();
return data.questions;
}
3. Replace placeholder in quiz.service.ts
Replace the generateQuiz method (lines 66-70):
// Before:
const generatedQuestions = this.createPlaceholderQuestions(data.courseId, data.moduleId);
// After:
let generatedQuestions;
try {
const aiQuestions = await generateQuizFromAI({
userId,
courseId: data.courseId,
moduleId: data.moduleId,
difficulty: data.difficulty ?? "beginner",
numQuestions: data.numQuestions ?? 5,
});
generatedQuestions = aiQuestions.map((q, i) => ({
id: `q${i + 1}`,
text: q.prompt,
options: q.options,
correctIndex: q.correct_index,
}));
} catch (err) {
logger.warn({ err }, "AI service unavailable, using placeholder questions");
generatedQuestions = this.createPlaceholderQuestions(data.courseId, data.moduleId);
}
4. Update quiz types if needed
Check src/modules/quizzes/quiz.types.ts — the GenerateQuizBody may need difficulty and numQuestions fields.
Files to change
src/config/index.ts — add aiServiceUrl
- New file:
src/modules/quizzes/ai-client.ts
src/modules/quizzes/quiz.service.ts — replace placeholder call
src/modules/quizzes/quiz.types.ts — add optional fields if needed
How to test
- Start the AI service:
cd chainlearn-ai && uvicorn src.main:app --reload
- Start the API:
cd chainlearn-api && npm run dev
- Create a user and enroll in a course
- Call
POST /api/quizzes/generate with courseId and moduleId
- Verify the response contains AI-generated questions, not the hardcoded Stellar questions
- Test fallback: stop the AI service, verify placeholder questions are returned
Description
The
generateQuizmethod insrc/modules/quizzes/quiz.service.tscurrently returns a hardcoded 3-question Stellar quiz regardless of courseId or module. This is the placeholder at lines 190-225:This should call the
chainlearn-aiservice'sPOST /generate-quizendpoint.What the AI service expects
Based on
chainlearn-ai/src/routes/quizzes.py:Implementation steps
1. Add
AI_SERVICE_URLto configIn
src/config/index.ts, add:2. Create AI service client
Create
src/modules/quizzes/ai-client.ts:3. Replace placeholder in quiz.service.ts
Replace the
generateQuizmethod (lines 66-70):4. Update quiz types if needed
Check
src/modules/quizzes/quiz.types.ts— theGenerateQuizBodymay needdifficultyandnumQuestionsfields.Files to change
src/config/index.ts— addaiServiceUrlsrc/modules/quizzes/ai-client.tssrc/modules/quizzes/quiz.service.ts— replace placeholder callsrc/modules/quizzes/quiz.types.ts— add optional fields if neededHow to test
cd chainlearn-ai && uvicorn src.main:app --reloadcd chainlearn-api && npm run devPOST /api/quizzes/generatewith courseId and moduleId