201 lines
6.2 KiB
Go
201 lines
6.2 KiB
Go
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() {
|
||
if loc, err := time.LoadLocation("Europe/Paris"); err == nil {
|
||
time.Local = loc
|
||
} else {
|
||
log.Printf("⚠️ Impossible de charger la timezone Europe/Paris: %v", err)
|
||
}
|
||
|
||
if err := godotenv.Load(); err != nil {
|
||
log.Println("⚠️ Aucun fichier .env trouvé, utilisation des valeurs par défaut.")
|
||
}
|
||
|
||
database := db.InitDB()
|
||
defer database.Close()
|
||
log.Printf("✅ Database initialisée: %+v", database)
|
||
db.InitRedis()
|
||
defer db.Redis.Close()
|
||
log.Println("✅ Redis initialisé avec succès")
|
||
|
||
geoService := services.NewGeoService(db.Redis, db.RedisCtx)
|
||
log.Println("✅ Service de géolocalisation initialisé")
|
||
|
||
lbService := services.NewLBTelegramService()
|
||
if lbService.IsConfigured() {
|
||
log.Println("✅ Service LBTelegram initialisé")
|
||
} else {
|
||
log.Println("ℹ️ Service LBTelegram désactivé (LBTELEGRAM_URL non défini)")
|
||
}
|
||
|
||
telegramService := services.NewTelegramService()
|
||
if telegramService.IsConfigured() {
|
||
log.Println("✅ Service Telegram initialisé")
|
||
if webhookURL := os.Getenv("TELEGRAM_WEBHOOK_URL"); webhookURL != "" {
|
||
if err := telegramService.SetWebhook(webhookURL); err != nil {
|
||
log.Printf("⚠️ [TELEGRAM] Erreur enregistrement webhook: %v", err)
|
||
}
|
||
}
|
||
} else {
|
||
log.Println("ℹ️ Service Telegram désactivé (TELEGRAM_BOT_TOKEN non défini)")
|
||
}
|
||
|
||
database.MigrateAddTelegramColumns()
|
||
|
||
if dbSettings, err := database.GetSettings(); err == nil {
|
||
telegramService.Reload(dbSettings.TelegramBotToken, dbSettings.TelegramBotUsername)
|
||
telegramService.SetNotificationsEnabled(dbSettings.TelegramNotificationsEnabled)
|
||
if dbSettings.TelegramBotToken != "" {
|
||
log.Printf("✅ [TELEGRAM] Config chargée depuis la DB (username: %s)", dbSettings.TelegramBotUsername)
|
||
if webhookURL := os.Getenv("TELEGRAM_WEBHOOK_URL"); webhookURL != "" {
|
||
if err := telegramService.SetWebhook(webhookURL); err != nil {
|
||
log.Printf("⚠️ [TELEGRAM] Erreur enregistrement webhook (DB reload): %v", err)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Ré-enrôler tous les comptes déjà liés dans lbtelegram (au cas où lbtelegram a redémarré)
|
||
if lbService.IsConfigured() {
|
||
go func() {
|
||
accounts, err := database.GetAllLinkedTelegramAccounts()
|
||
if err != nil {
|
||
log.Printf("⚠️ [LB_SYNC] Erreur lecture comptes liés: %v", err)
|
||
return
|
||
}
|
||
ok, fail := 0, 0
|
||
for _, a := range accounts {
|
||
if err := lbService.EnrollUser(a.ChatID, a.Username, a.Role); err != nil {
|
||
fail++
|
||
} else {
|
||
ok++
|
||
}
|
||
}
|
||
log.Printf("✅ [LB_SYNC] Re-enrollment terminé: %d OK, %d échecs (total %d comptes)", ok, fail, len(accounts))
|
||
}()
|
||
}
|
||
|
||
s3Service, err := services.NewS3Service(
|
||
os.Getenv("S3_REGION"),
|
||
os.Getenv("S3_BUCKET"),
|
||
os.Getenv("S3_ENDPOINT"),
|
||
services.S3Credentials{
|
||
S3KeyId: os.Getenv("RUSTFS_ACCESS_KEY"),
|
||
S3AccessKey: os.Getenv("RUSTFS_SECRET_KEY"),
|
||
},
|
||
)
|
||
if err != nil {
|
||
log.Fatalf("erreur init S3: %v", err)
|
||
}
|
||
|
||
var storage services.Storage
|
||
switch os.Getenv("STORAGE_DRIVER") {
|
||
case "s3":
|
||
storage = services.NewS3Storage(s3Service)
|
||
log.Println("✅ Storage driver: s3 (RustFS)")
|
||
default:
|
||
storage = services.NewLocalStorage("uploads")
|
||
log.Println("✅ Storage driver: local")
|
||
}
|
||
|
||
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")
|
||
}
|
||
}
|
||
|
||
go database.StartQueueCleanupScheduler()
|
||
log.Println("✅ Scheduler de nettoyage démarré (toutes les 5 min)")
|
||
|
||
if err := database.SyncAllDeliverymanStatuses(); err != nil {
|
||
log.Printf("⚠️ Erreur synchronisation statuts: %v", err)
|
||
} else {
|
||
log.Println("✅ Synchronisation des statuts livreurs terminée")
|
||
}
|
||
|
||
go workers.StartAutoAssignmentCron(database, geoService)
|
||
log.Println("✅ Cron job auto-assignation démarré (5 min)")
|
||
|
||
go workers.StartRedisWorkers(database)
|
||
log.Println("✅ Workers Redis démarrés")
|
||
|
||
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()
|
||
|
||
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))
|
||
|
||
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,
|
||
}))
|
||
|
||
r.Use(func(c *gin.Context) {
|
||
c.Set("database", database)
|
||
c.Set("geoService", geoService)
|
||
c.Set("s3Service", s3Service)
|
||
c.Set("storage", storage)
|
||
c.Next()
|
||
})
|
||
|
||
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()
|
||
})
|
||
|
||
r.Static("/uploads", "./uploads")
|
||
|
||
routes.SetupRoutes(r, database, geoService, s3Service)
|
||
|
||
if err := r.Run(":8080"); err != nil {
|
||
log.Fatalf("❌ Erreur au lancement du serveur : %v", err)
|
||
}
|
||
}
|