package main import ( "context" "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" "github.com/bams/backend/internal/api" "github.com/bams/backend/internal/config" "github.com/bams/backend/internal/logger" "github.com/bams/backend/internal/services" ) func main() { // Load configuration cfg, err := config.Load() if err != nil { log.Fatalf("Failed to load configuration: %v", err) } // Initialize logger logger := logger.New(cfg.LogLevel) // Initialize services svcManager := services.NewServiceManager(cfg, logger) // Initialize API router router := api.NewRouter(svcManager, logger) // Create HTTP server srv := &http.Server{ Addr: fmt.Sprintf(":%d", cfg.Port), Handler: router, ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 60 * time.Second, } // Start server in goroutine go func() { logger.Info("Starting BAMS backend server", "port", cfg.Port) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { logger.Error("Server failed to start", "error", err) os.Exit(1) } }() // Graceful shutdown quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit logger.Info("Shutting down server...") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { logger.Error("Server forced to shutdown", "error", err) } svcManager.Shutdown() logger.Info("Server exited") }