package app import ( "net/http" "tercul/auth" "tercul/config" "tercul/graph" "tercul/linguistics" "tercul/logger" "tercul/syncjob" "github.com/99designs/gqlgen/graphql/playground" "github.com/hibiken/asynq" ) // ServerFactory handles the creation of HTTP and background job servers type ServerFactory struct { appBuilder *ApplicationBuilder } // NewServerFactory creates a new ServerFactory func NewServerFactory(appBuilder *ApplicationBuilder) *ServerFactory { return &ServerFactory{ appBuilder: appBuilder, } } // CreateGraphQLServer creates and configures the GraphQL server func (f *ServerFactory) CreateGraphQLServer() (*http.Server, error) { logger.LogInfo("Setting up GraphQL server") // Create GraphQL resolver with all dependencies resolver := &graph.Resolver{ WorkRepo: f.appBuilder.GetRepositories().WorkRepository, UserRepo: f.appBuilder.GetRepositories().UserRepository, AuthorRepo: f.appBuilder.GetRepositories().AuthorRepository, TranslationRepo: f.appBuilder.GetRepositories().TranslationRepository, CommentRepo: f.appBuilder.GetRepositories().CommentRepository, LikeRepo: f.appBuilder.GetRepositories().LikeRepository, BookmarkRepo: f.appBuilder.GetRepositories().BookmarkRepository, CollectionRepo: f.appBuilder.GetRepositories().CollectionRepository, TagRepo: f.appBuilder.GetRepositories().TagRepository, CategoryRepo: f.appBuilder.GetRepositories().CategoryRepository, WorkService: f.appBuilder.GetServices().WorkService, Localization: f.appBuilder.GetServices().LocalizationService, AuthService: f.appBuilder.GetServices().AuthService, } // Create JWT manager for authentication jwtManager := auth.NewJWTManager() // Create GraphQL server with authentication srv := graph.NewServerWithAuth(resolver, jwtManager) // Create HTTP server with middleware httpServer := &http.Server{ Addr: config.Cfg.ServerPort, Handler: srv, } logger.LogInfo("GraphQL server created successfully", logger.F("port", config.Cfg.ServerPort)) return httpServer, nil } // CreateBackgroundJobServers creates and configures background job servers func (f *ServerFactory) CreateBackgroundJobServers() ([]*asynq.Server, error) { logger.LogInfo("Setting up background job servers") redisOpt := asynq.RedisClientOpt{ Addr: config.Cfg.RedisAddr, Password: config.Cfg.RedisPassword, DB: config.Cfg.RedisDB, } var servers []*asynq.Server // Setup data synchronization server logger.LogInfo("Setting up data synchronization server", logger.F("concurrency", config.Cfg.MaxRetries)) syncServer := asynq.NewServer(redisOpt, asynq.Config{Concurrency: config.Cfg.MaxRetries}) // Create sync job instance syncJobInstance := syncjob.NewSyncJob( f.appBuilder.GetDatabase(), f.appBuilder.GetAsynqClient(), ) // Register sync job handlers syncjob.RegisterQueueHandlers(syncServer, syncJobInstance) servers = append(servers, syncServer) // Setup linguistic analysis server logger.LogInfo("Setting up linguistic analysis server", logger.F("concurrency", config.Cfg.MaxRetries)) // Create linguistic sync job linguisticSyncJob := linguistics.NewLinguisticSyncJob( f.appBuilder.GetDatabase(), f.appBuilder.GetLinguistics().GetAnalyzer(), f.appBuilder.GetAsynqClient(), ) // Create linguistic server and register handlers linguisticServer := asynq.NewServer(redisOpt, asynq.Config{Concurrency: config.Cfg.MaxRetries}) // Register linguistic handlers linguisticMux := asynq.NewServeMux() linguistics.RegisterLinguisticHandlers(linguisticMux, linguisticSyncJob) // For now, we'll need to run the server with the mux when it's started // This is a temporary workaround - in production, you'd want to properly configure the server servers = append(servers, linguisticServer) logger.LogInfo("Background job servers created successfully", logger.F("serverCount", len(servers))) return servers, nil } // CreatePlaygroundServer creates the GraphQL playground server func (f *ServerFactory) CreatePlaygroundServer() *http.Server { logger.LogInfo("Setting up GraphQL playground") playgroundHandler := playground.Handler("GraphQL", "/query") playgroundServer := &http.Server{ Addr: config.Cfg.PlaygroundPort, Handler: playgroundHandler, } logger.LogInfo("GraphQL playground created successfully", logger.F("port", config.Cfg.PlaygroundPort)) return playgroundServer }