Generate high-quality board-style practice questions for notebook pages. Use when: creating questions, filling quiz gaps, adding vignettes, auditing quiz completeness, writing board-style questions, improving coverage, quiz JSON generation.
Generate high-quality, board-style practice questions for medical study guide pages. Questions are grounded in actual page content and source lectures, cross-referenced against the glossary for accuracy, and designed to fill coverage gaps in the existing quiz set.
Read all four sources before generating anything.
1a. Existing quiz file
Read src/data/quizzes/{Notebook}/{slug}.json. Catalog what's already covered: count questions by style, domain, and tags. Note the highest existing question ID number.
1b. Page data JSON
Read src/data/pages/{Notebook}/{slug}.json. Extract: learning_objectives, sections, source_lectures.
1c. Page JSX content
Read src/notebooks/{Notebook}/{subdirectory}/{slug}.jsx. Identify key concepts, mechanisms, clinical pearls, comparison tables, pathway steps, and warning boxes.
1d. Glossary cross-reference
Search src/data/drugs.json, src/data/pathologies.json, for entities mentioned on this page. Verify details match. Flag discrepancies to the user.
src/data/concepts.json1e. Image library (optional)
Read public/media/{Notebook}/images/ATTRIBUTIONS.json. Filter for images whose pages array includes the current slug. Available for image-based questions.
Present the gap analysis before generating. Example: "12 existing questions. Sections X and Y uncovered. 'mechanism' style has only 1 question. Objectives 3 and 7 untested. Suggesting 8 new questions."
Follow these principles:
See quiz schema for the exact JSON format.
Image-based questions: When relevant images exist, add "image" field. Preferred format: { "src": "/media/...", "alt": "...", "caption": "..." }. QuizHub also accepts a plain string path. Verify the image file exists in public/ before referencing. Reference in stem: "A peripheral blood smear is shown [see image]..." Use finding-based style for most.
rationale[correctIndex] starts with "CORRECT" and all others start with "INCORRECT". This is the #1 source of quiz bugs.image field exists, verify the file exists in public/Write the complete updated quiz file and present a summary: questions added, gaps filled, updated distribution.
After writing the quiz file, run:
node -e "
const fs=require('fs'),p=require('path');
const dir=p.join(process.cwd(),'src/data/quizzes');
let bad=0;
(function walk(d){fs.readdirSync(d).forEach(f=>{const fp=p.join(d,f);if(fs.statSync(fp).isDirectory())return walk(fp);if(!f.endsWith('.json'))return;const qs=JSON.parse(fs.readFileSync(fp,'utf8'));(Array.isArray(qs)?qs:qs.questions||[]).forEach(q=>{if(!q.rationale)return;for(const[k,v]of Object.entries(q.rationale)){if(k===String(q.correctIndex)&&!/^Correct/i.test(v)){console.log('MISMATCH',q.id,'correctIndex='+q.correctIndex,'but rationale['+k+'] says:',v.slice(0,60));bad++;}if(k!==String(q.correctIndex)&&/^Correct/i.test(v)){console.log('MISMATCH',q.id,'rationale['+k+'] says Correct but correctIndex='+q.correctIndex);bad++;}}if(q.image){const src=typeof q.image==='string'?q.image:q.image.src;if(src&&!fs.existsSync(p.join(process.cwd(),'public',src.replace(/^\//, ''))))console.log('MISSING IMAGE',q.id,src);}});})})(dir);
console.log(bad?bad+' issues found':'All clear');
// Distribution check
(function checkDist(d){fs.readdirSync(d).forEach(f=>{const fp=p.join(d,f);if(fs.statSync(fp).isDirectory())return checkDist(fp);if(!f.endsWith('.json'))return;const qs=JSON.parse(fs.readFileSync(fp,'utf8'));const arr=Array.isArray(qs)?qs:qs.questions||[];if(arr.length<5)return;const counts={};arr.forEach(q=>{const ci=q.correctIndex;counts[ci]=(counts[ci]||0)+1;});for(const[idx,cnt]of Object.entries(counts)){if(cnt/arr.length>0.4)console.log('BIAS',f,arr.length+'q',Math.round(cnt/arr.length*100)+'% at index '+idx);}});})(dir);
"
If issues are found, fix them before finishing.