chore: build
Backend - Build & Lint / build (push) Failing after 17m35s

This commit is contained in:
2026-06-28 16:01:23 +02:00
parent b8aab5643f
commit 1721f55060
7 changed files with 276 additions and 45 deletions
+56 -37
View File
@@ -4,7 +4,9 @@ import (
"fmt"
"gestion/db"
"gestion/models"
"gestion/services"
"gestion/utils"
"io"
"log"
"mime/multipart"
"net/http"
@@ -733,6 +735,7 @@ func UpdateStock(c *gin.Context) {
func DeleteMedia(c *gin.Context) {
database := c.MustGet("database").(*db.Database)
s3Service := c.MustGet("s3Service").(*services.S3Service)
// ✅ VÉRIFIER LE RÔLE
role := c.GetString("role")
@@ -753,28 +756,24 @@ func DeleteMedia(c *gin.Context) {
return
}
// ✅ SÉCURISER LE CHEMIN AVANT SUPPRESSION
filePath := strings.TrimPrefix(media.URL, "/")
safeFilePath, err := sanitizeFilePath(filePath)
if err != nil {
log.Printf("❌ [DeleteMedia] Path invalide: %v", err)
c.JSON(http.StatusBadRequest, gin.H{"error": "Chemin invalide"})
return
}
// ✅ SUPPRIMER LE FICHIER PHYSIQUE
if err := os.Remove(safeFilePath); err != nil && !os.IsNotExist(err) {
log.Printf("⚠️ [DeleteMedia] Erreur suppression fichier: %v", err)
}
// ✅ SUPPRIMER DE LA DB
err = database.DeleteMedia(mediaID)
if err != nil {
// ✅ SUPPRIMER DE LA DB EN PREMIER (source de vérité)
if err := database.DeleteMedia(mediaID); err != nil {
log.Printf("❌ [DeleteMedia] Erreur suppression DB: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur suppression"})
return
}
// ✅ SUPPRIMER LE FICHIER SUR RUSTFS
if media.Key != "" {
if err := s3Service.DeleteFile(media.Key); err != nil {
// On ne fait pas échouer la requête : l'entrée DB est déjà supprimée,
// mais on log pour pouvoir nettoyer manuellement un fichier orphelin si besoin.
log.Printf("⚠️ [DeleteMedia] Fichier non supprimé sur RustFS (clé: %s): %v", media.Key, err)
} else {
log.Printf("✅ [DeleteMedia] Fichier supprimé sur RustFS: %s", media.Key)
}
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "Média supprimé",
@@ -783,6 +782,7 @@ func DeleteMedia(c *gin.Context) {
func UploadMedia(c *gin.Context) {
database := c.MustGet("database").(*db.Database)
s3Service := c.MustGet("s3Service").(*services.S3Service)
// ✅ VÉRIFIER LE RÔLE
username, err := safeGetUsername(c)
@@ -792,7 +792,7 @@ func UploadMedia(c *gin.Context) {
}
role := c.GetString("role")
if role != "admin" && role != "cabine" {
if role != "admin" {
c.JSON(http.StatusForbidden, gin.H{"error": "Accès refusé"})
return
}
@@ -860,36 +860,33 @@ func UploadMedia(c *gin.Context) {
cleanProductName := cleanFileName(productName)
uniqueFileName := utils.GenerateUniqueFileName(cleanProductName, file.Filename)
// ✅ CRÉER LE DOSSIER
destFolder := filepath.Join("uploads", fileType+"s")
if err := os.MkdirAll(destFolder, 0750); err != nil {
log.Printf("❌ [UploadMedia] Erreur création dossier: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur création dossier"})
// ✅ UPLOAD VERS RUSTFS (remplace la sauvegarde disque locale)
folder := fileType + "s" // "images" ou "videos"
key, err := s3Service.UploadFileWithName(file, folder, uniqueFileName)
if err != nil {
log.Printf("❌ [UploadMedia] Erreur upload RustFS: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur upload fichier"})
return
}
// ✅ SAUVEGARDER LE FICHIER
filePath := filepath.Join(destFolder, uniqueFileName)
if err := c.SaveUploadedFile(file, filePath); err != nil {
log.Printf("❌ [UploadMedia] Erreur sauvegarde: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur sauvegarde fichier"})
return
}
log.Printf("✅ [UploadMedia] Fichier sauvegardé: %s", filePath)
log.Printf("✅ [UploadMedia] Fichier uploadé sur RustFS: %s", key)
// ✅ CRÉER L'ENTRÉE EN BASE
mediaURL := "/" + filepath.ToSlash(filePath)
// L'URL exposée passe par notre proxy /media/:key (RustFS est derrière le VPN,
// donc inaccessible directement depuis le client/navigateur).
media := models.Media{
ProductID: productID,
Type: fileType,
URL: mediaURL,
URL: "/media/" + key,
Key: key,
}
err = database.CreateMedia(&media)
if err != nil {
// Rollback: supprimer le fichier
os.Remove(filePath)
// Rollback: supprimer le fichier sur RustFS
if delErr := s3Service.DeleteFile(key); delErr != nil {
log.Printf("⚠️ [UploadMedia] Échec rollback RustFS (clé: %s): %v", key, delErr)
}
log.Printf("❌ [UploadMedia] Erreur DB: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur création média"})
return
@@ -908,6 +905,28 @@ func UploadMedia(c *gin.Context) {
})
}
func ServeMedia(c *gin.Context) {
s3Service := c.MustGet("s3Service").(*services.S3Service)
key := strings.TrimPrefix(c.Param("key"), "/")
if key == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "Clé manquante"})
return
}
body, contentType, err := s3Service.GetFile(key)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Média non trouvé"})
return
}
defer body.Close()
c.Header("Content-Type", contentType)
c.Header("Cache-Control", "public, max-age=31536000, immutable")
c.Status(http.StatusOK)
io.Copy(c.Writer, body)
}
func ActivePrice(c *gin.Context) {
database := c.MustGet("database").(*db.Database)
role := c.GetString("role")