Learn how to build a responsive, production-ready computer-based testing (CBT) application for JAMB and WAEC exams with timed sessions, real-time navigators, and step-by-step AI explanations.
The application utilizes a clean separation of concerns: Next.js App Router handles the UI state and client countdowns, while the official @massteck/aloc-sdk fetches curriculum questions and step-by-step explanations on demand.
Install the official ALOC TypeScript SDK in your Next.js project:
npm install @massteck/aloc-sdkCreate a singleton client helper at src/lib/aloc.ts:
import { AssessmentsApi, ExplanationsApi, Configuration } from "@massteck/aloc-sdk";
const config = new Configuration({
apiKey: process.env.ALOC_API_KEY || "",
basePath: process.env.ALOC_BASE_URL || "https://dev.aloc.com.ng/api/v1",
});
export const assessmentsClient = new AssessmentsApi(config);
export const explanationsClient = new ExplanationsApi(config);Create a route handler at src/app/api/assessment/route.ts to generate calibrated questions with option shuffling:
import { NextResponse } from "next/server";
import { assessmentsClient } from "@/lib/aloc";
export async function POST(req: Request) {
const { subject, examType = "jamb" } = await req.json();
const response = await assessmentsClient.generateAssessment({
generateAssessmentRequest: {
subject: subject || "mathematics",
examType: examType,
preset: "jamb_standard_40",
shuffleOptions: true,
seed: `candidate_${Date.now()}`,
},
});
return NextResponse.json(response.data);
}When the student completes the test or requests review on a missed question, query the L3 explanations endpoint:
const explanation = await explanationsClient.explainQuestion({
id: questionId,
explainQuestionRequest: { depth: "step_by_step" },
});
// Returns step-by-step derivations & common student mistakes
console.log(explanation.data.explanation);Clone the open-source Next.js starter with full UI, timer, and score cards.