Files
smartmate/backend/services/schedule/rpc/handler.go
Losita 3b6fca44a6 Version: 0.9.77.dev.260505
后端:
1.阶段 6 CP4/CP5 目录收口与共享边界纯化
- 将 backend 根目录收口为 services、client、gateway、cmd、shared 五个一级目录
- 收拢 bootstrap、inits、infra/kafka、infra/outbox、conv、respond、pkg、middleware,移除根目录旧实现与空目录
- 将 utils 下沉到 services/userauth/internal/auth,将 logic 下沉到 services/schedule/core/planning
- 将迁移期 runtime 桥接实现统一收拢到 services/runtime/{conv,dao,eventsvc,model},删除 shared/legacy 与未再被 import 的旧 service 实现
- 将 gateway/shared/respond 收口为 HTTP/Gin 错误写回适配,shared/respond 仅保留共享错误语义与状态映射
- 将 HTTP IdempotencyMiddleware 与 RateLimitMiddleware 收口到 gateway/middleware
- 将 GormCachePlugin 下沉到 shared/infra/gormcache,将共享 RateLimiter 下沉到 shared/infra/ratelimit,将 agent token budget 下沉到 services/agent/shared
- 删除 InitEino 兼容壳,收缩 cmd/internal/coreinit 仅保留旧组合壳残留域初始化语义
- 更新微服务迁移计划与桌面 checklist,补齐 CP4/CP5 当前切流点、目录终态与验证结果
- 完成 go test ./...、git diff --check 与最终真实 smoke;health、register/login、task/create+get、schedule/today、task-class/list、memory/items、agent chat/meta/timeline/context-stats 全部 200,SSE 合并结果为 CP5_OK 且 [DONE] 只有 1 个
2026-05-05 23:25:07 +08:00

179 lines
6.0 KiB
Go

