headless_lms_server/controllers/cms/
chapters.rs

1//! Controllers for requests starting with `/api/v0/cms/chapters`.
2
3use models::chapters::DatabaseChapter;
4use utoipa::OpenApi;
5
6use crate::prelude::*;
7
8#[derive(OpenApi)]
9#[openapi(paths(get_all_chapters_by_course_id))]
10pub(crate) struct CmsChaptersApiDoc;
11
12/**
13GET `/api/v0/cms/chapters/{course_id}/all-chapters-for-course` - Gets all chapters with a course_id
14*/
15#[instrument(skip(pool))]
16#[utoipa::path(
17    get,
18    path = "/{course_id}/all-chapters-for-course",
19    operation_id = "getAllChaptersByCourseId",
20    tag = "cms_chapters",
21    params(
22        ("course_id" = Uuid, Path, description = "Course id")
23    ),
24    responses(
25        (status = 200, description = "Course chapters", body = Vec<DatabaseChapter>)
26    )
27)]
28async fn get_all_chapters_by_course_id(
29    course_id: web::Path<Uuid>,
30    pool: web::Data<PgPool>,
31    user: AuthUser,
32) -> ControllerResult<web::Json<Vec<DatabaseChapter>>> {
33    let mut conn = pool.acquire().await?;
34    let token = authorize(&mut conn, Act::View, Some(user.id), Res::Course(*course_id)).await?;
35
36    let mut chapters = models::chapters::course_chapters(&mut conn, *course_id).await?;
37
38    chapters.sort_by(|a, b| a.chapter_number.cmp(&b.chapter_number));
39
40    token.authorized_ok(web::Json(chapters))
41}
42
43/**
44Add a route for each controller in this module.
45
46The name starts with an underline in order to appear before other functions in the module documentation.
47
48We add the routes by calling the route method instead of using the route annotations because this method preserves the function signatures for documentation.
49*/
50pub fn _add_routes(cfg: &mut ServiceConfig) {
51    cfg.route(
52        "/{course_id}/all-chapters-for-course",
53        web::get().to(get_all_chapters_by_course_id),
54    );
55}