后端: 1.阶段 5 course 服务边界落地 - 新增 cmd/course 独立进程入口,落地 services/course dao/rpc/sv - 新增 gateway/client/course、shared/contracts/course 和 shared/ports course port - 将 /api/v1/course/* HTTP 门面切到 course zrpc,gateway 只保留鉴权、限流、幂等、文件读取和响应透传 - 保留 course 迁移期直写 schedule_events / schedules 权限,维持课程导入两个表同事务写入语义 - 为 course parse-image 补 bytes RPC 契约和 gRPC 消息大小配置,兼容课表图片上传 - 补充 course.rpc 示例配置与阶段 5 文档基线、切流点、残留依赖和 smoke 记录
71 lines
2.0 KiB
Go
71 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"github.com/LoveLosita/smartflow/backend/bootstrap"
|
|
rootdao "github.com/LoveLosita/smartflow/backend/dao"
|
|
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"
|
|
llmservice "github.com/LoveLosita/smartflow/backend/services/llm"
|
|
"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)
|
|
courseImageClient := llmservice.NewArkResponsesClient(
|
|
os.Getenv("ARK_API_KEY"),
|
|
viper.GetString("agent.baseURL"),
|
|
viper.GetString("courseImport.visionModel"),
|
|
)
|
|
svc := coursesv.NewCourseService(
|
|
courseRepo,
|
|
scheduleRepo,
|
|
courseImageClient,
|
|
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")
|
|
}
|