220 lines
8.9 KiB
Go
220 lines
8.9 KiB
Go
// ============================================
|
|
// main.go - VERSION SIMPLIFIÉE AVEC CLEANUP AUTO
|
|
// ============================================
|
|
|
|
package main
|
|
|
|
import (
|
|
"gestion/db"
|
|
"gestion/routes"
|
|
"gestion/services"
|
|
"gestion/workers"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
"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() {
|
|
// Forcer la timezone Europe/Paris (UTC+1/+2)
|
|
if loc, err := time.LoadLocation("Europe/Paris"); err == nil {
|
|
time.Local = loc
|
|
} else {
|
|
log.Printf("⚠️ Impossible de charger la timezone Europe/Paris: %v", err)
|
|
}
|
|
|
|
// 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")
|
|
|
|
// Worker de vérification des paiements crypto (recharge les clés dynamiquement)
|
|
workers.StartDynamicPaymentChecker(database, func() *services.NowPaymentsClient {
|
|
s, err := database.GetSettings()
|
|
if err != nil || !s.CryptoPaymentEnabled || s.NowPaymentsAPIKey == "" {
|
|
return nil
|
|
}
|
|
return services.NewNowPaymentsClient(s.NowPaymentsAPIKey, s.NowPaymentsIPNSecret)
|
|
}, 2*time.Minute)
|
|
log.Println("✅ Worker paiements crypto démarré (2 min)")
|
|
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", "https://5.181.0.112.nip.io", "https://5.181.0.112.nip.io:8080", "https://5.181.0.112.nip.io:8443", "https://mln-uber.club", "http://localhost:5173", "http://5.181.0.112"},
|
|
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
|
|
AllowHeaders: []string{"Origin", "Content-Type", "Accept", "Authorization", "X-Request-ID"},
|
|
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()
|
|
})
|
|
|
|
// Middleware NowPayments : injecte le client si crypto activé dans les settings
|
|
r.Use(func(c *gin.Context) {
|
|
settings, err := database.GetSettings()
|
|
if err == nil && settings.CryptoPaymentEnabled && settings.NowPaymentsAPIKey != "" {
|
|
np := services.NewNowPaymentsClient(settings.NowPaymentsAPIKey, settings.NowPaymentsIPNSecret)
|
|
c.Set("nowpayments", np)
|
|
}
|
|
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("")
|
|
}
|