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

This commit is contained in:
2026-06-30 22:06:55 +02:00
parent 07936f0bf6
commit a95ee51f6c
4 changed files with 69 additions and 12 deletions
+25 -1
View File
@@ -1,6 +1,7 @@
package db
import (
"encoding/json"
"fmt"
"gestion/models"
"log"
@@ -424,9 +425,28 @@ func (d *Database) GetCommandByID(id int) (map[string]any, error) {
return command, nil
}
const lastDeliveryCoordsCacheTTL = 5 * time.Minute
func lastDeliveryCoordsCacheKey(livreurUsername string) string {
return fmt.Sprintf("livreur:last_delivery_coords:%s", livreurUsername)
}
// GetLastDeliveryCoords retourne les coordonnées GPS de la dernière livraison terminée d'un livreur.
// Utilisé comme fallback quand le GPS temps réel est indisponible.
// Utilisé comme fallback quand le GPS temps réel est indisponible. Mis en cache quelques minutes
// car appelé à chaque calcul d'ETA et la dernière livraison ne change pas souvent.
func (d *Database) GetLastDeliveryCoords(livreurUsername string) (float64, float64, error) {
cacheKey := lastDeliveryCoordsCacheKey(livreurUsername)
if cached, err := Redis.Get(RedisCtx, cacheKey).Result(); err == nil {
var coords struct {
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
}
if jsonErr := json.Unmarshal([]byte(cached), &coords); jsonErr == nil {
return coords.Lat, coords.Lon, nil
}
}
var result struct {
DestLatitude float64 `gorm:"column:dest_latitude"`
DestLongitude float64 `gorm:"column:dest_longitude"`
@@ -446,6 +466,10 @@ func (d *Database) GetLastDeliveryCoords(livreurUsername string) (float64, float
return 0, 0, fmt.Errorf("coordonnées introuvables pour dernière livraison de %s", livreurUsername)
}
if coordsJSON, err := json.Marshal(map[string]float64{"lat": result.DestLatitude, "lon": result.DestLongitude}); err == nil {
Redis.Set(RedisCtx, cacheKey, coordsJSON, lastDeliveryCoordsCacheTTL)
}
return result.DestLatitude, result.DestLongitude, nil
}
+5
View File
@@ -304,6 +304,11 @@ func InitDB() *Database {
log.Fatalf("❌ Erreur migration clients.parrain: %v", err)
}
// Migration: index sur clients.parrain (lookups filleuls + stats parrainage)
if _, err = database.Exec(`CREATE INDEX IF NOT EXISTS idx_clients_parrain ON clients(parrain) WHERE parrain IS NOT NULL`); err != nil {
log.Fatalf("❌ Erreur migration idx_clients_parrain: %v", err)
}
// Lancer le nettoyage périodique des tokens expirés
go database.cleanExpiredTokensPeriodically()
+30
View File
@@ -4,6 +4,8 @@ import (
"database/sql"
"fmt"
"gestion/models"
"gorm.io/gorm"
)
func (d *Database) SetClientParrain(clientUsername, parrainUsername string) error {
@@ -19,6 +21,34 @@ func (d *Database) SetClientParrain(clientUsername, parrainUsername string) erro
return nil
}
// SetClientParrainAndCredit assigne un parrain à un client et crédite le parrain
// dans une seule transaction, pour éviter un lien parrain enregistré sans le crédit associé.
func (d *Database) SetClientParrainAndCredit(clientUsername, parrainUsername string, creditAmount float64) error {
return d.GDB.Transaction(func(tx *gorm.DB) error {
result := tx.Model(&models.Client{}).
Where("username = ? AND (parrain IS NULL OR parrain = '')", clientUsername).
Update("parrain", parrainUsername)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("client introuvable ou parrain déjà défini")
}
if creditAmount > 0 {
result = tx.Model(&models.Client{}).Where("username = ?", parrainUsername).
Updates(map[string]any{"referral_balance": gorm.Expr("referral_balance + ?", creditAmount)})
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("parrain non trouvé")
}
}
return nil
})
}
func (d *Database) GetClientParrain(clientUsername string) (string, error) {
var parrain sql.NullString
err := d.GDB.Table("clients").
+9 -11
View File
@@ -46,25 +46,23 @@ func SetClientParrainAdmin(c *gin.Context) {
return
}
if err := database.SetClientParrain(targetUsername, req.Parrain); err != nil {
settings, _ := database.GetSettings()
creditAmount := 0.0
if settings.ReferralEnabled && settings.ReferralAmount > 0 {
creditAmount = settings.ReferralAmount
}
if err := database.SetClientParrainAndCredit(targetUsername, req.Parrain, creditAmount); err != nil {
utils.ServerErr(c, "Erreur enregistrement parrain", err)
return
}
settings, _ := database.GetSettings()
if settings.ReferralEnabled && settings.ReferralAmount > 0 {
if err := database.CreditClientReferral(req.Parrain, settings.ReferralAmount); err != nil {
log.Printf("⚠️ [PARRAIN] Impossible de créditer %s: %v", req.Parrain, err)
} else {
log.Printf("✅ [PARRAIN] %s parrainé par %s → +%.2f€ crédité", targetUsername, req.Parrain, settings.ReferralAmount)
}
}
log.Printf("✅ [PARRAIN] %s parrainé par %s → +%.2f€ crédité", targetUsername, req.Parrain, creditAmount)
c.JSON(http.StatusOK, gin.H{
"message": "Parrain enregistré",
"client": targetUsername,
"parrain": req.Parrain,
"amount_credited": settings.ReferralAmount,
"amount_credited": creditAmount,
})
}