131 lines
No EOL
3.8 KiB
Go
131 lines
No EOL
3.8 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/google/uuid"
|
|
|
|
"go.uber.org/zap"
|
|
"veza-backend-api/internal/models"
|
|
)
|
|
|
|
// PlaylistDuplicateService gère la duplication de playlists
|
|
// T0495: Create Playlist Duplicate Feature
|
|
type PlaylistDuplicateService struct {
|
|
playlistService *PlaylistService
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewPlaylistDuplicateService crée un nouveau service de duplication de playlists
|
|
func NewPlaylistDuplicateService(playlistService *PlaylistService, logger *zap.Logger) *PlaylistDuplicateService {
|
|
if logger == nil {
|
|
logger = zap.NewNop()
|
|
}
|
|
return &PlaylistDuplicateService{
|
|
playlistService: playlistService,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// DuplicatePlaylistRequest représente la requête de duplication
|
|
type DuplicatePlaylistRequest struct {
|
|
NewTitle string `json:"new_title"`
|
|
NewDescription string `json:"new_description,omitempty"`
|
|
IsPublic *bool `json:"is_public,omitempty"`
|
|
}
|
|
|
|
// DuplicatePlaylist duplique une playlist avec tous ses tracks
|
|
// T0495: Create Playlist Duplicate Feature
|
|
// MIGRATION UUID: Completée. playlistID et userID sont des UUIDs.
|
|
func (s *PlaylistDuplicateService) DuplicatePlaylist(
|
|
ctx context.Context,
|
|
playlistID uuid.UUID,
|
|
userID uuid.UUID,
|
|
request DuplicatePlaylistRequest,
|
|
) (*models.Playlist, error) {
|
|
// Récupérer la playlist originale
|
|
userIDPtr := &userID
|
|
originalPlaylist, err := s.playlistService.GetPlaylist(ctx, playlistID, userIDPtr)
|
|
if err != nil {
|
|
if err.Error() == "playlist not found" {
|
|
return nil, errors.New("playlist not found")
|
|
}
|
|
return nil, fmt.Errorf("failed to get playlist: %w", err)
|
|
}
|
|
|
|
// Vérifier que l'utilisateur a accès à la playlist (propriétaire, collaborateur ou publique)
|
|
if originalPlaylist.UserID != userID && !originalPlaylist.IsPublic {
|
|
// Vérifier si l'utilisateur est collaborateur
|
|
hasAccess, err := s.playlistService.CheckPermission(ctx, playlistID, userID, models.PlaylistPermissionRead)
|
|
if err != nil || !hasAccess {
|
|
return nil, errors.New("forbidden: you don't have access to this playlist")
|
|
}
|
|
}
|
|
|
|
// Déterminer le titre de la nouvelle playlist
|
|
newTitle := request.NewTitle
|
|
if newTitle == "" {
|
|
newTitle = originalPlaylist.Title + " (Copy)"
|
|
}
|
|
|
|
// Déterminer la description
|
|
newDescription := request.NewDescription
|
|
if newDescription == "" {
|
|
newDescription = originalPlaylist.Description
|
|
}
|
|
|
|
// Déterminer si la playlist est publique
|
|
isPublic := originalPlaylist.IsPublic
|
|
if request.IsPublic != nil {
|
|
isPublic = *request.IsPublic
|
|
}
|
|
|
|
// Créer la nouvelle playlist
|
|
newPlaylist, err := s.playlistService.CreatePlaylist(
|
|
ctx,
|
|
userID,
|
|
newTitle,
|
|
newDescription,
|
|
isPublic,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create duplicate playlist: %w", err)
|
|
}
|
|
|
|
// Dupliquer les tracks
|
|
if originalPlaylist.Tracks != nil && len(originalPlaylist.Tracks) > 0 {
|
|
for _, playlistTrack := range originalPlaylist.Tracks {
|
|
// Track est un struct (non-pointeur), toujours valide
|
|
{
|
|
// Ajouter le track à la nouvelle playlist avec la même position
|
|
err := s.playlistService.AddTrackToPlaylist(
|
|
ctx,
|
|
newPlaylist.ID,
|
|
playlistTrack.Track.ID,
|
|
userID,
|
|
playlistTrack.Position,
|
|
)
|
|
if err != nil {
|
|
// Log l'erreur mais continue avec les autres tracks
|
|
s.logger.Warn("Failed to add track to duplicated playlist",
|
|
zap.String("playlist_id", newPlaylist.ID.String()),
|
|
zap.String("track_id", playlistTrack.Track.ID.String()),
|
|
zap.Error(err),
|
|
)
|
|
// On continue avec les autres tracks plutôt que d'échouer complètement
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
s.logger.Info("Playlist duplicated",
|
|
zap.String("original_playlist_id", playlistID.String()),
|
|
zap.String("new_playlist_id", newPlaylist.ID.String()),
|
|
zap.String("user_id", userID.String()),
|
|
zap.Int("tracks_count", len(originalPlaylist.Tracks)),
|
|
)
|
|
|
|
return newPlaylist, nil
|
|
} |