gatekpr_email/lib.rs
1//! Email Notification Service for Gatekpr SaaS
2//!
3//! This crate provides a complete email notification system with:
4//! - SMTP email sending via [lettre](https://github.com/lettre/lettre)
5//! - Responsive HTML templates via [mrml](https://github.com/jdrouet/mrml) (Rust MJML)
6//! - Variable substitution via [handlebars](https://crates.io/crates/handlebars)
7//! - Type-safe email job definitions
8//! - Background job queue via [apalis](https://github.com/geofmureithi/apalis) (optional)
9//!
10//! # Architecture
11//!
12//! ## Synchronous Mode
13//!
14//! ```text
15//! ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
16//! │ EmailClient │────▶│ Template │────▶│ lettre │
17//! │ (facade) │ │ Renderer │ │ (SMTP) │
18//! └─────────────┘ └─────────────┘ └─────────────┘
19//! ```
20//!
21//! ## Queue Mode (with `queue` feature)
22//!
23//! ```text
24//! ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
25//! │ Producer │────▶│ Redis │────▶│ Worker │────▶│ SMTP │
26//! │ (enqueue) │ │ (queue) │ │ (process) │ │ (send) │
27//! └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
28//! ```
29//!
30//! # Example (Synchronous)
31//!
32//! ```rust,ignore
33//! use gatekpr_email::{EmailClient, EmailConfig, templates::WelcomeEmail};
34//!
35//! let config = EmailConfig::from_env()?;
36//! let client = EmailClient::new(config)?;
37//!
38//! let email = WelcomeEmail {
39//! to: "user@example.com".to_string(),
40//! name: "John".to_string(),
41//! verify_url: "https://example.com/verify/token123".to_string(),
42//! };
43//!
44//! client.send(email).await?;
45//! ```
46//!
47//! # Example (Queue Mode)
48//!
49//! ```rust,ignore
50//! use gatekpr_email::queue::{EmailJobProducer, EmailWorker};
51//!
52//! // Producer side (enqueue emails)
53//! let producer = EmailJobProducer::connect("redis://localhost:6379").await?;
54//! producer.send_welcome("user@example.com", "John", "https://verify.url").await?;
55//!
56//! // Worker side (process emails)
57//! let worker = EmailWorker::new(producer.storage(), email_client, config).await?;
58//! worker.run().await?;
59//! ```
60
61pub mod client;
62pub mod config;
63pub mod error;
64pub mod templates;
65
66#[cfg(feature = "queue")]
67pub mod queue;
68
69pub use client::EmailClient;
70pub use config::EmailConfig;
71pub use error::{EmailError, Result};
72pub use templates::{EmailTemplate, TemplateRenderer};