package rpc
import (
"context"
"encoding/json"
"errors"
"github.com/LoveLosita/smartflow/backend/services/schedule/rpc/pb"
schedulesv "github.com/LoveLosita/smartflow/backend/services/schedule/sv"
schedulecontracts "github.com/LoveLosita/smartflow/backend/shared/contracts/schedule"
"github.com/LoveLosita/smartflow/backend/shared/respond"
)
type Handler struct {
pb.UnimplementedScheduleServer
svc *schedulesv.ScheduleService
}
func NewHandler(svc *schedulesv.ScheduleService) *Handler {
return &Handler{svc: svc}
}
// Ping 供调用方在启动期确认 schedule zrpc 已可用。
func (h *Handler) Ping(ctx context.Context, req *pb.StatusResponse) (*pb.StatusResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
return &pb.StatusResponse{}, nil
}
func (h *Handler) GetToday(ctx context.Context, req *pb.UserRequest) (*pb.JSONResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
data, err := h.svc.GetUserTodaySchedule(ctx, int(req.UserId))
return jsonResponse(data, err)
}
func (h *Handler) GetWeek(ctx context.Context, req *pb.WeekRequest) (*pb.JSONResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
data, err := h.svc.GetUserWeeklySchedule(ctx, int(req.UserId), int(req.Week))
return jsonResponse(data, err)
}
func (h *Handler) DeleteEvents(ctx context.Context, req *pb.DeleteEventsRequest) (*pb.StatusResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
var events []schedulecontracts.UserDeleteScheduleEvent
if err := json.Unmarshal(req.EventsJson, &events); err != nil {
return nil, grpcErrorFromServiceError(respond.WrongParamType)
}
err := h.svc.DeleteScheduleEventByContract(ctx, schedulecontracts.DeleteScheduleEventsRequest{
UserID: int(req.UserId),
Events: events,
})
if err != nil {
return nil, grpcErrorFromServiceError(err)
}
return &pb.StatusResponse{}, nil
}
func (h *Handler) GetRecentCompleted(ctx context.Context, req *pb.RecentCompletedRequest) (*pb.JSONResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
data, err := h.svc.GetUserRecentCompletedSchedules(ctx, int(req.UserId), int(req.Index), int(req.Limit))
return jsonResponse(data, err)
}
func (h *Handler) GetCurrent(ctx context.Context, req *pb.UserRequest) (*pb.JSONResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
data, err := h.svc.GetUserOngoingSchedule(ctx, int(req.UserId))
return jsonResponse(data, err)
}
func (h *Handler) RevokeTaskItem(ctx context.Context, req *pb.RevokeTaskItemRequest) (*pb.StatusResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
if err := h.svc.RevocateUserTaskClassItem(ctx, int(req.UserId), int(req.EventId)); err != nil {
return nil, grpcErrorFromServiceError(err)
}
return &pb.StatusResponse{}, nil
}
func (h *Handler) SmartPlanning(ctx context.Context, req *pb.SmartPlanningRequest) (*pb.JSONResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
data, err := h.svc.SmartPlanning(ctx, int(req.UserId), int(req.TaskClassId))
return jsonResponse(data, err)
}
func (h *Handler) SmartPlanningMulti(ctx context.Context, req *pb.SmartPlanningMultiRequest) (*pb.JSONResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
taskClassIDs := make([]int, 0, len(req.TaskClassIds))
for _, id := range req.TaskClassIds {
taskClassIDs = append(taskClassIDs, int(id))
}
data, err := h.svc.SmartPlanningMulti(ctx, int(req.UserId), taskClassIDs)
return jsonResponse(data, err)
}
func (h *Handler) GetAgentWeekSchedule(ctx context.Context, req *pb.JSONRequest) (*pb.JSONResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
var contractReq schedulecontracts.AgentScheduleWeekRequest
if err := json.Unmarshal(req.PayloadJson, &contractReq); err != nil {
return nil, grpcErrorFromServiceError(respond.WrongParamType)
}
data, err := h.svc.GetAgentWeekSchedule(ctx, contractReq)
return jsonResponse(data, err)
}
func (h *Handler) GetScheduleFactsByWindow(ctx context.Context, req *pb.JSONRequest) (*pb.JSONResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
var contractReq schedulecontracts.ScheduleWindowRequest
if err := json.Unmarshal(req.PayloadJson, &contractReq); err != nil {
return nil, grpcErrorFromServiceError(respond.WrongParamType)
}
data, err := h.svc.GetScheduleFactsByWindow(ctx, contractReq)
return jsonResponse(data, err)
}
func (h *Handler) GetFeedbackSignal(ctx context.Context, req *pb.JSONRequest) (*pb.JSONResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
var contractReq schedulecontracts.FeedbackRequest
if err := json.Unmarshal(req.PayloadJson, &contractReq); err != nil {
return nil, grpcErrorFromServiceError(respond.WrongParamType)
}
feedback, found, err := h.svc.GetFeedbackSignal(ctx, contractReq)
return jsonResponse(schedulecontracts.FeedbackResponse{Feedback: feedback, Found: found}, err)
}
func (h *Handler) ApplyActiveScheduleChanges(ctx context.Context, req *pb.JSONRequest) (*pb.JSONResponse, error) {
if err := h.ensureReady(req); err != nil {
return nil, err
}
var contractReq schedulecontracts.ApplyActiveScheduleRequest
if err := json.Unmarshal(req.PayloadJson, &contractReq); err != nil {
return nil, grpcErrorFromServiceError(respond.WrongParamType)
}
data, err := h.svc.ApplyActiveScheduleChanges(ctx, contractReq)
return jsonResponse(data, err)
}
func (h *Handler) ensureReady(req any) error {
if h == nil || h.svc == nil {
return grpcErrorFromServiceError(errors.New("schedule service dependency not initialized"))
}
if req == nil {
return grpcErrorFromServiceError(respond.MissingParam)
}
return nil
}
func jsonResponse(value any, err error) (*pb.JSONResponse, error) {
if err != nil {
return nil, grpcErrorFromServiceError(err)
}
raw, err := json.Marshal(value)
if err != nil {
return nil, grpcErrorFromServiceError(err)
}
return &pb.JSONResponse{DataJson: raw}, nil
}