veza/veza-backend-api/internal/core/track/handler.go
senke 83ed4f315b
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
chore(release): v0.602 — Payout, Dette Technique & Tests E2E
- 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
2026-02-23 22:32:01 +01:00

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))
}