email_queue.rs
119 lignes · 3280 octets
use chrono::{DateTime, Utc}; use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; use uuid::Uuid; /// EmailQueue entity model /// /// Represents an email in the queue waiting to be sent. /// Emails are queued asynchronously to avoid blocking HTTP requests. /// /// # Email Lifecycle /// /// 1. **Enqueue**: Email added to queue with status 'pending' /// 2. **Processing**: Background task picks up pending emails /// 3. **Sending**: Attempt to send via SMTP /// 4. **Success**: Status set to 'sent', sent_at timestamp recorded /// 5. **Failure**: Status set to 'failed' after max attempts, error_message recorded /// /// # Retry Logic /// /// - Failed emails are retried with exponential backoff /// - Maximum 5 attempts before marking as failed /// - Retry delay increases with each attempt #[derive(Clone, Debug, Serialize, Deserialize, DeriveEntityModel)] #[sea_orm(table_name = "email_queue")] pub struct Model { /// Unique identifier for the email queue entry #[sea_orm(primary_key)] pub id: Uuid, /// Recipient email address pub to_email: String, /// Recipient name (optional) pub to_name: Option<String>, /// Sender email address pub from_email: String, /// Sender name (optional) pub from_name: Option<String>, /// Email subject pub subject: String, /// HTML body content pub body_html: String, /// Plain text body content pub body_text: String, /// Type of email (password_reset, email_validation, etc.) #[sea_orm(indexed)] pub email_type: String, /// Email status (pending, sent, failed) #[sea_orm(indexed)] pub status: String, /// Number of send attempts pub attempts: i32, /// Timestamp of last send attempt pub last_attempt_at: Option<DateTime<Utc>>, /// Timestamp when email was successfully sent pub sent_at: Option<DateTime<Utc>>, /// Error message if sending failed pub error_message: Option<String>, /// Last SMTP status code returned by server (if available) pub smtp_code: Option<String>, /// Last SMTP response message returned by server (if available) pub smtp_response: Option<String>, /// Creation timestamp #[sea_orm(indexed)] pub created_at: DateTime<Utc>, /// Last update timestamp pub updated_at: DateTime<Utc>, } /// SeaORM relations for the EmailQueue entity (none defined). #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation {} impl ActiveModelBehavior for ActiveModel {} impl Model { /// Check if the email can be retried /// /// # Returns /// /// `true` if the email has failed and hasn't exceeded max attempts, `false` otherwise pub fn can_retry(&self, max_attempts: u32) -> bool { self.status == "failed" && (self.attempts as u32) < max_attempts } /// Check if the email is pending /// /// # Returns /// /// `true` if the email status is 'pending', `false` otherwise pub fn is_pending(&self) -> bool { self.status == "pending" } /// Check if the email was successfully sent /// /// # Returns /// /// `true` if the email status is 'sent', `false` otherwise pub fn is_sent(&self) -> bool { self.status == "sent" } }
GitRust