package main import ( "context" "log" "net/http" "os" "os/signal" "syscall" "time" "customer-support-system/internal/database" "customer-support-system/internal/routes" "customer-support-system/pkg/config" "customer-support-system/pkg/logger" ) func main() { // Load configuration if err := config.LoadConfig(); err != nil { log.Fatalf("Failed to load configuration: %v", err) } // Initialize logger logger.InitLogger() // Connect to database if err := database.Connect(); err != nil { logger.WithError(err).Fatal("Failed to connect to database") } // Run migrations if err := database.AutoMigrate(); err != nil { logger.WithError(err).Fatal("Failed to run database migrations") } // Seed database with initial data if err := database.SeedDatabase(); err != nil { logger.WithError(err).Fatal("Failed to seed database") } // Set up routes router := routes.SetupRoutes() // Create HTTP server server := &http.Server{ Addr: config.AppConfig.Server.GetServerAddress(), Handler: router, ReadTimeout: config.AppConfig.Server.ReadTimeout, WriteTimeout: config.AppConfig.Server.WriteTimeout, } // Start server in a goroutine go func() { logger.WithField("address", server.Addr).Info("Starting server") if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { logger.WithError(err).Fatal("Failed to start server") } }() // Set up graceful shutdown quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit logger.Info("Shutting down server...") // Create context with timeout ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // Shutdown server if err := server.Shutdown(ctx); err != nil { logger.WithError(err).Fatal("Server forced to shutdown") } // Close database connection if err := database.Close(); err != nil { logger.WithError(err).Error("Failed to close database connection") } logger.Info("Server exited") }