The marking flow read student_submissions but there was no way to create them —
print→scan→mark could not be completed in-app. Add an "Upload scans" control to
the marking queue that posts PDFs to the existing POST /batches/{id}/scans and
refreshes the queue.
- examRepository.uploadScan(batchId, file, {studentId?, matchingMethod?}): multipart
upload (axios sets the boundary), returns the created/updated StudentSubmission.
- ExamMarkingPage: "Upload scans" button + hidden multi-file PDF input; uploads each
with matching_method='ordered' (fills the roster in order; unmatched scans become
reconcilable submissions), then reloads the queue with a success/failure summary.
No API or schema change (endpoint already existed). tsc clean; behaviour is covered
by the cc-browser-tester card (FX-V).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Description
React 18 + TypeScript + TLDraw 3.6 frontend for Classroom Copilot — whiteboard, transcription panel, timetable, and graph views
Languages
TypeScript
96.1%
CSS
3.1%
JavaScript
0.5%
Dockerfile
0.2%
HTML
0.1%