2025-12-03 19:29:37 +00:00
package services
import (
"context"
"fmt"
2025-12-24 10:52:49 +00:00
"veza-backend-api/internal/models"
2025-12-03 19:29:37 +00:00
"github.com/google/uuid" // Added import for uuid
"go.uber.org/zap"
"gorm.io/gorm"
)
// TrackUploadService gère le suivi de progression des uploads de tracks
type TrackUploadService struct {
db * gorm . DB
logger * zap . Logger
}
// NewTrackUploadService crée un nouveau service de suivi d'upload
func NewTrackUploadService ( db * gorm . DB , logger * zap . Logger ) * TrackUploadService {
if logger == nil {
logger = zap . NewNop ( )
}
return & TrackUploadService {
db : db ,
logger : logger ,
}
}
// GetUploadProgress récupère la progression d'un upload de track
func ( s * TrackUploadService ) GetUploadProgress ( ctx context . Context , trackID uuid . UUID ) ( * models . UploadProgress , error ) { // Changed trackID to uuid.UUID
var track models . Track
if err := s . db . WithContext ( ctx ) . First ( & track , "id = ?" , trackID ) . Error ; err != nil { // Updated query
if err == gorm . ErrRecordNotFound {
return nil , fmt . Errorf ( "track not found" )
}
return nil , fmt . Errorf ( "failed to get track: %w" , err )
}
// Calculer le pourcentage de progression basé sur le statut
progress := s . calculateProgress ( track . Status )
return & models . UploadProgress {
TrackID : trackID ,
Status : track . Status ,
Progress : progress ,
Message : track . StatusMessage ,
StreamStatus : track . StreamStatus ,
StreamManifestURL : track . StreamManifestURL ,
} , nil
}
2025-12-06 16:21:59 +00:00
2025-12-03 19:29:37 +00:00
// UpdateUploadStatus met à jour le statut d'un track
func ( s * TrackUploadService ) UpdateUploadStatus ( ctx context . Context , trackID uuid . UUID , status models . TrackStatus , message string ) error { // Changed trackID to uuid.UUID
updates := map [ string ] interface { } {
"status" : status ,
}
if message != "" {
updates [ "status_message" ] = message
}
if err := s . db . WithContext ( ctx ) . Model ( & models . Track { } ) . Where ( "id = ?" , trackID ) . Updates ( updates ) . Error ; err != nil {
return fmt . Errorf ( "failed to update status: %w" , err )
}
s . logger . Info ( "Track upload status updated" ,
zap . Any ( "track_id" , trackID ) , // Changed to zap.Any for uuid.UUID
zap . String ( "status" , string ( status ) ) ,
zap . String ( "message" , message ) ,
)
return nil
}
2025-12-06 16:21:59 +00:00
2025-12-03 19:29:37 +00:00
// calculateProgress calcule le pourcentage de progression basé sur le statut
func ( s * TrackUploadService ) calculateProgress ( status models . TrackStatus ) int {
switch status {
case models . TrackStatusUploading :
return 25 // 25% pendant l'upload
case models . TrackStatusProcessing :
return 50 // 50% pendant le traitement
case models . TrackStatusCompleted :
return 100 // 100% une fois terminé
case models . TrackStatusFailed :
return 0 // 0% en cas d'échec
default :
return 0
}
}
2025-12-24 10:52:49 +00:00
// GetUploadStats récupère les statistiques d'upload pour un utilisateur
// BE-API-032: Implement upload stats endpoint
func ( s * TrackUploadService ) GetUploadStats ( ctx context . Context , userID uuid . UUID ) ( map [ string ] interface { } , error ) {
stats := map [ string ] interface { } {
"total_uploads" : int64 ( 0 ) ,
"total_size" : int64 ( 0 ) ,
"audio_files" : int64 ( 0 ) ,
"image_files" : int64 ( 0 ) ,
"video_files" : int64 ( 0 ) ,
}
// Compter le nombre total d'uploads (tracks) pour l'utilisateur
var totalUploads int64
if err := s . db . WithContext ( ctx ) . Model ( & models . Track { } ) .
Where ( "creator_id = ?" , userID ) .
Count ( & totalUploads ) . Error ; err != nil {
return nil , fmt . Errorf ( "failed to count total uploads: %w" , err )
}
stats [ "total_uploads" ] = totalUploads
// Calculer la taille totale des fichiers
var totalSize int64
if err := s . db . WithContext ( ctx ) . Model ( & models . Track { } ) .
Where ( "creator_id = ?" , userID ) .
Select ( "COALESCE(SUM(file_size), 0)" ) .
Scan ( & totalSize ) . Error ; err != nil {
return nil , fmt . Errorf ( "failed to calculate total size: %w" , err )
}
stats [ "total_size" ] = totalSize
// Compter les fichiers audio (mp3, flac, wav, etc.)
var audioFiles int64
if err := s . db . WithContext ( ctx ) . Model ( & models . Track { } ) .
Where ( "creator_id = ? AND format IN (?)" , userID , [ ] string { "mp3" , "flac" , "wav" , "aac" , "ogg" , "m4a" } ) .
Count ( & audioFiles ) . Error ; err != nil {
return nil , fmt . Errorf ( "failed to count audio files: %w" , err )
}
stats [ "audio_files" ] = audioFiles
// Compter les fichiers image (jpg, png, gif, etc.)
// Note: Les images sont généralement dans cover_art_path, mais on peut aussi chercher dans les tracks
// Pour l'instant, on se concentre sur les tracks audio
var imageFiles int64
if err := s . db . WithContext ( ctx ) . Model ( & models . Track { } ) .
Where ( "creator_id = ? AND format IN (?)" , userID , [ ] string { "jpg" , "jpeg" , "png" , "gif" , "webp" } ) .
Count ( & imageFiles ) . Error ; err != nil {
// Si la requête échoue (format non supporté pour images), on laisse à 0
s . logger . Debug ( "Image files count query failed, setting to 0" , zap . Error ( err ) )
}
stats [ "image_files" ] = imageFiles
// Compter les fichiers vidéo (mp4, avi, etc.)
var videoFiles int64
if err := s . db . WithContext ( ctx ) . Model ( & models . Track { } ) .
Where ( "creator_id = ? AND format IN (?)" , userID , [ ] string { "mp4" , "avi" , "mov" , "mkv" , "webm" } ) .
Count ( & videoFiles ) . Error ; err != nil {
// Si la requête échoue (format non supporté pour vidéos), on laisse à 0
s . logger . Debug ( "Video files count query failed, setting to 0" , zap . Error ( err ) )
}
stats [ "video_files" ] = videoFiles
return stats , nil
}