Files
projet_gestion_commande/backend/gestion/db/redis_position.go
T

118 lines
3.6 KiB
Go

// db/redis_position.go
package db
import (
"encoding/json"
"fmt"
"gestion/models"
"log"
"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)
}
// 🔹 5️⃣ Logs anonymisés (troncature)
log.Printf("📍 Position GPS mise à jour pour %s: (lat: %.4f, lon: %.4f)", authUsername, truncate(lat), truncate(lon))
log.Printf("✅ Statut mis à jour pour %s: %s", authUsername, status)
// 🔹 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
}
// Tronque les coordonnées pour logs (4 décimales suffisent pour anonymiser)
func truncate(f float64) float64 {
return math.Round(f*10000) / 10000
}