FX-5: scan-ingestion UI on the marking page
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 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
7bd66fbaf0
commit
7a1dd4dccc
@@ -28,6 +28,7 @@ import type {
|
||||
Neo4jSyncResult,
|
||||
PatchQuestionPayload,
|
||||
SpecPoint,
|
||||
StudentSubmission,
|
||||
TemplateReplacePayload,
|
||||
UpdateTemplateMetaPayload,
|
||||
} from '../../types/exam.types';
|
||||
@@ -298,6 +299,21 @@ export const examRepository = {
|
||||
const res = await axios.put(`${EXAM_BASE}/marks/${markId}`, payload, { headers });
|
||||
return res.data;
|
||||
},
|
||||
|
||||
async uploadScan(
|
||||
batchId: string,
|
||||
file: File,
|
||||
opts: { studentId?: string; matchingMethod?: 'manual' | 'ordered' } = {},
|
||||
): Promise<StudentSubmission> {
|
||||
const headers = await authHeaders();
|
||||
const form = new FormData();
|
||||
form.append('file', file);
|
||||
form.append('matching_method', opts.matchingMethod ?? 'ordered');
|
||||
if (opts.studentId) form.append('student_id', opts.studentId);
|
||||
// Let axios set the multipart Content-Type + boundary (only Authorization is forwarded).
|
||||
const res = await axios.post<StudentSubmission>(`${EXAM_BASE}/batches/${batchId}/scans`, form, { headers });
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
export default examRepository;
|
||||
|
||||
Reference in New Issue
Block a user