1.9 KiB
1.9 KiB
Django Backend Specification (Minimal)
Purpose
Provide a tiny REST API to read exams from files, manage attempts, autosave progress, and produce an output JSON bundle.
Endpoints
- GET
/api/exams→ list published exams (frommanifest.jsonandinput/) - GET
/api/exams/{examId}→ return exam JSON (frominput/) - POST
/api/exams/{examId}/attempt→ start or resume attempt; returns attempt JSON - PUT
/api/attempts/{attemptId}→ autosave answers and timestamps; returns updated attempt - POST
/api/attempts/{attemptId}/submit→ finalize, write output bundle, mark finished; returns output path - GET
/api/progress/me→ return progress snapshot for current user
Storage Conventions
input/{examId}.json— canonical exam fileattempts/{userId}/{examId}/{attemptId}.json— active/resumed attemptoutput/{examId}_{attemptId}.json— bundled{ exam, attempt }progress/{userId}.json— progress summarymanifest.json— published flags and per-user finished/active sets
Attempt JSON shape
{
attemptId, userId, examId, status, startedAt, updatedAt, submittedAt?,
answers: [ { questionId, response, timeSec? } ]
}
Rules
- One active attempt per exam per user (unless configured otherwise)
- Use temp file + atomic rename for all writes
- Validate exam exists and is published before starting
- Resume uses most recent attempt by
updatedAt
Autosave
- Accept partial answers; update progress percent = answered/total
- Return server
updatedAtfor client reconciliation
Submit
- Change status to
submitted, thenfinished - Write bundle
{ exam, attempt }tooutput/ - Update manifest and progress
Security (minimal)
- Cookie-based session with
userId - CSRF for state-changing requests
- CORS allow Angular origin
Errors (examples)
- 404
EXAM_NOT_FOUND - 409
ATTEMPT_EXISTS - 400
INVALID_PAYLOAD - 423
EXAM_NOT_PUBLISHED