89 lines
2.6 KiB
Go
89 lines
2.6 KiB
Go
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
|
|
}
|