package workers import ( "context" "encoding/json" "fmt" "time" "github.com/google/uuid" "go.uber.org/zap" "gorm.io/gorm" ) // AnalyticsEventJob représente un job d'enregistrement d'événement analytics générique type AnalyticsEventJob struct { EventName string // Nom de l'événement (ex: "track_play", "user_login", "file_upload") UserID *uuid.UUID // ID de l'utilisateur (nullable pour événements anonymes) Payload map[string]interface{} // Données additionnelles de l'événement } // NewAnalyticsEventJob crée un nouveau job d'analytics générique func NewAnalyticsEventJob(eventName string, userID *uuid.UUID, payload map[string]interface{}) *AnalyticsEventJob { if payload == nil { payload = make(map[string]interface{}) } return &AnalyticsEventJob{ EventName: eventName, UserID: userID, Payload: payload, } } // AnalyticsEvent représente un événement analytics en base de données type AnalyticsEvent struct { ID uuid.UUID `gorm:"type:uuid;primaryKey"` EventName string `gorm:"not null;index:idx_analytics_events_name"` UserID *uuid.UUID `gorm:"type:uuid;index:idx_analytics_events_user_id"` Payload string `gorm:"type:jsonb"` // Stocké en JSONB pour PostgreSQL CreatedAt time.Time `gorm:"autoCreateTime;index:idx_analytics_events_created_at"` } // TableName définit le nom de la table pour GORM func (AnalyticsEvent) TableName() string { return "analytics_events" } // BeforeCreate hook GORM pour générer UUID si non défini func (a *AnalyticsEvent) BeforeCreate(tx *gorm.DB) error { if a.ID == uuid.Nil { a.ID = uuid.New() } return nil } // Execute exécute le job d'analytics générique func (j *AnalyticsEventJob) Execute(ctx context.Context, db *gorm.DB, logger *zap.Logger) error { // Valider le nom de l'événement if j.EventName == "" { return fmt.Errorf("event name is required") } // Sérialiser le payload en JSON payloadJSON, err := json.Marshal(j.Payload) if err != nil { return fmt.Errorf("failed to marshal payload: %w", err) } // Créer l'événement analytics event := AnalyticsEvent{ EventName: j.EventName, UserID: j.UserID, Payload: string(payloadJSON), CreatedAt: time.Now(), } // Enregistrer en base de données if err := db.WithContext(ctx).Create(&event).Error; err != nil { return fmt.Errorf("failed to save analytics event: %w", err) } logger.Info("Analytics event recorded", zap.String("event_name", j.EventName), zap.String("event_id", event.ID.String()), zap.Any("user_id", j.UserID), zap.Int("payload_size", len(payloadJSON)), ) return nil }