first working version
This commit is contained in:
55
docs/json-io-and-state.md
Normal file
55
docs/json-io-and-state.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# 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
|
||||
- `draft` → `published` → `in_progress` → `submitted` → `finished`
|
||||
|
||||
## 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
|
||||
Reference in New Issue
Block a user