203 lines
5.9 KiB
Go
203 lines
5.9 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"veza-backend-api/internal/models"
|
|
|
|
"github.com/google/uuid"
|
|
"go.uber.org/zap"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// TrackHistoryService gère l'historique des modifications de tracks
|
|
type TrackHistoryService struct {
|
|
db *gorm.DB
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewTrackHistoryService crée un nouveau service d'historique de tracks
|
|
func NewTrackHistoryService(db *gorm.DB, logger *zap.Logger) *TrackHistoryService {
|
|
if logger == nil {
|
|
logger = zap.NewNop()
|
|
}
|
|
return &TrackHistoryService{
|
|
db: db,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// RecordHistoryParams représente les paramètres pour enregistrer un historique
|
|
// MIGRATION UUID: UserID et TrackID en UUID
|
|
type RecordHistoryParams struct {
|
|
TrackID uuid.UUID
|
|
UserID uuid.UUID
|
|
Action models.TrackHistoryAction
|
|
OldValue interface{} // Peut être n'importe quel type, sera sérialisé en JSON
|
|
NewValue interface{} // Peut être n'importe quel type, sera sérialisé en JSON
|
|
}
|
|
|
|
// RecordHistory enregistre une entrée dans l'historique d'un track
|
|
func (s *TrackHistoryService) RecordHistory(ctx context.Context, params RecordHistoryParams) (*models.TrackHistory, error) {
|
|
// Vérifier que le track existe
|
|
var track models.Track
|
|
if err := s.db.WithContext(ctx).First(&track, "id = ?", params.TrackID).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, ErrTrackNotFound
|
|
}
|
|
return nil, fmt.Errorf("failed to get track: %w", err)
|
|
}
|
|
|
|
// Sérialiser old_value et new_value en JSON si nécessaire
|
|
var oldValueStr string
|
|
var newValueStr string
|
|
|
|
if params.OldValue != nil {
|
|
oldValueBytes, err := json.Marshal(params.OldValue)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to marshal old_value: %w", err)
|
|
}
|
|
oldValueStr = string(oldValueBytes)
|
|
}
|
|
|
|
if params.NewValue != nil {
|
|
newValueBytes, err := json.Marshal(params.NewValue)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to marshal new_value: %w", err)
|
|
}
|
|
newValueStr = string(newValueBytes)
|
|
}
|
|
|
|
// Créer l'entrée d'historique (TrackHistory utilise UUID)
|
|
history := &models.TrackHistory{
|
|
TrackID: params.TrackID,
|
|
UserID: params.UserID,
|
|
Action: params.Action,
|
|
OldValue: oldValueStr,
|
|
NewValue: newValueStr,
|
|
}
|
|
|
|
if err := s.db.WithContext(ctx).Create(history).Error; err != nil {
|
|
return nil, fmt.Errorf("failed to create track history: %w", err)
|
|
}
|
|
|
|
s.logger.Info("Track history recorded",
|
|
zap.String("track_id", params.TrackID.String()),
|
|
zap.String("user_id", params.UserID.String()),
|
|
zap.String("action", string(params.Action)),
|
|
zap.String("history_id", history.ID.String()),
|
|
)
|
|
|
|
return history, nil
|
|
}
|
|
|
|
// GetHistory récupère l'historique d'un track
|
|
func (s *TrackHistoryService) GetHistory(ctx context.Context, trackID uuid.UUID, limit, offset int) ([]models.TrackHistory, int64, error) {
|
|
// Vérifier que le track existe
|
|
var track models.Track
|
|
if err := s.db.WithContext(ctx).First(&track, "id = ?", trackID).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, 0, ErrTrackNotFound
|
|
}
|
|
return nil, 0, fmt.Errorf("failed to get track: %w", err)
|
|
}
|
|
|
|
// Compter le total d'entrées
|
|
var total int64
|
|
if err := s.db.WithContext(ctx).Model(&models.TrackHistory{}).
|
|
Where("track_id = ?", trackID).
|
|
Count(&total).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("failed to count track history: %w", err)
|
|
}
|
|
|
|
// Récupérer les entrées avec pagination
|
|
var histories []models.TrackHistory
|
|
query := s.db.WithContext(ctx).
|
|
Where("track_id = ?", trackID).
|
|
Order("created_at DESC")
|
|
|
|
if limit > 0 {
|
|
query = query.Limit(limit)
|
|
}
|
|
if offset > 0 {
|
|
query = query.Offset(offset)
|
|
}
|
|
|
|
if err := query.Find(&histories).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("failed to get track history: %w", err)
|
|
}
|
|
|
|
return histories, total, nil
|
|
}
|
|
|
|
// GetHistoryByUser récupère l'historique des tracks modifiés par un utilisateur
|
|
func (s *TrackHistoryService) GetHistoryByUser(ctx context.Context, userID uuid.UUID, limit, offset int) ([]models.TrackHistory, int64, error) {
|
|
// Compter le total d'entrées
|
|
var total int64
|
|
if err := s.db.WithContext(ctx).Model(&models.TrackHistory{}).
|
|
Where("user_id = ?", userID).
|
|
Count(&total).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("failed to count user track history: %w", err)
|
|
}
|
|
|
|
// Récupérer les entrées avec pagination
|
|
var histories []models.TrackHistory
|
|
query := s.db.WithContext(ctx).
|
|
Where("user_id = ?", userID).
|
|
Order("created_at DESC")
|
|
|
|
if limit > 0 {
|
|
query = query.Limit(limit)
|
|
}
|
|
if offset > 0 {
|
|
query = query.Offset(offset)
|
|
}
|
|
|
|
if err := query.Find(&histories).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("failed to get user track history: %w", err)
|
|
}
|
|
|
|
return histories, total, nil
|
|
}
|
|
|
|
// GetHistoryByAction récupère l'historique filtré par action
|
|
func (s *TrackHistoryService) GetHistoryByAction(ctx context.Context, trackID uuid.UUID, action models.TrackHistoryAction, limit, offset int) ([]models.TrackHistory, int64, error) {
|
|
// Vérifier que le track existe
|
|
var track models.Track
|
|
if err := s.db.WithContext(ctx).First(&track, "id = ?", trackID).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, 0, ErrTrackNotFound
|
|
}
|
|
return nil, 0, fmt.Errorf("failed to get track: %w", err)
|
|
}
|
|
|
|
// Compter le total d'entrées
|
|
var total int64
|
|
if err := s.db.WithContext(ctx).Model(&models.TrackHistory{}).
|
|
Where("track_id = ? AND action = ?", trackID, action).
|
|
Count(&total).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("failed to count track history by action: %w", err)
|
|
}
|
|
|
|
// Récupérer les entrées avec pagination
|
|
var histories []models.TrackHistory
|
|
query := s.db.WithContext(ctx).
|
|
Where("track_id = ? AND action = ?", trackID, action).
|
|
Order("created_at DESC")
|
|
|
|
if limit > 0 {
|
|
query = query.Limit(limit)
|
|
}
|
|
if offset > 0 {
|
|
query = query.Offset(offset)
|
|
}
|
|
|
|
if err := query.Find(&histories).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("failed to get track history by action: %w", err)
|
|
}
|
|
|
|
return histories, total, nil
|
|
}
|