headless_lms_models/
email_deliveries.rs

1use crate::prelude::*;
2use std::fmt::Display;
3
4#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
5pub struct EmailDelivery {
6    pub id: Uuid,
7    pub created_at: DateTime<Utc>,
8    pub updated_at: DateTime<Utc>,
9    pub deleted_at: Option<DateTime<Utc>>,
10    pub email_template_id: Uuid,
11    pub error: Option<String>,
12    pub sent: bool,
13    pub user_id: Uuid,
14}
15
16pub struct Email {
17    pub id: Uuid,
18    pub user_id: Uuid,
19    pub to: String,
20    pub subject: Option<String>,
21    pub body: Option<serde_json::Value>,
22    pub name: Option<String>,
23}
24
25pub async fn insert_email_delivery(
26    conn: &mut PgConnection,
27    user_id: Uuid,
28    email_template_id: Uuid,
29) -> ModelResult<Uuid> {
30    let id = Uuid::new_v4();
31
32    sqlx::query!(
33        r#"
34INSERT INTO email_deliveries (
35    id,
36    user_id,
37    email_template_id
38)
39VALUES ($1, $2, $3)
40        "#,
41        id,
42        user_id,
43        email_template_id
44    )
45    .execute(conn)
46    .await?;
47
48    Ok(id)
49}
50
51pub async fn fetch_emails(conn: &mut PgConnection) -> ModelResult<Vec<Email>> {
52    let emails = sqlx::query_as!(
53        Email,
54        r#"
55SELECT
56    ed.id AS id,
57    u.id AS user_id,
58    ud.email AS to,
59    et.subject AS subject,
60    et.content AS body,
61    et.name AS name
62FROM email_deliveries ed
63JOIN email_templates et ON et.id = ed.email_template_id
64JOIN users u ON u.id = ed.user_id
65JOIN user_details ud ON ud.user_id = u.id
66WHERE ed.deleted_at IS NULL
67  AND ed.sent = FALSE
68  AND ed.error IS NULL
69LIMIT 10000;
70        "#,
71    )
72    .fetch_all(conn)
73    .await?;
74
75    Ok(emails)
76}
77
78pub async fn mark_as_sent(email_id: Uuid, conn: &mut PgConnection) -> ModelResult<()> {
79    sqlx::query!(
80        "
81update email_deliveries
82set sent = TRUE
83where id = $1;
84    ",
85        email_id
86    )
87    .execute(conn)
88    .await?;
89
90    Ok(())
91}
92
93pub async fn save_err_to_email(
94    email_id: Uuid,
95    err: impl Display,
96    conn: &mut PgConnection,
97) -> ModelResult<()> {
98    sqlx::query!(
99        "
100update email_deliveries
101set sent = FALSE,
102  error = $1
103where id = $2;
104    ",
105        err.to_string(),
106        email_id
107    )
108    .execute(conn)
109    .await?;
110
111    Ok(())
112}