refactor(docs): 移除 ai07 classes 合并到 core-edu,16 AI 降为 15 AI
This commit is contained in:
@@ -1,123 +0,0 @@
|
||||
# classes 对接契约
|
||||
|
||||
> 负责人:ai07
|
||||
> 关联:[matrix.md](../matrix.md)、[classes.proto](../../../packages/shared-proto/proto/classes.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)、[02-architecture-design.md](../../../services/classes/docs/02-architecture-design.md)
|
||||
> 状态:黄金模板(P1 已实现),P3 合并入 core-edu
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
| Service | RPC | 请求 | 响应 | 端口 |
|
||||
| ------------ | ----------- | ------------------ | ------------------- | ------------------------------- |
|
||||
| ClassService | CreateClass | CreateClassRequest | Class | 50053(P3 启用,core-edu 承载) |
|
||||
| ClassService | GetClass | GetClassRequest | Class | 50053 |
|
||||
| ClassService | ListClasses | ListClassesRequest | ListClassesResponse | 50053 |
|
||||
| ClassService | UpdateClass | UpdateClassRequest | Class | 50053 |
|
||||
| ClassService | DeleteClass | DeleteClassRequest | Empty | 50053 |
|
||||
|
||||
> **注意**:classes 当前仅 REST(端口 3001),gRPC server 50053 在 P3 合并入 core-edu 后启用。proto 契约已就绪(classes.proto),由 core-edu 实现承载。
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
| Method | Path | 权限 | 说明 |
|
||||
| ------ | -------------- | ---------------- | ----------------------------- |
|
||||
| POST | `/classes` | `CLASSES_CREATE` | 创建班级 |
|
||||
| GET | `/classes` | `CLASSES_READ` | 列表(可选 `?gradeId=` 过滤) |
|
||||
| GET | `/classes/:id` | `CLASSES_READ` | 单条查询 |
|
||||
| PUT | `/classes/:id` | `CLASSES_UPDATE` | 更新 |
|
||||
| DELETE | `/classes/:id` | `CLASSES_DELETE` | 删除(先校验存在) |
|
||||
| GET | `/healthz` | 无 | liveness |
|
||||
| GET | `/readyz` | 无 | readiness(校验 DB) |
|
||||
| GET | `/metrics` | 无 | Prometheus 指标 |
|
||||
|
||||
> **响应信封**:ActionState(`{success:true, data:T}` / `{success:false, error:{code,message,details?,traceId?}}`)
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。classes 是业务服务,非 BFF。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
| Topic | Event | 消费方 | 阶段 |
|
||||
| --------------------------- | --------------------------------- | ------------------------------- | ------------------- |
|
||||
| `edu.org.class.created` | ClassEvent(action: created) | data-ana(建宽表行) | P3(core-edu 承载) |
|
||||
| `edu.org.class.updated` | ClassEvent(action: updated) | data-ana、msg(班主任变更通知) | P3 |
|
||||
| `edu.org.class.deleted` | ClassEvent(action: deleted) | data-ana、core-edu(关联检查) | P3 |
|
||||
| `edu.org.class.transferred` | ClassEvent(action: transferred) | msg(通知新/旧班主任) | P3 |
|
||||
|
||||
> **事件 message**:`events.proto` 的 `ClassEvent`(event_id / aggregate_id / event_type / occurred_at / class_id / name / action / metadata)
|
||||
> **发布方式**:Outbox 模式(P3 补齐 `shared/outbox/`),保证事务与事件最终一致
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`CLASSES_`(004 §11.4 确认保留,P3 合并入 core-edu 后保留历史遗留前缀)
|
||||
|
||||
| 错误码 | HTTP | 触发条件 |
|
||||
| --------------------------- | ---- | ----------------------------- |
|
||||
| `CLASSES_VALIDATION_ERROR` | 400 | Zod 校验失败 / 空 update body |
|
||||
| `CLASSES_NOT_FOUND` | 404 | 资源不存在 |
|
||||
| `CLASSES_PERMISSION_DENIED` | 403 | PermissionGuard 校验失败 |
|
||||
| `CLASSES_CONFLICT` | 409 | 并发冲突(预留) |
|
||||
| `CLASSES_BUSINESS_ERROR` | 422 | 业务规则违反(预留) |
|
||||
| `CLASSES_DATABASE_ERROR` | 500 | DB 操作失败 |
|
||||
| `CLASSES_INTERNAL_ERROR` | 500 | 未预期异常 |
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
当前无。P3 合并入 core-edu 后,可能调用 iam 的 `BatchGetUsers`(班主任信息批量查询)。
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
| Topic | Event | 消费动作 | 阶段 |
|
||||
| --------------------------- | ---------------------------- | -------------------------------------------- | ---- |
|
||||
| `edu.identity.user.deleted` | UserEvent(action: deleted) | 若 deleted user 是班主任,置空 headTeacherId | P3 |
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
无。classes 是基础数据源,不反向调用其他服务。
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] MySQL classes_db 可用(已就绪,P1)
|
||||
- [ ] api-gateway `/classes/*` 路由已注册(已就绪,P1)
|
||||
- [ ] P3:iam `BatchGetUsers` gRPC 可用(班主任信息查询)
|
||||
- [ ] P3:Kafka `edu.identity.user.deleted` topic 可消费
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [x] classes REST API 5 端点可用(P1 已实现)
|
||||
- [x] `/healthz` + `/readyz` 可用(P1 已实现)
|
||||
- [x] `/metrics` 可用(P1 已实现)
|
||||
- [ ] P3:gRPC 50053 启用(由 core-edu 承载,`ClassService` 5 RPC 可调用)
|
||||
- [ ] P3:`edu.org.class.created/updated/deleted/transferred` topic 可发布
|
||||
- [ ] P3:Outbox 模式落地(`shared/outbox/` 目录补齐)
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
classes 是 P1 黄金模板,REST API 已实现,**下游无需 mock,可直接调用真实服务**。
|
||||
|
||||
但为 P3 gRPC 迁移期间兼容,提供以下 mock 供下游在 gRPC 未启用时使用:
|
||||
|
||||
- **REST mock**(已可用):直接调用 `http://classes:3001/classes/*`,返回真实数据
|
||||
- **gRPC mock**(P3 过渡期):grpc-mock 拦截 50053,ClassService 5 RPC 返回固定 Class 数据
|
||||
- **Kafka mock**(P3 过渡期):classes 事件未发布前,下游订阅方使用本地 stub(固定 ClassEvent JSON)
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
- P3 期间 iam `BatchGetUsers` 未就绪时,使用 grpc-mock 返回固定用户信息(班主任姓名)
|
||||
- P3 期间 `edu.identity.user.deleted` topic 未就绪时,使用本地 Kafka mock consumer stub
|
||||
@@ -1,58 +0,0 @@
|
||||
# classes 问题记录
|
||||
|
||||
> 负责人:ai07
|
||||
> 关联:[coord.md](../coord.md)、[contracts/classes_contract.md](../contracts/classes_contract.md)
|
||||
> 规则:AI 遇到问题时在此追加条目,coord 仲裁后更新状态
|
||||
|
||||
---
|
||||
|
||||
## 问题列表
|
||||
|
||||
<!--
|
||||
追加条目格式:
|
||||
|
||||
### ISSUE-[编号]-[AI标识]:[标题]
|
||||
|
||||
- **提请方**:aiXX
|
||||
- **日期**:YYYY-MM-DD
|
||||
- **类型**:契约不明确 / 工作量超批 / 前置依赖缺失 / 编号冲突 / 其他
|
||||
- **描述**:[详细描述问题]
|
||||
- **建议方案**:[AI 的建议]
|
||||
- **状态**:待 coord 仲裁 / 已裁决(见 coord.md §X)
|
||||
-->
|
||||
|
||||
### ISSUE-001-ai07:P3 合并后 classes 目录保留方式
|
||||
|
||||
- **提请方**:ai07
|
||||
- **日期**:2026-07-10
|
||||
- **类型**:契约不明确
|
||||
- **描述**:classes 是黄金模板,P3 合并入 core-edu 后,`services/classes/` 目录是否保留?若保留,是只读对照基准还是改为 shared-ts 模板?若删除,黄金模板对照基准丢失,其他 TS 服务无法对齐。
|
||||
- **建议方案**:保留 `services/classes/` 作为只读对照基准(不删除),core-edu 复制其结构。黄金模板 checklist(02-architecture-design.md §10)由 ai07 持续维护。
|
||||
- **状态**:待 coord 仲裁
|
||||
|
||||
### ISSUE-002-ai07:cuid2 迁移时机
|
||||
|
||||
- **提请方**:ai07
|
||||
- **日期**:2026-07-10
|
||||
- **类型**:前置依赖缺失
|
||||
- **描述**:classes 当前用 uuid v4 生成 ID,project_rules 要求 cuid2。迁移时机有两种选择:(A) P1 黄金模板立即迁移;(B) P3 合并入 core-edu 时统一迁移。若选 A,黄金模板先行避免 ai08 继承 uuid 遗留;若选 B,减少一次迁移成本。
|
||||
- **建议方案**:选 A(P1 立即迁移),黄金模板应先行,避免其他服务继承 uuid 遗留。迁移涉及 classes 表主键、proto message 字段类型。
|
||||
- **状态**:待 coord 仲裁
|
||||
|
||||
### ISSUE-003-ai07:proto ClassService 合并后归属
|
||||
|
||||
- **提请方**:ai07
|
||||
- **日期**:2026-07-10
|
||||
- **类型**:契约不明确
|
||||
- **描述**:P3 合并入 core-edu 后,`classes.proto` 的 `ClassService` 是否迁移到 `core_edu.proto`?若迁移,破坏 proto 契约稳定性(下游需更新 import);若保留,core_edu.proto 不会膨胀但需在 core-edu 实现中 import classes.proto。
|
||||
- **建议方案**:保留 `classes.proto` 由 core-edu 实现(选项 B),保持契约稳定性,避免下游 import 路径变更。
|
||||
- **状态**:待 coord 仲裁
|
||||
|
||||
### ISSUE-004-ai07:node:20-alpine → node:22-alpine 升级时机
|
||||
|
||||
- **提请方**:ai07
|
||||
- **日期**:2026-07-10
|
||||
- **类型**:其他
|
||||
- **描述**:classes Dockerfile 用 `node:20-alpine`,project_rules §15.8 镜像预拉清单是 `node:22-alpine`。是 P1 立即升级还是等统一升级?
|
||||
- **建议方案**:P1 立即升级,影响所有 TS 服务 Dockerfile 基准,黄金模板应先行。
|
||||
- **状态**:待 coord 仲裁
|
||||
@@ -1,107 +0,0 @@
|
||||
# classes 工作排期
|
||||
|
||||
> 负责人:ai07
|
||||
> 关联:[workline.md](../workline.md)、[coord.md](../coord.md)、[contracts/classes_contract.md](../contracts/classes_contract.md)
|
||||
> 模式:全并行(各 AI 一口气完成 P2-P6 全部代码,最后统一集成测试)
|
||||
> 特殊说明:classes 是黄金模板(P1 已实现),P3 合并入 core-edu(ai08 接管)
|
||||
|
||||
---
|
||||
|
||||
## §1 总览
|
||||
|
||||
classes 是 Edu 微服务的黄金模板,P1 阶段已实现班级 CRUD + 全横切关注点。P3 阶段合并入 core-edu 后,classes 模块代码由 ai08 接管维护,但黄金模板对照 checklist 由 ai07 持续维护。
|
||||
|
||||
**全阶段目标**:
|
||||
|
||||
- P1(已完成):班级 CRUD + 黄金模板 + 6 项整改
|
||||
- P3:合并入 core-edu + Outbox + gRPC + DataScope + Redis 缓存 + cuid2 迁移
|
||||
- P6:黄金模板 checklist 持续维护 + 硬化
|
||||
|
||||
---
|
||||
|
||||
## §2 全阶段甘特图(P1-P6)
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
title ai07 classes 黄金模板全阶段排期
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %m-%d
|
||||
|
||||
section P1 黄金模板整改
|
||||
阶段1+2架构设计文档 :crit, a7a, 2026-07-10, 1d
|
||||
typeorm移除+tracer修复+@Query替换 :crit, a7b, 2026-07-10, 1d
|
||||
测试覆盖率60→80%+Dockerfile升级 :a7c, 2026-07-11, 1d
|
||||
schema索引补齐 :a7d, 2026-07-11, 1d
|
||||
|
||||
section P3 合并入core-edu
|
||||
shared/outbox目录补齐 :a7e, 2026-07-14, 2d
|
||||
cuid2迁移+DataScope注入 :a7f, 2026-07-15, 2d
|
||||
Redis缓存+软删除+分页 :a7g, 2026-07-17, 3d
|
||||
gRPC 50053启用+核心edu合并 :a7h, 2026-07-20, 2d
|
||||
|
||||
section P6 硬化
|
||||
黄金模板checklist持续维护 :a7i, 2026-07-25, 5d
|
||||
可观测性增强+告警规则 :a7j, 2026-07-30, 3d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §3 详细任务
|
||||
|
||||
### P1:黄金模板整改(立即)
|
||||
|
||||
| # | 任务 | 交付物 | 验收标准 | 状态 |
|
||||
| --- | ----------------------------------- | ------------------------------------------------------------------------- | --------------------------------- | --------- |
|
||||
| 1 | 阶段 1+2 架构设计文档 | `services/classes/docs/01-understanding.md` + `02-architecture-design.md` | coord 交叉审查通过 | ✅ 已完成 |
|
||||
| 2 | 移除 typeorm 冗余依赖 | `package.json` 删除 typeorm 行 | `pnpm install` 零错误 | 待执行 |
|
||||
| 3 | tracer.ts console.log → logger.info | `src/shared/observability/tracer.ts` L20 | grep `console.log` 返回 0 | 待执行 |
|
||||
| 4 | controller list @Req → @Query | `src/classes/classes.controller.ts` L49-53 | list 方法用 `@Query('gradeId')` | 待执行 |
|
||||
| 5 | 测试覆盖率阈值 60% → 80% | `vitest.config.ts` + 补测试用例 | `pnpm test:coverage` 达 80% | 待执行 |
|
||||
| 6 | Dockerfile node:20 → node:22 | `Dockerfile` | 基础镜像 `node:22-alpine` | 待执行 |
|
||||
| 7 | schema 补齐索引 | `classes.schema.ts` + 迁移脚本 | grade_id / head_teacher_id 有索引 | 待执行 |
|
||||
|
||||
### P3:合并入 core-edu(交接给 ai08)
|
||||
|
||||
| # | 任务 | 交付物 | 验收标准 | 状态 |
|
||||
| --- | ------------------------- | ---------------------------------------------------------- | ------------------------------- | ------ |
|
||||
| 1 | `shared/outbox/` 目录补齐 | outbox.repository / outbox.publisher / outbox.relay-worker | 事件可发布到 Kafka | 待执行 |
|
||||
| 2 | cuid2 迁移 | id 字段 uuid v4 → cuid2 + 数据迁移脚本 | 双写过渡期完成 | 待执行 |
|
||||
| 3 | DataScope 6 级 WHERE 注入 | Repository list 方法接收 dataScope 参数 | 6 级过滤生效 | 待执行 |
|
||||
| 4 | Redis 班级列表缓存 | cachedList 方法 + TTL 5 分钟 + 事件失效 | 缓存命中率 > 80% | 待执行 |
|
||||
| 5 | 软删除 + 审计字段 | deleted_at / created_by / updated_by | DELETE 改软删除 | 待执行 |
|
||||
| 6 | 分页 + 批量查询 | 游标分页 + POST /classes/batch | proto page_size/page_token 落地 | 待执行 |
|
||||
| 7 | gRPC server 50053 启用 | ClassService 5 RPC 实现 | gRPC health check SERVING | 待执行 |
|
||||
| 8 | PermissionGuard 改调 iam | 动态权限查询 getEffectivePermissions | 角色变更无需改代码重启 | 待执行 |
|
||||
|
||||
### P6:硬化
|
||||
|
||||
| # | 任务 | 交付物 | 验收标准 | 状态 |
|
||||
| --- | --------------------------- | ---------------------------------- | ---------------- | ------ |
|
||||
| 1 | 黄金模板 checklist 持续维护 | 02-architecture-design.md §10 更新 | 覆盖全部新模式 | 待执行 |
|
||||
| 2 | 可观测性增强 | 日志注入 traceId + Outbox 积压告警 | Grafana 面板可用 | 待执行 |
|
||||
|
||||
---
|
||||
|
||||
## §4 依赖与就绪信号
|
||||
|
||||
- **我依赖**:
|
||||
- MySQL classes_db(P1 已就绪)
|
||||
- api-gateway 路由注册(P1 已就绪)
|
||||
- P3:iam `BatchGetUsers` + `getEffectivePermissions`
|
||||
- P3:Kafka 基础设施(ai08 启用)
|
||||
- **我的就绪信号**:
|
||||
- P1:REST API 5 端点 + /healthz + /readyz + /metrics 可用(已就绪)
|
||||
- P3:gRPC 50053 + Outbox 事件发布 + Redis 缓存可用
|
||||
- **交接信号**:P3 合并时,ai07 向 ai08 交接 classes 模块,交接清单见 02-architecture-design.md §11
|
||||
|
||||
---
|
||||
|
||||
## §5 交接计划(ai07 → ai08)
|
||||
|
||||
| 交接项 | 内容 | 时间 |
|
||||
| ------------------ | ------------------------------------------------------- | --------- |
|
||||
| 源码交接 | `services/classes/src/` 全部源码 | P3 启动时 |
|
||||
| 文档交接 | `services/classes/docs/` 2 份设计文档 | P3 启动时 |
|
||||
| proto 交接 | `classes.proto` 由 core-edu 实现承载 | P3 启动时 |
|
||||
| 黄金模板保留 | `services/classes/` 保留作只读对照基准(待 coord 仲裁) | P3 合并后 |
|
||||
| checklist 持续维护 | ai07 持续维护 02-architecture-design.md §10 | 跨阶段 |
|
||||
Reference in New Issue
Block a user