api/routes/modules/assignments/mark_allocator/post.rs
1use crate::response::ApiResponse;
2use axum::{Json, extract::Path, http::StatusCode, response::IntoResponse};
3use util::mark_allocator::mark_allocator::{SaveError, generate_allocator};
4
5/// POST /api/modules/{module_id}/assignments/{assignment_id}/mark_allocator
6///
7/// Generate a new mark allocator configuration for a specific assignment. Accessible to users with
8/// Lecturer roles assigned to the module.
9///
10/// This endpoint automatically generates a mark allocator configuration based on the memo output
11/// files for the assignment. The generated configuration defines how marks are distributed across
12/// different tasks and criteria, ensuring proper weight allocation for the grading system.
13///
14/// ### Path Parameters
15/// - `module_id` (i64): The ID of the module containing the assignment
16/// - `assignment_id` (i64): The ID of the assignment to generate mark allocator for
17///
18/// ### Example Request
19/// ```bash
20/// curl -X POST http://localhost:3000/api/modules/1/assignments/2/mark_allocator \
21/// -H "Authorization: Bearer <token>"
22/// ```
23///
24/// ### Success Response (200 OK)
25/// ```json
26/// {
27/// "success": true,
28/// "message": "Mark allocator successfully generated.",
29/// "data": {
30/// "tasks": [
31/// {
32/// "task_number": 1,
33/// "weight": 0.4,
34/// "criteria": [
35/// {
36/// "name": "Correctness",
37/// "weight": 0.7
38/// },
39/// {
40/// "name": "Code Quality",
41/// "weight": 0.3
42/// }
43/// ]
44/// }
45/// ],
46/// "total_weight": 1.0
47/// }
48/// }
49/// ```
50///
51/// ### Error Responses
52///
53/// **404 Not Found** - Module or assignment folder does not exist
54/// ```json
55/// {
56/// "success": false,
57/// "message": "Module or assignment folder does not exist",
58/// "data": null
59/// }
60/// ```
61///
62/// **500 Internal Server Error** - Failed to generate mark allocator
63/// ```json
64/// {
65/// "success": false,
66/// "message": "Failed to generate mark allocator",
67/// "data": null
68/// }
69/// ```
70///
71/// ### Notes
72/// - This endpoint requires memo output files to exist in the assignment directory
73/// - The generated configuration is based on analysis of memo content and structure
74/// - Task weights are automatically calculated to ensure fair distribution
75/// - Generation is restricted to users with Lecturer permissions for the module
76/// - The generated allocator can be further customized using the PUT endpoint
77pub async fn generate(Path((module_id, assignment_id)): Path<(i64, i64)>) -> impl IntoResponse {
78 match generate_allocator(module_id, assignment_id).await {
79 Ok(json) => (
80 StatusCode::OK,
81 Json(ApiResponse::success(
82 json,
83 "Mark allocator successfully generated.",
84 )),
85 )
86 .into_response(),
87
88 Err(SaveError::DirectoryNotFound) => (
89 StatusCode::NOT_FOUND,
90 Json(ApiResponse::<()>::error(
91 "Module or assignment folder does not exist",
92 )),
93 )
94 .into_response(),
95
96 Err(_) => (
97 StatusCode::INTERNAL_SERVER_ERROR,
98 Json(ApiResponse::<()>::error(
99 "Failed to generate mark allocator",
100 )),
101 )
102 .into_response(),
103 }
104}