headless_lms_server/controllers/main_frontend/
proposed_edits.rs1use std::sync::Arc;
2
3use models::proposed_page_edits::{self, EditProposalInfo, PageProposal, ProposalCount};
4
5use crate::{
6 domain::{
7 models_requests::{self, JwtKey},
8 request_id::RequestId,
9 },
10 prelude::*,
11};
12
13#[derive(Debug, Deserialize)]
14#[cfg_attr(feature = "ts_rs", derive(TS))]
15pub struct GetEditProposalsQuery {
16 pending: bool,
17 #[serde(flatten)]
18 pagination: Pagination,
19}
20
21#[instrument(skip(pool))]
25pub async fn get_edit_proposals(
26 course_id: web::Path<Uuid>,
27 pool: web::Data<PgPool>,
28 query: web::Query<GetEditProposalsQuery>,
29 user: AuthUser,
30) -> ControllerResult<web::Json<Vec<PageProposal>>> {
31 let mut conn = pool.acquire().await?;
32
33 let feedback = proposed_page_edits::get_proposals_for_course(
34 &mut conn,
35 *course_id,
36 query.pending,
37 query.pagination,
38 )
39 .await?;
40
41 let token = authorize(
42 &mut conn,
43 Act::Teach,
44 Some(user.id),
45 Res::Course(*course_id),
46 )
47 .await?;
48 token.authorized_ok(web::Json(feedback))
49}
50
51#[instrument(skip(pool))]
55pub async fn get_edit_proposal_count(
56 course_id: web::Path<Uuid>,
57 pool: web::Data<PgPool>,
58 user: AuthUser,
59) -> ControllerResult<web::Json<ProposalCount>> {
60 let mut conn = pool.acquire().await?;
61
62 let edit_proposal_count =
63 proposed_page_edits::get_proposal_count_for_course(&mut conn, *course_id).await?;
64
65 let token = authorize(
66 &mut conn,
67 Act::Teach,
68 Some(user.id),
69 Res::Course(*course_id),
70 )
71 .await?;
72 token.authorized_ok(web::Json(edit_proposal_count))
73}
74
75#[instrument(skip(pool, app_conf))]
79pub async fn process_edit_proposal(
80 request_id: RequestId,
81 proposal: web::Json<EditProposalInfo>,
82 app_conf: web::Data<ApplicationConfiguration>,
83 user: AuthUser,
84 pool: web::Data<PgPool>,
85 jwt_key: web::Data<JwtKey>,
86) -> ControllerResult<HttpResponse> {
87 let mut conn = pool.acquire().await?;
88 let proposal = proposal.into_inner();
89
90 proposed_page_edits::process_proposal(
91 &mut conn,
92 proposal.page_id,
93 proposal.page_proposal_id,
94 proposal.block_proposals,
95 user.id,
96 models_requests::make_spec_fetcher(
97 app_conf.base_url.clone(),
98 request_id.0,
99 Arc::clone(&jwt_key),
100 ),
101 models_requests::fetch_service_info,
102 )
103 .await?;
104
105 let token = authorize(
106 &mut conn,
107 Act::Edit,
108 Some(user.id),
109 Res::Page(proposal.page_id),
110 )
111 .await?;
112 token.authorized_ok(HttpResponse::Ok().finish())
113}
114
115pub fn _add_routes(cfg: &mut ServiceConfig) {
123 cfg.route("/course/{course_id}", web::get().to(get_edit_proposals))
124 .route(
125 "/course/{course_id}/count",
126 web::get().to(get_edit_proposal_count),
127 )
128 .route(
129 "/process-edit-proposal",
130 web::post().to(process_edit_proposal),
131 );
132}