pub use crate::service::util::clamp_limit_offset; use crate::error::AppError; use crate::models::notifications::Notification; use sqlx::PgPool; use uuid::Uuid; impl Notification { pub async fn find_by_id( pool: &PgPool, id: Uuid, user_id: Uuid, ) -> Result, AppError> { sqlx::query_as::<_, Notification>( "SELECT id, user_id, actor_id, workspace_id, repo_id, issue_id, pull_request_id, \ channel_id, message_id, notification_type, title, body, target_type, target_id, \ action_url, priority, read_at, dismissed_at, metadata, created_at, updated_at, deleted_at \ FROM notification WHERE id = $1 AND user_id = $2 AND deleted_at IS NULL", ) .bind(id) .bind(user_id) .fetch_optional(pool) .await .map_err(AppError::Database) } pub async fn list_for_user( pool: &PgPool, user_id: Uuid, unread_only: bool, limit: i64, offset: i64, ) -> Result, AppError> { let sql = if unread_only { "SELECT id, user_id, actor_id, workspace_id, repo_id, issue_id, pull_request_id, \ channel_id, message_id, notification_type, title, body, target_type, target_id, \ action_url, priority, read_at, dismissed_at, metadata, created_at, updated_at, deleted_at \ FROM notification \ WHERE user_id = $1 AND deleted_at IS NULL AND read_at IS NULL AND dismissed_at IS NULL \ ORDER BY created_at DESC LIMIT $2 OFFSET $3" } else { "SELECT id, user_id, actor_id, workspace_id, repo_id, issue_id, pull_request_id, \ channel_id, message_id, notification_type, title, body, target_type, target_id, \ action_url, priority, read_at, dismissed_at, metadata, created_at, updated_at, deleted_at \ FROM notification \ WHERE user_id = $1 AND deleted_at IS NULL AND dismissed_at IS NULL \ ORDER BY created_at DESC LIMIT $2 OFFSET $3" }; sqlx::query_as::<_, Notification>(sql) .bind(user_id) .bind(limit) .bind(offset) .fetch_all(pool) .await .map_err(AppError::Database) } pub async fn count_unread(pool: &PgPool, user_id: Uuid) -> Result { sqlx::query_scalar( "SELECT COUNT(*) FROM notification \ WHERE user_id = $1 AND deleted_at IS NULL AND read_at IS NULL AND dismissed_at IS NULL", ) .bind(user_id) .fetch_one(pool) .await .map_err(AppError::Database) } }