api/routes/modules/
mod.rs

1//! # Modules Routes Module
2//!
3//! Defines and wires up routes for the `/api/modules` endpoint group.
4//!
5//! ## Structure
6//! - `post.rs` — POST handlers (e.g., create module, assign lecturers)
7//! - `get.rs` — GET handlers (e.g., fetch modules, lecturers, students)
8//! - `put.rs` — PUT handlers (e.g., edit module, edit lecturers)
9//! - `delete.rs` — DELETE handlers (e.g., remove lecturers, students, tutors)
10//! - `assignments.rs` — nested assignment routes under modules
11//!
12//! ## Usage
13//! Call `modules_routes()` to get a configured `Router` for `/modules` to be mounted in the main app.
14
15use axum::{middleware::{from_fn, from_fn_with_state}, routing::{delete, get, post, put}, Router};
16use delete::{delete_module, bulk_delete_modules};
17use get::{get_module, get_modules, get_my_details};
18use post::create;
19use put::{edit_module, bulk_edit_modules};
20use assignments::assignment_routes;
21use util::state::AppState;
22use crate::{auth::guards::{require_admin, require_assigned_to_module, require_lecturer}, routes::modules::{announcements::announcement_routes, personnel::personnel_routes}};
23
24pub mod assignments;
25pub mod personnel;
26pub mod delete;
27pub mod get;
28pub mod post;
29pub mod put;
30pub mod common;
31pub mod announcements;
32
33/// Builds and returns the `/modules` route group.
34///
35/// Routes:
36/// - `GET    /modules`                 → list all modules
37/// - `POST   /modules`                 → create a new module (admin only)
38/// - `GET    /modules/{module_id}`     → get a single module by ID
39/// - `PUT    /modules/{module_id}`     → edit module details (admin only)
40/// - `DELETE /modules/{module_id}`     → delete a module entirely (admin only)
41///
42/// - Nested students routes under `/modules/{module_id}/students`
43/// - Nested personnel routes under `/modules/{module_id}/personnel`
44///
45/// All modifying routes are protected by `require_admin` middleware.
46pub fn modules_routes(app_state: AppState) -> Router<AppState> {
47    Router::new()
48        .route("/", get(get_modules))
49        .route("/me", get(get_my_details))
50        .route("/{module_id}", get(get_module).route_layer(from_fn_with_state(app_state.clone(),require_assigned_to_module)))
51        .route("/", post(create).route_layer(from_fn(require_admin)))
52        .route("/{module_id}", put(edit_module).route_layer(from_fn(require_admin)))
53        .route("/{module_id}", delete(delete_module).route_layer(from_fn(require_admin)))
54        .route("/bulk", delete(bulk_delete_modules).route_layer(from_fn(require_admin)))
55        .route("/bulk", put(bulk_edit_modules).route_layer(from_fn(require_admin)))
56        .nest("/{module_id}/assignments", assignment_routes(app_state.clone()))
57        .nest("/{module_id}/personnel", personnel_routes().route_layer(from_fn_with_state(app_state.clone(),require_lecturer)))
58        .nest("/{module_id}/announcements", announcement_routes(app_state.clone()).route_layer(from_fn_with_state(app_state.clone(), require_assigned_to_module)))
59}