tercul-backend/internal/app/server_factory.go
Damir Mukimov 4957117cb6 Initial commit: Tercul Go project with comprehensive architecture
- Core Go application with GraphQL API using gqlgen
- Comprehensive data models for literary works, authors, translations
- Repository pattern with caching layer
- Authentication and authorization system
- Linguistics analysis capabilities with multiple adapters
- Vector search integration with Weaviate
- Docker containerization support
- Python data migration and analysis scripts
- Clean architecture with proper separation of concerns
- Production-ready configuration and middleware
- Proper .gitignore excluding vendor/, database files, and build artifacts
2025-08-13 07:42:32 +02:00

139 lines
4.3 KiB
Go

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
}