Skip to main content

headless_lms_models/library/agent_changesets/
summary.rs

1//! Changesets listed with the entities they change.
2
3use std::collections::HashMap;
4
5use utoipa::ToSchema;
6
7use crate::{
8    agent_changeset_entities::{self, ChangesetEntitySummary},
9    agent_changesets::{self, AgentChangeset},
10    prelude::*,
11};
12
13/// A changeset with what it changes. While it is open and close to expiry, `is_expiring_soon` is
14/// set and `entities` is what expiry would drop.
15#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)]
16pub struct ChangesetSummary {
17    pub changeset: AgentChangeset,
18    pub entities: Vec<ChangesetEntitySummary>,
19    pub has_risky_changes: bool,
20    pub is_expiring_soon: bool,
21}
22
23/// The changesets with their entities, in the given order.
24pub async fn get_summaries(
25    conn: &mut PgConnection,
26    changesets: Vec<AgentChangeset>,
27) -> ModelResult<Vec<ChangesetSummary>> {
28    let ids: Vec<Uuid> = changesets.iter().map(|changeset| changeset.id).collect();
29    let mut entities_by_changeset: HashMap<Uuid, Vec<ChangesetEntitySummary>> = HashMap::new();
30    for (changeset_id, entity) in
31        agent_changeset_entities::get_summaries_by_changeset_ids(conn, &ids).await?
32    {
33        entities_by_changeset
34            .entry(changeset_id)
35            .or_default()
36            .push(entity);
37    }
38    let now = Utc::now();
39    Ok(changesets
40        .into_iter()
41        .map(|changeset| {
42            let entities = entities_by_changeset
43                .remove(&changeset.id)
44                .unwrap_or_default();
45            ChangesetSummary {
46                has_risky_changes: entities.iter().any(|e| !e.risk_reasons.is_empty()),
47                is_expiring_soon: changeset.is_expiring_soon(now),
48                changeset,
49                entities,
50            }
51        })
52        .collect())
53}
54
55/// The user's changesets in the course with their entities, newest first.
56pub async fn get_summaries_for_user(
57    conn: &mut PgConnection,
58    user_id: Uuid,
59    course_id: Uuid,
60) -> ModelResult<Vec<ChangesetSummary>> {
61    let changesets = agent_changesets::get_by_user_and_course(conn, user_id, course_id).await?;
62    get_summaries(conn, changesets).await
63}