api/routes/modules/assignments/submissions/
mod.rs

1//! Submission routes module.
2//!
3//! Provides the `/submissions` route group for handling assignment submissions.
4//!
5//! Routes include:
6//! - Create, resubmit, remark, and get submissions
7//! - List all submissions
8//! - Get submission output
9//!
10//! Access control is enforced via middleware guards for students, tutors, or lecturers.
11
12use axum::{
13    middleware::from_fn_with_state,
14    routing::{get, post},
15    Router,
16};
17use get::{get_submission, list_submissions, get_submission_output};
18use post::{submit_assignment, remark_submissions, resubmit_submissions};
19use util::state::AppState;
20use crate::auth::guards::{
21    require_lecturer_or_assistant_lecturer, require_lecturer_or_tutor, require_ready_assignment,
22};
23
24pub mod common;
25pub mod get;
26pub mod post;
27
28/// Builds and returns the `/submissions` route group for a given assignment context.
29///
30/// Routes:
31/// - `GET    /`                          → List all submissions (restricted by role)
32/// - `GET    /{submission_id}`           → Get details of a specific submission
33/// - `GET    /{submission_id}/output`    → Get submission output (lecturer/tutor only)
34/// - `POST   /`                          → Submit a new assignment (student only)
35/// - `POST   /remark`                     → Remark submissions (lecturer/assistant lecturer only)
36/// - `POST   /resubmit`                   → Resubmit submissions (lecturer/assistant lecturer only)
37pub fn submission_routes(app_state: AppState) -> Router<AppState> {
38    Router::new()
39        .route("/", get(list_submissions))
40        .route("/{submission_id}", get(get_submission))
41        .route(
42            "/{submission_id}/output",
43            get(get_submission_output)
44                .route_layer(from_fn_with_state(app_state.clone(), require_lecturer_or_tutor)),
45        )
46        .route(
47            "/",
48            post(submit_assignment)
49                .route_layer(from_fn_with_state(app_state.clone(), require_ready_assignment)),
50        )
51        .route(
52            "/remark",
53            post(remark_submissions)
54                .route_layer(from_fn_with_state(
55                    app_state.clone(),
56                    require_lecturer_or_assistant_lecturer,
57                )),
58        )
59        .route(
60            "/resubmit",
61            post(resubmit_submissions)
62                .route_layer(from_fn_with_state(
63                    app_state.clone(),
64                    require_lecturer_or_assistant_lecturer,
65                )),
66        )
67}