package main import ( "context" "log" "os" "os/signal" "syscall" llmclient "github.com/LoveLosita/smartflow/backend/client/llm" coursedao "github.com/LoveLosita/smartflow/backend/services/course/dao" courserpc "github.com/LoveLosita/smartflow/backend/services/course/rpc" coursesv "github.com/LoveLosita/smartflow/backend/services/course/sv" rootdao "github.com/LoveLosita/smartflow/backend/services/runtime/dao" "github.com/LoveLosita/smartflow/backend/shared/infra/bootstrap" "github.com/spf13/viper" ) func main() { if err := bootstrap.LoadConfig(); err != nil { log.Fatalf("failed to load config: %v", err) } ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() db, err := coursedao.OpenDBFromConfig() if err != nil { log.Fatalf("failed to connect course database: %v", err) } // 1. course 自有 DAO 只承载课程导入对 schedule 表的迁移期写入。 // 2. scheduleRepo 用于复用既有冲突检查,后续若切 schedule RPC bridge 再替换这里。 courseRepo := coursedao.NewCourseDAO(db) scheduleRepo := rootdao.NewScheduleDAO(db) llmService, err := llmclient.NewService(llmclient.ServiceConfig{ ClientConfig: llmclient.ClientConfig{ Endpoints: viper.GetStringSlice("llm.rpc.endpoints"), Target: viper.GetString("llm.rpc.target"), Timeout: viper.GetDuration("llm.rpc.timeout"), }, CourseVisionModel: viper.GetString("courseImport.visionModel"), }) if err != nil { log.Fatalf("failed to initialize course llm client: %v", err) } svc := coursesv.NewCourseService( courseRepo, scheduleRepo, llmService.CourseImageResponsesClient(), coursesv.NewCourseImageParseConfig( viper.GetInt64("courseImport.maxImageBytes"), viper.GetInt("courseImport.maxTokens"), ), viper.GetString("courseImport.visionModel"), ) server, listenOn, err := courserpc.NewServer(courserpc.ServerOptions{ ListenOn: viper.GetString("course.rpc.listenOn"), Timeout: viper.GetDuration("course.rpc.timeout"), MaxImageBytes: viper.GetInt64("courseImport.maxImageBytes"), Service: svc, }) if err != nil { log.Fatalf("failed to build course zrpc server: %v", err) } defer server.Stop() go func() { log.Printf("course zrpc service starting on %s", listenOn) server.Start() }() <-ctx.Done() log.Println("course service stopping") }