Version: 0.9.73.dev.260505

后端:
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 记录
This commit is contained in:
Losita
2026-05-05 12:07:31 +08:00
parent 7ed8adf8d1
commit fd327f845b
21 changed files with 1882 additions and 42 deletions

View File

@@ -442,10 +442,16 @@ flowchart LR
8. 第三刀 `task-class` 已完成 HTTP 所有权切流:新增 `cmd/task-class``services/task_class/{dao,rpc,sv}``gateway/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`、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 与正式写日程均走 RPCcourse / agent 内部仍存在直接 DAO 调用,后续按继续
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。
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 阶段继续收。
19. 当前残留跨域 DB 依赖更新task-class 与 course 迁移期仍直接写 `schedule_events` / `schedules`task 服务迁移期仍 best-effort 写 `active_schedule_jobs`active-scheduler 仍直接写 agent 会话 / timeline 和 notification outbox 相关表agent 本地 task 查询、task-class upsert 和 schedule provider 仍保留 DAO 适配。
20. 已完成验证:`go test ./...` 通过避让默认端口启动完整本地服务组HTTP `18180`zrpc `19181-19187`course validate / import smoke 通过,并用 `docker exec` 核对课程导入写入 `schedule_events=1``schedules=2`
目标:
@@ -456,7 +462,7 @@ flowchart LR
这一步要做的事:
1. `schedule``task``task-class` 已先后独立;下一轮优先评估 `course`,再看 agent 残留 DAO 适配。
1. `schedule``task``task-class``course` 已先后独立;下一轮优先评估 agent 残留 DAO 适配和 memory/agent 阶段切分
2. 每个领域只维护自己的写模型。
3. 通过事件或明确 RPC 契约通信。
4. 继续保持并行迁移,旧实现和新实现可以短期并存。
@@ -899,7 +905,7 @@ graph TD
6. 阶段 4 `active-scheduler` 已完成首轮收口;后续不要再把它当成“未拆服务”,除非是在补契约测试或继续替换跨域 DB 访问。
7. `shared` 只保留跨进程契约和少量跨服务底座不承载业务逻辑、DAO、模型或状态机。
8. 如果后续要改目录,必须先回答“这个文件属于哪一个典型用例”,回答不清楚就先别动结构。
9. 当前文档已经可以作为切对话基线;后续代理默认按本文件推进。现阶段的迁移基线入口是 `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` 是阶段 5 已落地的独立服务入口。终态仍然是“一个服务一个独立 `main.go`”,只在出现新的契约风险、边界变化或业务语义变化时再重新讨论架构。
9. 当前文档已经可以作为切对话基线;后续代理默认按本文件推进。现阶段的迁移基线入口是 `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`”,只在出现新的契约风险、边界变化或业务语义变化时再重新讨论架构。
### 6.10 启动方式与进程模型
@@ -910,7 +916,7 @@ graph TD
5. 如果某些服务需要联动启动应通过脚本、Makefile、docker compose 或开发编排器去启动多个二进制,而不是把进程边界打穿。
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`。如果同机已有另一条线占用默认端口,应复制临时配置,把 HTTP / zrpc 端口整体平移后再启动服务。
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 端口整体平移后再启动服务。
### 6.11 测试自动化与 smoke 权限边界
@@ -1094,14 +1100,14 @@ graph TD
阶段 5 当前基线:
1. `backend/cmd/schedule/main.go` 是 schedule 独立进程入口,`backend/cmd/task/main.go` 是 task 独立进程入口,`backend/cmd/task-class/main.go` 是 task-class 独立进程入口,者各自初始化 DB / Redis / zrpc server 和所需服务内资源。
2. `backend/services/schedule` 拥有正式日程领域核心,`backend/services/task` 拥有任务池读写、完成/撤销、紧急性平移和 task outbox handler`backend/services/task_class` 拥有任务类与任务块维护、批量排入日程等核心逻辑。
3. `backend/gateway/api` 继续作为 HTTP 门面统一目录,`backend/gateway/client/schedule``backend/gateway/client/task``backend/gateway/client/taskclass` 作为 gateway 侧 zrpc client。
4. `backend/shared/contracts/schedule``backend/shared/contracts/task``backend/shared/contracts/taskclass``backend/shared/ports` 只承载跨进程契约与端口接口,不放 DAO、model 或业务状态机。
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。
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。
7. task-class 迁移期仍直接写 `schedule_events` / `schedules`,用于保留 `insert/apply` 与 item 状态更新的本地事务语义;服务启动只检查这些 schedule 依赖表,不 AutoMigrate schedule 表。
8. 本阶段残留task 服务仍 best-effort 写 `active_schedule_jobs`agent 本地 task 查询、quick task 创建、task-class upsertschedule provider 和 course 仍存在直接 DAO 调用active-scheduler 旧 Gorm apply adapter 保留为迁移期残留,不作为新流量主路径。
7. task-class 迁移期仍直接写 `schedule_events` / `schedules`,用于保留 `insert/apply` 与 item 状态更新的本地事务语义;course 迁移期仍直接写 `schedule_events` / `schedules`,用于保留课程导入两个表同事务写入;两个服务启动只检查 schedule 依赖表,不 AutoMigrate schedule 表。
8. 本阶段残留task 服务仍 best-effort 写 `active_schedule_jobs`agent 本地 task 查询、quick task 创建、task-class upsertschedule provider 仍存在直接 DAO 调用active-scheduler 旧 Gorm apply adapter 保留为迁移期残留,不作为新流量主路径。
---