- Stripe Connect: onboarding, balance, SellerDashboardView - Interceptors: auth.ts, error.ts extracted, facade - Grafana: dashboards enriched (p50, top endpoints, 4xx, WS, commerce) - E2E commerce: product->order->review->invoice - SMOKE_TEST_V0602, RETROSPECTIVE_V0602, PAYOUT_MANUAL - Archive V0_602 scope, V0_603 placeholder, SCOPE_CONTROL v0.603 - Fix sanitizer regex (Go no backreferences) - Marketplace test schema: product_licenses, product_images, orders, licenses
163 lines
6.4 KiB
Go
163 lines
6.4 KiB
Go
package track
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
apperrors "veza-backend-api/internal/errors"
|
|
"veza-backend-api/internal/handlers"
|
|
"veza-backend-api/internal/services"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// TrackHandler gère les opérations sur les tracks
|
|
type TrackHandler struct {
|
|
trackService *TrackService
|
|
trackUploadService *services.TrackUploadService
|
|
chunkService *services.TrackChunkService
|
|
likeService *services.TrackLikeService
|
|
streamService *services.StreamService
|
|
jobEnqueuer services.JobEnqueuer // Optional: for HLS transcoding via job queue
|
|
searchService *services.TrackSearchService
|
|
shareService *services.TrackShareService
|
|
versionService *services.TrackVersionService
|
|
historyService *services.TrackHistoryService
|
|
playbackAnalyticsService *services.PlaybackAnalyticsService // BE-API-019: Added for play analytics
|
|
permissionService *services.PermissionService // MOD-P1-003: Added for admin check
|
|
uploadValidator *services.UploadValidator // MOD-P1-001: Added for ClamAV scan before persistence
|
|
licenseChecker services.TrackDownloadLicenseChecker // A04: Verify paid track download rights
|
|
notificationService *services.NotificationService // Phase 2.2: Optional, for like notifications
|
|
trackRecommendationService *services.TrackRecommendationService
|
|
waveformService *services.WaveformService
|
|
}
|
|
|
|
// NewTrackHandler crée un nouveau handler de tracks
|
|
func NewTrackHandler(
|
|
trackService *TrackService,
|
|
trackUploadService *services.TrackUploadService,
|
|
chunkService *services.TrackChunkService,
|
|
likeService *services.TrackLikeService,
|
|
streamService *services.StreamService,
|
|
) *TrackHandler {
|
|
return &TrackHandler{
|
|
trackService: trackService,
|
|
trackUploadService: trackUploadService,
|
|
chunkService: chunkService,
|
|
likeService: likeService,
|
|
streamService: streamService,
|
|
}
|
|
}
|
|
|
|
// SetUploadValidator définit le validateur d'upload (pour injection de dépendance)
|
|
// MOD-P1-001: Added for ClamAV scan before persistence
|
|
func (h *TrackHandler) SetUploadValidator(uploadValidator *services.UploadValidator) {
|
|
h.uploadValidator = uploadValidator
|
|
}
|
|
|
|
// SetPermissionService définit le service de permissions (pour injection de dépendance)
|
|
// MOD-P1-003: Added for admin check in ownership verification
|
|
func (h *TrackHandler) SetPermissionService(permissionService *services.PermissionService) {
|
|
h.permissionService = permissionService
|
|
}
|
|
|
|
// SetSearchService définit le service de recherche (pour injection de dépendance)
|
|
func (h *TrackHandler) SetSearchService(searchService *services.TrackSearchService) {
|
|
h.searchService = searchService
|
|
}
|
|
|
|
// SetShareService définit le service de partage (pour injection de dépendance)
|
|
func (h *TrackHandler) SetShareService(shareService *services.TrackShareService) {
|
|
h.shareService = shareService
|
|
}
|
|
|
|
// SetVersionService définit le service de versioning (pour injection de dépendance)
|
|
func (h *TrackHandler) SetVersionService(versionService *services.TrackVersionService) {
|
|
h.versionService = versionService
|
|
}
|
|
|
|
// SetHistoryService définit le service d'historique (pour injection de dépendance)
|
|
func (h *TrackHandler) SetHistoryService(historyService *services.TrackHistoryService) {
|
|
h.historyService = historyService
|
|
}
|
|
|
|
// SetPlaybackAnalyticsService définit le service d'analytics de lecture (pour injection de dépendance)
|
|
// BE-API-019: Implement track play analytics endpoint
|
|
func (h *TrackHandler) SetPlaybackAnalyticsService(analyticsService *services.PlaybackAnalyticsService) {
|
|
h.playbackAnalyticsService = analyticsService
|
|
}
|
|
|
|
// SetLicenseChecker définit le vérificateur de licence pour les téléchargements de tracks payants (A04)
|
|
func (h *TrackHandler) SetLicenseChecker(checker services.TrackDownloadLicenseChecker) {
|
|
h.licenseChecker = checker
|
|
}
|
|
|
|
// SetJobEnqueuer définit le job enqueuer pour le transcoding HLS (optionnel)
|
|
func (h *TrackHandler) SetJobEnqueuer(enqueuer services.JobEnqueuer) {
|
|
h.jobEnqueuer = enqueuer
|
|
}
|
|
|
|
// SetNotificationService définit le service de notifications (Phase 2.2)
|
|
func (h *TrackHandler) SetNotificationService(notificationService *services.NotificationService) {
|
|
h.notificationService = notificationService
|
|
}
|
|
|
|
// SetTrackRecommendationService définit le service de recommandations
|
|
func (h *TrackHandler) SetTrackRecommendationService(svc *services.TrackRecommendationService) {
|
|
h.trackRecommendationService = svc
|
|
}
|
|
|
|
// SetWaveformService définit le service de waveform (S1-05)
|
|
func (h *TrackHandler) SetWaveformService(svc *services.WaveformService) {
|
|
h.waveformService = svc
|
|
}
|
|
|
|
// getUserID récupère l'ID utilisateur du contexte de manière sécurisée (fail-secure)
|
|
// MOD-P1-RES-003: Remplace c.MustGet() pour éviter les panics
|
|
// Retourne false si user_id est absent ou invalide (répond déjà avec 401)
|
|
func (h *TrackHandler) getUserID(c *gin.Context) (uuid.UUID, bool) {
|
|
userIDInterface, exists := c.Get("user_id")
|
|
if !exists {
|
|
// MOD-P1-RES-001: Utiliser RespondWithAppError au lieu de response.Unauthorized
|
|
handlers.RespondWithAppError(c, apperrors.NewUnauthorizedError("unauthorized"))
|
|
return uuid.Nil, false
|
|
}
|
|
|
|
userID, ok := userIDInterface.(uuid.UUID)
|
|
if !ok {
|
|
// MOD-P1-RES-001: Utiliser RespondWithAppError au lieu de response.Unauthorized
|
|
handlers.RespondWithAppError(c, apperrors.NewUnauthorizedError("unauthorized"))
|
|
return uuid.Nil, false
|
|
}
|
|
|
|
if userID == uuid.Nil {
|
|
// MOD-P1-RES-001: Utiliser RespondWithAppError au lieu de response.Unauthorized
|
|
handlers.RespondWithAppError(c, apperrors.NewUnauthorizedError("unauthorized"))
|
|
return uuid.Nil, false
|
|
}
|
|
|
|
return userID, true
|
|
}
|
|
|
|
// respondWithError est un helper pour migrer vers RespondWithAppError
|
|
// MOD-P1-RES-001: Helper pour standardiser les réponses d'erreur
|
|
func (h *TrackHandler) respondWithError(c *gin.Context, httpStatus int, message string) {
|
|
var errCode apperrors.ErrorCode
|
|
switch httpStatus {
|
|
case http.StatusBadRequest:
|
|
errCode = apperrors.ErrCodeValidation
|
|
case http.StatusUnauthorized:
|
|
errCode = apperrors.ErrCodeUnauthorized
|
|
case http.StatusForbidden:
|
|
errCode = apperrors.ErrCodeForbidden
|
|
case http.StatusNotFound:
|
|
errCode = apperrors.ErrCodeNotFound
|
|
case http.StatusInternalServerError:
|
|
errCode = apperrors.ErrCodeInternal
|
|
default:
|
|
errCode = apperrors.ErrCodeInternal
|
|
}
|
|
handlers.RespondWithAppError(c, apperrors.New(errCode, message))
|
|
}
|
|
|