headless_lms_models/
chatbot_page_sync_statuses.rs

1use std::collections::HashMap;
2
3use crate::prelude::*;
4
5#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
6#[cfg_attr(feature = "ts_rs", derive(TS))]
7pub struct ChatbotPageSyncStatus {
8    pub id: Uuid,
9    pub created_at: DateTime<Utc>,
10    pub updated_at: DateTime<Utc>,
11    pub deleted_at: Option<DateTime<Utc>>,
12    pub course_id: Uuid,
13    pub page_id: Uuid,
14    pub error_message: Option<String>,
15    pub synced_page_revision_id: Option<Uuid>,
16}
17
18pub async fn ensure_sync_statuses_exist(
19    conn: &mut PgConnection,
20    course_ids: &[Uuid],
21) -> ModelResult<HashMap<Uuid, Vec<ChatbotPageSyncStatus>>> {
22    sqlx::query!(
23        r#"
24INSERT INTO chatbot_page_sync_statuses (course_id, page_id)
25SELECT course_id,
26  id
27FROM pages
28WHERE course_id = ANY($1)
29  AND deleted_at IS NULL
30  AND hidden IS FALSE ON CONFLICT (page_id, deleted_at) DO NOTHING
31        "#,
32        course_ids
33    )
34    .execute(&mut *conn)
35    .await?;
36
37    let all_statuses = sqlx::query_as!(
38        ChatbotPageSyncStatus,
39        r#"
40SELECT *
41FROM chatbot_page_sync_statuses
42WHERE course_id = ANY($1)
43        "#,
44        course_ids
45    )
46    .fetch_all(&mut *conn)
47    .await?
48    .into_iter()
49    .fold(
50        HashMap::<Uuid, Vec<ChatbotPageSyncStatus>>::new(),
51        |mut map, status| {
52            map.entry(status.course_id).or_default().push(status);
53            map
54        },
55    );
56
57    Ok(all_statuses)
58}
59
60// Given a mapping from page id to the new revision id, update the sync statuses
61pub async fn update_page_revision_ids(
62    conn: &mut PgConnection,
63    page_id_to_new_revision_id: HashMap<Uuid, Uuid>,
64) -> ModelResult<()> {
65    // If there are no updates to perform, return early
66    if page_id_to_new_revision_id.is_empty() {
67        return Ok(());
68    }
69    let (page_ids, revision_ids): (Vec<Uuid>, Vec<Uuid>) =
70        page_id_to_new_revision_id.into_iter().unzip();
71
72    sqlx::query!(
73        r#"
74UPDATE chatbot_page_sync_statuses AS cps
75SET synced_page_revision_id = data.synced_page_revision_id
76FROM (
77    SELECT unnest($1::uuid []) AS page_id,
78      unnest($2::uuid []) AS synced_page_revision_id
79  ) AS data
80WHERE cps.page_id = data.page_id
81AND cps.deleted_at IS NULL
82    "#,
83        &page_ids,
84        &revision_ids
85    )
86    .execute(conn)
87    .await?;
88
89    Ok(())
90}