veza/veza-backend-api/cmd/modern-server/main.go
2025-12-03 20:29:37 +01:00

142 lines
4.6 KiB
Go

package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/gin-gonic/gin"
"github.com/joho/godotenv"
"go.uber.org/zap"
"veza-backend-api/internal/api"
// TODO: Réactiver internal/api/handlers après stabilisation du noyau
// "veza-backend-api/internal/api/handlers"
"veza-backend-api/internal/config"
// TODO: Réactiver services après stabilisation du noyau
// "veza-backend-api/internal/services"
)
func main() {
// Charger les variables d'environnement depuis le fichier .env
if err := godotenv.Load(); err != nil {
log.Printf("⚠️ Impossible de charger le fichier .env: %v", err)
}
// Configuration du logger
logger, err := zap.NewProduction()
if err != nil {
log.Fatalf("Impossible d'initialiser le logger: %v", err)
}
defer logger.Sync()
logger.Info("🚀 Démarrage du serveur Veza Backend API (Architecture Moderne)")
// Charger la configuration
cfg, err := config.NewConfig()
if err != nil {
logger.Fatal("❌ Impossible de charger la configuration", zap.Error(err))
}
// Valider la configuration
if err := cfg.Validate(); err != nil {
logger.Fatal("❌ Configuration invalide", zap.Error(err))
}
logger.Info("✅ Configuration validée avec succès")
// La base de données est déjà initialisée dans config.NewConfig()
db := cfg.Database
if db == nil {
logger.Fatal("❌ Base de données non initialisée")
}
defer db.Close()
// Initialiser la base de données (migrations, etc.)
if err := db.Initialize(); err != nil {
logger.Fatal("❌ Impossible d'initialiser la base de données", zap.Error(err))
}
// TODO: Réactiver les services après stabilisation du noyau et alignement des signatures
// Initialiser les services
// authService := services.NewAuthService(db, &cfg.JWT, logger)
// oauthService := services.NewOAuthService(db, cfg, logger)
// chatService := services.NewChatService(db, logger)
// twoFactorService := services.NewTwoFactorService(db, logger)
// rbacService := services.NewRBACService(db, logger)
// TODO: Réactiver les handlers après stabilisation du noyau et alignement des services
// Initialiser les handlers
// handlers.InitHandlers(authService, logger)
// handlers.InitOAuthHandlers(oauthService, authService, logger)
// handlers.InitChatHandlers(chatService, logger)
// handlers.InitTwoFactorHandlers(twoFactorService, authService, logger)
// handlers.InitRBACHandlers(rbacService, logger)
// Configuration de Gin selon l'environnement
gin.SetMode(gin.DebugMode) // TODO: Utiliser cfg.LogLevel pour déterminer le mode
// Créer le router Gin
router := gin.New()
// Configuration des routes avec la nouvelle architecture
apiRouter := api.NewAPIRouter(db, cfg) // Instantiate APIRouter
apiRouter.Setup(router) // Call its Setup method
// Configuration du serveur HTTP
port := fmt.Sprintf("%d", cfg.AppPort)
if port == "0" {
port = "8080"
}
server := &http.Server{
Addr: fmt.Sprintf(":%s", port),
Handler: router,
// TODO: Ajouter ReadTimeout et WriteTimeout si nécessaire
}
// Canal pour écouter les signaux du système
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
// Démarrer le serveur dans une goroutine
go func() {
logger.Info("🌐 Serveur HTTP démarré",
zap.String("port", port),
)
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logger.Fatal("❌ Erreur du serveur HTTP", zap.Error(err))
}
}()
logger.Info("✅ Serveur Veza Backend API prêt à recevoir des requêtes")
logger.Info("📋 Endpoints disponibles:")
logger.Info(" - GET /health - Health check global")
logger.Info(" - POST /api/v1/auth/register - Inscription utilisateur")
logger.Info(" - POST /api/v1/auth/login - Connexion utilisateur")
logger.Info(" - POST /api/v1/auth/refresh - Renouvellement de token")
logger.Info(" - POST /api/v1/auth/logout - Déconnexion utilisateur")
logger.Info(" - GET /api/v1/profile - Profil utilisateur")
logger.Info(" - PUT /api/v1/profile - Mise à jour profil")
logger.Info(" - GET /api/v1/health/detailed - Health check détaillé")
// Attendre un signal d'arrêt
<-quit
logger.Info("🔄 Arrêt du serveur en cours...")
// Créer un contexte avec timeout pour l'arrêt gracieux
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) // TODO: Utiliser config pour timeout
defer cancel()
// Arrêt gracieux du serveur
if err := server.Shutdown(ctx); err != nil {
logger.Error("❌ Erreur lors de l'arrêt du serveur", zap.Error(err))
} else {
logger.Info("✅ Serveur arrêté proprement")
}
}