package services import ( "context" "github.com/google/uuid" "go.uber.org/zap" ) // JobEnqueuer interface pour éviter le cycle d'importation // BE-SVC-003: Implement background job queue type JobEnqueuer interface { EnqueueEmailJob(to, subject, body string) EnqueueEmailJobWithTemplate(to, subject, templateName string, templateData map[string]interface{}) EnqueueThumbnailJob(inputPath, outputPath string, width, height int) EnqueueAnalyticsJob(eventName string, userID *uuid.UUID, payload map[string]interface{}) } // JobService gère les jobs en arrière-plan // BE-SVC-003: Implement background job queue type JobService struct { logger *zap.Logger jobEnqueuer JobEnqueuer } // Job types const ( TypeEmailSend = "email:send" TypeThumbnailGenerate = "thumbnail:generate" TypeAnalyticsProcess = "analytics:process" TypeWebhookDelivery = "webhook:delivery" ) // EmailPayload représente les données pour l'envoi d'email type EmailPayload struct { To string Subject string Body string } // ThumbnailPayload représente les données pour la génération de miniatures type ThumbnailPayload struct { TrackID uint FileID string FilePath string } // NewJobService crée un nouveau service de jobs func NewJobService(logger *zap.Logger) *JobService { return &JobService{ logger: logger, } } // SetJobEnqueuer définit le JobEnqueuer pour le service // BE-SVC-003: Connect JobService to JobWorker func (s *JobService) SetJobEnqueuer(jobEnqueuer JobEnqueuer) { s.jobEnqueuer = jobEnqueuer } // EnqueueEmail enfile un job d'envoi d'email // BE-SVC-003: Implement background job queue for email sending func (s *JobService) EnqueueEmail(ctx context.Context, payload *EmailPayload) error { if s.jobEnqueuer == nil { s.logger.Warn("JobEnqueuer not set, email job not enqueued", zap.String("to", payload.To), zap.String("subject", payload.Subject)) return nil // Fail gracefully } s.logger.Info("Email job enqueued", zap.String("to", payload.To), zap.String("subject", payload.Subject)) // Enqueue via JobEnqueuer (JobWorker) s.jobEnqueuer.EnqueueEmailJob(payload.To, payload.Subject, payload.Body) return nil } // EnqueueThumbnail enfile un job de génération de miniature // BE-SVC-003: Implement background job queue for thumbnail generation func (s *JobService) EnqueueThumbnail(ctx context.Context, payload *ThumbnailPayload) error { if s.jobEnqueuer == nil { s.logger.Warn("JobEnqueuer not set, thumbnail job not enqueued", zap.Uint("track_id", payload.TrackID)) return nil // Fail gracefully } s.logger.Info("Thumbnail job enqueued", zap.Uint("track_id", payload.TrackID)) // Enqueue via JobEnqueuer (assuming default dimensions) // Note: ThumbnailPayload uses uint for TrackID, but we need file paths // This is a simplified version - actual implementation may need adjustment if payload.FilePath != "" { // Default thumbnail size s.jobEnqueuer.EnqueueThumbnailJob(payload.FilePath, payload.FilePath+".thumb", 300, 300) } return nil }