Version: 0.9.72.dev.260505

后端:
1.task-class 服务边界落地
- 新增 cmd/task-class 独立进程入口,落地 services/task_class dao/rpc/sv
- 新增 gateway/client/taskclass、shared/contracts/taskclass 和 shared/ports task-class port
- 将 /api/v1/task-class/* HTTP 门面切到 task-class zrpc,gateway 只保留鉴权、幂等、参数绑定和响应透传
- 保留 task-class 迁移期直写 schedule_events / schedules 权限,维持 insert/apply 与 item 状态更新的本地事务语义
- 修复 task-class 删除已排入日程任务块时 schedules / schedule_events 的外键删除顺序
- 补充 taskClass.rpc 示例配置与阶段 5 文档基线、切流点、残留依赖和 smoke 记录
- 忽略根目录 .tmp 临时烟测产物
This commit is contained in:
Losita
2026-05-05 11:24:16 +08:00
parent 6843c7efac
commit 7ed8adf8d1
21 changed files with 2254 additions and 117 deletions

View File

@@ -18,6 +18,7 @@ import (
gatewaynotification "github.com/LoveLosita/smartflow/backend/gateway/client/notification"
gatewayschedule "github.com/LoveLosita/smartflow/backend/gateway/client/schedule"
gatewaytask "github.com/LoveLosita/smartflow/backend/gateway/client/task"
gatewaytaskclass "github.com/LoveLosita/smartflow/backend/gateway/client/taskclass"
gatewayuserauth "github.com/LoveLosita/smartflow/backend/gateway/client/userauth"
gatewayrouter "github.com/LoveLosita/smartflow/backend/gateway/router"
kafkabus "github.com/LoveLosita/smartflow/backend/infra/kafka"
@@ -239,6 +240,14 @@ func buildRuntime(ctx context.Context) (*appRuntime, error) {
if err != nil {
return nil, fmt.Errorf("failed to initialize task zrpc client: %w", err)
}
taskClassClient, err := gatewaytaskclass.NewClient(gatewaytaskclass.ClientConfig{
Endpoints: viper.GetStringSlice("taskClass.rpc.endpoints"),
Target: viper.GetString("taskClass.rpc.target"),
Timeout: viper.GetDuration("taskClass.rpc.timeout"),
})
if err != nil {
return nil, fmt.Errorf("failed to initialize task-class zrpc client: %w", err)
}
activeSchedulerClient, err := gatewayactivescheduler.NewClient(gatewayactivescheduler.ClientConfig{
Endpoints: viper.GetStringSlice("activeScheduler.rpc.endpoints"),
Target: viper.GetString("activeScheduler.rpc.target"),
@@ -254,7 +263,6 @@ func buildRuntime(ctx context.Context) (*appRuntime, error) {
taskSv := service.NewTaskService(taskRepo, cacheRepo, taskOutboxPublisher)
taskSv.SetActiveScheduleDAO(manager.ActiveSchedule)
courseService := buildCourseService(llmService, courseRepo, scheduleRepo)
taskClassService := service.NewTaskClassService(taskClassRepo, cacheRepo, scheduleRepo, manager)
scheduleService := service.NewScheduleService(scheduleRepo, taskClassRepo, manager, cacheRepo)
agentService := service.NewAgentServiceWithSchedule(
llmService,
@@ -317,7 +325,7 @@ func buildRuntime(ctx context.Context) (*appRuntime, error) {
return nil, err
}
agentService.SetActiveScheduleSessionRerunFunc(buildActiveScheduleSessionRerunFunc(manager.ActiveSchedule, activeScheduleGraphRunner, activeSchedulePreviewConfirm, activeScheduleFeedbackLocator))
handlers := buildAPIHandlers(taskClient, taskClassService, courseService, scheduleClient, agentService, memoryModule, activeSchedulerClient, notificationClient)
handlers := buildAPIHandlers(taskClient, taskClassClient, courseService, scheduleClient, agentService, memoryModule, activeSchedulerClient, notificationClient)
runtime := &appRuntime{
db: db,
@@ -906,7 +914,7 @@ func buildQuickTaskQueryFunc(agentService *service.AgentService) func(ctx contex
func buildAPIHandlers(
taskClient ports.TaskCommandClient,
taskClassService *service.TaskClassService,
taskClassClient ports.TaskClassCommandClient,
courseService *service.CourseService,
scheduleClient ports.ScheduleCommandClient,
agentService *service.AgentService,
@@ -916,7 +924,7 @@ func buildAPIHandlers(
) *api.ApiHandlers {
return &api.ApiHandlers{
TaskHandler: api.NewTaskHandler(taskClient),
TaskClassHandler: api.NewTaskClassHandler(taskClassService),
TaskClassHandler: api.NewTaskClassHandler(taskClassClient),
CourseHandler: api.NewCourseHandler(courseService),
ScheduleHandler: api.NewScheduleAPI(scheduleClient),
AgentHandler: api.NewAgentHandler(agentService),

View File

@@ -0,0 +1,66 @@
package main
import (
"context"
"log"
"os"
"os/signal"
"syscall"
"github.com/LoveLosita/smartflow/backend/bootstrap"
rootdao "github.com/LoveLosita/smartflow/backend/dao"
rootmiddleware "github.com/LoveLosita/smartflow/backend/middleware"
taskclassdao "github.com/LoveLosita/smartflow/backend/services/task_class/dao"
taskclassrpc "github.com/LoveLosita/smartflow/backend/services/task_class/rpc"
taskclasssv "github.com/LoveLosita/smartflow/backend/services/task_class/sv"
"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 := taskclassdao.OpenDBFromConfig()
if err != nil {
log.Fatalf("failed to connect task-class database: %v", err)
}
redisClient, err := taskclassdao.OpenRedisFromConfig()
if err != nil {
log.Fatalf("failed to connect task-class redis: %v", err)
}
defer redisClient.Close()
cacheRepo := rootdao.NewCacheDAO(redisClient)
if err := db.Use(rootmiddleware.NewGormCachePlugin(cacheRepo)); err != nil {
log.Fatalf("failed to initialize task-class cache deleter: %v", err)
}
// 1. task-class 自有 DAO 使用新服务目录下的实现,保持所有权边界清晰。
// 2. scheduleRepo / RepoManager 属于迁移期桥接依赖,用来保留原 insert/apply 的本地事务语义。
taskClassRepo := taskclassdao.NewTaskClassDAO(db)
scheduleRepo := rootdao.NewScheduleDAO(db)
manager := rootdao.NewManager(db)
svc := taskclasssv.NewTaskClassService(taskClassRepo, cacheRepo, scheduleRepo, manager)
server, listenOn, err := taskclassrpc.NewServer(taskclassrpc.ServerOptions{
ListenOn: viper.GetString("taskClass.rpc.listenOn"),
Timeout: viper.GetDuration("taskClass.rpc.timeout"),
Service: svc,
})
if err != nil {
log.Fatalf("failed to build task-class zrpc server: %v", err)
}
defer server.Stop()
go func() {
log.Printf("task-class zrpc service starting on %s", listenOn)
server.Start()
}()
<-ctx.Done()
log.Println("task-class service stopping")
}