GeminiGemini

I built a quiz engine from an XLSX in one afternoon

A client needed a timed quiz platform with anti-cheat. They handed me an XLSX of questions. I handed them a live platform in a day.

10 November 2025·
AWS AmplifyDynamoDBRoute53Mailgun
·
schedule3 hoursbar_chartMediumpayments$0 extra

infoThe Situation

A client needed to run timed quizzes for their candidates — with anti-cheat enforcement and automated result delivery. They had the questions ready in an XLSX. Everything else was a blank page. The timeline was tight: one afternoon to have something demonstrable.

outputWhat Came Out

A live branded quiz platform on a custom domain. Anti-cheat enforcement. Automated result delivery. All from an XLSX.

routeHow It Went Down

GeminiStep 1Gemini

Read the client's XLSX file containing all quiz questions

Extracted questions, options, correct answers, timing data — structured and ready

GeminiStep 2Gemini

Prompted to transform the XLSX data into DynamoDB-compatible JSON records

Clean JSON matching DynamoDB schema — no manual reformatting needed

AWS AmplifyStep 3AWS Amplify

Set up hosting, wired up the frontend quiz interface

Live URL with custom domain via Route53

Step 4DynamoDB

Populated questions via script generated in step 2

Full question bank live in the database, ready to serve

Step 5Custom JS

Built anti-cheat: window blur / alt-tab detection → strike system

1 strike = warning banner. 3 strikes = disqualified, quiz auto-submitted

MailgunStep 6Mailgun

Wired up result email on quiz completion

Candidates receive their results within seconds of submitting

I didn't rebuild the data manually. I didn't manually key in 60 questions into a web form. I prompt-engineered the boring part away and focused on the architecture that actually mattered.

starThe Key Move

Gemini didn't just read the XLSX — it restructured it to match DynamoDB schema in one shot. That was the whole hack. Without that step, I'd have spent the whole afternoon manually reformatting 60 questions.

thumb_upWhat Made It Satisfying

The Gemini transformation step was the key. What would have been hours of manual data entry became a 5-minute prompt. The rest was standard AWS plumbing.

schoolLessons Learned

warningWhat Was Hard

Getting the anti-cheat UX right. A blur event can fire innocuously — when a user switches to another tab to check something. The strike threshold and warning copy had to feel fair, not punitive.

redoWhat I'd Do Differently

I'd add a review screen before final submission so candidates can double-check answers. The anti-cheat was non-negotiable for the client, but a review step would make the experience less stressful.

codeAnti-cheat detection (the key UX piece)

javascript
// Detect tab switch / window blur = strike
document.addEventListener('visibilitychange', () => {
  if (document.hidden) {
    addStrike();
  }
});

window.addEventListener('blur', () => {
  addStrike();
});

function addStrike() {
  strikes++;
  if (strikes >= 3) {
    submitQuiz(true); // force disqualified
    showDisqualifiedScreen();
  } else {
    showWarning(`Strike ${strikes}/3`);
  }
}
I built a quiz engine from an XLSX in one afternoon | Nextfusion Inspirations | Nextfusion