Files
Edu/docs/architecture/issues/contracts/classes_contract.md
SpecialX faaaf29f67 docs: ai 协作文档体系重构与多 ai 仲裁结果落地
1.AI 协作文档体系重构(objections/worklines/contracts+matrix.md)

2.coord 仲裁文档(final-decisions/cross-review/final-rulings/orchestration)

3.各服务 01/02 文档补全

4.共享包初始化(shared-ts/shared-go/hooks/ui-components/ui-tokens)

5.Proto 契约补全

6.004 架构影响地图更新

7.端口分配表

8.设计规格文档
2026-07-10 12:58:22 +08:00

124 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 | 50053P3 启用core-edu 承载) |
| ClassService | GetClass | GetClassRequest | Class | 50053 |
| ClassService | ListClasses | ListClassesRequest | ListClassesResponse | 50053 |
| ClassService | UpdateClass | UpdateClassRequest | Class | 50053 |
| ClassService | DeleteClass | DeleteClassRequest | Empty | 50053 |
> **注意**classes 当前仅 REST端口 3001gRPC 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` | ClassEventaction: created | data-ana建宽表行 | P3core-edu 承载) |
| `edu.org.class.updated` | ClassEventaction: updated | data-ana、msg班主任变更通知 | P3 |
| `edu.org.class.deleted` | ClassEventaction: deleted | data-ana、core-edu关联检查 | P3 |
| `edu.org.class.transferred` | ClassEventaction: 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` | UserEventaction: deleted | 若 deleted user 是班主任,置空 headTeacherId | P3 |
### 2.3 HTTP 调用(如有)
无。classes 是基础数据源,不反向调用其他服务。
---
## §3 就绪信号
### 3.1 我依赖的上游就绪标志
- [ ] MySQL classes_db 可用已就绪P1
- [ ] api-gateway `/classes/*` 路由已注册已就绪P1
- [ ] P3iam `BatchGetUsers` gRPC 可用(班主任信息查询)
- [ ] P3Kafka `edu.identity.user.deleted` topic 可消费
### 3.2 我的就绪标志(供下游消费)
- [x] classes REST API 5 端点可用P1 已实现)
- [x] `/healthz` + `/readyz` 可用P1 已实现)
- [x] `/metrics` 可用P1 已实现)
- [ ] P3gRPC 50053 启用(由 core-edu 承载,`ClassService` 5 RPC 可调用)
- [ ] P3`edu.org.class.created/updated/deleted/transferred` topic 可发布
- [ ] P3Outbox 模式落地(`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 拦截 50053ClassService 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