Version: 0.9.66.dev.260504
后端: 1. 阶段 2 user/auth 服务边界落地,新增 `cmd/userauth` go-zero zrpc 服务、`services/userauth` 核心实现、gateway user API/zrpc client 与 shared contracts/ports,迁移注册、登录、刷新 token、登出、JWT、黑名单和 token 额度治理 2. gateway 与启动装配切流,`cmd/all` 只保留边缘路由、鉴权和轻量组合,通过 userauth zrpc 访问核心用户能力;拆分 MySQL/Redis 初始化与 AutoMigrate 边界,`userauth` 自迁 `users` 和 token 记账幂等表,`all` 不再迁用户表 3. 清退 Gin 单体旧 user/auth DAO、model、service、router、middleware 和 JWT handler,并同步调整 agent/schedule/cache/outbox 相关调用依赖 4. 补齐 refresh token 防并发重放、MySQL 幂等 token 记账、额度 `>=` 拦截和 RPC 错误映射,避免重复记账与内部错误透出 文档: 1. 新增《学习计划论坛与Token商店PRD》
This commit is contained in:
@@ -21,7 +21,10 @@ import (
|
||||
activesvc "github.com/LoveLosita/smartflow/backend/active_scheduler/service"
|
||||
activeTrigger "github.com/LoveLosita/smartflow/backend/active_scheduler/trigger"
|
||||
"github.com/LoveLosita/smartflow/backend/api"
|
||||
"github.com/LoveLosita/smartflow/backend/bootstrap"
|
||||
"github.com/LoveLosita/smartflow/backend/dao"
|
||||
gatewayrouter "github.com/LoveLosita/smartflow/backend/gateway/router"
|
||||
gatewayuserauth "github.com/LoveLosita/smartflow/backend/gateway/userauth"
|
||||
kafkabus "github.com/LoveLosita/smartflow/backend/infra/kafka"
|
||||
outboxinfra "github.com/LoveLosita/smartflow/backend/infra/outbox"
|
||||
"github.com/LoveLosita/smartflow/backend/inits"
|
||||
@@ -37,7 +40,6 @@ import (
|
||||
"github.com/LoveLosita/smartflow/backend/newAgent/tools/web"
|
||||
"github.com/LoveLosita/smartflow/backend/notification"
|
||||
"github.com/LoveLosita/smartflow/backend/pkg"
|
||||
"github.com/LoveLosita/smartflow/backend/routers"
|
||||
"github.com/LoveLosita/smartflow/backend/service"
|
||||
agentsvcsvc "github.com/LoveLosita/smartflow/backend/service/agentsvc"
|
||||
eventsvc "github.com/LoveLosita/smartflow/backend/service/events"
|
||||
@@ -59,7 +61,6 @@ type appRuntime struct {
|
||||
db *gorm.DB
|
||||
redisClient *redis.Client
|
||||
cacheRepo *dao.CacheDAO
|
||||
userRepo *dao.UserDAO
|
||||
agentRepo *dao.AgentDAO
|
||||
agentCache *dao.AgentCache
|
||||
manager *dao.RepoManager
|
||||
@@ -71,21 +72,12 @@ type appRuntime struct {
|
||||
notificationService *notification.NotificationService
|
||||
limiter *pkg.RateLimiter
|
||||
handlers *api.ApiHandlers
|
||||
userAuthClient *gatewayuserauth.Client
|
||||
}
|
||||
|
||||
// loadConfig 加载应用配置。
|
||||
// loadConfig 锻炼?
|
||||
func loadConfig() error {
|
||||
viper.SetConfigName("config")
|
||||
viper.SetConfigType("yaml")
|
||||
viper.AddConfigPath(".")
|
||||
// 1. 兼容从仓库根目录执行 `go run ./backend/cmd/api` 的场景;
|
||||
// 2. 从 backend 目录执行时仍优先命中当前目录,不改变现有默认行为。
|
||||
viper.AddConfigPath("backend")
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
return fmt.Errorf("failed to read config file: %w", err)
|
||||
}
|
||||
log.Println("Config loaded successfully")
|
||||
return nil
|
||||
return bootstrap.LoadConfig()
|
||||
}
|
||||
|
||||
// Start 保留历史兼容入口,当前默认等价于 StartAll。
|
||||
@@ -154,12 +146,15 @@ func buildRuntime(ctx context.Context) (*appRuntime, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db, err := inits.ConnectDB()
|
||||
db, err := inits.ConnectCoreDB()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to database: %w", err)
|
||||
}
|
||||
|
||||
rdb := inits.InitRedis()
|
||||
rdb, err := inits.InitCoreRedis()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to redis: %w", err)
|
||||
}
|
||||
limiter := pkg.NewRateLimiter(rdb)
|
||||
|
||||
aiHub, err := inits.InitEino()
|
||||
@@ -198,7 +193,6 @@ func buildRuntime(ctx context.Context) (*appRuntime, error) {
|
||||
cacheRepo := dao.NewCacheDAO(rdb)
|
||||
agentCacheRepo := dao.NewAgentCache(rdb)
|
||||
_ = db.Use(middleware.NewGormCachePlugin(cacheRepo))
|
||||
userRepo := dao.NewUserDAO(db)
|
||||
taskRepo := dao.NewTaskDAO(db)
|
||||
courseRepo := dao.NewCourseDAO(db)
|
||||
taskClassRepo := dao.NewTaskClassDAO(db)
|
||||
@@ -213,12 +207,19 @@ func buildRuntime(ctx context.Context) (*appRuntime, error) {
|
||||
}
|
||||
|
||||
// Service 层初始化。
|
||||
userService := service.NewUserService(userRepo, cacheRepo)
|
||||
userAuthClient, err := gatewayuserauth.NewClient(gatewayuserauth.ClientConfig{
|
||||
Endpoints: viper.GetStringSlice("userauth.rpc.endpoints"),
|
||||
Target: viper.GetString("userauth.rpc.target"),
|
||||
Timeout: viper.GetDuration("userauth.rpc.timeout"),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize userauth zrpc client: %w", err)
|
||||
}
|
||||
taskSv := service.NewTaskService(taskRepo, cacheRepo, eventBus)
|
||||
taskSv.SetActiveScheduleDAO(manager.ActiveSchedule)
|
||||
courseService := buildCourseService(llmService, courseRepo, scheduleRepo)
|
||||
taskClassService := service.NewTaskClassService(taskClassRepo, cacheRepo, scheduleRepo, manager)
|
||||
scheduleService := service.NewScheduleService(scheduleRepo, userRepo, taskClassRepo, manager, cacheRepo)
|
||||
scheduleService := service.NewScheduleService(scheduleRepo, taskClassRepo, manager, cacheRepo)
|
||||
agentService := service.NewAgentServiceWithSchedule(
|
||||
llmService,
|
||||
agentRepo,
|
||||
@@ -304,13 +305,13 @@ func buildRuntime(ctx context.Context) (*appRuntime, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
handlers := buildAPIHandlers(userService, taskSv, taskClassService, courseService, scheduleService, agentService, memoryModule, activeScheduleDryRun, activeSchedulePreviewConfirm, activeScheduleTrigger, notificationChannelService)
|
||||
handlers := buildAPIHandlers(taskSv, taskClassService, courseService, scheduleService, agentService, memoryModule, activeScheduleDryRun, activeSchedulePreviewConfirm, activeScheduleTrigger, notificationChannelService)
|
||||
|
||||
runtime := &appRuntime{
|
||||
db: db,
|
||||
redisClient: rdb,
|
||||
cacheRepo: cacheRepo,
|
||||
userRepo: userRepo,
|
||||
db: db,
|
||||
redisClient: rdb,
|
||||
cacheRepo: cacheRepo,
|
||||
|
||||
agentRepo: agentRepo,
|
||||
agentCache: agentCacheRepo,
|
||||
manager: manager,
|
||||
@@ -322,6 +323,7 @@ func buildRuntime(ctx context.Context) (*appRuntime, error) {
|
||||
notificationService: notificationService,
|
||||
limiter: limiter,
|
||||
handlers: handlers,
|
||||
userAuthClient: userAuthClient,
|
||||
}
|
||||
if runtime.eventBus != nil {
|
||||
if err := runtime.registerEventHandlers(); err != nil {
|
||||
@@ -835,7 +837,6 @@ func buildQuickTaskQueryFunc(agentService *service.AgentService) func(ctx contex
|
||||
}
|
||||
|
||||
func buildAPIHandlers(
|
||||
userService *service.UserService,
|
||||
taskService *service.TaskService,
|
||||
taskClassService *service.TaskClassService,
|
||||
courseService *service.CourseService,
|
||||
@@ -848,7 +849,6 @@ func buildAPIHandlers(
|
||||
notificationChannelService *notification.ChannelService,
|
||||
) *api.ApiHandlers {
|
||||
return &api.ApiHandlers{
|
||||
UserHandler: api.NewUserHandler(userService),
|
||||
TaskHandler: api.NewTaskHandler(taskService),
|
||||
TaskClassHandler: api.NewTaskClassHandler(taskClassService),
|
||||
CourseHandler: api.NewCourseHandler(courseService),
|
||||
@@ -896,6 +896,7 @@ func (r *appRuntime) registerEventHandlers() error {
|
||||
r.memoryModule,
|
||||
r.activeTriggerWorkflow,
|
||||
r.notificationService,
|
||||
r.userAuthClient,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -903,8 +904,8 @@ func (r *appRuntime) registerEventHandlers() error {
|
||||
}
|
||||
|
||||
func (r *appRuntime) startHTTP(ctx context.Context) {
|
||||
router := routers.RegisterRouters(r.handlers, r.cacheRepo, r.userRepo, r.limiter)
|
||||
routers.StartEngine(ctx, router)
|
||||
router := gatewayrouter.RegisterRouters(r.handlers, r.userAuthClient, r.cacheRepo, r.limiter)
|
||||
gatewayrouter.StartEngine(ctx, router)
|
||||
}
|
||||
|
||||
func (r *appRuntime) close() {
|
||||
|
||||
Reference in New Issue
Block a user