email_dto.rs
248 lignes · 7823 octets
//! Email DTOs for request/response handling //! //! This module contains Data Transfer Objects for email-related endpoints: //! - Password reset requests //! - Email validation requests //! - Email queue admin endpoints use serde::{Deserialize, Serialize}; use uuid::Uuid; use validator::Validate; /// Tracking states for critical emails (SMTP traceability) #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum EmailDeliveryState { /// Email has been queued but not yet sent. Queued, /// Email is currently being transmitted to the SMTP server. Sending, /// SMTP server accepted the message for delivery. Accepted, /// SMTP server rejected the message. Rejected, /// Email was not delivered before its expiry deadline. Expired, /// Final delivery confirmed (via DSN) Delivered, /// Bounce received (via DSN) Bounced, } impl EmailDeliveryState { /// Returns a static string representation of this delivery state. pub fn as_str(self) -> &'static str { match self { EmailDeliveryState::Queued => "queued", EmailDeliveryState::Sending => "sending", EmailDeliveryState::Accepted => "accepted", EmailDeliveryState::Rejected => "rejected", EmailDeliveryState::Expired => "expired", EmailDeliveryState::Delivered => "delivered", EmailDeliveryState::Bounced => "bounced", } } /// Parses a string slice into an `EmailDeliveryState`, defaulting to `Queued` for unknown values. pub fn parse(value: &str) -> Self { match value { "queued" => EmailDeliveryState::Queued, "sending" => EmailDeliveryState::Sending, "accepted" => EmailDeliveryState::Accepted, "rejected" => EmailDeliveryState::Rejected, "expired" => EmailDeliveryState::Expired, "delivered" => EmailDeliveryState::Delivered, "bounced" => EmailDeliveryState::Bounced, _ => EmailDeliveryState::Queued, } } } /// Request to initiate password reset #[derive(Debug, Deserialize, Validate)] pub struct ForgotPasswordRequest { /// User email address #[validate(email)] pub email: String, } /// Response for password reset request #[derive(Debug, Serialize)] pub struct ForgotPasswordResponse { /// Success message (always the same for security - don't reveal if email exists) pub message: String, } /// Request to reset password with token #[derive(Debug, Deserialize, Validate)] pub struct ResetPasswordRequest { /// Password reset token from email #[validate(length(min = 1))] pub token: String, /// New password (must meet password requirements) #[validate(length(min = 8))] pub new_password: String, } /// Response for password reset #[derive(Debug, Serialize)] pub struct ResetPasswordResponse { /// Success message pub message: String, } /// Request to resend email validation #[derive(Debug, Deserialize, Validate)] pub struct ResendVerificationRequest { /// User email address #[validate(email)] pub email: String, } /// Response for resend verification request #[derive(Debug, Serialize)] pub struct ResendVerificationResponse { /// Success message (always the same for security) pub message: String, } /// Response for email verification #[derive(Debug, Serialize)] pub struct VerifyEmailResponse { /// Success message pub message: String, /// Whether email was verified pub verified: bool, } /// Email queue entry response (for admin endpoints) #[derive(Debug, Serialize)] pub struct EmailQueueEntry { /// Email queue entry ID pub id: Uuid, /// Recipient email pub to_email: String, /// Recipient name pub to_name: Option<String>, /// Subject pub subject: String, /// Email type pub email_type: String, /// Status (pending, sent, failed) pub status: String, /// Number of attempts pub attempts: i32, /// Last SMTP code if available pub smtp_code: Option<String>, /// Last SMTP response if available pub smtp_response: Option<String>, /// Creation timestamp pub created_at: chrono::DateTime<chrono::Utc>, /// Sent timestamp pub sent_at: Option<chrono::DateTime<chrono::Utc>>, } /// Email queue list response (for admin endpoints) #[derive(Debug, Serialize)] pub struct EmailQueueListResponse { /// List of email queue entries pub emails: Vec<EmailQueueEntry>, /// Total number of emails matching filters pub total: u64, /// Limit used pub limit: usize, /// Offset used pub offset: usize, } /// Email queue detail response (for admin endpoints) #[derive(Debug, Serialize)] pub struct EmailQueueDetailResponse { /// Email queue entry ID pub id: Uuid, /// Recipient email pub to_email: String, /// Recipient name pub to_name: Option<String>, /// Sender email pub from_email: String, /// Sender name pub from_name: Option<String>, /// Subject pub subject: String, /// HTML body content pub body_html: String, /// Plain text body content pub body_text: String, /// Email type pub email_type: String, /// Status (pending, sent, failed) pub status: String, /// Number of attempts pub attempts: i32, /// Last attempt timestamp pub last_attempt_at: Option<chrono::DateTime<chrono::Utc>>, /// Sent timestamp pub sent_at: Option<chrono::DateTime<chrono::Utc>>, /// Error message if failed pub error_message: Option<String>, /// Last SMTP code if available pub smtp_code: Option<String>, /// Last SMTP response if available pub smtp_response: Option<String>, /// Creation timestamp pub created_at: chrono::DateTime<chrono::Utc>, /// Last update timestamp pub updated_at: chrono::DateTime<chrono::Utc>, } /// Response for retry email request #[derive(Debug, Serialize)] pub struct RetryEmailResponse { /// Success message pub message: String, /// Email queue entry ID pub email_id: Uuid, /// Current status pub status: String, } /// Delivery status response for critical emails (admin) #[derive(Debug, Serialize)] pub struct EmailDeliveryStatusResponse { /// Unique identifier of the email queue entry. pub id: Uuid, /// Type of email (e.g. `password_reset`, `email_validation`). pub email_type: String, /// Recipient email address. pub recipient: String, /// Template name used to render the email. pub template: String, /// Current delivery state. pub state: EmailDeliveryState, /// SMTP response code from the last delivery attempt. pub smtp_code: Option<String>, /// Full SMTP response message from the last delivery attempt. pub smtp_response: Option<String>, /// Number of delivery attempts made so far. pub attempt_count: i32, /// Timestamp of the most recent delivery attempt. pub last_attempt_at: Option<chrono::DateTime<chrono::Utc>>, /// Timestamp of the last state change. pub last_state_at: chrono::DateTime<chrono::Utc>, /// Optional correlation ID linking to the originating request. pub correlation_id: Option<Uuid>, /// Timestamp when the queue entry was created. pub created_at: chrono::DateTime<chrono::Utc>, /// Timestamp of the last update to this entry. pub updated_at: chrono::DateTime<chrono::Utc>, } /// Paginated list of email delivery status entries. #[derive(Debug, Serialize)] pub struct EmailDeliveryStatusListResponse { /// Page of delivery status entries. pub items: Vec<EmailDeliveryStatusResponse>, /// Cursor for retrieving the next page, if any. pub next_cursor: Option<String>, }
GitRust