feat: init
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::error::AppError;
|
||||
use crate::models::common::DigestFrequency;
|
||||
use crate::models::users::UserNotifySetting;
|
||||
use crate::service::UserService;
|
||||
use crate::session::Session;
|
||||
|
||||
use super::util::parse_enum;
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone, Debug, utoipa::ToSchema)]
|
||||
pub struct UpdateUserNotifySettingParams {
|
||||
pub email_notifications: Option<bool>,
|
||||
pub web_notifications: Option<bool>,
|
||||
pub mention_notifications: Option<bool>,
|
||||
pub review_notifications: Option<bool>,
|
||||
pub security_notifications: Option<bool>,
|
||||
pub marketing_emails: Option<bool>,
|
||||
pub digest_frequency: Option<String>,
|
||||
}
|
||||
|
||||
impl UserService {
|
||||
pub async fn user_notify_setting(&self, ctx: &Session) -> Result<UserNotifySetting, AppError> {
|
||||
let user_uid = ctx.user().ok_or(AppError::Unauthorized)?;
|
||||
self.ensure_user_notify_setting(user_uid).await
|
||||
}
|
||||
|
||||
pub async fn user_update_notify_setting(
|
||||
&self,
|
||||
ctx: &Session,
|
||||
params: UpdateUserNotifySettingParams,
|
||||
) -> Result<UserNotifySetting, AppError> {
|
||||
let user_uid = ctx.user().ok_or(AppError::Unauthorized)?;
|
||||
let current = self.ensure_user_notify_setting(user_uid).await?;
|
||||
let digest_frequency = parse_enum(
|
||||
params.digest_frequency,
|
||||
current.digest_frequency,
|
||||
DigestFrequency::Unknown,
|
||||
"digest_frequency",
|
||||
)?;
|
||||
|
||||
sqlx::query_as::<_, UserNotifySetting>(
|
||||
"UPDATE user_notify_setting SET email_notifications = $1, web_notifications = $2, \
|
||||
mention_notifications = $3, review_notifications = $4, security_notifications = $5, \
|
||||
marketing_emails = $6, digest_frequency = $7, updated_at = $8 WHERE user_id = $9 \
|
||||
RETURNING user_id, email_notifications, web_notifications, mention_notifications, \
|
||||
review_notifications, security_notifications, marketing_emails, digest_frequency, \
|
||||
created_at, updated_at",
|
||||
)
|
||||
.bind(
|
||||
params
|
||||
.email_notifications
|
||||
.unwrap_or(current.email_notifications),
|
||||
)
|
||||
.bind(
|
||||
params
|
||||
.web_notifications
|
||||
.unwrap_or(current.web_notifications),
|
||||
)
|
||||
.bind(
|
||||
params
|
||||
.mention_notifications
|
||||
.unwrap_or(current.mention_notifications),
|
||||
)
|
||||
.bind(
|
||||
params
|
||||
.review_notifications
|
||||
.unwrap_or(current.review_notifications),
|
||||
)
|
||||
.bind(
|
||||
params
|
||||
.security_notifications
|
||||
.unwrap_or(current.security_notifications),
|
||||
)
|
||||
.bind(params.marketing_emails.unwrap_or(current.marketing_emails))
|
||||
.bind(digest_frequency)
|
||||
.bind(chrono::Utc::now())
|
||||
.bind(user_uid)
|
||||
.fetch_one(self.ctx.db.writer())
|
||||
.await
|
||||
.map_err(AppError::Database)
|
||||
}
|
||||
|
||||
async fn ensure_user_notify_setting(
|
||||
&self,
|
||||
user_uid: uuid::Uuid,
|
||||
) -> Result<UserNotifySetting, AppError> {
|
||||
if let Some(setting) = self.find_user_notify_setting(user_uid).await? {
|
||||
return Ok(setting);
|
||||
}
|
||||
let now = chrono::Utc::now();
|
||||
sqlx::query(
|
||||
"INSERT INTO user_notify_setting (user_id, email_notifications, web_notifications, \
|
||||
mention_notifications, review_notifications, security_notifications, marketing_emails, \
|
||||
digest_frequency, created_at, updated_at) \
|
||||
VALUES ($1, true, true, true, true, true, false, 'realtime', $2, $2) ON CONFLICT (user_id) DO NOTHING",
|
||||
)
|
||||
.bind(user_uid)
|
||||
.bind(now)
|
||||
.execute(self.ctx.db.writer())
|
||||
.await
|
||||
.map_err(AppError::Database)?;
|
||||
self.find_user_notify_setting(user_uid)
|
||||
.await?
|
||||
.ok_or(AppError::UserNotFound)
|
||||
}
|
||||
|
||||
async fn find_user_notify_setting(
|
||||
&self,
|
||||
user_uid: uuid::Uuid,
|
||||
) -> Result<Option<UserNotifySetting>, AppError> {
|
||||
sqlx::query_as::<_, UserNotifySetting>(
|
||||
"SELECT user_id, email_notifications, web_notifications, mention_notifications, \
|
||||
review_notifications, security_notifications, marketing_emails, digest_frequency, \
|
||||
created_at, updated_at FROM user_notify_setting WHERE user_id = $1",
|
||||
)
|
||||
.bind(user_uid)
|
||||
.fetch_optional(self.ctx.db.reader())
|
||||
.await
|
||||
.map_err(AppError::Database)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user