veza/veza-backend-api/internal/services/track_repost_service.go
senke 6111ae6136
Some checks failed
Backend API CI / test-unit (push) Failing after 0s
Backend API CI / test-integration (push) Failing after 0s
Frontend CI / test (push) Failing after 0s
Storybook Audit / Build & audit Storybook (push) Failing after 0s
feat(v0.10.3): Commentaires & Interactions Sociales - F201-F215
- F201: Commentaires avec timestamp cliquable, modération mots-clés
- F202: Likes privés (compteur visible créateur uniquement)
- F203: Reposts de tracks sur le profil, bouton Repost, onglet Reposts
- F204: Notifications (commentaire, repost), pas de gamification

Backend: migrations 127/128, comment_moderation_service, track_repost_service,
  GetTrackLikes/GetTrack masquent like_count pour non-créateurs
Frontend: LikeButton isCreator, RepostButton, Reposts tab profil, timestamp seek
2026-03-09 10:30:47 +01:00

94 lines
2.7 KiB
Go

package services
import (
"context"
"fmt"
"github.com/google/uuid"
"veza-backend-api/internal/models"
"gorm.io/gorm"
)
// TrackRepostService handles track repost operations (v0.10.3 F203).
type TrackRepostService struct {
db *gorm.DB
}
// NewTrackRepostService creates a new track repost service.
func NewTrackRepostService(db *gorm.DB) *TrackRepostService {
return &TrackRepostService{db: db}
}
// RepostTrack adds a repost of a track to the user's profile.
func (s *TrackRepostService) RepostTrack(ctx context.Context, userID, trackID uuid.UUID) error {
var track models.Track
if err := s.db.WithContext(ctx).First(&track, "id = ?", trackID).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return fmt.Errorf("track not found")
}
return fmt.Errorf("failed to check track: %w", err)
}
repost := models.TrackRepost{
UserID: userID,
TrackID: trackID,
}
if err := s.db.WithContext(ctx).Where("user_id = ? AND track_id = ?", userID, trackID).FirstOrCreate(&repost).Error; err != nil {
return fmt.Errorf("failed to create repost: %w", err)
}
return nil
}
// UnrepostTrack removes a repost.
func (s *TrackRepostService) UnrepostTrack(ctx context.Context, userID, trackID uuid.UUID) error {
if err := s.db.WithContext(ctx).
Where("user_id = ? AND track_id = ?", userID, trackID).
Delete(&models.TrackRepost{}).Error; err != nil {
return fmt.Errorf("failed to delete repost: %w", err)
}
return nil
}
// IsReposted returns whether the user has reposted the track.
func (s *TrackRepostService) IsReposted(ctx context.Context, userID, trackID uuid.UUID) (bool, error) {
var count int64
err := s.db.WithContext(ctx).Model(&models.TrackRepost{}).
Where("user_id = ? AND track_id = ?", userID, trackID).
Count(&count).Error
if err != nil {
return false, fmt.Errorf("failed to check repost: %w", err)
}
return count > 0, nil
}
// GetUserRepostedTracks returns tracks reposted by the user, paginated.
func (s *TrackRepostService) GetUserRepostedTracks(ctx context.Context, userID uuid.UUID, limit, offset int) ([]models.Track, int64, error) {
var total int64
if err := s.db.WithContext(ctx).Model(&models.TrackRepost{}).
Where("user_id = ?", userID).
Count(&total).Error; err != nil {
return nil, 0, fmt.Errorf("failed to count reposts: %w", err)
}
var reposts []models.TrackRepost
if err := s.db.WithContext(ctx).
Where("user_id = ?", userID).
Order("created_at DESC").
Limit(limit).
Offset(offset).
Preload("Track").
Preload("Track.User").
Find(&reposts).Error; err != nil {
return nil, 0, fmt.Errorf("failed to get reposts: %w", err)
}
tracks := make([]models.Track, 0, len(reposts))
for _, r := range reposts {
if r.Track.ID != uuid.Nil {
tracks = append(tracks, r.Track)
}
}
return tracks, total, nil
}