Skip to content
CO
All projects

Case study

CBT Engine

A computer-based testing platform built for high concurrency, low latency and offline-first exam environments.

  • Live

The problem

Schools and organisations running computer-based exams need many candidates to sit an exam at once — often on unreliable connections — without losing answers.

What I built

  • Multi-tenant: each organisation runs its own exams, candidates and staff
  • Multiple-choice questions marked automatically, with shuffled options
  • Essay questions assigned to graders, with AI-assisted essay grading
  • Timed sessions that are submitted automatically at the deadline
  • Proctoring with webcam, a phone as a second camera, and periodic screenshots
  • Candidate bulk import, invite links and custom candidate fields
  • Separate apps for candidates, organisation staff and platform admins

My role

Sole developer: I designed and built the API, the four React front ends and the self-hosted media server, and run load tests and production deployments.

Tech stack

  • TypeScript
  • Node.js
  • Express
  • MongoDB
  • Redis
  • BullMQ
  • Socket.IO
  • React

Technical challenges & decisions

  • Many candidates at once

    The API is a Node.js modular monolith, so throughput scales with replicas: several backend containers run behind an nginx edge, with Redis for shared state and Socket.IO fan-out. Deadline auto-submits are delayed BullMQ jobs that can run on a separate worker fleet so a whole hall hitting the same deadline doesn't stall live requests, and capacity is checked with k6 load-test scripts before large sittings.

  • Offline-first answers

    Every answer is written to IndexedDB on each keystroke and drained to the server by a retrying loop, so a dropped connection or closed tab loses nothing. Submitting waits until every pending answer has reached the server, the submit endpoint is idempotent, and proctoring events queue the same way instead of disappearing while offline.

  • Not trusting the candidate's clock

    Exam windows are judged against a server-anchored clock rather than the device's, after a candidate whose clock ran 35 minutes slow was shown an exam as 'upcoming' until its real start cutoff had passed.