Files
lnet_tutor/docs/django-backend-spec.md
2025-10-22 20:14:31 +08:00

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 (from manifest.json and input/)
  • GET /api/exams/{examId} → return exam JSON (from input/)
  • 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 file
  • attempts/{userId}/{examId}/{attemptId}.json — active/resumed attempt
  • output/{examId}_{attemptId}.json — bundled { exam, attempt }
  • progress/{userId}.json — progress summary
  • manifest.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 updatedAt for client reconciliation

Submit

  • Change status to submitted, then finished
  • Write bundle { exam, attempt } to output/
  • 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