package app import ( "backend/config" "backend/internal/repository/cache" "backend/internal/repository/storage" "backend/internal/repository/storage/types" "backend/internal/usecase" cachePackage "backend/pkg/cache" "backend/pkg/postgres" "fmt" "log" "gorm.io/gorm" ) type AppContainer struct { cfg config.Config dbConn *gorm.DB redis *cachePackage.Redis authService usecase.AuthService } func NewAppContainer(cfg config.Config) (*AppContainer, error) { dbOptions := postgres.DBConnOptions{ User: cfg.DB.User, Pass: cfg.DB.Pass, Host: cfg.DB.Host, Port: uint(cfg.DB.Port), DBName: cfg.DB.DBName, } dbConn, err := postgres.NewPsqlGormConnection(dbOptions) if err != nil { return nil, fmt.Errorf("failed to connect to database: %w", err) } dbConn.AutoMigrate(&types.User{}) redis, err := cachePackage.NewRedis(cfg.Redis) if err != nil { return nil, fmt.Errorf("failed to connect to Redis: %w", err) } userRepo := storage.NewUserRepository(dbConn) sessionRepo := cache.NewSessionRepository(redis) challengeRepo := cache.NewChallengeRepository(redis) authService := usecase.NewAuthService( userRepo, sessionRepo, challengeRepo, 30, cfg.JWT, ) return &AppContainer{ cfg: cfg, dbConn: dbConn, redis: redis, authService: authService, }, nil } func (app *AppContainer) AuthService() usecase.AuthService { return app.authService } func (app *AppContainer) Close() { if app.redis != nil { if err := app.redis.Close(); err != nil { log.Printf("Error closing Redis connection: %v", err) } } if app.dbConn != nil { if sqlDB, err := app.dbConn.DB(); err == nil { if err := sqlDB.Close(); err != nil { log.Printf("Error closing database connection: %v", err) } } } }