veza/veza-backend-api/internal/services/playlist_notification_service.go

224 lines
7.1 KiB
Go

package services
import (
"context"
"fmt"
"github.com/google/uuid"
"veza-backend-api/internal/repositories"
"go.uber.org/zap"
)
// PlaylistNotificationService handles playlist-specific notifications
// T0508: Create Playlist Notifications
type PlaylistNotificationService struct {
notificationService *NotificationService
playlistRepo repositories.PlaylistRepository
collaboratorRepo repositories.PlaylistCollaboratorRepository
logger *zap.Logger
}
// NewPlaylistNotificationService creates a new playlist notification service
func NewPlaylistNotificationService(
notificationService *NotificationService,
playlistRepo repositories.PlaylistRepository,
collaboratorRepo repositories.PlaylistCollaboratorRepository,
logger *zap.Logger,
) *PlaylistNotificationService {
if logger == nil {
logger = zap.NewNop()
}
return &PlaylistNotificationService{
notificationService: notificationService,
playlistRepo: playlistRepo,
collaboratorRepo: collaboratorRepo,
logger: logger,
}
}
// NotifyCollaboratorAdded notifies a user when they are added as a collaborator
// T0508: Create Playlist Notifications
// MIGRATION UUID: Completée.
func (pns *PlaylistNotificationService) NotifyCollaboratorAdded(ctx context.Context, playlistID uuid.UUID, collaboratorUserID uuid.UUID, addedByUserID uuid.UUID) error {
// Get playlist info
playlist, err := pns.playlistRepo.GetByID(ctx, playlistID)
if err != nil {
return fmt.Errorf("failed to get playlist: %w", err)
}
// Get collaborator info using GetCollaborator (which takes playlistID and userID)
_, err = pns.collaboratorRepo.GetCollaborator(ctx, playlistID, collaboratorUserID)
if err != nil {
return fmt.Errorf("failed to get collaborator: %w", err)
}
// Get added by user info (we'll use a simple query for now)
// In a real implementation, you might want to get the username
title := "Nouveau collaborateur"
content := fmt.Sprintf("Vous avez été ajouté comme collaborateur à la playlist \"%s\"", playlist.Title)
link := fmt.Sprintf("/playlists/%s", playlistID.String())
return pns.notificationService.CreateNotification(
collaboratorUserID,
"playlist_collaborator_added",
title,
content,
link,
)
}
// NotifyTrackAdded notifies playlist owner and collaborators when a track is added
// T0508: Create Playlist Notifications
// trackTitle can be empty if not available, will use a generic message
// MIGRATION UUID: Completée.
func (pns *PlaylistNotificationService) NotifyTrackAdded(ctx context.Context, playlistID uuid.UUID, trackTitle string, addedByUserID uuid.UUID) error {
// Get playlist info
playlist, err := pns.playlistRepo.GetByID(ctx, playlistID)
if err != nil {
return fmt.Errorf("failed to get playlist: %w", err)
}
// Notify playlist owner (if not the one who added the track)
if playlist.UserID != addedByUserID {
title := "Track ajouté"
var content string
if trackTitle != "" {
content = fmt.Sprintf("Un nouveau track \"%s\" a été ajouté à votre playlist \"%s\"", trackTitle, playlist.Title)
} else {
content = fmt.Sprintf("Un nouveau track a été ajouté à votre playlist \"%s\"", playlist.Title)
}
link := fmt.Sprintf("/playlists/%s", playlistID.String())
if err := pns.notificationService.CreateNotification(
playlist.UserID,
"playlist_track_added",
title,
content,
link,
); err != nil {
pns.logger.Warn("Failed to notify playlist owner", zap.Error(err))
}
}
// Notify all collaborators (except the one who added the track)
collaborators, err := pns.collaboratorRepo.GetCollaborators(ctx, playlistID)
if err != nil {
pns.logger.Warn("Failed to get collaborators", zap.Error(err))
return nil // Don't fail the whole operation if we can't notify collaborators
}
title := "Track ajouté"
var content string
if trackTitle != "" {
content = fmt.Sprintf("Un nouveau track \"%s\" a été ajouté à la playlist \"%s\"", trackTitle, playlist.Title)
} else {
content = fmt.Sprintf("Un nouveau track a été ajouté à la playlist \"%s\"", playlist.Title)
}
link := fmt.Sprintf("/playlists/%s", playlistID.String())
for _, collaborator := range collaborators {
// Skip the user who added the track
if collaborator.UserID == addedByUserID {
continue
}
if err := pns.notificationService.CreateNotification(
collaborator.UserID,
"playlist_track_added",
title,
content,
link,
); err != nil {
pns.logger.Warn("Failed to notify collaborator", zap.String("userID", collaborator.UserID.String()), zap.Error(err))
}
}
return nil
}
// NotifyPlaylistShared notifies when a playlist is shared via a share link
// T0508: Create Playlist Notifications
// MIGRATION UUID: Completée.
func (pns *PlaylistNotificationService) NotifyPlaylistShared(ctx context.Context, playlistID uuid.UUID, sharedByUserID uuid.UUID) error {
// Get playlist info
playlist, err := pns.playlistRepo.GetByID(ctx, playlistID)
if err != nil {
return fmt.Errorf("failed to get playlist: %w", err)
}
// Notify playlist owner (if not the one who shared)
if playlist.UserID != sharedByUserID {
title := "Playlist partagée"
content := fmt.Sprintf("Votre playlist \"%s\" a été partagée", playlist.Title)
link := fmt.Sprintf("/playlists/%s", playlistID.String())
return pns.notificationService.CreateNotification(
playlist.UserID,
"playlist_shared",
title,
content,
link,
)
}
return nil
}
// NotifyPlaylistUpdated notifies collaborators when a playlist is updated
// T0508: Create Playlist Notifications
// MIGRATION UUID: Completée.
func (pns *PlaylistNotificationService) NotifyPlaylistUpdated(ctx context.Context, playlistID uuid.UUID, updatedByUserID uuid.UUID) error {
// Get playlist info
playlist, err := pns.playlistRepo.GetByID(ctx, playlistID)
if err != nil {
return fmt.Errorf("failed to get playlist: %w", err)
}
// Notify playlist owner (if not the one who updated)
if playlist.UserID != updatedByUserID {
title := "Playlist mise à jour"
content := fmt.Sprintf("La playlist \"%s\" a été mise à jour", playlist.Title)
link := fmt.Sprintf("/playlists/%s", playlistID.String())
if err := pns.notificationService.CreateNotification(
playlist.UserID,
"playlist_updated",
title,
content,
link,
); err != nil {
pns.logger.Warn("Failed to notify playlist owner", zap.Error(err))
}
}
// Notify all collaborators (except the one who updated)
collaborators, err := pns.collaboratorRepo.GetCollaborators(ctx, playlistID)
if err != nil {
pns.logger.Warn("Failed to get collaborators", zap.Error(err))
return nil
}
title := "Playlist mise à jour"
content := fmt.Sprintf("La playlist \"%s\" a été mise à jour", playlist.Title)
link := fmt.Sprintf("/playlists/%s", playlistID.String())
for _, collaborator := range collaborators {
// Skip the user who updated
if collaborator.UserID == updatedByUserID {
continue
}
if err := pns.notificationService.CreateNotification(
collaborator.UserID,
"playlist_updated",
title,
content,
link,
); err != nil {
pns.logger.Warn("Failed to notify collaborator", zap.String("userID", collaborator.UserID.String()), zap.Error(err))
}
}
return nil
}