package db import ( "encoding/json" "fmt" "gestion/services" "log" "time" ) func (d *Database) NotifyClient(username string, commandID int, notifType, message string) error { // Sauvegarder la notification dans Redis notifKey := fmt.Sprintf("notifications:%s", username) notification := map[string]any{ "command_id": commandID, "type": notifType, "message": message, "created_at": time.Now().Format(time.RFC3339), "read": false, } notifJSON, _ := json.Marshal(notification) Redis.LPush(RedisCtx, notifKey, notifJSON) Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour) // Diffusion Telegram si le client a lié son compte if services.TelegramBot != nil && services.TelegramBot.IsConfigured() { if chatID, ok, err := d.GetClientTelegramChatID(username); err == nil && ok { go services.TelegramBot.SendMessage(chatID, fmt.Sprintf("🔔 Notification\n\n%s", message)) } } log.Printf("📬 Notification envoyée à %s: %s", username, message) return nil } // NotifyLivreur envoie une notification in-app (Redis) à un livreur func (d *Database) NotifyLivreur(username string, commandID int, notifType, message string) error { notifKey := fmt.Sprintf("notifications:%s", username) notification := map[string]any{ "command_id": commandID, "type": notifType, "message": message, "created_at": time.Now().Format(time.RFC3339), "read": false, } notifJSON, _ := json.Marshal(notification) Redis.LPush(RedisCtx, notifKey, notifJSON) Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour) // Diffusion Telegram si le livreur a lié son compte if services.TelegramBot != nil && services.TelegramBot.IsConfigured() { if chatID, ok, err := d.GetUserTelegramChatID(username); err == nil && ok { go services.TelegramBot.SendMessage(chatID, fmt.Sprintf("🔔 Notification\n\n%s", message)) } } log.Printf("📬 [LIVREUR_NOTIF] Notification envoyée à %s: %s", username, message) return nil } // NotifyAllAdminCabine stocke une notification Redis pour tous les admins/cabines // et envoie un push aux ceux qui ont un token. Appelé dès qu'une nouvelle commande est créée. func (d *Database) NotifyAllAdminCabine(commandID int, clientUsername, deliveryAddr string) { rows, err := d.Query( `SELECT username FROM users WHERE role IN ('admin','cabine')`, ) if err != nil { log.Printf("❌ [ADMIN_NOTIF] Erreur lecture users admin/cabine: %v", err) return } defer rows.Close() msg := fmt.Sprintf("Nouvelle commande #%d de %s — %s", commandID, clientUsername, deliveryAddr) notification := map[string]any{ "command_id": commandID, "type": "new_order", "message": msg, "created_at": time.Now().Format(time.RFC3339), "read": false, } notifJSON, _ := json.Marshal(notification) count := 0 for rows.Next() { var username string if err := rows.Scan(&username); err != nil { continue } notifKey := fmt.Sprintf("notifications:%s", username) Redis.LPush(RedisCtx, notifKey, notifJSON) Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour) // Diffusion Telegram individuelle if services.TelegramBot != nil && services.TelegramBot.IsConfigured() { if chatID, ok, err := d.GetUserTelegramChatID(username); err == nil && ok { capturedChatID := chatID capturedMsg := msg go services.TelegramBot.SendMessage(capturedChatID, fmt.Sprintf("🔔 Nouvelle commande\n\n%s", capturedMsg)) } } count++ } log.Printf("📬 [ADMIN_NOTIF] Notif Redis (%d users) pour commande #%d", count, commandID) } // NotifyAllAdminCabineAlert envoie une notification Redis + push à tous les admins/cabines // lors du déclenchement d'une alerte par un livreur. func (d *Database) NotifyAllAdminCabineAlert(alertID int, livreurUsername, alertMessage string) { rows, err := d.Query( `SELECT username FROM users WHERE role IN ('admin','cabine')`, ) if err != nil { log.Printf("❌ [ALERT_NOTIF] Erreur lecture users admin/cabine: %v", err) return } defer rows.Close() body := fmt.Sprintf("%s — livreur : %s", alertMessage, livreurUsername) notification := map[string]any{ "alert_id": alertID, "type": "alert", "message": body, "created_at": time.Now().Format(time.RFC3339), "read": false, } notifJSON, _ := json.Marshal(notification) count := 0 for rows.Next() { var username string if err := rows.Scan(&username); err != nil { continue } notifKey := fmt.Sprintf("notifications:%s", username) Redis.LPush(RedisCtx, notifKey, notifJSON) Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour) // Diffusion Telegram individuelle if services.TelegramBot != nil && services.TelegramBot.IsConfigured() { if chatID, ok, err := d.GetUserTelegramChatID(username); err == nil && ok { capturedChatID := chatID capturedBody := body go services.TelegramBot.SendMessage(capturedChatID, fmt.Sprintf("🚨 Alerte livreur\n\n%s", capturedBody)) } } count++ } log.Printf("🚨 [ALERT_NOTIF] Notif Redis (%d users) pour alerte #%d de %s", count, alertID, livreurUsername) } // AddDeliveryRating ajoute une note pour un livreur func (d *Database) AddDeliveryRating(livreurUsername string, commandID, rating int, comment string) error { query := ` INSERT INTO delivery_ratings (livreur_username, command_id, rating, comment, created_at) VALUES (?, ?, ?, ?, NOW()) ` _, err := d.Exec(query, livreurUsername, commandID, rating, comment) if err != nil { log.Printf("⚠️ Erreur sauvegarde note livreur: %v", err) return err } log.Printf("⭐ Note %d/5 ajoutée pour livreur %s (commande %d)", rating, livreurUsername, commandID) return nil }