veza/veza-backend-api/docs/JOB_WORKER_EMAIL.md
okinrev b7955a680c P0: stabilisation backend/chat/stream + nouvelle base migrations v1
Backend Go:
- Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN.
- Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError).
- Sécurisation de config.go, CORS, statuts de santé et monitoring.
- Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles).
- Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés.
- Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*.

Chat server (Rust):
- Refonte du pipeline JWT + sécurité, audit et rate limiting avancé.
- Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing).
- Nettoyage des panics, gestion d’erreurs robuste, logs structurés.
- Migrations chat alignées sur le schéma UUID et nouvelles features.

Stream server (Rust):
- Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core.
- Transactions P0 pour les jobs et segments, garanties d’atomicité.
- Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION).

Documentation & audits:
- TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services.
- Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3).
- Scripts de reset et de cleanup pour la lab DB et la V1.

Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 11:14:38 +01:00

8.8 KiB

Job Worker Email - Documentation Complète

📋 Vue d'ensemble

Le système de Job Worker Email permet l'envoi asynchrone d'emails transactionnels (password reset, welcome, notifications) via un système de queue et de workers en arrière-plan.

🏗️ Architecture

Composants principaux

  1. JobWorker (internal/workers/job_worker.go)

    • Gère la queue de jobs
    • Exécute les jobs via des workers en parallèle
    • Gère les retries avec exponential backoff
    • Supporte plusieurs types de jobs (email, thumbnail, analytics)
  2. EmailJob (internal/workers/email_job.go)

    • Représente un job d'envoi d'email
    • Supporte l'envoi direct (body) ou via template
    • Rend les templates HTML avec données dynamiques
  3. EmailSender (internal/email/sender.go)

    • Interface pour l'envoi d'emails
    • Implémentation SMTP avec SMTPEmailSender
    • Supporte MailHog en développement
  4. Templates Email (templates/email/)

    • Templates HTML pour différents types d'emails
    • Utilise Go templates (html/template)
    • Supporte les données dynamiques

🚀 Démarrage

1. Configuration SMTP

Le système charge la configuration SMTP depuis les variables d'environnement :

# Configuration SMTP (production)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_FROM=noreply@veza.app
SMTP_FROM_NAME=Veza

# En développement, fallback sur MailHog
MAILHOG_HOST=localhost
MAILHOG_PORT=1025

Note : En développement, si SMTP_HOST n'est pas défini, le système utilise automatiquement MailHog (localhost:1025).

2. Démarrage automatique

Le Job Worker démarre automatiquement au lancement du backend dans cmd/api/main.go :

if cfg.JobWorker != nil {
    workerCtx, workerCancel := context.WithCancel(context.Background())
    defer workerCancel()
    cfg.JobWorker.Start(workerCtx)
    logger.Info("✅ Job Worker démarré")
}

3. Configuration du répertoire des templates

Par défaut, les templates sont cherchés dans templates/email/. Vous pouvez changer cela via :

EMAIL_TEMPLATE_DIR=/path/to/templates

📧 Utilisation

Envoi d'email simple

// Depuis un service ou handler
jobWorker.EnqueueEmailJob(
    "user@example.com",
    "Welcome to Veza",
    "<h1>Welcome!</h1><p>Thanks for joining.</p>",
)

Envoi d'email avec template

// Préparer les données du template
templateData := map[string]interface{}{
    "Username": "john_doe",
    "ResetURL": "http://localhost:5173/reset-password?token=abc123",
}

// Enqueue le job
jobWorker.EnqueueEmailJobWithTemplate(
    "user@example.com",
    "Reset your Veza password",
    "password_reset",  // Nom du template (sans .html)
    templateData,
)

Depuis AuthService (exemple : Password Reset)

Le AuthService utilise automatiquement le Job Worker pour envoyer les emails de reset :

// Dans internal/core/auth/service.go
s.jobWorker.EnqueueEmailJobWithTemplate(
    user.Email,
    "Reset your Veza password",
    "password_reset",
    templateData,
)

📝 Templates Email

Structure des templates

Les templates sont des fichiers HTML dans templates/email/ avec l'extension .html.

Exemple : templates/email/password_reset.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Reset your Veza password</title>
</head>
<body>
    <h1>Reset your password</h1>
    <p>Hello {{.Username}},</p>
    <p>Click here to reset: <a href="{{.ResetURL}}">Reset Password</a></p>
</body>
</html>

Variables disponibles

Les variables sont passées via templateData dans EnqueueEmailJobWithTemplate.

Template password_reset.html :

  • {{.Username}} - Nom d'utilisateur
  • {{.ResetURL}} - URL de reset avec token

Template welcome.html :

  • {{.Username}} - Nom d'utilisateur
  • {{.VerifyURL}} - URL de vérification email

🧪 Tests

Tests unitaires

# Tests du module email
go test ./internal/email/... -v

