// db/redis_position.go package db import ( "encoding/json" "fmt" "gestion/models" "math" "time" ) // ============================================ // GESTION DES POSITIONS GPS // ============================================ // ============================================ // LEGACY: UpdateLivreurPosition (compatibilité) // ============================================ // UpdateLivreurPosition met à jour la position GPS ET le statut du livreur (LEGACY) func (d *Database) UpdateLivreurPosition(authUsername string, lat, lon float64, status string) error { // 🔹 1️⃣ Validation du username côté serveur if authUsername == "" { return fmt.Errorf("username non fourni ou non authentifié") } // 🔹 2️⃣ Validation des coordonnées GPS if !isValidCoordinates(lat, lon) { return fmt.Errorf("coordonnées GPS invalides") } // 🔹 3️⃣ Mise à jour position GPS (Redis) positionKey := fmt.Sprintf("livreur:position:%s", authUsername) position := models.LivreurPosition{ Latitude: lat, Longitude: lon, UpdatedAt: time.Now(), Status: status, } positionData, err := json.Marshal(position) if err != nil { return fmt.Errorf("erreur serialisation position: %w", err) } if err := Redis.Set(RedisCtx, positionKey, positionData, 2*time.Hour).Err(); err != nil { return fmt.Errorf("erreur mise à jour position: %w", err) } // 🔹 4️⃣ Mise à jour statut sécurisé statusKey := fmt.Sprintf("delivery:status:%s", authUsername) var deliveryStatus models.DeliveryPersonStatus existingData, _ := Redis.Get(RedisCtx, statusKey).Result() if existingData != "" { json.Unmarshal([]byte(existingData), &deliveryStatus) deliveryStatus.Status = status deliveryStatus.LastUpdate = time.Now() } else { deliveryStatus = models.DeliveryPersonStatus{ Username: authUsername, Status: status, CurrentCommand: 0, LastUpdate: time.Now(), } } statusData, err := json.Marshal(deliveryStatus) if err != nil { return fmt.Errorf("erreur serialisation statut: %w", err) } if err := Redis.Set(RedisCtx, statusKey, statusData, 24*time.Hour).Err(); err != nil { return fmt.Errorf("erreur mise à jour statut: %w", err) } // 🔹 6️⃣ Publication événement sécurisée (à sécuriser côté subscriber) d.PublishDeliveryPersonLocationUpdate(authUsername, lat, lon) return nil } // GetLivreurPosition récupère la position d'un livreur depuis Redis (LEGACY) func (d *Database) GetLivreurPosition(authUsername string) (*models.LivreurPosition, error) { if authUsername == "" { return nil, fmt.Errorf("username non fourni ou non authentifié") } key := fmt.Sprintf("livreur:position:%s", authUsername) data, err := Redis.Get(RedisCtx, key).Result() if err != nil { return nil, fmt.Errorf("position non trouvée: %w", err) } var position models.LivreurPosition if err := json.Unmarshal([]byte(data), &position); err != nil { return nil, fmt.Errorf("erreur parsing position: %w", err) } return &position, nil } // Vérifie si la latitude et longitude sont valides func isValidCoordinates(lat, lon float64) bool { return !math.IsNaN(lat) && !math.IsNaN(lon) && lat >= -90 && lat <= 90 && lon >= -180 && lon <= 180 }