pub async fn submit_assignment(
__arg0: State<AppState>,
__arg1: Path<(i64, i64)>,
__arg2: Extension<AuthUser>,
multipart: Multipart,
) -> impl IntoResponse
Expand description
POST /api/modules/{module_id}/assignments/{assignment_id}/submissions
Submit an assignment file for grading. Accessible to authenticated students assigned to the module.
This endpoint accepts a multipart form upload containing the assignment file and optional flags. The file is saved, graded, and a detailed grading report is returned. The grading process includes code execution, mark allocation, and optional code coverage/complexity analysis.
§Path Parameters
module_id
(i64): The ID of the module containing the assignmentassignment_id
(i64): The ID of the assignment to submit to
§Request (multipart/form-data)
file
(required): The assignment file to upload (.tgz
,.gz
,.tar
, or.zip
only)is_practice
(optional): If set totrue
or1
, marks this as a practice submission
§Example Request
curl -X POST http://localhost:3000/api/modules/1/assignments/2/submissions \
-H "Authorization: Bearer <token>" \
-F "[email protected]" \
-F "is_practice=true"
§Success Response (200 OK)
{
"success": true,
"message": "Submission received and graded",
"data": {
"id": 123,
"attempt": 2,
"filename": "solution.zip",
"hash": "d41d8cd98f00b204e9800998ecf8427e",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"mark": { "earned": 85, "total": 100 },
"is_practice": true,
"is_late": false,
"tasks": [ ... ],
"code_coverage": [ ... ],
"code_complexity": {
"summary": { "earned": 10, "total": 15 },
"metrics": [ ... ]
}
}
}
§Error Responses
404 Not Found - Assignment not found
{ "success": false, "message": "Assignment not found" }
422 Unprocessable Entity - File missing, invalid, or empty
{ "success": false, "message": "No file provided" }
or
{ "success": false, "message": "Only .tgz, .gz, .tar, and .zip files are allowed" }
or
{ "success": false, "message": "Empty file provided" }
500 Internal Server Error - Grading or system error
{ "success": false, "message": "Failed to save submission" }
or
{ "success": false, "message": "Failed to run code for submission" }
or
{ "success": false, "message": "Failed to load mark allocator" }
or
{ "success": false, "message": "Failed to mark submission" }
§Side Effects
- Saves the uploaded file and generated outputs to disk
- Triggers code execution and marking
- Saves a copy of the grading report as
submission_report.json
in the attempt folder
§Filesystem
- Uploaded file and outputs are stored under:
ASSIGNMENT_STORAGE_ROOT/module_{module_id}/assignment_{assignment_id}/assignment_submissions/user_{user_id}/attempt_{n}/
§Notes
- Each submission increments the attempt number for the user/assignment
- Only one file per submission is accepted
- Practice submissions are marked and reported but may not count toward final grade
- The returned report includes detailed per-task grading, code coverage, and complexity if available
- The endpoint is restricted to authenticated students assigned to the module
- All errors are returned in a consistent JSON format