Paper Checker is a role-based school application for evaluating handwritten exam papers with Gemini. Teachers upload a question paper PDF, an optional answer key PDF, and handwritten student answer sheets. The system stores detailed, question-wise reports in the database so teachers, school admins, and students can review the outcome later.
SUPER_ADMIN: creates schools and platform-level users.SCHOOL_ADMIN: manages teachers and students within one school.TEACHER: creates checking sets, uploads question papers, and triggers evaluation.STUDENT: views their saved reports.
- Next.js 15 App Router
- TypeScript
- Prisma + SQLite
- Cookie-based JWT auth
- Gemini API integration through
generateContent
Copy .env.example to .env and set:
DATABASE_URL="file:/app/data/paper-checker.db"
JWT_SECRET="replace-with-a-long-random-secret"
GEMINI_API_KEY="your-gemini-api-key"
GEMINI_MODEL="gemini-2.0-flash"npm install
npm run prisma:generate
npm run db:init
npm run db:seed
npm run devIf prisma db push works in your environment, you can use that instead of npm run db:init. In this workspace, Prisma client generation works, but the schema engine used by db push is unreliable, so a checked-in SQLite bootstrap script is provided at scripts/init-db.sql.
Build and run:
docker build -t paper-checker .
docker run -d \
--name paper-checker \
-p 8081:8081 \
-e PORT="8081" \
-e HOSTNAME="0.0.0.0" \
-e JWT_SECRET="replace-with-a-long-random-secret" \
-e GEMINI_API_KEY="your-gemini-api-key" \
-e GEMINI_MODEL="gemini-2.0-flash" \
-e DATABASE_URL="file:/app/data/paper-checker.db" \
-e SEED_DEMO_DATA="true" \
-v paper_checker_data:/app/data \
-v paper_checker_uploads:/app/uploads \
paper-checkerOr with Compose:
docker compose up -d --buildThe provided Compose file seeds the demo school and users by default on first boot.
Container behavior:
- Binds to
0.0.0.0and serves on port8081 - Stores the SQLite database in
/app/data/paper-checker.db - Stores uploaded PDFs in
/app/uploads - Initializes the schema automatically on first boot
- Seeds demo users only if
SEED_DEMO_DATA=true
For production, set a strong JWT_SECRET, use a real GEMINI_API_KEY, and usually keep SEED_DEMO_DATA=false after the first run.
All seeded users use password password123.
superadmin@paperchecker.localschooladmin@greenfield.localteacher@greenfield.localstudent@greenfield.local
- Super admin creates schools.
- School admin creates teacher and student accounts.
- Teacher creates a checking set with:
- title, subject, class grade, section
- total marks
- question paper PDF
- optional answer key PDF
- custom evaluation instructions
- Teacher opens the checking set and uploads the handwritten answer sheet PDF with student name and roll number.
- Gemini receives:
- default evaluation prompt
- teacher custom instructions
- question paper PDF
- optional answer key PDF
- handwritten answer sheet PDF
- The app stores:
- answer sheet path
- submission status
- detailed question-wise breakdown
- marks awarded
- strengths and improvement notes
- raw Gemini response for audit/debugging
- Uploaded files are written to
uploads/. - The default grading prompt is in
lib/default-prompt.ts. - Gemini calls happen in
lib/gemini.ts. - SQLite is used for local development so the project starts quickly. Swap Prisma datasource settings for Postgres/MySQL when deploying.