diff --git a/backend/gestion/db/db_notifications.go b/backend/gestion/db/db_notifications.go
index 148aff17..fef89dde 100644
--- a/backend/gestion/db/db_notifications.go
+++ b/backend/gestion/db/db_notifications.go
@@ -33,8 +33,11 @@ func (d *Database) NotifyClient(username string, commandID int, notifType, messa
}
notifJSON, _ := json.Marshal(notification)
- Redis.LPush(RedisCtx, notifKey, notifJSON)
- Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour)
+ pipe := Redis.Pipeline()
+ pipe.LPush(RedisCtx, notifKey, notifJSON)
+ pipe.LTrim(RedisCtx, notifKey, 0, 199)
+ pipe.Expire(RedisCtx, notifKey, 7*24*time.Hour)
+ pipe.Exec(RedisCtx) //nolint
if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
if chatID, ok, err := d.GetClientTelegramChatID(username); err == nil && ok {
@@ -64,8 +67,11 @@ func (d *Database) NotifyLivreur(username string, commandID int, notifType, mess
}
notifJSON, _ := json.Marshal(notification)
- Redis.LPush(RedisCtx, notifKey, notifJSON)
- Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour)
+ pipe2 := Redis.Pipeline()
+ pipe2.LPush(RedisCtx, notifKey, notifJSON)
+ pipe2.LTrim(RedisCtx, notifKey, 0, 199)
+ pipe2.Expire(RedisCtx, notifKey, 7*24*time.Hour)
+ pipe2.Exec(RedisCtx) //nolint
if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
if chatID, ok, err := d.GetUserTelegramChatID(username); err == nil && ok {
@@ -103,19 +109,23 @@ func (d *Database) NotifyAllAdminCabine(commandID int, clientUsername, deliveryA
}
notifJSON, _ := json.Marshal(notification)
- count := 0
+ pipe := Redis.Pipeline()
for _, u := range users {
notifKey := fmt.Sprintf("notifications:%s", u.Username)
- Redis.LPush(RedisCtx, notifKey, notifJSON)
- Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour)
+ pipe.LPush(RedisCtx, notifKey, notifJSON)
+ pipe.LTrim(RedisCtx, notifKey, 0, 199)
+ pipe.Expire(RedisCtx, notifKey, 7*24*time.Hour)
+ }
+ pipe.Exec(RedisCtx) //nolint
- if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
+ count := len(users)
+ if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
+ for _, u := range users {
if chatID, ok, err := d.GetUserTelegramChatID(u.Username); err == nil && ok {
capturedChatID := chatID
go sendTelegramNotif(capturedChatID, fmt.Sprintf("🔔 Nouvelle commande\n\n%s", msg))
}
}
- count++
}
log.Printf("📬 [ADMIN_NOTIF] Notif Redis (%d users) pour commande #%d", count, commandID)
}
@@ -141,19 +151,23 @@ func (d *Database) NotifyAllAdminCabineAlert(alertID int, livreurUsername, alert
}
notifJSON, _ := json.Marshal(notification)
- count := 0
+ pipe := Redis.Pipeline()
for _, u := range users {
notifKey := fmt.Sprintf("notifications:%s", u.Username)
- Redis.LPush(RedisCtx, notifKey, notifJSON)
- Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour)
+ pipe.LPush(RedisCtx, notifKey, notifJSON)
+ pipe.LTrim(RedisCtx, notifKey, 0, 199)
+ pipe.Expire(RedisCtx, notifKey, 7*24*time.Hour)
+ }
+ pipe.Exec(RedisCtx) //nolint
- if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
+ count := len(users)
+ if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
+ for _, u := range users {
if chatID, ok, err := d.GetUserTelegramChatID(u.Username); err == nil && ok {
capturedChatID := chatID
go sendTelegramNotif(capturedChatID, fmt.Sprintf("🚨 Alerte livreur\n\n%s", body))
}
}
- count++
}
log.Printf("🚨 [ALERT_NOTIF] Notif Redis (%d users) pour alerte #%d de %s", count, alertID, livreurUsername)
}
diff --git a/backend/gestion/db/redis_queue_clean_up.go b/backend/gestion/db/redis_queue_clean_up.go
index 9b5fb81f..36904a35 100644
--- a/backend/gestion/db/redis_queue_clean_up.go
+++ b/backend/gestion/db/redis_queue_clean_up.go
@@ -13,7 +13,7 @@ import (
func (d *Database) CleanupInvalidQueueCommands() (int, error) {
log.Println("🧹 [CLEANUP] Démarrage du nettoyage des commandes invalides...")
- keys, err := Redis.Keys(RedisCtx, "queue:pending:*").Result()
+ keys, err := scanRedisKeys("queue:pending:*")
if err != nil {
return 0, fmt.Errorf("erreur récupération des clés: %w", err)
}
@@ -94,7 +94,7 @@ func (d *Database) removeInvalidCommand(key string, commandID int, reason string
Redis.ZRem(RedisCtx, "queue:priority:sorted", commandIDStr)
// 3. Supprimer des queues de livreurs
- livreurKeys, _ := Redis.Keys(RedisCtx, "queue:deliveryman:*").Result()
+ livreurKeys, _ := scanRedisKeys("queue:deliveryman:*")
for _, queueKey := range livreurKeys {
if len(queueKey) > 6 && queueKey[len(queueKey)-6:] == ":count" {
continue
diff --git a/backend/gestion/db/redis_queue_info.go b/backend/gestion/db/redis_queue_info.go
index 5a27b350..7a518981 100644
--- a/backend/gestion/db/redis_queue_info.go
+++ b/backend/gestion/db/redis_queue_info.go
@@ -68,8 +68,9 @@ func (d *Database) GetAllQueuesOverview() (map[string]any, error) {
overview["general_queue"] = generalQueueSize
deliverymanQueues := make(map[string]any)
- keys, _ := Redis.Keys(RedisCtx, "queue:deliveryman:*").Result()
+ keys, _ := scanRedisKeys("queue:deliveryman:*")
+ var totalPending int64 = generalQueueSize
for _, key := range keys {
if len(key) > 6 && key[len(key)-6:] == ":count" {
continue
@@ -83,16 +84,7 @@ func (d *Database) GetAllQueuesOverview() (map[string]any, error) {
"can_accept_more": queueSize < MAX_COMMANDS_PER_DELIVERYMAN,
"capacity": fmt.Sprintf("%d/%d", queueSize, MAX_COMMANDS_PER_DELIVERYMAN),
}
- }
-
- overview["deliveryman_queues"] = deliverymanQueues
- var totalPending int64 = generalQueueSize
- for _, key := range keys {
- if len(key) > 6 && key[len(key)-6:] == ":count" {
- continue
- }
- size, _ := Redis.ZCard(RedisCtx, key).Result()
- totalPending += size
+ totalPending += queueSize
}
overview["total_pending"] = totalPending
@@ -105,7 +97,7 @@ func (d *Database) GetQueueStats() (map[string]any, error) {
priorityCount, _ := Redis.ZCard(RedisCtx, "queue:priority:sorted").Result()
var deliverymanQueueCount int64
- keys, _ := Redis.Keys(RedisCtx, "queue:deliveryman:*").Result()
+ keys, _ := scanRedisKeys("queue:deliveryman:*")
for _, key := range keys {
if len(key) > 6 && key[len(key)-6:] == ":count" {
continue
@@ -117,7 +109,8 @@ func (d *Database) GetQueueStats() (map[string]any, error) {
var totalWaitTime int64
var commandCount int64
- normalResults, _ := Redis.ZRangeWithScores(RedisCtx, "queue:pending:sorted", 0, -1).Result()
+ // Limité aux 100 premières entrées pour ne pas bloquer Redis sur une grande queue
+ normalResults, _ := Redis.ZRangeWithScores(RedisCtx, "queue:pending:sorted", 0, 99).Result()
for _, result := range normalResults {
commandID := extractCommandID(result.Member)
if commandID <= 0 {
diff --git a/backend/gestion/db/redis_queue_management.go b/backend/gestion/db/redis_queue_management.go
index ae5097ce..4d46d060 100644
--- a/backend/gestion/db/redis_queue_management.go
+++ b/backend/gestion/db/redis_queue_management.go
@@ -153,7 +153,7 @@ func (d *Database) RemoveCommandFromQueue(commandID int) error {
pipe.ZRem(RedisCtx, "queue:priority:sorted", commandIDStr)
// Trouver et retirer de la queue du livreur
- keys, _ := Redis.Keys(RedisCtx, "queue:deliveryman:*").Result()
+ keys, _ := scanRedisKeys("queue:deliveryman:*")
var affectedDeliveryman string
for _, queueKey := range keys {
@@ -303,7 +303,7 @@ func (d *Database) SyncAllDeliverymanStatuses() error {
// iterDeliveryStatuses itère sur tous les statuts Redis des livreurs et appelle fn pour chacun.
func (d *Database) iterDeliveryStatuses(fn func(models.DeliveryPersonStatus)) error {
- keys, err := Redis.Keys(RedisCtx, "delivery:status:*").Result()
+ keys, err := scanRedisKeys("delivery:status:*")
if err != nil {
return err
}
@@ -320,3 +320,21 @@ func (d *Database) iterDeliveryStatuses(fn func(models.DeliveryPersonStatus)) er
}
return nil
}
+
+// scanRedisKeys remplace KEYS * par SCAN pour ne pas bloquer Redis.
+func scanRedisKeys(pattern string) ([]string, error) {
+ var all []string
+ cursor := uint64(0)
+ for {
+ batch, next, err := Redis.Scan(RedisCtx, cursor, pattern, 200).Result()
+ if err != nil {
+ return nil, err
+ }
+ all = append(all, batch...)
+ cursor = next
+ if cursor == 0 {
+ break
+ }
+ }
+ return all, nil
+}
diff --git a/backend/gestion/handlers/auth.go b/backend/gestion/handlers/auth.go
index ff51915e..03eee1fc 100644
--- a/backend/gestion/handlers/auth.go
+++ b/backend/gestion/handlers/auth.go
@@ -838,6 +838,14 @@ func CreateUser(c *gin.Context) {
return
}
+ hashed, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
+ if err != nil {
+ log.Printf("❌ [CREATE_USER] Erreur bcrypt: %v", err)
+ c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur traitement mot de passe"})
+ return
+ }
+ user.Password = string(hashed)
+
if err := database.CreateUser(&user); err != nil {
log.Printf("❌ [CREATE_USER] Erreur: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur création"})