Assignments & AI Grading¶
Last updated: 2026-07-13 (creation flow rewritten after PR #1335 replaced the 3-step wizard with the adaptive Compose → Review → Proctor flow, and PR #1341 added the live SSE generation stepper)
A multi-type assessment platform with AI-assisted grading. Trainers create assignments, learners attempt and submit, parents get a read-only view. It supports 8 question types, rubric-based evaluation, handwritten physical-exam OCR, code challenges, and proctoring, covering K-12 homework through university exam evaluation.
How it works¶
Create (trainer)¶
/assignments/new is a single AI-first flow whose step sequence adapts to the assignment type. It replaced the old fixed 3-step Info / Questions / Settings wizard in PR #1335.
Compose ──▶ Review ──▶ Proctor
(always) (skipped for (only when the type
physical_exam) surfaces a setting)
The sequence is computed, not hardcoded (helpers/steps.ts:61-65):
- Compose is always present.
- Review is dropped for
physical_exam: there are no online questions to review. - Proctor appears only when the type's
settings_visibilityactually surfaces something: proctoring, or at least one of auto-grade, shuffle questions, shuffle options, show correct answers, allow late submission (computeHasProctorStep,helpers/steps.ts:32-52). A type with none of these publishes straight from Review.
So a quiz can be a 3-step flow and an essay a 2-step one, and the progress dots plus the "step N of M" subtitle reflect whichever sequence the current type produced.
Compose. Title, description, instructions, type chips, due date, time limit (when the type requires one), total marks for physical_exam, file uploads (question paper, model answer), and targeting. Targeting is Standalone, Course, Direct (class / section / learner), or College (academic level); it is not schema-validated, so a submit with empty recipients bounces back to Compose with an error toast (index.tsx:122-137).
The inline AI brief. Compose carries an AI brief panel rather than a separate "generate" page (components/AIBriefSection/). The trainer writes a topic prompt, optionally picks a subject to ground on, and picks a source: a curated template pick from Drive or the library, or freshly staged reference documents. A collapsed "Fine-tune" accordion holds the rest:
- Question count, Auto or Custom. Auto sends no count and lets the backend pick per type; Custom sends an explicit number (1-50, defaulting to the type's own count: 5 for homework, 10 for quiz, 20 for test, 1 for essay, and so on. See
constants.ts:85-99andAIBriefFineTune.tsx:29-65). - Difficulty, and a question mix of type chips seeded from the type's
recommended_question_types(recommended ones are ticked).
Generating runs Compose validation first, then streams. On success the generated instructions land in the form, the questions are appended (or replace an untouched blank question), and the flow jumps straight to Review.
Live generation progress. Generation calls the SSE endpoint POST /ai-teacher/generate-homework/stream and renders a live stepper over the three phases the agent actually streams: grounding → generating → validating (components/AIBriefSection/generationPhases.ts:4, GenerationProgress.tsx). Labels are type-aware ("grounding in Physics", "writing your quiz"); an unrecognised phase falls back to the agent's own label rather than rendering blank. If the stream is unavailable or dies mid-way, the client silently falls back to the blocking POST /ai-teacher/generate-homework call, so generation still completes without progress (AIBriefSection/index.tsx:154-196). Added in PR #1341.
Review. The generated (or hand-written) questions, per type: content (rich text), options (MCQ), correct answers, marks, code starter and test cases. Questions can be added by hand from the type selector. Leaving Review runs per-question validation and surfaces the failures inline on the offending question, not as one generic form error.
Proctor. Delivery settings (late penalty, attempts allowed, show correct answers, shuffle) and the proctoring toggles, both filtered by the type's settings_visibility. This is where the trainer publishes.
After create, a toast with a "View Assignment" link confirms.
List (/assignments)¶
A table on md+, cards on small screens. Row click opens a quick-look modal: title, type, due, status, target groups, and submission stats (trainer) or submission status + grade (learner). Footer buttons deep-link to the full detail and submissions pages. Sorting is client-side. The learner "Upcoming" tab stays card-grouped (Today / Tomorrow / Overdue / Upcoming).
/homework and /homework/new are legacy redirects to /assignments and /assignments/new.
Attempt (learner)¶
From the list, the learner opens the detail page (instructions, marks, time limit), starts the attempt with a question-navigator sidebar, and answers per type (radio / checkbox / textarea / code editor / file upload). Draft answers auto-save to localStorage with a beforeunload warning on unsaved changes. Submit posts to /submissions/{id}/submit, then results show marks per question, feedback, and pass/fail. Code runs client-side via Pyodide.
Grade (trainer)¶
The submissions page filters by status (submitted / graded / pending / late). Per submission, the trainer sees question-by-question answers, AI evaluation results, and proctoring flags, then grades with per-question marks + feedback and overall feedback.
AI grading evaluates a submission against the rubric and model answer, returning per-question marks, a confidence score (0-100%), feedback, and strengths/improvements. The trainer reviews in the accept-grade modal, adjusts, and accepts. Confidence bands: green 80%+, yellow 60-79%, red below 60%. Rubrics weight criteria (for example Content 40%, Clarity 30%, Engagement 30%) with scored levels (Excellent / Good / Fair / Poor).
Physical exam¶
1. Create exam → upload question paper PDF
2. Extract questions (OCR + LLM) → review & confirm
3. Upload answer sheets (PDF per learner)
4. OCR → learner mapping → batch AI evaluation
5. Review: 3-panel layout (questions | question paper | answer sheet)
6. Finalize marks per sheet
7. Marks register: summary stats, per-learner table, CSV export
Routes under /physical-exams: /physical-exams, /physical-exams/create, /:id/upload, /:id/review/:sheetId, /:id/marks-register.
Question types¶
| Type | Grading | Description |
|---|---|---|
| MCQ | Auto | Single correct answer |
| MCQ Multi-Select | Auto | Multiple correct answers |
| True/False | Auto | Binary choice |
| Short Answer | Auto/AI | 1-2 sentence response |
| Fill in the Blank | Auto | Complete the sentence |
| Code Challenge | Auto + AI | Python/JS with test cases |
| Long Answer/Essay | AI/Manual | Detailed written response |
| File Upload | Manual | Documents, images |
Assignment types¶
- K-12: Homework, Quiz, Worksheet, Classwork, Test, Competition
- Higher Ed: Case Study, Seminar, Research Paper, Coding Competition, Assessment
- Corporate: Knowledge Check, Compliance Training, 360 Feedback, Practical Exercise
- Physical: Physical Exam (handwritten answer sheets via OCR)
Endpoints¶
AI generation (used by the Compose-step brief):
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /ai-teacher/generate-homework/stream |
SSE generation: status frames (grounding / generating / validating), then done with the assignment |
| POST | /ai-teacher/generate-homework |
Blocking fallback when the stream is unavailable |
AI evaluation (/evaluations):
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /evaluations/submissions/{id}/evaluate |
Trigger AI eval |
| GET | /evaluations/submissions/{id} |
Get results |
| POST | /evaluations/submissions/{id}/accept |
Accept AI grade |
| POST | /evaluations/batch |
Batch evaluate |
| GET/POST/PATCH/DELETE | /evaluations/rubrics, /evaluations/rubrics/{id} |
Rubric CRUD |
| POST | /evaluations/ocr/extract |
OCR extract |
Physical exams (/physical-exams):
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /physical-exams |
Create exam |
| POST | /physical-exams/{id}/upload-question-paper |
Upload question paper PDF |
| POST | /physical-exams/{id}/extract-questions |
OCR extract questions |
| POST | /physical-exams/{id}/confirm-questions |
Confirm extracted questions |
| POST | /physical-exams/{id}/answer-sheets/upload |
Upload answer sheets |
| POST | /physical-exams/{id}/evaluate-batch |
Batch evaluate |
| GET | /physical-exams/{id}/review/{sheetId} |
Review data |
| POST | /physical-exams/{id}/review/{sheetId}/finalize |
Finalize marks |
| GET | /physical-exams/{id}/marks-register |
Marks summary |
| GET | /physical-exams/{id}/marks-register/export |
CSV export |
Where it lives¶
Routes: /assignments, /assignments/new, /assignments/:id, /physical-exams.
pages/teacher/CreateAssignmentPage/: the adaptive creation flow.index.tsx: form provider, step sequence, submit.helpers/steps.ts:getStepSequence,computeHasProctorStep, per-step field lists.components/ComposeStep.tsx,components/QuestionsStep.tsx(the Review step),components/SettingsStep.tsx(the Proctor step),components/WizardProgress.tsx.components/AIBriefSection/:index.tsx(brief + generate + SSE consumer),AIBriefFineTune.tsx(Auto/Custom count, difficulty, question mix),AIBriefSourcePicker.tsx(template vs staged document),GenerationProgress.tsx+generationPhases.ts(grounding → generating → validating).types.ts:STEPS = { COMPOSE, REVIEW, PROCTOR }.- There is no
InfoStep.tsx; it was removed with the old wizard.
pages/shared/HomeworkPage/: list surface (table + quick-look modal)pages/shared/AssignmentDetailPage/: learner attempt + resultscomponents/evaluation/: AcceptAIGradeModal