package app import ( "context" "net/http" "time" "go.uber.org/zap" "gorm.io/gorm" "api_bb/internal/config" "api_bb/internal/database" "api_bb/internal/routes" "api_bb/pkg/logger" ) type App struct { cfg *config.Config db *database.Database server *http.Server } func NewApp(cfg *config.Config) *App { return &App{ cfg: cfg, } } // Initialize инициализирует приложение (БД, миграции, роутинг) func (a *App) Initialize() error { zapLogger := logger.Get() // Инициализация базы данных dbConfig := &database.Config{ URL: a.cfg.DatabaseURL, } a.db = database.NewDatabase(dbConfig) // Подключение к БД if err := a.db.Connect(); err != nil { return err } // Проверка соединения if err := a.db.Ping(); err != nil { return err } // Выполнение миграций if err := a.db.Migrate(); err != nil { return err } // Настройка роутера router := routes.SetupRouter(a.db.DB, a.cfg) // Настройка HTTP сервера a.server = &http.Server{ Addr: ":" + a.cfg.Port, Handler: router, } zapLogger.Info("application initialized successfully") return nil } // Start запускает HTTP сервер func (a *App) Start() error { zapLogger := logger.Get() zapLogger.Info("starting HTTP server", zap.String("port", a.cfg.Port)) if err := a.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { return err } return nil } // Shutdown gracefully останавливает приложение func (a *App) Shutdown() error { zapLogger := logger.Get() zapLogger.Info("shutdown signal received") // Graceful shutdown сервера ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() a.server.SetKeepAlivesEnabled(false) if err := a.server.Shutdown(ctx); err != nil { zapLogger.Error("could not gracefully shutdown the server", zap.Error(err)) return err } // Закрытие соединения с БД if err := a.db.Close(); err != nil { return err } zapLogger.Info("application shutdown completed") return nil } // GetDB возвращает экземпляр базы данных func (a *App) GetDB() *gorm.DB { return a.db.DB }