mirror of
https://github.com/SamyRai/tercul-backend.git
synced 2025-12-27 05:11:34 +00:00
- 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
139 lines
4.3 KiB
Go
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
|
|
}
|