201 lines
7.7 KiB
Rust
201 lines
7.7 KiB
Rust
use crate::AppService;
|
|
use crate::error::AppError;
|
|
use chrono::Utc;
|
|
use models::users::{user_activity_log, user_notification};
|
|
use sea_orm::*;
|
|
use serde::{Deserialize, Serialize};
|
|
use session::Session;
|
|
use uuid::Uuid;
|
|
|
|
#[derive(Deserialize, Serialize, Clone, Debug, utoipa::ToSchema)]
|
|
pub struct NotificationPreferencesParams {
|
|
pub email_enabled: Option<bool>,
|
|
pub in_app_enabled: Option<bool>,
|
|
pub push_enabled: Option<bool>,
|
|
pub digest_mode: Option<String>,
|
|
pub dnd_enabled: Option<bool>,
|
|
pub dnd_start_minute: Option<i32>,
|
|
pub dnd_end_minute: Option<i32>,
|
|
pub marketing_enabled: Option<bool>,
|
|
pub security_enabled: Option<bool>,
|
|
pub product_enabled: Option<bool>,
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize, Clone, Debug, utoipa::ToSchema)]
|
|
pub struct NotificationPreferencesResponse {
|
|
pub user_id: Uuid,
|
|
pub email_enabled: bool,
|
|
pub in_app_enabled: bool,
|
|
pub push_enabled: bool,
|
|
pub digest_mode: String,
|
|
pub dnd_enabled: bool,
|
|
pub dnd_start_minute: Option<i32>,
|
|
pub dnd_end_minute: Option<i32>,
|
|
pub marketing_enabled: bool,
|
|
pub security_enabled: bool,
|
|
pub product_enabled: bool,
|
|
pub created_at: chrono::DateTime<Utc>,
|
|
pub updated_at: chrono::DateTime<Utc>,
|
|
}
|
|
|
|
impl From<user_notification::Model> for NotificationPreferencesResponse {
|
|
fn from(prefs: user_notification::Model) -> Self {
|
|
NotificationPreferencesResponse {
|
|
user_id: prefs.user,
|
|
email_enabled: prefs.email_enabled,
|
|
in_app_enabled: prefs.in_app_enabled,
|
|
push_enabled: prefs.push_enabled,
|
|
digest_mode: prefs.digest_mode,
|
|
dnd_enabled: prefs.dnd_enabled,
|
|
dnd_start_minute: prefs.dnd_start_minute,
|
|
dnd_end_minute: prefs.dnd_end_minute,
|
|
marketing_enabled: prefs.marketing_enabled,
|
|
security_enabled: prefs.security_enabled,
|
|
product_enabled: prefs.product_enabled,
|
|
created_at: prefs.created_at,
|
|
updated_at: prefs.updated_at,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AppService {
|
|
pub async fn user_get_notification_preferences(
|
|
&self,
|
|
context: &Session,
|
|
) -> Result<NotificationPreferencesResponse, AppError> {
|
|
let user_uid = context.user().ok_or(AppError::Unauthorized)?;
|
|
|
|
let prefs = user_notification::Entity::find_by_id(user_uid)
|
|
.one(&self.db)
|
|
.await?;
|
|
|
|
if let Some(prefs) = prefs {
|
|
Ok(NotificationPreferencesResponse::from(prefs))
|
|
} else {
|
|
self.user_create_default_notification_preferences(user_uid)
|
|
.await
|
|
}
|
|
}
|
|
|
|
pub async fn user_update_notification_preferences(
|
|
&self,
|
|
context: &Session,
|
|
params: NotificationPreferencesParams,
|
|
) -> Result<NotificationPreferencesResponse, AppError> {
|
|
let user_uid = context.user().ok_or(AppError::Unauthorized)?;
|
|
|
|
let prefs = user_notification::Entity::find_by_id(user_uid)
|
|
.one(&self.db)
|
|
.await?;
|
|
|
|
let updated_prefs = if let Some(prefs) = prefs {
|
|
let mut active_prefs: user_notification::ActiveModel = prefs.into();
|
|
|
|
if let Some(email_enabled) = params.email_enabled {
|
|
active_prefs.email_enabled = Set(email_enabled);
|
|
}
|
|
if let Some(in_app_enabled) = params.in_app_enabled {
|
|
active_prefs.in_app_enabled = Set(in_app_enabled);
|
|
}
|
|
if let Some(push_enabled) = params.push_enabled {
|
|
active_prefs.push_enabled = Set(push_enabled);
|
|
}
|
|
if let Some(digest_mode) = params.digest_mode.clone() {
|
|
active_prefs.digest_mode = Set(digest_mode);
|
|
}
|
|
if let Some(dnd_enabled) = params.dnd_enabled {
|
|
active_prefs.dnd_enabled = Set(dnd_enabled);
|
|
}
|
|
if let Some(dnd_start_minute) = params.dnd_start_minute {
|
|
active_prefs.dnd_start_minute = Set(Some(dnd_start_minute));
|
|
}
|
|
if let Some(dnd_end_minute) = params.dnd_end_minute {
|
|
active_prefs.dnd_end_minute = Set(Some(dnd_end_minute));
|
|
}
|
|
if let Some(marketing_enabled) = params.marketing_enabled {
|
|
active_prefs.marketing_enabled = Set(marketing_enabled);
|
|
}
|
|
if let Some(security_enabled) = params.security_enabled {
|
|
active_prefs.security_enabled = Set(security_enabled);
|
|
}
|
|
if let Some(product_enabled) = params.product_enabled {
|
|
active_prefs.product_enabled = Set(product_enabled);
|
|
}
|
|
active_prefs.updated_at = Set(Utc::now());
|
|
|
|
active_prefs.update(&self.db).await?
|
|
} else {
|
|
let new_prefs = user_notification::ActiveModel {
|
|
user: Set(user_uid),
|
|
email_enabled: Set(params.email_enabled.unwrap_or(true)),
|
|
in_app_enabled: Set(params.in_app_enabled.unwrap_or(true)),
|
|
push_enabled: Set(params.push_enabled.unwrap_or(false)),
|
|
digest_mode: Set(params
|
|
.digest_mode
|
|
.clone()
|
|
.unwrap_or_else(|| "daily".to_string())),
|
|
dnd_enabled: Set(params.dnd_enabled.unwrap_or(false)),
|
|
dnd_start_minute: Set(params.dnd_start_minute),
|
|
dnd_end_minute: Set(params.dnd_end_minute),
|
|
marketing_enabled: Set(params.marketing_enabled.unwrap_or(false)),
|
|
security_enabled: Set(params.security_enabled.unwrap_or(true)),
|
|
product_enabled: Set(params.product_enabled.unwrap_or(false)),
|
|
created_at: Set(Utc::now()),
|
|
updated_at: Set(Utc::now()),
|
|
};
|
|
|
|
new_prefs.insert(&self.db).await?
|
|
};
|
|
|
|
let _ = user_activity_log::ActiveModel {
|
|
user_uid: Set(Some(user_uid)),
|
|
action: Set("notification_preferences_update".to_string()),
|
|
ip_address: Set(context.ip_address()),
|
|
user_agent: Set(context.user_agent()),
|
|
details: Set(serde_json::json!({
|
|
"updated_fields": {
|
|
"email_enabled": params.email_enabled.is_some(),
|
|
"in_app_enabled": params.in_app_enabled.is_some(),
|
|
"push_enabled": params.push_enabled.is_some(),
|
|
"digest_mode": params.digest_mode.is_some(),
|
|
"dnd_enabled": params.dnd_enabled.is_some(),
|
|
"marketing_enabled": params.marketing_enabled.is_some(),
|
|
"security_enabled": params.security_enabled.is_some(),
|
|
"product_enabled": params.product_enabled.is_some(),
|
|
}
|
|
})),
|
|
created_at: Set(Utc::now()),
|
|
..Default::default()
|
|
}
|
|
.insert(&self.db)
|
|
.await;
|
|
|
|
Ok(NotificationPreferencesResponse::from(updated_prefs))
|
|
}
|
|
|
|
async fn user_create_default_notification_preferences(
|
|
&self,
|
|
user_uid: Uuid,
|
|
) -> Result<NotificationPreferencesResponse, AppError> {
|
|
let prefs = user_notification::ActiveModel {
|
|
user: Set(user_uid),
|
|
email_enabled: Set(true),
|
|
in_app_enabled: Set(true),
|
|
push_enabled: Set(false),
|
|
digest_mode: Set("daily".to_string()),
|
|
dnd_enabled: Set(false),
|
|
dnd_start_minute: Set(None),
|
|
dnd_end_minute: Set(None),
|
|
marketing_enabled: Set(false),
|
|
security_enabled: Set(true),
|
|
product_enabled: Set(false),
|
|
created_at: Set(Utc::now()),
|
|
updated_at: Set(Utc::now()),
|
|
};
|
|
|
|
let created_prefs = prefs.insert(&self.db).await?;
|
|
|
|
Ok(NotificationPreferencesResponse::from(created_prefs))
|
|
}
|
|
}
|