121 lines
4.3 KiB
Go
121 lines
4.3 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/google/uuid" // Added import for uuid
|
|
"go.uber.org/zap"
|
|
"gorm.io/gorm"
|
|
"veza-backend-api/internal/models"
|
|
)
|
|
|
|
// PlaylistAnalyticsService gère les analytics de playlists
|
|
// T0491: Create Playlist Analytics Backend
|
|
type PlaylistAnalyticsService struct {
|
|
db *gorm.DB
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewPlaylistAnalyticsService crée un nouveau service d'analytics de playlists
|
|
func NewPlaylistAnalyticsService(db *gorm.DB, logger *zap.Logger) *PlaylistAnalyticsService {
|
|
if logger == nil {
|
|
logger = zap.NewNop()
|
|
}
|
|
return &PlaylistAnalyticsService{
|
|
db: db,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// PlaylistStats représente les statistiques d'une playlist
|
|
type PlaylistStats struct {
|
|
Plays int64 `json:"plays"` // Nombre total de lectures (somme des plays des tracks)
|
|
Shares int64 `json:"shares"` // Nombre de liens de partage créés
|
|
Likes int64 `json:"likes"` // Nombre de follows (équivalent aux likes)
|
|
Followers int64 `json:"followers"` // Nombre de followers (déjà dans Playlist.FollowerCount)
|
|
TrackCount int `json:"track_count"` // Nombre de tracks dans la playlist
|
|
}
|
|
|
|
// GetPlaylistStats récupère les statistiques d'une playlist
|
|
func (s *PlaylistAnalyticsService) GetPlaylistStats(ctx context.Context, playlistID uuid.UUID) (*PlaylistStats, error) { // Changed playlistID to uuid.UUID
|
|
// Vérifier que la playlist existe
|
|
var playlist models.Playlist
|
|
if err := s.db.WithContext(ctx).First(&playlist, "id = ?", playlistID).Error; err != nil { // Updated query
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, errors.New("playlist not found")
|
|
}
|
|
return nil, fmt.Errorf("failed to get playlist: %w", err)
|
|
}
|
|
|
|
var stats PlaylistStats
|
|
|
|
// Track count (déjà dans le modèle)
|
|
stats.TrackCount = playlist.TrackCount
|
|
|
|
// Followers count (déjà dans le modèle)
|
|
stats.Followers = int64(playlist.FollowerCount)
|
|
|
|
// Count shares (nombre de liens de partage créés, non supprimés)
|
|
if err := s.db.WithContext(ctx).Model(&models.PlaylistShareLink{}).
|
|
Where("playlist_id = ? AND deleted_at IS NULL", playlistID).
|
|
Count(&stats.Shares).Error; err != nil {
|
|
return nil, fmt.Errorf("failed to count shares: %w", err)
|
|
}
|
|
|
|
// Count likes (nombre de follows, non supprimés)
|
|
if err := s.db.WithContext(ctx).Model(&models.PlaylistFollow{}).
|
|
Where("playlist_id = ? AND deleted_at IS NULL", playlistID).
|
|
Count(&stats.Likes).Error; err != nil {
|
|
return nil, fmt.Errorf("failed to count likes: %w", err)
|
|
}
|
|
|
|
// Count plays: somme des plays de tous les tracks dans la playlist
|
|
// On compte les TrackPlay pour tous les tracks de la playlist
|
|
type PlayCountResult struct {
|
|
TotalPlays int64
|
|
}
|
|
var playCountResult PlayCountResult
|
|
|
|
// Récupérer tous les track IDs de la playlist
|
|
var trackIDs []uuid.UUID // Changed to []uuid.UUID
|
|
if err := s.db.WithContext(ctx).Model(&models.PlaylistTrack{}).
|
|
Where("playlist_id = ?", playlistID).
|
|
Pluck("track_id", &trackIDs).Error; err != nil {
|
|
return nil, fmt.Errorf("failed to get playlist tracks: %w", err)
|
|
}
|
|
|
|
// Si la playlist a des tracks, compter les plays
|
|
if len(trackIDs) > 0 {
|
|
if err := s.db.WithContext(ctx).Model(&models.TrackPlay{}).
|
|
Where("track_id IN ?", trackIDs).
|
|
Count(&playCountResult.TotalPlays).Error; err != nil {
|
|
return nil, fmt.Errorf("failed to count plays: %w", err)
|
|
}
|
|
}
|
|
|
|
stats.Plays = playCountResult.TotalPlays
|
|
|
|
s.logger.Debug("Playlist stats retrieved",
|
|
zap.Any("playlist_id", playlistID), // Changed to zap.Any for uuid.UUID
|
|
zap.Int64("plays", stats.Plays),
|
|
zap.Int64("shares", stats.Shares),
|
|
zap.Int64("likes", stats.Likes),
|
|
zap.Int64("followers", stats.Followers),
|
|
)
|
|
|
|
return &stats, nil
|
|
}
|
|
|
|
// IncrementPlaylistPlays incrémente le compteur de plays d'une playlist
|
|
// Cette méthode peut être appelée lorsqu'un track de la playlist est joué
|
|
func (s *PlaylistAnalyticsService) IncrementPlaylistPlays(ctx context.Context, playlistID uuid.UUID) error { // Changed playlistID to uuid.UUID
|
|
// Note: Pour l'instant, on ne stocke pas de compteur de plays dans Playlist
|
|
// car on le calcule dynamiquement à partir des TrackPlay
|
|
// Cette méthode est prévue pour une future optimisation avec cache
|
|
s.logger.Debug("Playlist play incremented",
|
|
zap.Any("playlist_id", playlistID), // Changed to zap.Any for uuid.UUID
|
|
)
|
|
return nil
|
|
}
|