// ============================================ // main.go - VERSION SIMPLIFIÉE AVEC CLEANUP AUTO // ============================================ package main import ( "gestion/db" "gestion/routes" "gestion/services" "gestion/workers" "log" "net/http" "os" "github.com/gin-contrib/cors" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" "github.com/joho/godotenv" ) func main() { // Chargement des variables d'environnement if err := godotenv.Load(); err != nil { log.Println("⚠️ Aucun fichier .env trouvé, utilisation des valeurs par défaut.") } // Initialisation de la base de données database := db.InitDB() defer database.Close() log.Printf("✅ Database initialisée: %+v", database) // Initialisation de Redis db.InitRedis() defer db.Redis.Close() log.Println("✅ Redis initialisé avec succès") // Initialisation du service de géolocalisation geoService := services.NewGeoService(db.Redis, db.RedisCtx) log.Println("✅ Service de géolocalisation initialisé") // ============================================ // 🧹 NETTOYAGE INITIAL DES COMMANDES INVALIDES // ============================================ log.Println("") log.Println("🧹 Démarrage du nettoyage des commandes invalides...") removed, err := database.CleanupInvalidQueueCommands() if err != nil { log.Printf("❌ Erreur lors du nettoyage initial: %v", err) } else { if removed > 0 { log.Printf("✅ Nettoyage initial terminé: %d commandes invalides supprimées", removed) } else { log.Println("✅ Nettoyage initial: Aucune commande invalide trouvée") } } // ============================================ // 🔄 DÉMARRAGE DU SCHEDULER DE NETTOYAGE AUTO // ============================================ go database.StartQueueCleanupScheduler() log.Println("✅ Scheduler de nettoyage démarré (toutes les 5 min)") // ============================================ // 🔄 SYNCHRONISATION DES STATUTS LIVREURS // ============================================ if err := database.SyncAllDeliverymanStatuses(); err != nil { log.Printf("⚠️ Erreur synchronisation statuts: %v", err) } else { log.Println("✅ Synchronisation des statuts livreurs terminée") } // ============================================ // ⭐ DÉMARRAGE DU CRON JOB AUTO-ASSIGNATION // ============================================ go workers.StartAutoAssignmentCron(database, geoService) log.Println("✅ Cron job auto-assignation démarré (5 min)") // Démarrage des workers Redis en arrière-plan go workers.StartRedisWorkers(database) log.Println("✅ Workers Redis démarrés") gin.SetMode(gin.ReleaseMode) r := gin.Default() // Configuration des sessions store := cookie.NewStore([]byte(os.Getenv("SESSION_SECRET"))) store.Options(sessions.Options{ Path: "/", Domain: "", MaxAge: 3600, HttpOnly: true, Secure: true, SameSite: http.SameSiteStrictMode, }) r.Use(sessions.Sessions("mysession", store)) // Configuration CORS r.Use(cors.New(cors.Config{ AllowOrigins: []string{"https://uber-stup.club", "http://localhost:5173"}, AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, AllowHeaders: []string{"Origin", "Content-Type", "Accept", "Authorization"}, ExposeHeaders: []string{"Content-Length"}, AllowCredentials: true, })) // Middleware pour injecter la base de données et geoService r.Use(func(c *gin.Context) { c.Set("database", database) c.Set("geoService", geoService) c.Next() }) // Fichiers statiques r.Static("/uploads", "./uploads") // ============================================ // ENREGISTRER TOUTES LES ROUTES // ============================================ routes.SetupRoutes(r, database, geoService) // ============================================ // LANCEMENT DU SERVEUR // ============================================ printServerInfo() if err := r.Run(":8080"); err != nil { log.Fatalf("❌ Erreur au lancement du serveur : %v", err) } } // printServerInfo affiche les infos du serveur au démarrage func printServerInfo() { log.Println("") log.Println("═══════════════════════════════════════════════════════════") log.Println("🚀 Serveur lancé sur http://localhost:8080") log.Println("═══════════════════════════════════════════════════════════") log.Println("") log.Println("📡 API Endpoints disponibles:") log.Println("") log.Println(" 🌍 PUBLIC:") log.Println(" GET /api/v1/health - Health check") log.Println(" GET /api/v1/products - Liste produits") log.Println("") log.Println(" 👤 CLIENTS:") log.Println(" POST /api/v1/auth/register - Inscription") log.Println(" POST /api/v1/auth/login - Connexion") log.Println(" POST /api/v1/checkout - ✅ PASSER COMMANDE (avec auto-assign)") log.Println(" GET /api/v1/my-commands - Mes commandes avec suivi") log.Println(" GET /api/v1/commands/:id/status - ✅ Statut temps réel") log.Println(" GET /api/v1/commands/:id/tracking - ✅ Suivi détaillé") log.Println(" POST /api/v1/commands/:id/approve - Confirmer livraison") log.Println("") log.Println(" 🚗 LIVREURS:") log.Println(" GET /api/v1/livreur/deliveries - ✅ Mes livraisons (SANS téléphone client)") log.Println(" GET /api/v1/livreur/deliveries/:id - ✅ Détail livraison filtrée") log.Println(" PUT /api/v1/livreur/deliveries/:id/status - MAJ statut (avec GPS)") log.Println(" POST /api/v1/livreur/location/update - MAJ position GPS") log.Println(" GET /api/v1/livreur/queue - Ma queue de livraisons") log.Println("") log.Println(" 🔐 ADMIN:") log.Println(" POST /api/v2/admin/auth/login - Connexion admin") log.Println(" GET /api/v2/admin/protected/orders - Toutes les commandes") log.Println(" POST /api/v2/admin/protected/orders/:id/auto-assign - ✅ Auto-assign GPS") log.Println(" POST /api/v2/admin/protected/commands/auto-assign-all - ✅ Assigner toutes") log.Println(" GET /api/v2/admin/protected/delivery/queues - Queues livreurs") log.Println("") log.Println("⏰ Workers & Services actifs:") log.Println(" - ✅ AutoAssignmentCron (5min) - Assignation backup") log.Println(" - ✅ QueueCleanupScheduler (5min) - 🧹 Nettoyage commandes invalides") log.Println(" - ✅ NotificationWorker (30s) - Notifications ETA") log.Println(" - ✅ StockCleanupWorker (5min) - Nettoyage stock") log.Println("") log.Println("🎯 Fonctionnalités activées:") log.Println(" 1. ✅ Auto-assignation au checkout (immédiate)") log.Println(" 2. ✅ Cron job backup (toutes les 5 min)") log.Println(" 3. ✅ Validation stricte avant ajout à la queue") log.Println(" 4. ✅ Nettoyage automatique des commandes invalides") log.Println(" 5. ✅ Vue livreur filtrée (sans téléphone)") log.Println(" 6. ✅ Vue client avec suivi temps réel") log.Println(" 7. ✅ Gestion automatique statut BUSY (queue >= 10)") log.Println("") log.Println("🔒 Règles de validation automatique:") log.Println(" - Username non vide ✓") log.Println(" - Adresse de livraison non vide ✓") log.Println(" - Coordonnées GPS valides (lat != 0, lng != 0) ✓") log.Println(" - Date de création valide ✓") log.Println(" - Prix total > 0 (recommandé) ✓") log.Println("") log.Println("═══════════════════════════════════════════════════════════") log.Println("") }