# Tests du job worker
go test ./internal/workers/... -v

Tests d'intégration avec MailHog

  1. Démarrer MailHog (en développement) :
# Via Docker
docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog

# Ou installer MailHog localement
# https://github.com/mailhog/MailHog
  1. Configurer les variables d'environnement :
MAILHOG_HOST=localhost
MAILHOG_PORT=1025
  1. Démarrer le backend :
cd veza-backend-api
go run cmd/api/main.go
  1. Vérifier les emails dans MailHog :

Ouvrir http://localhost:8025 dans votre navigateur pour voir les emails reçus.

Test manuel : Envoyer un email de reset

# Via curl
curl -X POST http://localhost:8080/api/v1/auth/password/reset-request \
  -H "Content-Type: application/json" \
  -d '{"email": "test@example.com"}'

Vérifier dans MailHog que l'email a été reçu.

🔧 Configuration avancée

Paramètres du Job Worker

Le Job Worker est configuré dans internal/config/config.go :

config.JobWorker = workers.NewJobWorker(
    config.Database.GormDB,
    jobService,
    logger,
    100,   // queueSize - Taille de la queue
    3,     // workers - Nombre de workers parallèles
    3,     // maxRetries - Nombre maximum de tentatives
    config.EmailSender,
)

Variables d'environnement

Variable Description Défaut Requis
SMTP_HOST Serveur SMTP localhost (dev) Production: Oui
SMTP_PORT Port SMTP 1025 (dev) Production: Oui
SMTP_USERNAME Utilisateur SMTP - Production: Oui
SMTP_PASSWORD Mot de passe SMTP - Production: Oui
SMTP_FROM Email expéditeur - Production: Oui
SMTP_FROM_NAME Nom expéditeur - Non
EMAIL_TEMPLATE_DIR Répertoire des templates templates/email Non
FRONTEND_URL URL du frontend (pour liens) http://localhost:5173 Non

📊 Monitoring

Statistiques du worker

stats := jobWorker.GetStats()
// Retourne:
// - queue_size: Nombre de jobs en attente
// - workers: Nombre de workers actifs
// - max_retries: Nombre maximum de retries

Logs

Le système log toutes les opérations importantes :

  • Enqueue : Job enqueued (DEBUG)
  • Processing : Processing job (INFO)
  • Success : Job executed successfully (INFO)
  • Error : Job execution failed (ERROR)
  • Retry : Retrying job (INFO)
  • Final failure : Job permanently failed (ERROR)

🐛 Dépannage

Emails non envoyés

  1. Vérifier la configuration SMTP :

    echo $SMTP_HOST
    echo $SMTP_PORT
    
  2. Vérifier les logs :

    • Chercher Job execution failed dans les logs
    • Vérifier les erreurs SMTP
  3. Tester la connexion SMTP :

    telnet $SMTP_HOST $SMTP_PORT
    

Template non trouvé

  1. Vérifier le chemin :

    ls -la templates/email/
    
  2. Vérifier la variable d'environnement :

    echo $EMAIL_TEMPLATE_DIR
    
  3. Vérifier les logs :

    • Chercher Failed to read template file dans les logs

Queue pleine

Si la queue est pleine, les nouveaux jobs sont rejetés avec un warning :

Job queue full, dropping job

Solution : Augmenter la taille de la queue dans config.go :

workers.NewJobWorker(..., 200, ...) // Augmenter queueSize

🔐 Sécurité

  1. Secrets SMTP : Ne jamais commiter les credentials SMTP dans le code
  2. Validation email : Les emails sont validés avant envoi
  3. Rate limiting : Le système de rate limiting s'applique aussi aux endpoints qui envoient des emails
  4. Logs : Les emails ne sont jamais loggés en clair (seulement les métadonnées)

🚀 Production

Checklist avant déploiement

  • Variables SMTP configurées et testées
  • Templates email créés et testés
  • MailHog désactivé (pas de fallback en prod)
  • Monitoring configuré (logs, métriques)
  • Tests d'intégration passés
  • Documentation à jour

Recommandations

  1. Utiliser un service SMTP professionnel :

    • SendGrid
    • Mailgun
    • AWS SES
    • Postmark
  2. Monitoring :

    • Surveiller la taille de la queue
    • Alerter sur les échecs répétés
    • Tracer les temps d'envoi
  3. Scalabilité :

    • Augmenter le nombre de workers si nécessaire
    • Considérer une queue persistante (Redis, RabbitMQ) pour haute charge

📚 Références

🔄 Évolutions futures

  • Support de plusieurs providers SMTP (SendGrid, Mailgun)
  • Queue persistante (Redis, RabbitMQ)
  • Dead letter queue pour les échecs définitifs
  • Métriques Prometheus
  • Dashboard de monitoring
  • Support des pièces jointes
  • Support du format texte + HTML