package bootstrap import ( "context" "resume-platform/internal/agent" aiprovider "resume-platform/internal/ai" "resume-platform/internal/handler" "resume-platform/internal/repository" "resume-platform/internal/security" "resume-platform/internal/service/chat" "resume-platform/internal/service/document" "resume-platform/internal/service/knowledge" "resume-platform/internal/service/portfolio" "resume-platform/internal/service/quiz" "resume-platform/internal/service/resume" "resume-platform/internal/service/system" "resume-platform/internal/service/user" aiservice "resume-platform/internal/service/ai" "resume-platform/pkg/config" ) type ServiceContainer struct { // Repository Repo repository.ResumeRepository // Core Services ResumeService resume.ResumeService SystemService system.SystemService DocumentService document.DocumentService UserService user.UserService PortfolioService portfolio.PortfolioService QuizService quiz.QuizService // AI Services AIProvider aiprovider.Provider AIService *aiservice.AIService QuestionGenerator *aiservice.QuestionGeneratorService ResumeGenerator *resume.ResumeGeneratorService ResumeAgent *agent.ResumeAgent // Knowledge Services EmbeddingService *knowledge.EmbeddingService VectorService *knowledge.VectorService KnowledgeBaseService *knowledge.KnowledgeBaseService RAGService *knowledge.RAGService // Chat Services ChatService chat.ChatService IMService *chat.IMService // Handlers ResumeHandler *handler.ResumeHandler AdminHandler *handler.AdminHandler AIHandler *handler.AIHandler DocumentHandler *handler.DocumentHandler ChatHandler *handler.ChatHandler IMHandler *handler.IMHandler KnowledgeHandler *handler.KnowledgeHandler } func NewServiceContainer(cfg *config.Config) (*ServiceContainer, error) { container := &ServiceContainer{} if err := container.initRepository(cfg); err != nil { return nil, err } if err := container.initAIServices(cfg); err != nil { return nil, err } if err := container.initCoreServices(cfg); err != nil { return nil, err } if err := container.initKnowledgeServices(cfg); err != nil { return nil, err } if err := container.initChatServices(cfg); err != nil { return nil, err } if err := container.initHandlers(cfg); err != nil { return nil, err } return container, nil } func (c *ServiceContainer) initRepository(cfg *config.Config) error { dbPath := cfg.Database.Path if dbPath == "" { dbPath = "./data/resume.db" } repo, err := repository.NewSQLiteRepository(dbPath, cfg.Database.Password) if err != nil { return err } c.Repo = repo return nil } func (c *ServiceContainer) initCoreServices(cfg *config.Config) error { c.ResumeService = resume.NewResumeService(c.Repo) c.SystemService = system.NewSystemService(c.Repo) if _, err := c.ResumeService.InitDefaultResume(); err != nil { return err } if err := c.SystemService.InitDefaultMenus(); err != nil { return err } c.DocumentService = document.NewDocumentService(c.Repo, c.ResumeGenerator) c.UserService = user.NewUserService(c.Repo) c.PortfolioService = portfolio.NewPortfolioService(c.Repo) c.QuizService = quiz.NewQuizService(c.Repo) return nil } func (c *ServiceContainer) initAIServices(cfg *config.Config) error { if !cfg.AI.Enabled { return nil } provider, err := aiprovider.NewProvider(&cfg.AI) if err != nil { return err } c.AIProvider = provider c.AIService = aiservice.NewAIService(provider) c.QuestionGenerator = aiservice.NewQuestionGeneratorService(provider) c.ResumeGenerator = resume.NewResumeGeneratorService(provider) return nil } func (c *ServiceContainer) initKnowledgeServices(cfg *config.Config) error { if c.AIProvider == nil { return nil } c.EmbeddingService = knowledge.NewEmbeddingService(c.AIProvider, c.Repo) c.VectorService = knowledge.NewVectorService(c.EmbeddingService, c.Repo) c.KnowledgeBaseService = knowledge.NewKnowledgeBaseService(c.EmbeddingService, c.VectorService, c.Repo) c.RAGService = knowledge.NewRAGService(c.AIProvider, c.KnowledgeBaseService) c.DocumentService = document.NewDocumentServiceWithKnowledge(c.Repo, c.ResumeGenerator, c.KnowledgeBaseService) return nil } func (c *ServiceContainer) initChatServices(cfg *config.Config) error { c.ChatService = chat.NewChatService(c.Repo, c.AIService) c.IMService = chat.NewIMService(c.AIProvider, c.ResumeAgent) return nil } func (c *ServiceContainer) initHandlers(cfg *config.Config) error { c.ResumeHandler = handler.NewResumeHandler( c.ResumeService, c.DocumentService, c.UserService, c.PortfolioService, c.QuizService, c.SystemService, ) rateLimiter := security.NewRateLimiter(cfg.Auth.MaxLoginAttempts, cfg.Auth.LockoutDuration) c.AdminHandler = handler.NewAdminHandler(cfg, rateLimiter) c.AIHandler = handler.NewAIHandler(c.AIService, c.QuestionGenerator, nil, c.ResumeService, c.QuizService) c.DocumentHandler = handler.NewDocumentHandler(c.DocumentService) c.ChatHandler = handler.NewChatHandler(c.ChatService) c.IMHandler = handler.NewIMHandler(c.IMService) if c.KnowledgeBaseService != nil { c.KnowledgeHandler = handler.NewKnowledgeHandler(c.KnowledgeBaseService, c.RAGService) } return nil } func (c *ServiceContainer) InitResumeAgent(ctx context.Context, cfg *config.Config) error { if !cfg.AI.Enabled || c.AIProvider == nil { return nil } agent, err := agent.NewResumeAgent(ctx, &cfg.AI) if err != nil { return err } c.ResumeAgent = agent c.AIHandler.SetResumeAgent(agent) return nil }