headless_lms_server/controllers/main_frontend/credit_registration_admin/
materialize.rs1use headless_lms_models::credit_registration_admin_actions::{
4 CreditRegistrationAdminAction, CreditRegistrationAdminActionTarget, GLOBAL_ADMIN_ROLE,
5 NewCreditRegistrationAdminAction,
6};
7use headless_lms_models::credit_registrations;
8use headless_lms_models::library::credit_registration::preconditions::{
9 PRECONDITIONS_LIMIT, recompute_preconditions,
10};
11use utoipa::ToSchema;
12
13use crate::prelude::*;
14use headless_lms_credit_registration::{CreditRegistrationPhase, Materialized, materialize_now};
15
16use super::authorize_credit_registration_admin;
17
18#[derive(Debug, Deserialize, ToSchema)]
19pub struct AdminMaterializePayload {
20 pub reason: Option<String>,
21}
22
23#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, ToSchema)]
24pub struct AdminMaterializeResult {
25 pub created_registration_count: i64,
28 pub moved_registration_count: i64,
29}
30
31#[instrument(skip(pool, payload))]
40#[utoipa::path(
41 post,
42 path = "/materialize",
43 operation_id = "adminMaterializeCreditRegistrations",
44 tag = "credit-registration-admin",
45 request_body = AdminMaterializePayload,
46 responses(
47 (status = 200, description = "How many rows were created and moved", body = AdminMaterializeResult)
48 )
49)]
50pub async fn admin_materialize_credit_registrations(
51 user: AuthUser,
52 pool: web::Data<PgPool>,
53 payload: web::Json<AdminMaterializePayload>,
54) -> ControllerResult<web::Json<AdminMaterializeResult>> {
55 let mut conn = pool.acquire().await?;
56 let token = authorize_credit_registration_admin(&mut conn, user.id).await?;
57
58 info!(actor = %user.id, "Admin ran materialize and preconditions now");
59 let mut tx = conn.begin().await?;
60 let scope = credit_registrations::RegistrationScope::default();
61 let Materialized {
62 created,
63 re_attempted,
64 } = materialize_now(&mut tx, &scope).await?;
65 let created_registration_count = created + re_attempted;
66 let moved_registration_count =
67 recompute_preconditions(&mut tx, &scope, PRECONDITIONS_LIMIT).await?;
68 info!(
69 created_registration_count,
70 moved_registration_count, "Admin materialize finished"
71 );
72 models::credit_registration_admin_actions::record(
73 &mut tx,
74 &NewCreditRegistrationAdminAction {
75 target_phase: Some(CreditRegistrationPhase::Materialize.as_str().to_string()),
76 reason: payload.reason.clone(),
77 details: Some(serde_json::json!({
78 "created_registration_count": created_registration_count,
79 "moved_registration_count": moved_registration_count,
80 })),
81 affected_row_count: Some(
82 i32::try_from(created_registration_count + moved_registration_count)
83 .unwrap_or(i32::MAX),
84 ),
85 ..NewCreditRegistrationAdminAction::new(
86 CreditRegistrationAdminAction::RequeueBatch,
87 CreditRegistrationAdminActionTarget::Phase,
88 user.id,
89 GLOBAL_ADMIN_ROLE,
90 )
91 },
92 )
93 .await?;
94 tx.commit().await?;
95
96 token.authorized_ok(web::Json(AdminMaterializeResult {
97 created_registration_count,
98 moved_registration_count,
99 }))
100}
101
102pub fn _add_routes(cfg: &mut ServiceConfig) {
103 cfg.route(
104 "/materialize",
105 web::post().to(admin_materialize_credit_registrations),
106 );
107}