Implement complete worksheet grading system with AI analysis and mastery tracking: Features: - GPT-5 vision integration for single-pass grading (OCR + analysis) - Three upload modes: file upload, desktop camera, QR code for smartphone - Real-time batch upload workflow via QR code scanning - Automatic mastery profile updates based on grading results - AI feedback with error pattern detection and next step suggestions - Guest user support for anonymous uploads Technical Implementation: - New database tables: worksheet_attempts, problem_attempts, worksheet_mastery - Removed foreign key constraints to support guest users - Session-based batch uploads for efficient multi-worksheet grading - Validation and retry logic for robust AI responses - Browser-compatible UUID generation (Web Crypto API) Components: - CameraCapture: Desktop/mobile camera capture with high resolution - QRCodeDisplay: Real-time upload tracking with 2-second polling - UploadWorksheetModal: Unified interface with three upload tabs - AttemptResultsPage: Detailed grading results with AI analysis API Endpoints: - POST /api/worksheets/upload: Upload and trigger grading - GET /api/worksheets/sessions/[sessionId]: Poll batch uploads - GET /api/worksheets/attempts/[attemptId]: Get grading results Cost: ~$0.04 per worksheet graded Documentation: - AI_MASTERY_ASSESSMENT_PLAN.md: Complete system architecture - PROMPTING_STRATEGY.md: GPT-5 prompting and validation - UX_EXECUTIVE_SUMMARY.md: Stakeholder-friendly overview - UX_UI_PLAN.md: Complete interface design - IMPLEMENTATION_STATUS.md: Testing checklist 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
96 lines
2.6 KiB
TypeScript
96 lines
2.6 KiB
TypeScript
#!/usr/bin/env tsx
|
|
/**
|
|
* Test script for GPT-5 worksheet grading
|
|
*
|
|
* Usage:
|
|
* npx tsx scripts/testGrading.ts path/to/worksheet.jpg
|
|
*
|
|
* This will:
|
|
* 1. Call GPT-5 vision API to grade the worksheet
|
|
* 2. Validate the response
|
|
* 3. Print the results (score, feedback, suggested step)
|
|
*/
|
|
|
|
import { gradeWorksheetWithVision } from '../src/lib/ai/gradeWorksheet'
|
|
import { join } from 'path'
|
|
|
|
async function main() {
|
|
const args = process.argv.slice(2)
|
|
|
|
if (args.length === 0) {
|
|
console.error('Usage: npx tsx scripts/testGrading.ts path/to/worksheet.jpg')
|
|
console.error('\nExample:')
|
|
console.error(' npx tsx scripts/testGrading.ts data/uploads/test-worksheet.jpg')
|
|
process.exit(1)
|
|
}
|
|
|
|
const imagePath = args[0]
|
|
const absolutePath = imagePath.startsWith('/') ? imagePath : join(process.cwd(), imagePath)
|
|
|
|
console.log('🔍 Testing GPT-5 Worksheet Grading')
|
|
console.log('━'.repeat(60))
|
|
console.log(`Image: ${absolutePath}`)
|
|
console.log('━'.repeat(60))
|
|
console.log()
|
|
|
|
try {
|
|
console.log('📤 Calling GPT-5 vision API...')
|
|
const startTime = Date.now()
|
|
|
|
const result = await gradeWorksheetWithVision(absolutePath)
|
|
|
|
const duration = ((Date.now() - startTime) / 1000).toFixed(1)
|
|
console.log(`✅ Grading complete in ${duration}s`)
|
|
console.log()
|
|
|
|
// Print results
|
|
console.log('📊 GRADING RESULTS')
|
|
console.log('━'.repeat(60))
|
|
console.log(
|
|
`Score: ${result.correctCount}/${result.totalProblems} (${(result.accuracy * 100).toFixed(1)}%)`
|
|
)
|
|
console.log()
|
|
|
|
console.log('🤖 AI Feedback:')
|
|
console.log(result.feedback)
|
|
console.log()
|
|
|
|
console.log('🏷️ Error Patterns:')
|
|
if (result.errorPatterns.length === 0) {
|
|
console.log(' None detected')
|
|
} else {
|
|
result.errorPatterns.forEach((pattern) => {
|
|
console.log(` • ${pattern}`)
|
|
})
|
|
}
|
|
console.log()
|
|
|
|
console.log('📈 Progression:')
|
|
console.log(` Current estimate: ${result.currentStepEstimate}`)
|
|
console.log(` Suggested step: ${result.suggestedStepId}`)
|
|
console.log()
|
|
|
|
console.log('🧮 Problem Breakdown:')
|
|
console.log('━'.repeat(60))
|
|
result.problems.forEach((p) => {
|
|
const status = p.isCorrect ? '✓' : '✗'
|
|
const answer = p.studentAnswer !== null ? p.studentAnswer : 'blank'
|
|
console.log(
|
|
`#${p.index + 1}: ${p.operandA} + ${p.operandB} = ${p.correctAnswer} ` +
|
|
`(student: ${answer}) ${status}`
|
|
)
|
|
})
|
|
console.log()
|
|
|
|
console.log('💭 AI Reasoning:')
|
|
console.log(result.reasoning)
|
|
console.log()
|
|
} catch (error) {
|
|
console.error('❌ Grading failed:')
|
|
console.error(error)
|
|
process.exit(1)
|
|
}
|
|
}
|
|
|
|
main()
|