Files
lnet_tutor/docs/json-io-and-state.md
2025-10-22 20:14:31 +08:00

1.6 KiB

JSON I/O, State Machine, and Folders (Minimal)

Folders

  • input/ — source exam JSON files
  • attempts/{userId}/{examId}/{attemptId}.json — current attempt files
  • output/{examId}_{attemptId}.json — final bundle { exam, attempt }
  • progress/{userId}.json — per-user snapshot
  • manifest.json — registry of published exams and user completion

Input Exam JSON

  • Must conform to docs/exam-format.md

Attempt JSON

{
  "attemptId": "<id>",
  "userId": "<user>",
  "examId": "<exam>",
  "status": "in_progress|submitted|finished",
  "startedAt": "ISO-8601",
  "updatedAt": "ISO-8601",
  "submittedAt": "ISO-8601?",
  "answers": [ { "questionId": "q1", "response": <any>, "timeSec": 25 } ]
}

Output JSON

{
  "exam": { /* original exam JSON */ },
  "attempt": { /* final attempt JSON */ }
}

State Machine

  • draftpublishedin_progresssubmittedfinished

Publish & Finish

  • Publish: manifest.json marks { examId, published: true }
  • Finish for a user: attempt.status finished AND output bundle exists AND manifest.users[userId].finished includes examId

Autosave & Integrity

  • Write to temp file then atomic rename for attempts/progress/output/manifest
  • Server returns updatedAt for reconciliation
  • One active attempt per exam per user (simple lock)

Naming

  • attemptId = <userId>-<examId>-<timestamp>
  • Output file name: <examId>_<attemptId>.json

Versioning

  • Store examVersion in attempt; warn on resume if drift

Permissions (minimal)

  • Local file permissions: read-only for input/; write for others