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 个
This commit is contained in:
Losita
2026-05-05 23:25:07 +08:00
parent 2a96f4c6f9
commit 3b6fca44a6
226 changed files with 731 additions and 3497 deletions

View File

@@ -59,7 +59,7 @@ Gin Gateway 只做边缘层职责:
3. 请求编排。
4. SSE / 流式返回。
5. 前端所需的轻量组合逻辑。
6. API 层错误响应适配。迁移期可以继续复用 `backend/respond`,等全部服务边界稳定后再整体收进 gateway/shared
6. API 层错误响应适配。阶段 6 后 gateway HTTP 门面已通过 `backend/gateway/shared/respond` 统一入口复用 `backend/respond` 语义;根 `backend/respond` 迁移期继续服务 RPC/client/旧实现,避免服务层反向依赖 gateway。
网关不再承担这些职责:
@@ -73,7 +73,7 @@ Gin Gateway 只做边缘层职责:
1. `/api/v1/user/*``backend/gateway/api/userauth` 承载 HTTP 入口,核心能力通过 zrpc client 调 `cmd/userauth` zrpc。
2. `gateway/middleware` 的 JWT 鉴权和 token quota guard 只调 `userauth`,不直接读写 `users`、Redis 黑名单或额度缓存。
3. `notification``active-scheduler``agent``memory` 等跨服务 zrpc client 终态统一放在 `backend/client/<service>`;当前 `backend/gateway/client/<service>` 是迁移期旧位置,下一轮目录收口应机械迁出
3. `notification``active-scheduler``agent``memory` 等跨服务 zrpc client 终态统一放在 `backend/client/<service>`;当前已完成 `backend/gateway/client/<service>` `backend/client/<service>` 的机械迁移,`backend/gateway/client` 不再作为活跃 client 位置
4. zrpc client 不放进 `cmd``cmd` 只负责进程入口和装配,不承载跨服务 client 语义。
5. HTTP 门面统一放在 `backend/gateway/api`gateway 内部可新增 `backend/gateway/shared`,只放 HTTP/SSE/bind/multipart/respond 等门面复用能力,禁止服务层 import。
@@ -99,11 +99,11 @@ gozero 服务负责领域能力:
>
> 当前状态:`llm-service` / `rag-service` 这两个边界已经先做成 `backend/services/*` 的服务内模块,调用仍由 `backend/cmd/start.go` 在同一进程内装配,不是 gozero 独立进程。
>
> 当前状态:`user/auth` 已经完成 go-zero zrpc 独立进程拆分,是阶段 2 样板。服务端在 `backend/services/userauth`,进程入口在 `backend/cmd/userauth`gateway HTTP 门面在 `backend/gateway/api/userauth`gateway client 在 `backend/gateway/client/userauth`。
> 当前状态:`user/auth` 已经完成 go-zero zrpc 独立进程拆分,是阶段 2 样板。服务端在 `backend/services/userauth`,进程入口在 `backend/cmd/userauth`gateway HTTP 门面在 `backend/gateway/api/userauth`zrpc client 在 `backend/client/userauth`。
>
> 当前状态:`notification` 已经完成阶段 3 拆分。服务端在 `backend/services/notification`,进程入口在 `backend/cmd/notification`gateway client 在 `backend/gateway/client/notification`,服务级 outbox consumer 和 retry loop 已随服务入口迁出。
> 当前状态:`notification` 已经完成阶段 3 拆分。服务端在 `backend/services/notification`,进程入口在 `backend/cmd/notification`zrpc client 在 `backend/client/notification`,服务级 outbox consumer 和 retry loop 已随服务入口迁出。
>
> 当前状态:`active-scheduler` 已经完成阶段 4 首轮收口。服务端在 `backend/services/active_scheduler`,进程入口在 `backend/cmd/active-scheduler`gateway HTTP 门面在 `backend/gateway/api`gateway client 在 `backend/gateway/client/activescheduler`。
> 当前状态:`active-scheduler` 已经完成阶段 4 首轮收口。服务端在 `backend/services/active_scheduler`,进程入口在 `backend/cmd/active-scheduler`gateway HTTP 门面在 `backend/gateway/api`zrpc client 在 `backend/client/activescheduler`。
### 3.3 事件层
@@ -319,7 +319,7 @@ flowchart LR
1. 新增 `backend/cmd/userauth/main.go` 作为 userauth 独立进程入口。
2. 新增 `backend/services/userauth/**`,承载注册、登录、刷新 token、登出、JWT 签发/校验、黑名单、token 额度治理和 token 记账幂等。
3. 新增并归档到 `backend/gateway/api/userauth/**`,承载 `/api/v1/user/register``/api/v1/user/login``/api/v1/user/refresh-token``/api/v1/user/logout` 的 HTTP handler。
4. 新增并归档到 `backend/gateway/client/userauth/**`,承载 gateway 侧 zrpc client 和 gRPC 错误反解。
4. 新增并归档到 `backend/gateway/client/userauth/**`,承载迁移期 gateway 侧 zrpc client 和 gRPC 错误反解;阶段 6 后已机械迁到 `backend/client/userauth/**`
5. 新增 `backend/gateway/middleware/**`,把 JWT 鉴权和 token quota guard 改成调用 userauth不再直接碰 users 表或 Redis 黑名单细节。
6. 新增 `backend/shared/contracts/userauth``backend/shared/ports`,只放跨层契约和端口接口。
7. 拆分 MySQL / Redis 初始化和 AutoMigrate 边界:`cmd/all``ConnectCoreDB` / `InitCoreRedis`,只迁单体残留域;`cmd/userauth` 自己迁 `users``user_token_usage_adjustments`
@@ -335,7 +335,7 @@ flowchart LR
当前切流点:
1. 前端仍访问 `/api/v1/user/*`
2. gateway 的 user handler 只做参数绑定、调用 userauth client、复用 `respond` 写回前端。
2. gateway 的 user handler 只做参数绑定、调用 userauth client、通过 `backend/gateway/shared/respond` 写回前端。
3. gateway 鉴权和 quota guard 只依赖 `ports.UserAuthClient`,不直接依赖 userauth DAO/model。
4. `agent/chat` 的 token quota 门禁已经通过 userauth 服务判断;会话完成后的 token 记账由 agent 事件处理链路调用 userauth `AdjustTokenUsage`
@@ -349,7 +349,7 @@ flowchart LR
遗留约定:
1. `respond` 暂时继续放在 `backend/respond` 复用;等全部阶段收尾后再整体收进 gateway/shared
1. `backend/respond` 暂时继续作为服务层、RPC 层、client 层和旧实现的兼容响应语义;阶段 6 后 gateway HTTP 门面已切到 `backend/gateway/shared/respond`,该包只做薄转发,不允许服务层 import
2. `cmd/all` 单独启动不再覆盖 user/auth 完整能力,后续 smoke 必须同时确认 userauth 已启动。
3. 不要再把 user/auth 当成后续待办;阶段 3 的接手人应从 notification 开始。
@@ -386,7 +386,7 @@ flowchart LR
本轮收口状态2026-05-04
1. `cmd/notification` 已承载 notification zrpc 启动、DB 迁移、服务级 outbox consumer 和重试扫描。
2. `backend/services/notification` 已收进 DAO、model、sv、rpc、飞书 provider 和 outbox handlergateway 通过 `backend/gateway/client/notification` zrpc client 调用。
2. `backend/services/notification` 已收进 DAO、model、sv、rpc、飞书 provider 和 outbox handlergateway 通过 `backend/client/notification` zrpc client 调用。
3. 主动调度侧只写入 `notification.feishu.requested`publisher 侧只注册事件归属到 `notification`,不再启动单体 notification consumer。
4.`backend/notification`、旧 DAO/model 和旧 `service/events/notification_feishu.go` 已删除review 发现的 sending 租约恢复和 RPC timeout 边界已修复。
5. 真实 smoke 已通过:`notification_outbox_messages.id=3` 已从 `pending` 推进到 `consumed``smartflow.notification.outbox` 已出现 `outbox_id=3`,对应 `notification_records` 生成并按未启用通道进入 `skipped`
@@ -424,7 +424,7 @@ flowchart LR
1. `cmd/active-scheduler` 已承载 active-scheduler zrpc 启动、DB 迁移、服务级 outbox consumer、relay、retry loop 和 due job scanner。
2. `backend/services/active_scheduler` 已收进 DAO、sv、rpc 和主动调度核心逻辑;复杂领域流程统一下沉到 `backend/services/active_scheduler/core`,旧 `backend/active_scheduler` 活跃实现已移除。
3. gateway HTTP 门面已统一到 `backend/gateway/api`active-scheduler、notification、userauth 的 zrpc client 已统一到 `backend/gateway/client/*`
3. gateway HTTP 门面已统一到 `backend/gateway/api`active-scheduler、notification、userauth 的 zrpc client 已统一到 `backend/client/*`
4. 单体 `cmd/start.go` 不再启动 active-scheduler workflow / scanner / handlergateway 的 `/api/v1/active-schedule/*` 只做鉴权、参数绑定、超时和 zrpc 转发。
5. 迁移期仍共享主库读取 / 写入 task、schedule、agent 会话与 notification outbox 相关表active-scheduler 启动时会显式检查这些运行时依赖表,后续阶段 5/6 再逐步切成 RPC 或 read model。
6. 已完成真实 smoke`trigger -> active_scheduler_outbox_messages -> consume -> preview ready` 闭环通过,当前 trigger 没有出现单体误消费导致的 dead handler。
@@ -435,21 +435,21 @@ flowchart LR
当前进展2026-05-05
1. 首刀 `schedule` 已完成服务化:新增 `cmd/schedule``services/schedule/{dao,rpc,sv,core}``gateway/client/schedule``shared/contracts/schedule``shared/ports` schedule port。
1. 首刀 `schedule` 已完成服务化:新增 `cmd/schedule``services/schedule/{dao,rpc,sv,core}`迁移期 `gateway/client/schedule`(阶段 6 后已迁到 `backend/client/schedule``shared/contracts/schedule``shared/ports` schedule port。
2. gateway 的 `/api/v1/schedule/*` HTTP 门面已切到 schedule zrpc clientgateway 不再通过 `backend/service.ScheduleService` 直接承载 schedule HTTP 入口业务。
3. active-scheduler 的 schedule facts / feedback / confirm apply 已改为调用 schedule RPC adapter`cmd/active-scheduler` 启动依赖检查已移除 `schedule_events``schedules``task_classes``task_items`
4. 第二刀 `task` 已开始服务化:新增 `cmd/task``services/task/{dao,rpc,sv}``gateway/client/task``shared/contracts/task``shared/ports` task port。
4. 第二刀 `task` 已开始服务化:新增 `cmd/task``services/task/{dao,rpc,sv}`迁移期 `gateway/client/task`(阶段 6 后已迁到 `backend/client/task``shared/contracts/task``shared/ports` task port。
5. gateway 的 `/api/v1/task/*` HTTP 门面已切到 task zrpc clientgateway 只负责鉴权、参数绑定、短超时和响应透传,不再直接调用 `backend/service.TaskService`
6. active-scheduler 的 task facts / due job scanner 已切到 task RPC adapter`cmd/active-scheduler` 启动依赖检查已移除 `tasks`,进一步缩小 active-scheduler 对跨域主库表的直接依赖。
7. `task.urgency.promote.requested` 的 handler、relay、retry loop 已迁入 `cmd/task`;单体 outbox worker 只保留 agent / memory consumerAgent 残留查询链路只允许 publish-only 写入 `task_outbox_messages`,避免单体和 task 独立服务抢同一 task consumer group。
8. 第三刀 `task-class` 已完成 HTTP 所有权切流:新增 `cmd/task-class``services/task_class/{dao,rpc,sv}``gateway/client/taskclass``shared/contracts/taskclass``shared/ports` task-class port。
8. 第三刀 `task-class` 已完成 HTTP 所有权切流:新增 `cmd/task-class``services/task_class/{dao,rpc,sv}`迁移期 `gateway/client/taskclass`(阶段 6 后已迁到 `backend/client/taskclass``shared/contracts/taskclass``shared/ports` task-class port。
9. gateway 的 `/api/v1/task-class/*` HTTP 门面已切到 task-class zrpc clientgateway 只负责鉴权、参数绑定、短超时和响应透传,不再直接调用 `backend/service.TaskClassService`
10. task-class 本轮按主人拍板保留迁移期直写 `schedule_events` / `schedules` 权限,不走 schedule RPC bridge以保留 `insert into schedule` / `apply batch into schedule` 与 task item 状态更新的本地事务语义;`cmd/task-class` 只 AutoMigrate `task_classes` / `task_items`,启动时显式检查 schedule 依赖表是否存在。
11. 旧实现仍保留:`backend/service/schedule.go``backend/dao/schedule.go``backend/service/task.go``backend/dao/task.go``backend/service/task-class.go``backend/dao/task-class.go``backend/service/course*.go``backend/dao/course.go`、active-scheduler 旧 Gorm apply adapter 暂时保留,用于 agent 迁移期、单体残留路径和回退。
12. 当前切流点HTTP schedule 流量进入 `cmd/schedule`HTTP task 流量进入 `cmd/task`HTTP task-class 流量进入 `cmd/task-class`active-scheduler 读取 task/schedule facts 与正式写日程均走 RPCagent 内部仍存在直接 DAO 调用,后续按 agent/memory 阶段继续收。
13. 当前残留跨域 DB 依赖task-class 迁移期仍直接写 `schedule_events` / `schedules`task 服务迁移期仍 best-effort 写 `active_schedule_jobs`active-scheduler 仍直接写 agent 会话 / timeline 和 notification outbox 相关表agent 本地 task 查询、task-class upsert 和 schedule provider 仍保留 DAO 适配。
14. 已完成验证:`go test ./...` 通过避让默认端口启动完整本地服务组HTTP `18080`zrpc `19081-19086`task-class add / list / get / insert-into-schedule / delete-item / delete-class smoke 通过,并用 `docker exec` 核对 task-class 与 schedule 相关表无残留。
15. 第四刀 `course` 已完成 HTTP 所有权切流:新增 `cmd/course``services/course/{dao,rpc,sv}``gateway/client/course``shared/contracts/course``shared/ports` course port。
15. 第四刀 `course` 已完成 HTTP 所有权切流:新增 `cmd/course``services/course/{dao,rpc,sv}`迁移期 `gateway/client/course`(阶段 6 后已迁到 `backend/client/course``shared/contracts/course``shared/ports` course port。
16. gateway 的 `/api/v1/course/*` HTTP 门面已切到 course zrpc clientgateway 只负责鉴权、限流、幂等、multipart 文件读取、短超时和响应透传,不再直接调用 `backend/service.CourseService`
17. course 本轮保留迁移期直写 `schedule_events` / `schedules` 权限,不走 schedule RPC bridge以保留课程导入两个表同事务写入和冲突返回语义`cmd/course` 不 AutoMigrate schedule 表,启动时显式检查依赖表是否存在。
18. 当前切流点更新HTTP schedule / task / task-class / course 流量均进入各自独立 zrpc 服务active-scheduler 读取 task/schedule facts 与正式写日程均走 RPCagent 内部仍存在 task、task-class、schedule DAO 适配,后续按 agent/memory 阶段继续收。
@@ -509,13 +509,24 @@ flowchart LR
3. `backend/cmd/agent/main.go` 已补齐独立进程入口:负责 DB / Redis / LLM / RAG 初始化、agent outbox consumer 启停和 agent zrpc server 生命周期;旧 `backend/cmd/start.go` 的 gateway 本地链路继续保留。
4. agent 事件归属继续复用 `backend/service/events` 与服务级 outbox 路由:`chat.*` / `agent.*` 事件归 `ServiceAgent``memory.extract.requested` 只登记路由不再由 agent 进程消费,`task.urgency.promote.requested` 仍是 publish-only 写入 `task_outbox_messages`
5. `backend/services/agent/rpc` 已补齐 `Ping``Chat` server-stream 以及 conversation meta/list/timeline、schedule-preview、context-stats、schedule-state 6 个 unary JSON 透传 RPC跨进程 chat 边界传 `ChatChunk`,不传 Go channelGateway 继续对前端输出原 SSE 协议。
6. `backend/gateway/client/agent``gateway/api/agent.go` 已接入 `agent.rpc.chat.enabled``agent.rpc.api.enabled` 两个开关;本地 `config.yaml``config.example.yaml` 当前默认 `true`,真实 UTF-8 中文 SSE smoke 已通过chat 主链路走 `agent RPC Chat(stream)` 再转 SSE非 chat `/agent/*` 走 agent unary RPC。
6. `backend/client/agent``gateway/api/agent.go` 已接入 `agent.rpc.chat.enabled``agent.rpc.api.enabled` 两个开关;本地 `config.yaml``config.example.yaml` 当前默认 `true`,真实 UTF-8 中文 SSE smoke 已通过chat 主链路走 `agent RPC Chat(stream)` 再转 SSE非 chat `/agent/*` 走 agent unary RPC。
7. 历史 timeline payload key`newagent_history_kind`)暂不改名,避免破坏旧会话兼容。
8. `backend/memory/*` 已物理迁入 `backend/services/memory/*``module.go``model/``observe/` 作为公共门面保留,`cleanup/``orchestrator/``repo/``service/``utils/``vectorsync/``worker/` 收入 `internal/`,旧 `backend/memory` 目录已删除。
9. `cmd/start.go` 不再创建/注册/启动 agent outbox event busagent relay / consumer 由 `cmd/agent` 独占memory worker / 管理能力由 `cmd/memory` 承担。
10. `cmd/start.go` 已收缩 gateway 本地 `AgentService` 构建:当 `agent.rpc.chat.enabled=true``agent.rpc.api.enabled=true`gateway 不再初始化 agent 本地编排、LLM、RAG、memory reader fallback只有任一 RPC 开关关闭时才保守装配本地 fallback。
11. 最新验证:重建并重启 `api` / `agent`UTF-8 中文 SSE smoke 通过且只有单个 `[DONE]`6 个非 chat `/agent/*` HTTP smoke 中 meta/list/timeline/context-stats 返回 200schedule-preview / schedule-state 在无快照场景返回预期业务 400。
12. 下一轮目录收口按新口径推进:把 `backend/gateway/client/*` 机械迁到 `backend/client/*`gateway 和服务进程共同复用 zrpc client;保留根 `backend/shared` 承载跨服务契约,同时新增 `backend/gateway/shared` 承载 HTTP/SSE/bind/respond 等 gateway 门面复用
12. 轮目录收口 CP1 已按新口径完成:`backend/gateway/client/*` 机械迁到 `backend/client/*`gateway 和服务进程共同复用 zrpc client。
13. 本轮目录收口 CP2 已新增 `backend/gateway/shared/respond`gateway/api 与 gateway/middleware 不再直接 import 根 `backend/respond`;根 `backend/respond` 作为迁移期兼容语义保留给 RPC、client、服务层和旧实现服务代码禁止 import `backend/gateway/shared`
14. CP2 验证结果:`go test ./...``git diff --check` 通过;真实 smoke 覆盖 health、未带 token 的鉴权错误、register/login、受保护 task/memory 接口、agent SSE 和 conversation timeline确认 `gateway/shared/respond` 写回的 `401 + 40009 missing token` 保持旧协议SSE 中文合并为 `CP2中文响应正常` 且只有单个 `[DONE]`
15. 本轮目录收口 CP3 先完成低风险切流:`cmd/start.go``cmd/agent/runtime.go` 不再直接 import 根 `backend/service` 主包gateway fallback 与独立 agent runtime 的 task / schedule 注入已改用 `backend/services/task/sv``backend/services/schedule/sv` 及对应服务 DAO未使用的 course 装配 helper 也改到 `backend/services/course/sv`
16. CP3 不硬搬根 `backend/dao``backend/model`:两者当前仍被 cmd、services、gateway、旧回退面和跨域迁移期链路广泛引用直接整包搬迁风险过高后续按单一能力域继续缩小例如 task due job、schedule apply、agent 会话快照等。
17. CP3 旧实现保留:根 `backend/service/*.go``backend/dao/*.go``backend/model/*.go` 继续作为并行迁移期回退面和共享历史模型存在;当前切流点是正式启动装配不再直连根 `backend/service` 主包,服务内活跃实现优先使用 `backend/services/<service>/sv`
18. CP3 验证结果:`go test ./...``git diff --check` 通过;正式 Go 代码里对根 `github.com/LoveLosita/smartflow/backend/service` 主包的 direct import 已归零。真实 smoke 在 `D:\SmartFlow-Agent\.tmp\cp3-service-root-smoke-20260505-203454` 完成,覆盖 health、register/login、`task/create` + `task/get``schedule/today``memory/items`、agent chat SSE、conversation meta/timeline/context-stats确认 gateway 已走 `agent RPC` 而非本地 fallback中文 SSE 合并为 `CP3中文响应正常` 且只有单个 `[DONE]`
19. CP4 第一轮先收最窄的根目录公共件:`backend/bootstrap` 当前只承载统一配置加载职责,已新增 canonical 入口 `backend/shared/infra/bootstrap`,并把 `cmd/start.go``cmd/agent``cmd/memory``cmd/notification``cmd/active-scheduler``cmd/schedule``cmd/task``cmd/task-class``cmd/course``cmd/userauth` 的 import 切到新路径。
20. CP4 当前仍保留根 `backend/bootstrap` 兼容包装层,避免并行迁移期一次性删除旧目录;当前切流点是所有正式启动入口优先依赖 `backend/shared/infra/bootstrap`,后续确认无残留引用后再删除根目录兼容层。
21. CP4 第二轮继续只收“纯连接底座”这一类:已新增 `backend/shared/infra/mysql``backend/shared/infra/redis``backend/shared/infra/eino` 三个 canonical 入口,只承载 MySQL 连接、Redis 连接和 Eino `AIHub` 构造,不承载任何服务私有 AutoMigrate、回填、outbox 或 worker 启停语义。
22. CP4 当前切流点:`cmd/agent` 直接依赖 `shared/infra/mysql|redis|eino``cmd/active-scheduler``cmd/memory` 以及 `cmd/start.go` 里的本地 agent fallback LLM 构造已切到 `shared/infra/eino`;各服务 `dao/connect.go` 复用 `shared/infra/mysql|redis` 负责“开连接”,但仍在各自目录内保留本服务 own 的 AutoMigrate、依赖表检查与 outbox 建表逻辑。
23. CP4 旧实现保留:根 `backend/inits` 目前收缩为兼容入口 + core 残留域初始化;其中 `ConnectCoreDB``AutoMigrateCoreStorage``InitCoreRedis` 仍服务于旧组合壳和迁移期 core 残留域,暂不下沉到 `shared/infra`,避免把服务私有 schema 语义重新做成“大公共篮子”。
建议提交点:
@@ -756,11 +767,11 @@ SmartFlow-Agent/
> 当前目录到目标目录的映射:
>
> 1. `backend/services/userauth/*` 已经是阶段 2 终态样板;旧 `backend/api/user.go`、`backend/service/user.go`、`backend/dao/user.go`、`backend/model/user.go`、`backend/model/auth.go`、`backend/auth/jwt_handler.go`、`backend/middleware/token_handler.go`、`backend/middleware/token_quota_guard.go`、`backend/routers/routers.go` 不再作为活跃实现。
> 2. `backend/gateway/api/userauth/*` 是 user HTTP 入口,`backend/gateway/client/userauth/*` 是 userauth zrpc client,二者都属于 gateway 边缘层。
> 2. `backend/gateway/api/userauth/*` 是 user HTTP 入口,`backend/client/userauth/*` 是 userauth zrpc clientHTTP 门面属于 gateway 边缘zrpc client 属于跨进程共享 client 层。
> 3. `backend/service/*.go` 这批现有业务逻辑,后面要分别迁到各自服务根目录下的 `sv/`。
> 4. `backend/services/agent/*` 已承接原 `backend/newAgent/*` 内核,`backend/services/agent/sv/*` 已承接原 `backend/service/agentsvc/*` 编排层;后面再按风险拆到 `internal/{prompt,graph,stream,tool,session,router}`。
> 5. `backend/services/notification/*` 已经是阶段 3 终态样板;`backend/cmd/notification` 是独立进程入口,`backend/gateway/client/notification` 是 gateway 侧 zrpc client`backend/shared/contracts/notification` 只放跨层契约;旧 `backend/notification/*`、旧 DAO/model 和旧 `service/events/notification_feishu.go` 不再作为活跃实现。
> 6. `backend/services/active_scheduler/*` 已经是阶段 4 当前样板;`backend/cmd/active-scheduler` 是独立进程入口,`backend/gateway/client/activescheduler` 是 gateway 侧 zrpc client`backend/services/active_scheduler/core` 承载迁移期领域核心;旧 `backend/active_scheduler/*` 不再作为活跃实现。
> 5. `backend/services/notification/*` 已经是阶段 3 终态样板;`backend/cmd/notification` 是独立进程入口,`backend/client/notification` 是跨进程 zrpc client`backend/shared/contracts/notification` 只放跨层契约;旧 `backend/notification/*`、旧 DAO/model 和旧 `service/events/notification_feishu.go` 不再作为活跃实现。
> 6. `backend/services/active_scheduler/*` 已经是阶段 4 当前样板;`backend/cmd/active-scheduler` 是独立进程入口,`backend/client/activescheduler` 是跨进程 zrpc client`backend/services/active_scheduler/core` 承载迁移期领域核心;旧 `backend/active_scheduler/*` 不再作为活跃实现。
> 7. `backend/services/memory/*` 已成为 memory 当前 canonical 入口;`module.go`、`model/`、`observe/` 是对外可见门面,服务私有实现已收入 `internal/`,旧 `backend/memory/*` 只在 legacy 文档中作为历史路径出现。
>
> 说明 4`shared` 先保留 `events` 和少量跨服务底座型 `infra`。以后如果真的出现跨服务 DTO / 枚举 / 常量,再新增 `contracts` 一类目录,但不要把 `dao`、`model`、`sv`、`handler` 这类服务私有层塞进去。
@@ -771,7 +782,7 @@ SmartFlow-Agent/
>
> 说明 7目录树里如果暂时写成 `backend/services/llm/` 和 `backend/services/rag/`,那只是目录名写法;后文所有职责判断都以 `llm-service` / `rag-service` 这两个逻辑服务名为准。
>
> 说明 8阶段 2 已经采用 `backend/services/userauth/` 作为实际目录名,不再使用 `user-auth`。阶段 3 已经采用 `backend/services/notification/` 作为实际目录名。zrpc client 终态放在 `backend/client/<service>/`,迁移期旧 `backend/gateway/client/<service>/` 要按机械迁移逐步挪出;进程入口放在 `backend/cmd/<service>/`,不要把 rpc client 放进 `cmd`。
> 说明 8阶段 2 已经采用 `backend/services/userauth/` 作为实际目录名,不再使用 `user-auth`。阶段 3 已经采用 `backend/services/notification/` 作为实际目录名。zrpc client 终态放在 `backend/client/<service>/`,迁移期旧 `backend/gateway/client/<service>/` 已在阶段 6 后按 CP1 机械迁出;进程入口放在 `backend/cmd/<service>/`,不要把 rpc client 放进 `cmd`。
### 6.3 哪些可以不用变
@@ -814,7 +825,7 @@ SmartFlow-Agent/
| 服务 | 典型用例 | 结构收束建议 | 不允许的改法 |
| --- | --- | --- | --- |
| `user/auth` | 注册、登录、刷新、登出、JWT 签发、黑名单、token 额度门禁、token 记账幂等 | 已完成:`cmd/userauth` + `services/userauth/{sv,dao,model,internal/auth,rpc}`gateway 侧是 `gateway/api/userauth` + `gateway/client/userauth` | 不要恢复旧 Gin user/auth 实现;不要让 gateway 直连 users 表、Redis 黑名单或额度缓存;不要把 zrpc client 放进 `cmd` |
| `user/auth` | 注册、登录、刷新、登出、JWT 签发、黑名单、token 额度门禁、token 记账幂等 | 已完成:`cmd/userauth` + `services/userauth/{sv,dao,model,internal/auth,rpc}`gateway 侧是 `gateway/api/userauth`,跨进程 client 是 `backend/client/userauth` | 不要恢复旧 Gin user/auth 实现;不要让 gateway 直连 users 表、Redis 黑名单或额度缓存;不要把 zrpc client 放进 `cmd` |
| `course` | 课程导入、图片解析、课表校验、课程落表,图片解析走 `llm-service` | `handler.go` / `sv/` / `dao/` / `model/` / `internal/{parse,import,conflict,adapter}/` | 不要把课程解析代码写成网关临时脚本 |
| `task-class` | 任务类创建/更新、items 批量 upsert、嵌入时间同步 | `handler.go` / `sv/` / `dao/` / `model/` / `internal/{convert,batch,item}/` | 不要把批处理拼装沉到 handler 里,也不要让 agent 直接改库 |
| `notification` | 消费 `notification.feishu.requested`、写通知记录、幂等、重试、provider 投递 | `start.go` / `handler.go` / `sv/` / `dao/` / `model/` / `internal/{provider,runner,dedupe,channel,retry}/` | 不要把通知投递逻辑散回 worker 或 gateway |
@@ -922,8 +933,8 @@ graph TD
5. 阶段 3 `notification` 已完成实现、code review 修复和真实 smoke`llm-service``rag-service` 也已完成,不要重新当成待办。
6. 阶段 4 `active-scheduler` 已完成首轮收口;后续不要再把它当成“未拆服务”,除非是在补契约测试或继续替换跨域 DB 访问。
7. `shared` 只保留跨进程契约和少量跨服务底座不承载业务逻辑、DAO、模型或状态机。
8. `backend/client` 是 zrpc client 的终态共享位置,`backend/gateway/client` 只是迁移期旧位置;后续服务或 gateway 需要复用 client 时,优先推进机械搬迁到`client`
9. `backend/gateway/shared` 只放 gateway 门面复用,服务代码禁止 import跨服务契约仍留在根 `backend/shared`
8. `backend/client` 是 zrpc client 的终态共享位置,`backend/gateway/client` 只是迁移期旧位置且 CP1 已完成机械迁出;后续服务或 gateway 需要复用 client 时,统一使用`client`
9. `backend/gateway/shared` 只放 gateway 门面复用,服务代码禁止 import跨服务契约仍留在根 `backend/shared`当前已落地 `backend/gateway/shared/respond` 作为 HTTP 响应适配薄门面。
10. 如果后续要改目录,必须先回答“这个文件属于哪一个典型用例”,回答不清楚就先别动结构。
11. 当前文档已经可以作为切对话基线;后续代理默认按本文件推进。现阶段的迁移基线入口是 `backend/cmd/api``backend/cmd/worker``backend/cmd/all`,它们只是当前仓库的启动壳,不是终态。`backend/cmd/userauth` 是阶段 2 的独立服务入口,`backend/cmd/notification` 是阶段 3 的独立服务入口,`backend/cmd/active-scheduler` 是阶段 4 的独立服务入口,`backend/cmd/schedule``backend/cmd/task``backend/cmd/task-class``backend/cmd/course` 是阶段 5 已落地的独立服务入口。终态仍然是“一个服务一个独立 `main.go`”,只在出现新的契约风险、边界变化或业务语义变化时再重新讨论架构。
@@ -937,7 +948,7 @@ graph TD
6. 带 worker 的服务可以继续保留多入口角色,例如 `api` / `worker` / `all`,但它们仍然是同一服务的不同可执行角色,不是把多个服务硬塞进一个进程。
7. MySQL / Redis 容器的启动归 `docker compose` 或运维层Go 服务只负责在自己的进程里建立连接、做自己的 AutoMigrate 和连通性检查。
8. 阶段 5 后,旧 `cmd/start.go` / `cmd/all` 只是 gateway 和迁移期组合壳;本地完整 smoke 必须额外启动 `cmd/userauth``cmd/notification``cmd/active-scheduler``cmd/schedule``cmd/task``cmd/task-class``cmd/course`。如果同机已有另一条线占用默认端口,应复制临时配置,把 HTTP / zrpc 端口整体平移后再启动服务。
9. 阶段 6 后,`cmd/agent``cmd/memory` 也应纳入完整本地 smoke目录收口时优先把服务与 gateway 共同使用的 zrpc client 从 `gateway/client` 挪到根 `client`,再清理 gateway 门面复用到 `gateway/shared`
9. 阶段 6 后,`cmd/agent``cmd/memory` 也应纳入完整本地 smoke目录收口 CP1 已把服务与 gateway 共同使用的 zrpc client 从 `gateway/client` 挪到根 `client`CP2 已把 gateway HTTP 响应适配入口收进 `gateway/shared/respond`CP3 已先切掉 `cmd` 对根 `backend/service` 主包的直接装配依赖。下一步再按风险迁 SSE/bind/multipart 等门面复用或继续收窄根 dao/model 依赖
### 6.11 测试自动化与 smoke 权限边界
@@ -1057,7 +1068,7 @@ graph TD
5. 跑完 `go test ./...` 后必须清理工作区 `.gocache`
6. 不擅自回滚、覆盖、删除用户或其他代理的无关改动。
7. 不主动 `git commit` / `git branch`,除非用户明确要求。
8. 服务间错误传递优先使用 go-zero / gRPC 内置 `error`,调用侧保持 `res, err :=` 风格API 层对前端错误继续复用 `respond`,后续总收尾再考虑迁到 gateway/shared
8. 服务间错误传递优先使用 go-zero / gRPC 内置 `error`,调用侧保持 `res, err :=` 风格API 层对前端错误通过 `backend/gateway/shared/respond` 写回,根 `backend/respond` 继续承载迁移期跨层响应语义
9. MySQL / Redis 容器启动归 `docker compose` 或运维层Go 服务只负责自己的连接初始化、AutoMigrate 和运行时依赖。
10. gateway 只做边缘转发、鉴权和轻量组合;不要把核心业务表、服务内部 Redis key、JWT 签发、额度账本放回 gateway。
11. 新服务开发可以和后续迁移并行,但必须独立目录、端口、配置和契约,不能污染正在迁移的服务边界。
@@ -1094,7 +1105,7 @@ graph TD
1. `backend/cmd/userauth/main.go` 是 userauth 独立进程入口。
2. `backend/services/userauth` 拥有 user/auth 核心业务、DAO、模型、JWT、黑名单、额度治理、zrpc server 和 token 记账幂等表。
3. `backend/gateway/api/userauth` 是 HTTP user 入口,`backend/gateway/client/userauth` 是 zrpc client`backend/gateway/middleware` 只调 userauth 做鉴权和额度门禁。
3. `backend/gateway/api/userauth` 是 HTTP user 入口,`backend/client/userauth` 是 zrpc client`backend/gateway/middleware` 只调 userauth 做鉴权和额度门禁。
4. `backend/shared/contracts/userauth``backend/shared/ports` 只承载跨层契约,不承载服务私有业务实现。
5. `cmd/all` 不再迁 `users``cmd/userauth` 自己迁 `users``user_token_usage_adjustments`
6. 完整本地 smoke 需要同时启动 `cmd/all``cmd/userauth`
@@ -1103,7 +1114,7 @@ graph TD
1. `backend/cmd/notification/main.go` 是 notification 独立进程入口,负责 DB 迁移、zrpc server、notification outbox consumer 和 retry loop 的统一生命周期。
2. `backend/services/notification` 拥有 notification 核心业务、DAO、模型、飞书 provider、幂等、投递记录状态机、重试扫描和 outbox handler。
3. `backend/gateway/client/notification` gateway 侧 zrpc clientgateway 只保留 notification HTTP 入口、鉴权和轻量组合逻辑,不再直连 notification DAO/service。
3. `backend/client/notification`跨进程 zrpc clientgateway 只保留 notification HTTP 入口、鉴权和轻量组合逻辑,不再直连 notification DAO/service。
4. `backend/shared/contracts/notification``backend/shared/ports` 只承载跨层契约和端口接口,不承载服务私有业务实现。
5. notification 内部是 `userauth` 同款最小手搓 zrpc 框架,不使用 goctl 自动脚手架;`rpc` 只保留 `NewServer``cmd/notification` 管理 signal、outbox consumer、retry loop 和 server 生命周期。
6.`backend/notification/*`、旧 `backend/dao/notification_channel.go`、旧 `backend/model/notification_channel.go` 和旧 `backend/service/events/notification_feishu.go` 已删除;若 `backend/notification` 目录壳仍存在,它不参与编译,也不作为活跃实现。
@@ -1114,7 +1125,7 @@ graph TD
1. `backend/cmd/active-scheduler/main.go` 是 active-scheduler 独立进程入口,负责 DB 迁移、zrpc server、active-scheduler outbox consumer、relay、retry loop 和 due job scanner 的统一生命周期。
2. `backend/services/active_scheduler` 拥有 active-scheduler DAO、rpc、sv 和领域核心;核心流程当前在 `backend/services/active_scheduler/core`,旧 `backend/active_scheduler` 不再作为活跃实现存在。
3. `backend/gateway/api` 是 HTTP 门面统一目录,`backend/gateway/client/activescheduler` gateway 侧 zrpc client。
3. `backend/gateway/api` 是 HTTP 门面统一目录,`backend/client/activescheduler`跨进程 zrpc client。
4. `backend/shared/contracts/activescheduler``backend/shared/ports` 只承载跨层契约和端口接口,不承载服务私有业务实现。
5. `cmd/all` 不再启动 active-scheduler workflow / scanner / handler完整本地 smoke 需要同时启动 `cmd/all``cmd/userauth``cmd/notification``cmd/active-scheduler`
6. 阶段 4 收口时仍共享主库访问 task、schedule、agent 会话和 notification outbox 相关表;阶段 5 已先通过 schedule / task RPC 继续缩小这条共享边界。
@@ -1123,7 +1134,7 @@ graph TD
1. `backend/cmd/schedule/main.go` 是 schedule 独立进程入口,`backend/cmd/task/main.go` 是 task 独立进程入口,`backend/cmd/task-class/main.go` 是 task-class 独立进程入口,`backend/cmd/course/main.go` 是 course 独立进程入口,四者各自初始化 DB / Redis / zrpc server 和所需服务内资源。
2. `backend/services/schedule` 拥有正式日程领域核心,`backend/services/task` 拥有任务池读写、完成/撤销、紧急性平移和 task outbox handler`backend/services/task_class` 拥有任务类与任务块维护、批量排入日程等核心逻辑,`backend/services/course` 拥有课程校验、课程导入和课表图片解析逻辑。
3. `backend/gateway/api` 继续作为 HTTP 门面统一目录,`backend/gateway/client/schedule``backend/gateway/client/task``backend/gateway/client/taskclass``backend/gateway/client/course` 作为 gateway 侧 zrpc client。
3. `backend/gateway/api` 继续作为 HTTP 门面统一目录,`backend/client/schedule``backend/client/task``backend/client/taskclass``backend/client/course` 作为跨进程 zrpc client。
4. `backend/shared/contracts/schedule``backend/shared/contracts/task``backend/shared/contracts/taskclass``backend/shared/contracts/course``backend/shared/ports` 只承载跨进程契约与端口接口,不放 DAO、model 或业务状态机。
5. active-scheduler 的 schedule facts / feedback / confirm apply 已走 schedule RPCtask facts / due job scanner 已走 task RPC启动依赖检查不再要求 `schedule_events``schedules``task_classes``task_items``tasks`
6. `task.urgency.promote.requested` 的消费边界已迁入 `cmd/task`;单体 outbox worker 不再启动 task service bus只保留 Agent 残留路径的 publish-only 写入能力,避免迁移期重复 relay / consume。
@@ -1199,6 +1210,43 @@ graph TD
处理:
1. 以当前编译入口和路由装配为准:`gateway/api/userauth` + `gateway/client/userauth` + `services/userauth` 是阶段 2 当前样板。
2. 任何 user/auth 新能力先放进 `services/userauth`gateway 只做 HTTP 适配respond 响应。
1. 以当前编译入口和路由装配为准:`gateway/api/userauth` + `backend/client/userauth` + `services/userauth` 是阶段 2 当前样板。
2. 任何 user/auth 新能力先放进 `services/userauth`gateway 只做 HTTP 适配,并通过 `backend/gateway/shared/respond`响应。
3. 如果 user/auth 调用失败,先查 `cmd/userauth` 是否启动、zrpc endpoint 是否正确、服务内 MySQL/Redis 是否可连,不要把逻辑搬回 gateway。
## 7. CP4 最终收口记录2026-05-05
1. `backend` 根目录已收口到 5 个一级目录:`services``client``gateway``cmd``shared`
2.`backend/bootstrap` 已删除;统一配置加载 canonical 入口为 `backend/shared/infra/bootstrap`
3.`backend/inits` 已迁入 `backend/cmd/internal/coreinit`,仅保留旧组合壳 `cmd/start.go` 所需的 core 残留域初始化语义;纯连接/句柄构造已切到 `backend/shared/infra/mysql``backend/shared/infra/redis``backend/shared/infra/eino`,历史 `InitEino` 兼容壳已删除。
4.`backend/infra/kafka``backend/infra/outbox` 已迁入 `backend/shared/infra/{kafka,outbox}``backend/infra/rag` 历史文档已迁到 `docs/backend/legacy-infra-rag-from-backend`
5.`backend/conv``backend/respond``backend/pkg``backend/middleware` 已分别迁入:
- `backend/shared/conv`
- `backend/shared/respond`
- `backend/shared/pkg`
- `backend/shared/middleware`
6.`backend/dao``backend/model` 的活跃迁移桥已整体迁入 `backend/shared/runtime/{dao,model}`;根 `backend/service/events` 的活跃事件胶水已迁入 `backend/shared/runtime/eventsvc`。这三处是 CP4 结束时的迁移期 runtime 收容区,不是长期 canonical 归属,只是为了先把根目录收口并保持编译、启动与回退面可用。
7. `backend/shared/legacy/service/*.go` 这批未再被 import 的旧业务实现已删除,不再继续以兼容回退面保留。
8. `backend/utils/pwd_encryption.go` 已下沉到 `backend/services/userauth/internal/auth/password.go`;根 `backend/utils` 已删除。
9. `backend/logic/smart_planning.go` 已下沉到 `backend/services/schedule/core/planning/smart_planning.go`;根 `backend/logic` 已删除。
10. `backend/shared/respond` 已收缩为纯共享错误语义与状态映射,不再直接依赖 `gin``backend/gateway/shared/respond` 继续只承载 gateway HTTP 写回应与错误适配。
11. `backend/shared/middleware``backend/shared/pkg``backend/shared/runtime` 已全部清空并删除HTTP middleware 已归到 `backend/gateway/middleware``GormCachePlugin` 已拆到 `backend/shared/infra/gormcache`,共享 `RateLimiter` 已拆到 `backend/shared/infra/ratelimit`agent token budget 已下沉到 `backend/services/agent/shared/token_budget.go`
12. `backend/shared` 当前目录口径已收敛为:`contracts``events``infra``ports``respond`;迁移期 runtime 桥接实现已挪到 `backend/services/runtime/{conv,dao,eventsvc,model}`
13. 本轮验证结果:
- `go test ./...` 通过,且 `.gocache` 已清理。
- `git diff --check` 通过。
- 最终真实 smoke 通过,产物见 `.tmp/backend-artifacts/cp4-final-clean-smoke-20260505-1/smoke-summary-final.json`
- smoke 覆盖:`health``register/login``task/create + task/get``schedule/today``task-class/list``memory/items``agent/chat``conversation-meta``conversation-timeline``context-stats`;全部返回 `200`SSE 合并结果为 `CP4_OK`,且 `[DONE]` 只有 1 个。
## 8. CP5 最终收口记录2026-05-05
1. `backend/shared` 已不再承载迁移期业务实现、DAO、GORM 实体或事件胶水;根共享层当前只保留 `contracts``events``infra``ports``respond` 五类内容。
2. 迁移期 runtime 桥接实现已从根共享层下沉到 `backend/services/runtime/{conv,dao,eventsvc,model}`,不再伪装成“全后端共享契约层”。
3. `backend/gateway/shared/respond` 已接管 Gin `DealWithError` 写回逻辑;根 `backend/shared/respond` 仅保留共享错误码、错误体和状态映射。
4. `backend/gateway/middleware` 已接管 HTTP `IdempotencyMiddleware``RateLimitMiddleware`;共享层只保留基础设施 `ratelimit``gormcache`
5.`InitEino` 兼容壳、旧 `shared/legacy` 命名以及未再被 import 的 `service/*.go` 旧实现均已删除。
6. CP5 最终验证:
- `go test ./...` 通过,且 `.gocache` 已清理。
- `git diff --check` 通过。
- 最终真实 smoke 通过,产物见 `.tmp/backend-artifacts/cp5-final-smoke-20260505-1/smoke-summary-final.json`
- smoke 覆盖:`health``register/login``task/create + task/get``schedule/today``task-class/list``memory/items``agent/chat``conversation-meta``conversation-timeline``context-stats`;全部返回 `200`SSE 合并结果为 `CP5_OK`,且 `[DONE]` 只有 1 个。
7. 至此 CP5“最终清理与文档收口”中与目录形态、共享层纯化、兼容壳清理、编译、diff check 和真实 smoke 相关的核心目标均已完成。