headless_lms_server/controllers/main_frontend/
pages.rs1use std::sync::Arc;
4
5use models::{
6    page_history::PageHistory,
7    pages::{HistoryRestoreData, NewPage, Page, PageDetailsUpdate, PageInfo},
8};
9
10use crate::{
11    domain::{
12        models_requests::{self, JwtKey},
13        request_id::RequestId,
14    },
15    prelude::*,
16};
17
18#[instrument(skip(pool, app_conf))]
48async fn post_new_page(
49    request_id: RequestId,
50    payload: web::Json<NewPage>,
51    pool: web::Data<PgPool>,
52    app_conf: web::Data<ApplicationConfiguration>,
53    user: AuthUser,
54    jwt_key: web::Data<JwtKey>,
55) -> ControllerResult<web::Json<Page>> {
56    let mut conn = pool.acquire().await?;
57    let new_page = payload.0;
58    let course_id = new_page.course_id.ok_or_else(|| {
59        ControllerError::new(
60            ControllerErrorType::BadRequest,
61            "Cannot create a new page without a course id".to_string(),
62            None,
63        )
64    })?;
65    let token = authorize(&mut conn, Act::Edit, Some(user.id), Res::Course(course_id)).await?;
66
67    let page = models::pages::insert_new_content_page(
68        &mut conn,
69        new_page,
70        user.id,
71        models_requests::make_spec_fetcher(
72            app_conf.base_url.clone(),
73            request_id.0,
74            Arc::clone(&jwt_key),
75        ),
76        models_requests::fetch_service_info,
77    )
78    .await?;
79    token.authorized_ok(web::Json(page))
80}
81
82#[instrument(skip(pool))]
91async fn delete_page(
92    page_id: web::Path<Uuid>,
93    pool: web::Data<PgPool>,
94    user: AuthUser,
95) -> ControllerResult<web::Json<Page>> {
96    let mut conn = pool.acquire().await?;
97    let token = authorize(&mut conn, Act::Edit, Some(user.id), Res::Page(*page_id)).await?;
98    let deleted_page =
99        models::pages::delete_page_and_exercises(&mut conn, *page_id, user.id).await?;
100
101    token.authorized_ok(web::Json(deleted_page))
102}
103
104#[instrument(skip(pool))]
108async fn history(
109    pool: web::Data<PgPool>,
110    page_id: web::Path<Uuid>,
111    pagination: web::Query<Pagination>,
112    user: AuthUser,
113) -> ControllerResult<web::Json<Vec<PageHistory>>> {
114    let mut conn = pool.acquire().await?;
115    let token = authorize(&mut conn, Act::Teach, Some(user.id), Res::Page(*page_id)).await?;
116
117    let res = models::page_history::history(&mut conn, *page_id, *pagination).await?;
118
119    token.authorized_ok(web::Json(res))
120}
121
122#[instrument(skip(pool))]
126async fn history_count(
127    pool: web::Data<PgPool>,
128    page_id: web::Path<Uuid>,
129    user: AuthUser,
130) -> ControllerResult<web::Json<i64>> {
131    let mut conn = pool.acquire().await?;
132    let token = authorize(&mut conn, Act::Teach, Some(user.id), Res::Page(*page_id)).await?;
133    let res = models::page_history::history_count(&mut conn, *page_id).await?;
134
135    token.authorized_ok(web::Json(res))
136}
137
138#[instrument(skip(pool, app_conf))]
143async fn restore(
144    request_id: RequestId,
145    pool: web::Data<PgPool>,
146    page_id: web::Path<Uuid>,
147    restore_data: web::Json<HistoryRestoreData>,
148    app_conf: web::Data<ApplicationConfiguration>,
149    user: AuthUser,
150    jwt_key: web::Data<JwtKey>,
151) -> ControllerResult<web::Json<Uuid>> {
152    let mut conn = pool.acquire().await?;
153    let token = authorize(&mut conn, Act::Edit, Some(user.id), Res::Page(*page_id)).await?;
154    let res = models::pages::restore(
155        &mut conn,
156        *page_id,
157        restore_data.history_id,
158        user.id,
159        models_requests::make_spec_fetcher(
160            app_conf.base_url.clone(),
161            request_id.0,
162            Arc::clone(&jwt_key),
163        ),
164        models_requests::fetch_service_info,
165    )
166    .await?;
167
168    token.authorized_ok(web::Json(res))
169}
170
171async fn get_page_info(
177    page_id: web::Path<Uuid>,
178    pool: web::Data<PgPool>,
179    user: AuthUser,
180) -> ControllerResult<web::Json<PageInfo>> {
181    let mut conn = pool.acquire().await?;
182    let token = authorize(&mut conn, Act::Edit, Some(user.id), Res::Page(*page_id)).await?;
183
184    let page_info = models::pages::get_page_info(&mut conn, *page_id).await?;
185
186    token.authorized_ok(web::Json(page_info))
187}
188
189#[instrument(skip(pool))]
193async fn update_page_details(
194    page_id: web::Path<Uuid>,
195    payload: web::Json<PageDetailsUpdate>,
196    pool: web::Data<PgPool>,
197    user: AuthUser,
198) -> ControllerResult<web::Json<bool>> {
199    let mut conn = pool.acquire().await?;
200
201    let token = authorize(&mut conn, Act::Edit, Some(user.id), Res::Page(*page_id)).await?;
202
203    models::pages::update_page_details(&mut conn, *page_id, &payload).await?;
204    token.authorized_ok(web::Json(true))
205}
206
207async fn get_all_pages_by_course_id(
211    course_id: web::Path<Uuid>,
212    pool: web::Data<PgPool>,
213    user: AuthUser,
214) -> ControllerResult<web::Json<Vec<Page>>> {
215    let mut conn = pool.acquire().await?;
216    let token = authorize(&mut conn, Act::Edit, Some(user.id), Res::Course(*course_id)).await?;
217
218    let mut pages = models::pages::get_pages_by_course_id(&mut conn, *course_id).await?;
219
220    pages.sort_by(|a, b| a.order_number.cmp(&b.order_number));
221
222    token.authorized_ok(web::Json(pages))
223}
224
225pub fn _add_routes(cfg: &mut ServiceConfig) {
233    cfg.route("", web::post().to(post_new_page))
234        .route("/{page_id}", web::delete().to(delete_page))
235        .route("/{page_id}/info", web::get().to(get_page_info))
236        .route(
237            "/{page_id}/page-details",
238            web::put().to(update_page_details),
239        )
240        .route("/{page_id}/history", web::get().to(history))
241        .route("/{page_id}/history_count", web::get().to(history_count))
242        .route("/{history_id}/restore", web::post().to(restore))
243        .route(
244            "/{course_id}/all-course-pages-for-course",
245            web::get().to(get_all_pages_by_course_id),
246        );
247}