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.设计规格文档
This commit is contained in:
129
docs/architecture/issues/contracts/admin-portal_contract.md
Normal file
129
docs/architecture/issues/contracts/admin-portal_contract.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# admin-portal 对接契约
|
||||
|
||||
> 负责人:ai16
|
||||
> 关联:[matrix.md](./matrix.md)、[iam.proto](../../../packages/shared-proto/proto/iam.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
无。admin-portal 是前端微前端 Remote。
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
| Method | Path | 用途 | 认证 |
|
||||
| ------ | ----------- | ---------------- | --------------------- |
|
||||
| GET | / | 管理后台首页 | JWT 必需 + admin 角色 |
|
||||
| GET | /users | 用户管理 | JWT 必需 + admin |
|
||||
| GET | /roles | 角色权限管理 | JWT 必需 + admin |
|
||||
| GET | /classes | 班级管理(全局) | JWT 必需 + admin |
|
||||
| GET | /teachers | 教师管理 | JWT 必需 + admin |
|
||||
| GET | /students | 学生管理 | JWT 必需 + admin |
|
||||
| GET | /audit-logs | 审计日志 | JWT 必需 + admin |
|
||||
| GET | /dashboard | 管理员仪表盘 | JWT 必需 + admin |
|
||||
| GET | /system | 系统配置 | JWT 必需 + admin |
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。admin-portal 消费 teacher-bff GraphQL admin namespace,自身不提供 schema。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
无。
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
无(前端不定义错误码前缀,透传 BFF 错误码)。
|
||||
|
||||
### 1.6 微前端架构(补充)
|
||||
|
||||
| 角色 | 说明 |
|
||||
| ---------------------- | ----------------------------------------------- |
|
||||
| MF Remote | 管理后台是微前端远程模块 |
|
||||
| 暴露的 remote 模块 | AdminApp(管理后台完整应用)、shared 管理端组件 |
|
||||
| module federation 配置 | `apps/admin-portal/module-federation.config.ts` |
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
无。前端不直接调 gRPC。
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
无。前端不直接订阅 Kafka(审计日志通过 GraphQL 查询,非直接订阅)。
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
| 被调用方 | Method.Path | 用途 | mock 策略 |
|
||||
| ------------------- | ----------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| api-gateway (ai01) | POST /api/admin/graphql | 管理 GraphQL 查询(经网关代理到 teacher-bff admin namespace) | api-gateway/teacher-bff 就绪前使用 MSW 拦截返回 mock GraphQL 响应 |
|
||||
| api-gateway (ai01) | POST /api/auth/login | 管理员登录 | api-gateway 就绪前使用 MSW 返回固定 JWT(admin 角色) |
|
||||
| push-gateway (ai02) | GET /ws | WebSocket 实时通知 | push-gateway 就绪前使用 mock-socket 模拟 WS 推送 |
|
||||
|
||||
### 2.4 GraphQL 查询域(经 api-gateway 代理到 teacher-bff admin namespace)
|
||||
|
||||
| Query/Mutation | 用途 | mock 策略 |
|
||||
| ------------------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| currentUser | 当前管理员信息 | MSW 返回固定管理员(admin 角色) |
|
||||
| adminUsers / createUser / updateUser / deleteUser | 用户管理 | MSW 返回固定 50 个用户 + CRUD success |
|
||||
| adminRoles / updateRolePermissions | 角色权限管理 | MSW 返回固定 5 个角色 + 权限矩阵 |
|
||||
| adminClasses | 班级管理(全局) | MSW 返回固定 20 个班级 |
|
||||
| adminTeachers | 教师管理 | MSW 返回固定 50 个教师 |
|
||||
| adminStudents | 学生管理 | MSW 返回固定 1200 个学生 |
|
||||
| auditLogs | 审计日志(聚合 iam AuditEvent) | MSW 返回固定 100 条审计日志 |
|
||||
| adminDashboard | 管理员仪表盘 | MSW 返回固定仪表盘(total_teachers=50, total_students=1200, school_avg_score=80.0) |
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] api-gateway HTTP :8080 启用(ai01)—— 前端请求入口 + admin 角色校验
|
||||
- [ ] teacher-bff GraphQL :3003 启用(ai03)—— admin namespace 可用
|
||||
- [ ] iam gRPC 50052 启用(ai06)—— 用户/角色/审计日志数据来源
|
||||
- [ ] edu.iam.audit.created topic 有事件发布(ai06)—— 审计日志来源
|
||||
- [ ] data-ana gRPC 50055 启用(ai11)—— adminDashboard 数据来源
|
||||
- [ ] push-gateway WebSocket :8081/ws 启用(ai02)—— 实时通知
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] admin-portal dev server :4003 启用
|
||||
- [ ] MF Remote 可被 AppShell 加载(暴露 AdminApp 模块)
|
||||
- [ ] 独立壳渲染(首页 + 导航 + 路由守卫 + admin 角色校验)
|
||||
- [ ] 登录流程可用(POST /api/auth/login 获取 JWT,前端校验 admin 角色)
|
||||
- [ ] GraphQL 查询可执行(currentUser / adminDashboard / auditLogs 返回数据)
|
||||
- [ ] 用户/角色 CRUD 可执行(createUser / updateRolePermissions)
|
||||
- [ ] WebSocket 通知可接收
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
admin-portal 是前端,无下游消费方。但对开发体验提供:
|
||||
|
||||
- **Storybook**:各组件独立 story(含权限矩阵编辑器、审计日志表格等复杂组件)
|
||||
- **MSW handlers**:`apps/admin-portal/src/mocks/handlers.ts`,拦截所有 GraphQL/HTTP 请求
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,admin-portal 使用以下 mock:
|
||||
|
||||
- **HTTP/GraphQL mock**:使用 MSW 拦截所有请求
|
||||
- POST /api/auth/login → 返回固定 JWT + UserInfo(admin 角色,permissions=["*"])
|
||||
- POST /api/admin/graphql → 根据 operationName 返回对应 mock 响应(与 teacher-bff admin namespace mock 数据一致)
|
||||
- auditLogs mock 返回固定 100 条审计日志(含 action: create/update/delete/login/logout/permission_change)
|
||||
- adminDashboard mock 返回固定全校统计仪表盘
|
||||
- 所有 mock 响应定义在 `apps/admin-portal/src/mocks/fixtures/*.json`
|
||||
- **WebSocket mock**:使用 mock-socket 库
|
||||
- 连接后每 30 秒推送 1 条 mock 系统通知
|
||||
- **JWT mock**:使用固定 mock JWT(admin 角色),存入 httpOnly cookie
|
||||
- **权限矩阵 mock**:内置固定 5 个角色 + 完整权限矩阵(teacher/student/parent/admin/super_admin)
|
||||
- **环境切换**:通过 `NEXT_PUBLIC_API_MOCKING=enabled` 环境变量控制,上游就绪后设为 `disabled`
|
||||
108
docs/architecture/issues/contracts/ai_contract.md
Normal file
108
docs/architecture/issues/contracts/ai_contract.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# ai 对接契约
|
||||
|
||||
> 负责人:ai12
|
||||
> 关联:[matrix.md](./matrix.md)、[ai.proto](../../../packages/shared-proto/proto/ai.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
| Service | RPC | 请求 | 响应 | 端口 |
|
||||
| --------- | ---------------------- | ----------------------------- | ------------------------ | ----- |
|
||||
| AiService | Chat | ChatRequest | ChatResponse | 50057 |
|
||||
| AiService | StreamChat | ChatRequest | stream ChatChunk | 50057 |
|
||||
| AiService | GenerateQuestion | GenerateQuestionRequest | GeneratedQuestion | 50057 |
|
||||
| AiService | OptimizeExpression | OptimizeExpressionRequest | OptimizedExpression | 50057 |
|
||||
| AiService | GenerateLessonPlan | GenerateLessonPlanRequest | LessonPlan | 50057 |
|
||||
| AiService | StreamGenerateQuestion | StreamGenerateQuestionRequest | stream GeneratedQuestion | 50057 |
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
无对外 HTTP 端点,仅 gRPC(含 2 个 Server Streaming RPC:StreamChat / StreamGenerateQuestion)。
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
| Topic | Event | 消费方 |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------- | -------- |
|
||||
| edu.ai.usage.events | AIUsageEvent(operation: chat/generate_question/optimize_expression/lesson_preparation) | data-ana |
|
||||
|
||||
> 注:AIUsageEvent 豁免 Outbox 模式(派生数据事件,见 004 §12.2 + §15.3 #6)。
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`AI_`(如 AI_PROVIDER_UNAVAILABLE、AI_TOKEN_LIMIT_EXCEEDED、AI_CONTENT_FILTERED)
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
| 被调用方 | Service.RPC | 用途 | mock 策略 |
|
||||
| --------------- | -------------------------------------- | ---------------------------- | ----------------------------------------------------------- |
|
||||
| content (ai09) | KnowledgeGraphService.GetPrerequisites | 生成题目时获取知识点前置依赖 | content 就绪前使用本地知识点 stub(固定 3 个前置知识点) |
|
||||
| content (ai09) | QuestionService.SearchQuestions | 备课时检索同类题目参考 | content 就绪前返回空列表 |
|
||||
| data-ana (ai11) | AnalyticsService.GetStudentWeakness | 个性化出题时获取学生薄弱点 | data-ana 就绪前使用本地薄弱点 stub(固定 2 个 weak_points) |
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
| Topic | Event | 发布方 | mock 策略 |
|
||||
| ---------------------------------- | ------------------- | -------------- | -------------------------------------- |
|
||||
| edu.content.knowledge_point.events | KnowledgePointEvent | content (ai09) | content 就绪前不订阅,使用内置知识点表 |
|
||||
| edu.content.question.events | QuestionEvent | content (ai09) | content 就绪前忽略 |
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
| 被调用方 | Method.Path | 用途 | mock 策略 |
|
||||
| -------------------------------- | ------------------------- | ------------------ | ------------------------------------------------------------------ |
|
||||
| LLM Provider(OpenAI/百川/本地) | POST /v1/chat/completions | 调用大模型生成内容 | 开发期使用本地 mock server 返回固定 ChatResponse,不消耗真实 token |
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] content gRPC 50054 启用(ai09)—— 知识点维度 + 题库检索
|
||||
- [ ] edu.content.knowledge_point.events topic 有事件发布(ai09)
|
||||
- [ ] data-ana gRPC 50055 启用(ai11)—— 学生薄弱点(可选,ai 可先独立运行)
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] ai gRPC 50057 启用(HealthService.Check 返回 SERVING)
|
||||
- [ ] AiService.Chat / StreamChat 可调用(含流式响应)
|
||||
- [ ] AiService.GenerateQuestion / StreamGenerateQuestion 可调用
|
||||
- [ ] AiService.GenerateLessonPlan 可调用(P5 补全)
|
||||
- [ ] AiService.OptimizeExpression 可调用
|
||||
- [ ] edu.ai.usage.events topic 可发布(供 data-ana 统计 AI 用量)
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
在 ai 真实服务就绪前,为下游(teacher-bff)提供以下 mock:
|
||||
|
||||
- **gRPC mock**:使用 grpc-mock 拦截 50057 端口
|
||||
- AiService.Chat 返回固定 ChatResponse(content="这是 AI 助手的模拟回复")
|
||||
- AiService.StreamChat 返回固定流(3 个 ChatChunk,最后一个 done=true)
|
||||
- AiService.GenerateQuestion 返回固定 GeneratedQuestion(question/answer/explanation)
|
||||
- AiService.GenerateLessonPlan 返回固定 LessonPlan(3 个 LessonSection)
|
||||
- AiService.StreamGenerateQuestion 返回固定流(2 个 GeneratedQuestion)
|
||||
- **Kafka mock**:ai 就绪前不发布真实 AIUsageEvent,data-ana 仪表盘 AI 用量显示"暂无数据"
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,ai 使用以下 mock:
|
||||
|
||||
- **LLM Provider mock**:本地启动 mock server,POST /v1/chat/completions 返回固定 JSON(不消耗真实 token,不产生费用)
|
||||
- **content 知识点**:内置固定知识点表(数学 20 个知识点 + 前置依赖关系),不依赖 content gRPC
|
||||
- **data-ana 薄弱点**:内置固定学生薄弱点(2 个 weak_points),不依赖 data-ana gRPC
|
||||
- **事件订阅**:不订阅 content 事件,知识点维度表静态
|
||||
102
docs/architecture/issues/contracts/api-gateway_contract.md
Normal file
102
docs/architecture/issues/contracts/api-gateway_contract.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# api-gateway 对接契约
|
||||
|
||||
> 负责人:ai01
|
||||
> 关联:[matrix.md](./matrix.md)、[iam.proto](../../../packages/shared-proto/proto/iam.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
无。api-gateway 是 HTTP 入口,不对外提供 gRPC。
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
| Method | Path | 用途 | 认证 |
|
||||
| ------ | -------------- | ------------------------------------------- | ---------------------- |
|
||||
| ANY | /api/auth/* | 代理到 iam 认证相关(登录/注册/刷新 token) | 公开(登录注册免认证) |
|
||||
| ANY | /api/teacher/* | 代理到 teacher-bff GraphQL(:3003) | JWT 必需 |
|
||||
| ANY | /api/student/* | 代理到 student-bff GraphQL(:3009) | JWT 必需 |
|
||||
| ANY | /api/parent/* | 代理到 parent-bff GraphQL(:3010) | JWT 必需 |
|
||||
| ANY | /api/admin/* | 代理到 teacher-bff GraphQL admin namespace | JWT 必需 + admin 角色 |
|
||||
| GET | /healthz | 网关健康检查(liveness) | 公开 |
|
||||
| GET | /readyz | 网关就绪检查(readiness,含 iam 连通性) | 公开 |
|
||||
| GET | /metrics | Prometheus 指标端点 | 公开(内网) |
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。api-gateway 仅做 HTTP 反向代理 + JWT 验签,不解析 GraphQL。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
无。api-gateway 不发布事件。
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`GW_`(如 GW_UNAUTHORIZED、GW_RATE_LIMITED、GW_CIRCUIT_OPEN、GW_BACKEND_UNAVAILABLE)
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
| 被调用方 | Service.RPC | 用途 | mock 策略 |
|
||||
| ---------- | ----------------------------- | ---------------------------------------- | ----------------------------------------------------------------- |
|
||||
| iam (ai06) | IamService.GetPublicKey | 启动时拉取 RS256 公钥,用于 JWT 验签 | iam 就绪前使用本地固定 mock 公钥(与 mock 私钥配对签发 mock JWT) |
|
||||
| iam (ai06) | IamService.GetEffectiveAccess | 权限校验(可选,部分路由需要细粒度权限) | iam 就绪前放行所有请求(仅校验 JWT 签名) |
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
无。api-gateway 不订阅 Kafka 事件。
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
| 被调用方 | Method.Path | 用途 | mock 策略 |
|
||||
| ------------------ | ------------- | --------------------------- | -------------------------------------------------- |
|
||||
| teacher-bff (ai03) | POST /graphql | 反向代理教师端 GraphQL 请求 | teacher-bff 就绪前返回 502,前端使用本地 mock 数据 |
|
||||
| student-bff (ai04) | POST /graphql | 反向代理学生端 GraphQL 请求 | student-bff 就绪前返回 502 |
|
||||
| parent-bff (ai05) | POST /graphql | 反向代理家长端 GraphQL 请求 | parent-bff 就绪前返回 502 |
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] iam gRPC 50052 启用(ai06)—— GetPublicKey 拉取验签公钥
|
||||
- [ ] teacher-bff GraphQL :3003 启用(ai03)
|
||||
- [ ] student-bff GraphQL :3009 启用(ai04)
|
||||
- [ ] parent-bff GraphQL :3010 启用(ai05)
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] api-gateway HTTP :8080 启用(/healthz 返回 200)
|
||||
- [ ] /readyz 返回 200(含 iam 连通性检查通过)
|
||||
- [ ] JWT 验签链路打通(使用 iam 公钥校验 access_token)
|
||||
- [ ] /api/auth/* 代理到 iam 认证链路可用
|
||||
- [ ] /api/teacher/* /api/student/* /api/parent/* 反向代理到各 BFF 可用
|
||||
- [ ] 限流(IP 级令牌桶)+ 熔断(各后端独立熔断器)生效
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
在 api-gateway 真实就绪前,为下游(各前端 portal)提供以下 mock:
|
||||
|
||||
- **HTTP mock**:使用 MSW(Mock Service Worker)或本地 nginx 拦截
|
||||
- /api/auth/login 返回固定 JWT(mock 签发)+ UserInfo
|
||||
- /api/teacher/* /api/student/* /api/parent/* 直接返回各 BFF 的 mock GraphQL 响应
|
||||
- /healthz /readyz 返回 200
|
||||
- **JWT mock**:前端开发期使用固定 mock JWT(api-gateway 就绪前不走真实验签)
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,api-gateway 使用以下 mock:
|
||||
|
||||
- **iam 公钥**:使用本地固定 mock RS256 公钥(与 mock 私钥配对),验签 mock JWT
|
||||
- **iam 权限校验**:GetEffectiveAccess 返回 allowed=true,放行所有请求
|
||||
- **各 BFF 代理**:BFF 就绪前返回 503 + Retry-After,前端降级到本地 mock 数据
|
||||
123
docs/architecture/issues/contracts/classes_contract.md
Normal file
123
docs/architecture/issues/contracts/classes_contract.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# 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
|
||||
110
docs/architecture/issues/contracts/content_contract.md
Normal file
110
docs/architecture/issues/contracts/content_contract.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# content 对接契约
|
||||
|
||||
> 负责人:ai09
|
||||
> 关联:[matrix.md](./matrix.md)、[content.proto](../../../packages/shared-proto/proto/content.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
| Service | RPC | 请求 | 响应 | 端口 |
|
||||
| --------------------- | ------------------ | ------------------------- | -------------------------- | ----- |
|
||||
| TextbookService | CreateTextbook | CreateTextbookRequest | Textbook | 50054 |
|
||||
| TextbookService | GetTextbook | GetTextbookRequest | Textbook | 50054 |
|
||||
| TextbookService | ListTextbooks | ListTextbooksRequest | ListTextbooksResponse | 50054 |
|
||||
| ChapterService | GetChapter | GetChapterRequest | Chapter | 50054 |
|
||||
| ChapterService | ListChapters | ListChaptersRequest | ListChaptersResponse | 50054 |
|
||||
| ChapterService | CreateChapter | CreateChapterRequest | Chapter | 50054 |
|
||||
| ChapterService | UpdateChapter | UpdateChapterRequest | Chapter | 50054 |
|
||||
| KnowledgeGraphService | GetPrerequisites | GetPrerequisitesRequest | KnowledgePointsResponse | 50054 |
|
||||
| KnowledgeGraphService | GetLearningPath | GetLearningPathRequest | LearningPath | 50054 |
|
||||
| KnowledgeGraphService | AddPrerequisite | AddPrerequisiteRequest | AddPrerequisiteResponse | 50054 |
|
||||
| KnowledgeGraphService | RemovePrerequisite | RemovePrerequisiteRequest | RemovePrerequisiteResponse | 50054 |
|
||||
| QuestionService | CreateQuestion | CreateQuestionRequest | Question | 50054 |
|
||||
| QuestionService | GetQuestion | GetQuestionRequest | Question | 50054 |
|
||||
| QuestionService | ListQuestions | ListQuestionsRequest | ListQuestionsResponse | 50054 |
|
||||
| QuestionService | UpdateQuestion | UpdateQuestionRequest | Question | 50054 |
|
||||
| QuestionService | DeleteQuestion | DeleteQuestionRequest | DeleteQuestionResponse | 50054 |
|
||||
| QuestionService | PublishQuestion | PublishQuestionRequest | PublishQuestionResponse | 50054 |
|
||||
| QuestionService | SearchQuestions | SearchQuestionsRequest | SearchQuestionsResponse | 50054 |
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
无对外 HTTP 端点,仅 gRPC。
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
| Topic | Event | 消费方 |
|
||||
| ---------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------- |
|
||||
| edu.content.knowledge_point.events | KnowledgePointEvent(action: created/updated/prerequisite_added/prerequisite_removed) | data-ana / ai / Neo4j Sync Worker / ES Sync Worker |
|
||||
| edu.content.question.events | QuestionEvent(action: created/updated/published/deleted) | data-ana |
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`CONTENT_`(如 CONTENT_TEXTBOOK_NOT_FOUND、CONTENT_QUESTION_DUPLICATE)
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
无直接 gRPC 调用上游。content 通过 Kafka 事件接收 core-edu 班级/学生变更用于数据一致性。
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
| Topic | Event | 发布方 | mock 策略 |
|
||||
| ---------------- | --------------------------------- | --------------- | ----------------------------------------------------- |
|
||||
| edu.class.events | ClassEvent(action: transferred) | core-edu (ai08) | core-edu 就绪前不订阅,content 内部不依赖班级实时数据 |
|
||||
| edu.exam.events | ExamEvent | core-edu (ai08) | core-edu 就绪前忽略,题目关联知识点不依赖考试事件 |
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
无。
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] core-edu gRPC 50053 启用(ai08)—— 用于知识点与班级关联(可选,content 可先独立运行)
|
||||
- [ ] edu.class.events / edu.exam.events topic 有事件发布(ai08)
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] content gRPC 50054 启用(HealthService.Check 返回 SERVING)
|
||||
- [ ] TextbookService 3 RPC 可调用
|
||||
- [ ] ChapterService 4 RPC 可调用
|
||||
- [ ] KnowledgeGraphService 4 RPC 可调用(GetPrerequisites/GetLearningPath/AddPrerequisite/RemovePrerequisite)
|
||||
- [ ] QuestionService 7 RPC 可调用(含 SearchQuestions 全文检索)
|
||||
- [ ] edu.content.knowledge_point.events / edu.content.question.events topic 可发布
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
在 content 真实服务就绪前,为下游(teacher-bff / student-bff / ai / data-ana)提供以下 mock:
|
||||
|
||||
- **gRPC mock**:使用 grpc-mock 拦截 50054 端口
|
||||
- TextbookService.ListTextbooks 返回固定 5 个 Textbook(语数英理化)
|
||||
- ChapterService.ListChapters 返回固定章节树(每教材 10 章)
|
||||
- KnowledgeGraphService.GetLearningPath 返回固定 8 个 KnowledgePoint 推荐顺序
|
||||
- KnowledgeGraphService.GetPrerequisites 返回固定 3 个前置知识点
|
||||
- QuestionService.SearchQuestions 返回固定 20 个 Question(含 options)
|
||||
- **Kafka mock**:content 就绪前不发布真实事件,下游使用本地 stub
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实 core-edu 就绪前,content 使用以下 mock:
|
||||
|
||||
- 班级/学生数据:不依赖 core-edu 实时数据,知识点关联使用固定 subject_id/grade
|
||||
- 事件订阅:不订阅 edu.class.events / edu.exam.events,内部数据自洽
|
||||
118
docs/architecture/issues/contracts/core-edu_contract.md
Normal file
118
docs/architecture/issues/contracts/core-edu_contract.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# core-edu 对接契约
|
||||
|
||||
> 负责人:ai08
|
||||
> 关联:[matrix.md](./matrix.md)、[core_edu.proto](../../../packages/shared-proto/proto/core_edu.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
| Service | RPC | 请求 | 响应 | 端口 |
|
||||
| ----------------- | ----------------------- | ------------------------------ | --------------------------- | ----- |
|
||||
| ClassService | GetClass | GetClassRequest | ClassInfo | 50053 |
|
||||
| ClassService | GetClassesByTeacher | GetClassesByTeacherRequest | GetClassesByTeacherResponse | 50053 |
|
||||
| ClassService | BatchGetClasses | BatchGetClassesRequest | BatchGetClassesResponse | 50053 |
|
||||
| ClassService | ListStudentsByClass | ListStudentsByClassRequest | ListStudentsByClassResponse | 50053 |
|
||||
| ExamService | CreateExam | CreateExamRequest | CreateExamResponse | 50053 |
|
||||
| ExamService | GetExam | GetExamRequest | Exam | 50053 |
|
||||
| ExamService | ListExamsByClass | ListExamsByClassRequest | ListExamsResponse | 50053 |
|
||||
| ExamService | UpdateExam | UpdateExamRequest | UpdateExamResponse | 50053 |
|
||||
| ExamService | DeleteExam | DeleteExamRequest | DeleteExamResponse | 50053 |
|
||||
| HomeworkService | AssignHomework | AssignHomeworkRequest | AssignHomeworkResponse | 50053 |
|
||||
| HomeworkService | GetHomework | GetHomeworkRequest | Homework | 50053 |
|
||||
| HomeworkService | ListHomeworkByClass | ListHomeworkByClassRequest | ListHomeworkResponse | 50053 |
|
||||
| HomeworkService | SubmitHomework | SubmitHomeworkRequest | SubmitHomeworkResponse | 50053 |
|
||||
| GradeService | RecordGrade | RecordGradeRequest | RecordGradeResponse | 50053 |
|
||||
| GradeService | GetGrade | GetGradeRequest | Grade | 50053 |
|
||||
| GradeService | ListGradesByStudent | ListGradesByStudentRequest | ListGradesResponse | 50053 |
|
||||
| GradeService | ListGradesByExam | ListGradesByExamRequest | ListGradesResponse | 50053 |
|
||||
| GradeService | ListGradesByHomework | ListGradesByHomeworkRequest | ListGradesResponse | 50053 |
|
||||
| AttendanceService | RecordAttendance | RecordAttendanceRequest | RecordAttendanceResponse | 50053 |
|
||||
| AttendanceService | GetAttendance | GetAttendanceRequest | Attendance | 50053 |
|
||||
| AttendanceService | ListAttendanceByStudent | ListAttendanceByStudentRequest | ListAttendanceResponse | 50053 |
|
||||
| AttendanceService | ListAttendanceByClass | ListAttendanceByClassRequest | ListAttendanceResponse | 50053 |
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
无对外 HTTP 端点,仅 gRPC。
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
| Topic | Event | 消费方 |
|
||||
| ------------------- | -------------------------------------------------- | -------------- |
|
||||
| edu.exam.events | ExamEvent(action: created/updated/deleted) | msg / data-ana |
|
||||
| edu.homework.events | HomeworkEvent(action: assigned/submitted/graded) | msg / data-ana |
|
||||
| edu.grade.events | GradeEvent(action: recorded/updated) | msg / data-ana |
|
||||
| edu.class.events | ClassEvent(action: transferred) | msg / data-ana |
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`CORE_EDU_`(如 CORE_EDU_CLASS_NOT_FOUND、CORE_EDU_EXAM_CONFLICT)
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
无直接 gRPC 调用上游。core-edu 通过 Kafka 事件接收 iam 用户变更,不主动调 iam。
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
| Topic | Event | 发布方 | mock 策略 |
|
||||
| ------------------- | --------------------------------------------------------- | ---------- | -------------------------------------------------------------------- |
|
||||
| edu.iam.user.events | UserEvent(action: created/updated/deleted/role_changed) | iam (ai06) | iam 就绪前不订阅,使用本地内置用户数据(teacher_id/student_id 固定) |
|
||||
| edu.iam.role.events | RoleEvent(action: created/updated) | iam (ai06) | iam 就绪前忽略,权限校验在 core-edu 内部 mock |
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
无。
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] iam gRPC 50052 启用(ai06)—— 用于用户身份一致性校验(可选,core-edu 可先独立运行)
|
||||
- [ ] edu.iam.user.events topic 有事件发布(ai06)—— 用于同步用户缓存
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] core-edu gRPC 50053 启用(HealthService.Check 返回 SERVING)
|
||||
- [ ] ClassService 4 RPC 可调用(GetClass/GetClassesByTeacher/BatchGetClasses/ListStudentsByClass)
|
||||
- [ ] ExamService 5 RPC 可调用
|
||||
- [ ] HomeworkService 4 RPC 可调用
|
||||
- [ ] GradeService 5 RPC 可调用
|
||||
- [ ] AttendanceService 4 RPC 可调用
|
||||
- [ ] edu.exam.events / edu.homework.events / edu.grade.events / edu.class.events topic 可发布
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
在 core-edu 真实服务就绪前,为下游(teacher-bff / student-bff / parent-bff / content / msg / data-ana)提供以下 mock:
|
||||
|
||||
- **gRPC mock**:使用 grpc-mock 拦截 50053 端口
|
||||
- ClassService.GetClassesByTeacher 返回固定 3 个 ClassInfo
|
||||
- ClassService.ListStudentsByClass 返回固定 30 个 StudentInfo
|
||||
- ExamService.ListExamsByClass 返回固定 2 个 Exam
|
||||
- HomeworkService.ListHomeworkByClass 返回固定 3 个 Homework
|
||||
- GradeService.ListGradesByStudent 返回固定 5 个 Grade
|
||||
- AttendanceService.ListAttendanceByStudent 返回固定 10 条 Attendance
|
||||
- **Kafka mock**:core-edu 就绪前不发布真实事件,下游 data-ana/msg 使用本地 stub 事件
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实 iam 就绪前,core-edu 使用以下 mock:
|
||||
|
||||
- 用户数据:内置固定 teacher_id / student_id(不订阅 edu.iam.user.events)
|
||||
- 权限校验:core-edu 内部不校验权限(由 Gateway/BFF 层负责),仅记录 created_by 字段
|
||||
121
docs/architecture/issues/contracts/data-ana_contract.md
Normal file
121
docs/architecture/issues/contracts/data-ana_contract.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# data-ana 对接契约
|
||||
|
||||
> 负责人:ai11
|
||||
> 关联:[matrix.md](./matrix.md)、[analytics.proto](../../../packages/shared-proto/proto/analytics.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
| Service | RPC | 请求 | 响应 | 端口 |
|
||||
| ---------------- | ---------------------- | ----------------------------- | ------------------------- | ----- |
|
||||
| AnalyticsService | GetClassPerformance | GetClassPerformanceRequest | ClassPerformance | 50055 |
|
||||
| AnalyticsService | GetStudentWeakness | GetStudentWeaknessRequest | StudentWeakness | 50055 |
|
||||
| AnalyticsService | GetLearningTrend | GetLearningTrendRequest | LearningTrend | 50055 |
|
||||
| AnalyticsService | GetTeacherDashboard | GetTeacherDashboardRequest | TeacherDashboard | 50055 |
|
||||
| AnalyticsService | GetStudentDashboard | GetStudentDashboardRequest | StudentDashboard | 50055 |
|
||||
| AnalyticsService | GetParentDashboard | GetParentDashboardRequest | ParentDashboard | 50055 |
|
||||
| AnalyticsService | GetAdminDashboard | GetAdminDashboardRequest | AdminDashboard | 50055 |
|
||||
| AnalyticsService | GetWarningList | GetWarningListRequest | WarningListResponse | 50055 |
|
||||
| AnalyticsService | TriggerWarning | TriggerWarningRequest | TriggerWarningResponse | 50055 |
|
||||
| AnalyticsService | GetMasteryDistribution | GetMasteryDistributionRequest | MasteryDistribution | 50055 |
|
||||
| AnalyticsService | GetStudentMastery | GetStudentMasteryRequest | StudentMastery | 50055 |
|
||||
| AnalyticsService | SubscribeMasteryUpdate | SubscribeMasteryUpdateRequest | stream MasteryUpdateEvent | 50055 |
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
无对外 HTTP 端点,仅 gRPC(含 1 个 Server Streaming RPC)。
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
| Topic | Event | 消费方 |
|
||||
| --------------------------- | --------------------------------------------------------- | -------------- |
|
||||
| edu.data_ana.mastery.events | MasteryEvent(action: mastery.updated/warning.triggered) | core-edu / msg |
|
||||
|
||||
> 注:MasteryEvent 豁免 Outbox 模式(派生数据事件,见 004 §12.2 + §15.3 #6)。
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`DATA_ANA_`(如 DATA_ANA_DASHBOARD_UNAVAILABLE、DATA_ANA_MASTERY_NOT_COMPUTED)
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
无主动 gRPC 调用上游。data-ana 通过 CDC + Kafka 事件接收数据,计算后发布 MasteryEvent。
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
| Topic | Event | 发布方 | mock 策略 |
|
||||
| ---------------------------------- | ------------------- | --------------- | ------------------------------------------------- |
|
||||
| edu.exam.events | ExamEvent | core-edu (ai08) | core-edu 就绪前使用 CDC 模拟数据 + 本地 stub 事件 |
|
||||
| edu.homework.events | HomeworkEvent | core-edu (ai08) | 同上 |
|
||||
| edu.grade.events | GradeEvent | core-edu (ai08) | 同上 |
|
||||
| edu.class.events | ClassEvent | core-edu (ai08) | 同上 |
|
||||
| edu.content.knowledge_point.events | KnowledgePointEvent | content (ai09) | content 就绪前使用内置知识点维度表 |
|
||||
| edu.content.question.events | QuestionEvent | content (ai09) | content 就绪前忽略 |
|
||||
| edu.ai.usage.events | AIUsageEvent | ai (ai12) | ai 就绪前忽略,AI 用量统计为空 |
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
无。
|
||||
|
||||
### 2.4 CDC 数据源(补充)
|
||||
|
||||
| 数据源 | 用途 | mock 策略 |
|
||||
| ----------------------------------------------------- | ------------------------------- | --------------------------------------------------------------------------- |
|
||||
| core-edu MySQL(exams/homework/grades/attendance 表) | Debezium CDC → Kafka 同步读模型 | core-edu 就绪前使用 ClickHouse 内置模拟数据集(30 学生 × 5 考试 × 10 作业) |
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] core-edu gRPC 50053 启用(ai08)—— 业务事件 + CDC 数据源
|
||||
- [ ] edu.exam.events / edu.homework.events / edu.grade.events / edu.class.events topic 有事件发布(ai08)
|
||||
- [ ] content gRPC 50054 启用(ai09)—— 知识点维度
|
||||
- [ ] edu.content.knowledge_point.events topic 有事件发布(ai09)
|
||||
- [ ] ai gRPC 50057 启用(ai12)—— AI 用量统计(可选,仪表盘补全)
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] data-ana gRPC 50055 启用(HealthService.Check 返回 SERVING)
|
||||
- [ ] AnalyticsService 12 RPC 可调用(含 4 端 Dashboard + Server Streaming SubscribeMasteryUpdate)
|
||||
- [ ] GetTeacherDashboard / GetStudentDashboard / GetParentDashboard / GetAdminDashboard 返回结构化数据
|
||||
- [ ] edu.data_ana.mastery.events topic 可发布(mastery.updated / warning.triggered)
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
在 data-ana 真实服务就绪前,为下游(teacher-bff / student-bff / parent-bff / admin-portal / msg)提供以下 mock:
|
||||
|
||||
- **gRPC mock**:使用 grpc-mock 拦截 50055 端口
|
||||
- GetTeacherDashboard 返回固定仪表盘(total_classes=3, class_avg_score=82.5, top_students 5 个, pending_homework_count=8)
|
||||
- GetStudentDashboard 返回固定仪表盘(avg_score=85.0, class_rank=5, weak_points 3 个)
|
||||
- GetParentDashboard 返回固定仪表盘(child_avg_score=85.0, child_class_rank=5)
|
||||
- GetAdminDashboard 返回固定仪表盘(total_teachers=50, total_students=1200, school_avg_score=80.0)
|
||||
- GetWarningList 返回固定 5 条预警(severity: warning/critical)
|
||||
- GetMasteryDistribution 返回固定分布(mastered=20, progressing=7, weak=3)
|
||||
- SubscribeMasteryUpdate 返回固定流(每 5 秒推 1 个 MasteryUpdateEvent)
|
||||
- **Kafka mock**:data-ana 就绪前不发布真实 MasteryEvent,msg 使用本地 stub 预警
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,data-ana 使用以下 mock:
|
||||
|
||||
- 业务数据:ClickHouse 内置模拟数据集(30 学生 × 5 考试 × 10 作业 × 30 天出勤),不依赖 core-edu CDC
|
||||
- 知识点维度:内置固定知识点表(数学 50 个知识点),不依赖 content 事件
|
||||
- AI 用量:AIUsageEvent 为空,仪表盘 AI 用量区块显示"暂无数据"
|
||||
- CDC 通道:core-edu 就绪前 Debezium 不启动,使用 ClickHouse 批量导入模拟数据
|
||||
95
docs/architecture/issues/contracts/iam_contract.md
Normal file
95
docs/architecture/issues/contracts/iam_contract.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# iam 对接契约
|
||||
|
||||
> 负责人:ai06
|
||||
> 关联:[matrix.md](./matrix.md)、[iam.proto](../../../packages/shared-proto/proto/iam.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
| Service | RPC | 请求 | 响应 | 端口 |
|
||||
| ---------- | ----------------------- | ------------------------------ | ---------------------------- | ----- |
|
||||
| IamService | Register | RegisterRequest | AuthResponse | 50052 |
|
||||
| IamService | Login | LoginRequest | AuthResponse | 50052 |
|
||||
| IamService | RefreshToken | RefreshTokenRequest | TokenPair | 50052 |
|
||||
| IamService | Logout | LogoutRequest | LogoutResponse | 50052 |
|
||||
| IamService | GetUserInfo | GetUserInfoRequest | UserInfo | 50052 |
|
||||
| IamService | BatchGetUsers | BatchGetUsersRequest | BatchGetUsersResponse | 50052 |
|
||||
| IamService | GetEffectivePermissions | GetEffectivePermissionsRequest | EffectivePermissionsResponse | 50052 |
|
||||
| IamService | GetEffectiveAccess | GetEffectiveAccessRequest | EffectiveAccessResponse | 50052 |
|
||||
| IamService | GetEffectiveDataScope | GetEffectiveDataScopeRequest | DataScopeResponse | 50052 |
|
||||
| IamService | GetViewports | GetViewportsRequest | ViewportsResponse | 50052 |
|
||||
| IamService | GetPublicKey | GetPublicKeyRequest | PublicKeyResponse | 50052 |
|
||||
| IamService | GetChildrenByParent | GetChildrenByParentRequest | ChildrenResponse | 50052 |
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
无对外 HTTP 端点,仅 gRPC。
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
| Topic | Event | 消费方 |
|
||||
| --------------------- | ------------------------------------------------------------------------- | --------------------------------------------------------- |
|
||||
| edu.iam.user.events | UserEvent(action: created/updated/deleted/role_changed) | core-edu / msg / push-gateway / teacher-bff / student-bff |
|
||||
| edu.iam.role.events | RoleEvent(action: created/updated) | core-edu / teacher-bff |
|
||||
| edu.iam.audit.created | AuditEvent(action: create/update/delete/login/logout/permission_change) | admin-portal |
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`IAM_`(如 IAM_UNAUTHORIZED、IAM_USER_NOT_FOUND、IAM_PERMISSION_DENIED)
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
无。iam 是身份根服务,不依赖其他业务服务。
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
无。
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
无。
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
无上游依赖。
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] iam gRPC 50052 启用(HealthService.Check 返回 SERVING)
|
||||
- [ ] IamService.Register/Login/RefreshToken/Logout 可调用(返回 AuthResponse/TokenPair)
|
||||
- [ ] IamService.GetPublicKey 可用(返回 RS256 PEM 公钥,供 api-gateway 验签)
|
||||
- [ ] IamService.GetChildrenByParent 可用(供 parent-bff 查孩子列表)
|
||||
- [ ] edu.iam.user.events / edu.iam.role.events / edu.iam.audit.created topic 可发布
|
||||
- [ ] JWT RS256 签发链路打通(access_token + refresh_token)
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
在 iam 真实服务就绪前,为下游(api-gateway / 各 BFF)提供以下 mock:
|
||||
|
||||
- **gRPC mock**:使用 grpc-mock 拦截 50052 端口,Register/Login 返回固定 AuthResponse(user.id="mock-user-001", tokens.access_token="mock-access-token")
|
||||
- **GetPublicKey mock**:返回固定 RS256 公钥 PEM(与 mock 私钥配对),供 api-gateway 验签 mock JWT
|
||||
- **GetChildrenByParent mock**:返回固定 ChildInfo 列表(2 个孩子)
|
||||
- **Kafka mock**:iam 服务就绪前不发布真实事件,下游订阅方使用本地 stub
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
不适用(无上游依赖)。
|
||||
110
docs/architecture/issues/contracts/msg_contract.md
Normal file
110
docs/architecture/issues/contracts/msg_contract.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# msg 对接契约
|
||||
|
||||
> 负责人:ai10
|
||||
> 关联:[matrix.md](./matrix.md)、[msg.proto](../../../packages/shared-proto/proto/msg.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
| Service | RPC | 请求 | 响应 | 端口 |
|
||||
| ----------------------------- | ---------------------- | ----------------------------- | --------------------------- | ----- |
|
||||
| NotificationService | SendNotification | SendNotificationRequest | Notification | 50056 |
|
||||
| NotificationService | ListNotifications | ListNotificationsRequest | ListNotificationsResponse | 50056 |
|
||||
| NotificationService | MarkAsRead | MarkAsReadRequest | MarkAsReadResponse | 50056 |
|
||||
| NotificationService | SearchNotifications | SearchNotificationsRequest | SearchNotificationsResponse | 50056 |
|
||||
| NotificationService | RecallNotification | RecallNotificationRequest | RecallNotificationResponse | 50056 |
|
||||
| NotificationPreferenceService | GetPreference | GetPreferenceRequest | NotificationPreference | 50056 |
|
||||
| NotificationPreferenceService | UpdatePreference | UpdatePreferenceRequest | NotificationPreference | 50056 |
|
||||
| NotificationPreferenceService | GetPreferenceByChannel | GetPreferenceByChannelRequest | ChannelPreference | 50056 |
|
||||
| NotificationPreferenceService | ListPreferences | ListPreferencesRequest | ListPreferencesResponse | 50056 |
|
||||
| NotificationTemplateService | CreateTemplate | CreateTemplateRequest | NotificationTemplate | 50056 |
|
||||
| NotificationTemplateService | GetTemplate | GetTemplateRequest | NotificationTemplate | 50056 |
|
||||
| NotificationTemplateService | ListTemplates | ListTemplatesRequest | ListTemplatesResponse | 50056 |
|
||||
| NotificationTemplateService | RenderTemplate | RenderTemplateRequest | RenderedTemplate | 50056 |
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
无对外 HTTP 端点,仅 gRPC。
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
| Topic | Event | 消费方 |
|
||||
| --------------------------- | ------------------------------------------------------ | ----------------------- |
|
||||
| edu.msg.notification.events | NotificationEvent(action: sent/read/recalled/failed) | push-gateway / data-ana |
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`MSG_`(如 MSG_TEMPLATE_NOT_FOUND、MSG_CHANNEL_DISABLED、MSG_RATE_LIMITED)
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
无主动 gRPC 调用上游。msg 通过 Kafka 事件被动接收业务事件后触发通知。
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
| Topic | Event | 发布方 | mock 策略 |
|
||||
| --------------------------- | --------------------------------------------------------- | --------------- | ------------------------------------------------------- |
|
||||
| edu.iam.user.events | UserEvent | iam (ai06) | iam 就绪前使用本地用户偏好默认值 |
|
||||
| edu.exam.events | ExamEvent(action: created/updated/deleted) | core-edu (ai08) | core-edu 就绪前不订阅,使用本地 stub 事件触发 mock 通知 |
|
||||
| edu.homework.events | HomeworkEvent(action: assigned/submitted/graded) | core-edu (ai08) | 同上 |
|
||||
| edu.grade.events | GradeEvent(action: recorded/updated) | core-edu (ai08) | 同上 |
|
||||
| edu.class.events | ClassEvent(action: transferred) | core-edu (ai08) | 同上 |
|
||||
| edu.data_ana.mastery.events | MasteryEvent(action: mastery.updated/warning.triggered) | data-ana (ai11) | data-ana 就绪前不订阅,预警通知使用本地 stub |
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
无。
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] iam gRPC 50052 启用(ai06)—— 用于用户通知偏好查询(可选)
|
||||
- [ ] core-edu gRPC 50053 启用(ai08)—— 业务事件来源
|
||||
- [ ] edu.exam.events / edu.homework.events / edu.grade.events / edu.class.events topic 有事件发布(ai08)
|
||||
- [ ] data-ana gRPC 50055 启用(ai11)—— 预警事件来源
|
||||
- [ ] edu.data_ana.mastery.events topic 有事件发布(ai11)
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] msg gRPC 50056 启用(HealthService.Check 返回 SERVING)
|
||||
- [ ] NotificationService 5 RPC 可调用
|
||||
- [ ] NotificationPreferenceService 4 RPC 可调用
|
||||
- [ ] NotificationTemplateService 4 RPC 可调用(含 RenderTemplate 模板渲染)
|
||||
- [ ] edu.msg.notification.events topic 可发布(供 push-gateway 推送)
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
在 msg 真实服务就绪前,为下游(teacher-bff / student-bff / parent-bff / push-gateway)提供以下 mock:
|
||||
|
||||
- **gRPC mock**:使用 grpc-mock 拦截 50056 端口
|
||||
- NotificationService.ListNotifications 返回固定 10 条未读通知
|
||||
- NotificationService.MarkAsRead 返回 success=true
|
||||
- NotificationPreferenceService.GetPreference 返回默认偏好(in_app+email 开启,sms+push 关闭)
|
||||
- NotificationTemplateService.RenderTemplate 返回固定 title+content
|
||||
- **Kafka mock**:msg 就绪前不发布真实 NotificationEvent,push-gateway 使用本地 stub 推送
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,msg 使用以下 mock:
|
||||
|
||||
- 业务事件:core-edu/data-ana 就绪前,msg 内置定时器发布本地 stub 事件(ExamEvent/HomeworkEvent),触发 mock 通知流程
|
||||
- 用户偏好:iam 就绪前使用默认偏好(所有用户 in_app 开启)
|
||||
- 模板渲染:内置 5 个常用模板(exam.created / homework.assigned / grade.recorded / warning.triggered / system.notice)
|
||||
121
docs/architecture/issues/contracts/parent-bff_contract.md
Normal file
121
docs/architecture/issues/contracts/parent-bff_contract.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# parent-bff 对接契约
|
||||
|
||||
> 负责人:ai05
|
||||
> 关联:[matrix.md](./matrix.md)、[iam.proto](../../../packages/shared-proto/proto/iam.proto)、[core_edu.proto](../../../packages/shared-proto/proto/core_edu.proto)、[analytics.proto](../../../packages/shared-proto/proto/analytics.proto)、[msg.proto](../../../packages/shared-proto/proto/msg.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
无对外 gRPC。parent-bff 是 GraphQL 聚合层。
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
| Method | Path | 用途 | 认证 |
|
||||
| ------ | -------- | ----------------------------------------- | ---------------------- |
|
||||
| POST | /graphql | 家长 BFF GraphQL 端点 | JWT 必需 + parent 角色 |
|
||||
| GET | /graphql | GraphQL Playground(开发环境) | 开发环境公开 |
|
||||
| GET | /healthz | 健康检查(liveness) | 公开 |
|
||||
| GET | /readyz | 就绪检查(readiness,含下游 gRPC 连通性) | 公开 |
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
GraphQL schema 文件路径:`apps/parent-bff/src/schema/*.graphql`(端口 :3010)
|
||||
|
||||
核心 Query / Mutation 域:
|
||||
|
||||
- **auth**:currentUser(聚合 iam.GetUserInfo + GetEffectivePermissions + GetViewports)
|
||||
- **children**:myChildren(聚合 iam.GetChildrenByParent,核心依赖 I3 裁决)
|
||||
- **childSummary**:childSummary(聚合 data-ana.AnalyticsService.GetParentDashboard)
|
||||
- **childGrades**:childGrades(聚合 core-edu.GradeService.ListGradesByStudent)
|
||||
- **childAttendance**:childAttendance(聚合 core-edu.AttendanceService.ListAttendanceByStudent)
|
||||
- **childHomework**:childHomework(聚合 core-edu.HomeworkService.ListHomeworkByClass)
|
||||
- **childWeakness**:childWeakness(聚合 data-ana.AnalyticsService.GetStudentWeakness)
|
||||
- **childTrend**:childTrend(聚合 data-ana.AnalyticsService.GetLearningTrend)
|
||||
- **notifications**:myNotifications / markAsRead(聚合 msg.NotificationService)
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
无。parent-bff 不发布事件,仅做 gRPC 聚合。
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`BFF_PARENT_`(如 BFF_PARENT_UPSTREAM_UNAVAILABLE、BFF_PARENT_AGGREGATION_FAILED、BFF_PARENT_NO_CHILDREN、BFF_PARENT_FORBIDDEN)
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
| 被调用方 | Service.RPC | 用途 | mock 策略 |
|
||||
| --------------- | ----------------------------------------- | ------------------------ | ------------------------------------------------------ |
|
||||
| iam (ai06) | IamService.GetUserInfo | 获取当前家长信息 | iam 就绪前返回固定 UserInfo(parent 角色) |
|
||||
| iam (ai06) | IamService.GetEffectivePermissions | 权限校验 | iam 就绪前返回家长权限集 |
|
||||
| iam (ai06) | IamService.GetViewports | 家长导航菜单 | iam 就绪前返回固定视口列表 |
|
||||
| iam (ai06) | IamService.GetChildrenByParent | 查询关联孩子列表(核心) | iam 就绪前返回固定 2 个 ChildInfo(I3/ISSUE-047 裁决) |
|
||||
| core-edu (ai08) | GradeService.ListGradesByStudent | 孩子成绩 | core-edu 就绪前返回固定 5 个 Grade |
|
||||
| core-edu (ai08) | AttendanceService.ListAttendanceByStudent | 孩子考勤 | core-edu 就绪前返回固定 10 条 Attendance |
|
||||
| core-edu (ai08) | HomeworkService.ListHomeworkByClass | 孩子作业 | core-edu 就绪前返回固定 3 个 Homework |
|
||||
| data-ana (ai11) | AnalyticsService.GetParentDashboard | 家长仪表盘 | data-ana 就绪前返回固定仪表盘(child_avg_score=85.0) |
|
||||
| data-ana (ai11) | AnalyticsService.GetStudentWeakness | 孩子薄弱点 | data-ana 就绪前返回固定 3 个 weak_points |
|
||||
| data-ana (ai11) | AnalyticsService.GetLearningTrend | 孩子学习趋势 | data-ana 就绪前返回固定趋势数据 |
|
||||
| msg (ai10) | NotificationService.ListNotifications | 家长通知 | msg 就绪前返回固定 10 条通知 |
|
||||
| msg (ai10) | NotificationService.MarkAsRead | 标记已读 | msg 就绪前返回 success=true |
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
无。parent-bff 不订阅 Kafka 事件,仅做同步 gRPC 聚合。
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
无。
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] iam gRPC 50052 启用(ai06)—— **核心依赖 GetChildrenByParent(I3/ISSUE-047 裁决)**
|
||||
- [ ] core-edu gRPC 50053 启用(ai08)
|
||||
- [ ] data-ana gRPC 50055 启用(ai11)
|
||||
- [ ] msg gRPC 50056 启用(ai10)
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] parent-bff GraphQL :3010 启用(/healthz 返回 200)
|
||||
- [ ] /readyz 返回 200(含 4 个下游 gRPC 连通性检查)
|
||||
- [ ] GraphQL schema 可内省(POST /graphql 返回 schema)
|
||||
- [ ] 核心 Query 可执行:currentUser / myChildren / childSummary / childGrades
|
||||
- [ ] 核心 Mutation 可执行:markAsRead
|
||||
- [ ] 数据范围校验生效(家长只能查自己孩子的数据,基于 iam.GetChildrenByParent 返回的 user_id 校验)
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
在 parent-bff 真实就绪前,为下游(parent-portal)提供以下 mock:
|
||||
|
||||
- **GraphQL mock**:使用 Apollo Server mockProviders 或 MSW 拦截 POST /graphql
|
||||
- currentUser 返回固定家长(id="parent-001", name="王家长", roles=["parent"])
|
||||
- myChildren 返回固定 2 个孩子(id="student-001" 李同学 + id="student-002" 李妹妹)
|
||||
- childSummary 返回固定仪表盘(child_avg_score=85.0, child_class_rank=5)
|
||||
- childGrades 返回固定 5 个成绩
|
||||
- childAttendance 返回固定 10 条考勤
|
||||
- myNotifications 返回固定 10 条通知
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,parent-bff 使用以下 mock(详见 §2.1 mock 策略列):
|
||||
|
||||
- **iam mock**:固定 UserInfo + 家长权限 + 固定视口 + 固定 2 个 ChildInfo(家长-学生关联核心数据)
|
||||
- **core-edu mock**:固定孩子成绩/考勤/作业
|
||||
- **data-ana mock**:固定家长仪表盘/孩子薄弱点/趋势
|
||||
- **msg mock**:固定通知列表 + MarkAsRead success
|
||||
|
||||
> 关键:iam.GetChildrenByParent 的 mock 必须返回与 core-edu mock 数据一致的 student_id,否则数据范围校验会失败。parent-bff 启动时校验 myChildren 返回的 user_id 与下游查询的 student_id 一致性。
|
||||
124
docs/architecture/issues/contracts/parent-portal_contract.md
Normal file
124
docs/architecture/issues/contracts/parent-portal_contract.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# parent-portal 对接契约
|
||||
|
||||
> 负责人:ai15
|
||||
> 关联:[matrix.md](./matrix.md)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
无。parent-portal 是前端微前端 Remote。
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
| Method | Path | 用途 | 认证 |
|
||||
| ------ | --------------------- | ------------ | ------------------------------------- |
|
||||
| GET | / | 家长门户首页 | JWT 必需(前端路由守卫) |
|
||||
| GET | /children | 我的孩子列表 | JWT 必需 |
|
||||
| GET | /child/:id/summary | 孩子概况 | JWT 必需 + 数据范围校验(仅自己孩子) |
|
||||
| GET | /child/:id/grades | 孩子成绩 | JWT 必需 + 数据范围校验 |
|
||||
| GET | /child/:id/attendance | 孩子考勤 | JWT 必需 + 数据范围校验 |
|
||||
| GET | /child/:id/homework | 孩子作业 | JWT 必需 + 数据范围校验 |
|
||||
| GET | /child/:id/weakness | 孩子薄弱点 | JWT 必需 + 数据范围校验 |
|
||||
| GET | /notifications | 通知中心 | JWT 必需 |
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。parent-portal 消费 parent-bff GraphQL,自身不提供 schema。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
无。
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
无(前端不定义错误码前缀,透传 BFF 错误码)。
|
||||
|
||||
### 1.6 微前端架构(补充)
|
||||
|
||||
| 角色 | 说明 |
|
||||
| ---------------------- | ------------------------------------------------ |
|
||||
| MF Remote | 家长门户是微前端远程模块 |
|
||||
| 暴露的 remote 模块 | ParentApp(家长端完整应用)、shared 家长端组件 |
|
||||
| module federation 配置 | `apps/parent-portal/module-federation.config.ts` |
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
无。前端不直接调 gRPC。
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
无。前端不直接订阅 Kafka。
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
| 被调用方 | Method.Path | 用途 | mock 策略 |
|
||||
| ------------------- | ------------------------ | -------------------------------------------- | ---------------------------------------------------------------- |
|
||||
| api-gateway (ai01) | POST /api/parent/graphql | 家长 GraphQL 查询(经网关代理到 parent-bff) | api-gateway/parent-bff 就绪前使用 MSW 拦截返回 mock GraphQL 响应 |
|
||||
| api-gateway (ai01) | POST /api/auth/login | 家长登录 | api-gateway 就绪前使用 MSW 返回固定 JWT |
|
||||
| push-gateway (ai02) | GET /ws | WebSocket 实时通知 | push-gateway 就绪前使用 mock-socket 模拟 WS 推送 |
|
||||
|
||||
### 2.4 GraphQL 查询域(经 api-gateway 代理到 parent-bff)
|
||||
|
||||
| Query/Mutation | 用途 | mock 策略 |
|
||||
| ---------------------------- | -------------------- | ----------------------------- |
|
||||
| currentUser | 当前家长信息 | MSW 返回固定家长 |
|
||||
| myChildren | 我的孩子列表(核心) | MSW 返回固定 2 个孩子 |
|
||||
| childSummary | 孩子概况 | MSW 返回固定仪表盘 |
|
||||
| childGrades | 孩子成绩 | MSW 返回固定 5 个成绩 |
|
||||
| childAttendance | 孩子考勤 | MSW 返回固定 10 条考勤 |
|
||||
| childHomework | 孩子作业 | MSW 返回固定 3 个作业 |
|
||||
| childWeakness | 孩子薄弱点 | MSW 返回固定 3 个 weak_points |
|
||||
| childTrend | 孩子学习趋势 | MSW 返回固定趋势数据 |
|
||||
| myNotifications / markAsRead | 通知中心 | MSW 返回固定通知 |
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] api-gateway HTTP :8080 启用(ai01)—— 前端请求入口
|
||||
- [ ] parent-bff GraphQL :3010 启用(ai05)—— 数据来源
|
||||
- [ ] push-gateway WebSocket :8081/ws 启用(ai02)—— 实时通知
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] parent-portal dev server :4002 启用
|
||||
- [ ] MF Remote 可被 AppShell 加载(暴露 ParentApp 模块)
|
||||
- [ ] 独立壳渲染(首页 + 导航 + 路由守卫)
|
||||
- [ ] 登录流程可用(POST /api/auth/login 获取 JWT 存入 cookie)
|
||||
- [ ] GraphQL 查询可执行(currentUser / myChildren / childSummary 返回数据)
|
||||
- [ ] 数据范围校验生效(前端路由守卫校验 child:id 是否在 myChildren 返回列表中)
|
||||
- [ ] WebSocket 通知可接收
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
parent-portal 是前端,无下游消费方。但对开发体验提供:
|
||||
|
||||
- **Storybook**:各组件独立 story
|
||||
- **MSW handlers**:`apps/parent-portal/src/mocks/handlers.ts`,拦截所有 GraphQL/HTTP 请求
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,parent-portal 使用以下 mock:
|
||||
|
||||
- **HTTP/GraphQL mock**:使用 MSW 拦截所有请求
|
||||
- POST /api/auth/login → 返回固定 JWT + UserInfo(parent 角色)
|
||||
- POST /api/parent/graphql → 根据 operationName 返回对应 mock 响应(与 parent-bff mock 数据一致)
|
||||
- myChildren mock 必须返回固定 2 个孩子(id="student-001" + "student-002"),与其他 child* 查询的 student_id 一致
|
||||
- 所有 mock 响应定义在 `apps/parent-portal/src/mocks/fixtures/*.json`
|
||||
- **WebSocket mock**:使用 mock-socket 库
|
||||
- 连接后每 30 秒推送 1 条 mock 通知
|
||||
- **JWT mock**:使用固定 mock JWT,存入 httpOnly cookie
|
||||
- **环境切换**:通过 `NEXT_PUBLIC_API_MOCKING=enabled` 环境变量控制,上游就绪后设为 `disabled`
|
||||
101
docs/architecture/issues/contracts/push-gateway_contract.md
Normal file
101
docs/architecture/issues/contracts/push-gateway_contract.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# push-gateway 对接契约
|
||||
|
||||
> 负责人:ai02
|
||||
> 关联:[matrix.md](./matrix.md)、[msg.proto](../../../packages/shared-proto/proto/msg.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
无对外 gRPC。push-gateway 是 WebSocket/SSE 推送入口。
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
| Method | Path | 用途 | 认证 |
|
||||
| ------ | ------------------- | -------------------------------------- | -------------------------------- |
|
||||
| GET | /ws | WebSocket 升级端点(实时推送通知) | JWT 必需(query param 传 token) |
|
||||
| GET | /sse | SSE 推送端点(备选实时通道) | JWT 必需 |
|
||||
| POST | /internal/broadcast | 内部广播接口(msg 服务触发) | 内网 mTLS |
|
||||
| POST | /internal/send | 内部单推接口(msg 服务触发) | 内网 mTLS |
|
||||
| GET | /healthz | 健康检查(liveness) | 公开 |
|
||||
| GET | /readyz | 就绪检查(readiness,含 Kafka 连通性) | 公开 |
|
||||
| GET | /metrics | Prometheus 指标端点 | 公开(内网) |
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
无。push-gateway 不发布事件,仅消费事件触发推送。
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`PUSH_`(如 PUSH_CONNECTION_FAILED、PUSH_CHANNEL_CLOSED、PUSH_AUTH_INVALID)
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
无主动 gRPC 调用上游。
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
| Topic | Event | 发布方 | mock 策略 |
|
||||
| --------------------------- | --------------------------------- | ---------- | --------------------------------------------------------------------------- |
|
||||
| edu.msg.notification.events | NotificationEvent(action: sent) | msg (ai10) | msg 就绪前不订阅,使用本地定时器每 30 秒推送 1 条 mock 通知到所有连接客户端 |
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
无。
|
||||
|
||||
### 2.4 内部接口(msg 调用 push-gateway)
|
||||
|
||||
| 被调用方 | Method.Path | 用途 | 说明 |
|
||||
| ------------ | ------------------------ | ------------------ | ---------------------------------------- |
|
||||
| push-gateway | POST /internal/broadcast | msg 服务批量推送 | msg 收到业务事件后渲染模板,调此接口广播 |
|
||||
| push-gateway | POST /internal/send | msg 服务单用户推送 | msg 渲染后定向推送给目标用户 |
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] msg gRPC 50056 启用(ai10)—— 通知事件来源
|
||||
- [ ] edu.msg.notification.events topic 有事件发布(ai10)
|
||||
- [ ] iam gRPC 50052 启用(ai06)—— WebSocket 连接时 JWT 验签(可选,push-gateway 可独立验签)
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] push-gateway HTTP :8081 启用(/healthz 返回 200)
|
||||
- [ ] /readyz 返回 200(含 Kafka 连通性检查通过)
|
||||
- [ ] WebSocket /ws 端点可升级连接(JWT 鉴权后建立长连接)
|
||||
- [ ] SSE /sse 端点可建立 EventStream
|
||||
- [ ] /internal/broadcast + /internal/send 接收 msg 推送并下发到在线客户端
|
||||
- [ ] Kafka consumer edu.msg.notification.events 订阅成功
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
在 push-gateway 真实就绪前,为下游(各前端 portal)提供以下 mock:
|
||||
|
||||
- **WebSocket mock**:前端开发期使用 mock-socket 库模拟 WS 连接
|
||||
- 连接成功后每 30 秒推送 1 条 mock 通知(type="system", title="测试通知")
|
||||
- **SSE mock**:前端使用 EventSource polyfill,本地定时推送 mock 事件
|
||||
- **HTTP mock**:/internal/* 接口返回 200 success
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,push-gateway 使用以下 mock:
|
||||
|
||||
- **NotificationEvent mock**:msg 就绪前,push-gateway 内置定时器每 30 秒生成 1 条 mock NotificationEvent(action=sent),推送到所有在线客户端
|
||||
- **JWT 验签**:iam 就绪前使用本地固定 mock RS256 公钥验签 WebSocket 连接的 token
|
||||
- **Kafka 订阅**:msg 就绪前不启动 Kafka consumer,使用本地定时器替代
|
||||
130
docs/architecture/issues/contracts/student-bff_contract.md
Normal file
130
docs/architecture/issues/contracts/student-bff_contract.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# student-bff 对接契约
|
||||
|
||||
> 负责人:ai04
|
||||
> 关联:[matrix.md](./matrix.md)、[iam.proto](../../../packages/shared-proto/proto/iam.proto)、[core_edu.proto](../../../packages/shared-proto/proto/core_edu.proto)、[content.proto](../../../packages/shared-proto/proto/content.proto)、[analytics.proto](../../../packages/shared-proto/proto/analytics.proto)、[msg.proto](../../../packages/shared-proto/proto/msg.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
无对外 gRPC。student-bff 是 GraphQL 聚合层。
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
| Method | Path | 用途 | 认证 |
|
||||
| ------ | -------- | ----------------------------------------- | ----------------------- |
|
||||
| POST | /graphql | 学生 BFF GraphQL 端点 | JWT 必需 + student 角色 |
|
||||
| GET | /graphql | GraphQL Playground(开发环境) | 开发环境公开 |
|
||||
| GET | /healthz | 健康检查(liveness) | 公开 |
|
||||
| GET | /readyz | 就绪检查(readiness,含下游 gRPC 连通性) | 公开 |
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
GraphQL schema 文件路径:`apps/student-bff/src/schema/*.graphql`(端口 :3009)
|
||||
|
||||
核心 Query / Mutation 域:
|
||||
|
||||
- **auth**:currentUser(聚合 iam.GetUserInfo + GetEffectivePermissions + GetViewports)
|
||||
- **myClasses**:我的班级(聚合 core-edu.ClassService.GetClass + ListStudentsByClass)
|
||||
- **myExams**:我的考试列表(聚合 core-edu.ExamService.ListExamsByClass)
|
||||
- **myHomework**:我的作业(聚合 core-edu.HomeworkService.ListHomeworkByClass + SubmitHomework)
|
||||
- **myGrades**:我的成绩(聚合 core-edu.GradeService.ListGradesByStudent)
|
||||
- **myAttendance**:我的考勤(聚合 core-edu.AttendanceService.ListAttendanceByStudent)
|
||||
- **content**:textbooks / chapters / learningPath(聚合 content.KnowledgeGraphService.GetLearningPath)
|
||||
- **dashboard**:studentDashboard(聚合 data-ana.AnalyticsService.GetStudentDashboard)
|
||||
- **weakness**:myWeakness(聚合 data-ana.AnalyticsService.GetStudentWeakness)
|
||||
- **trend**:myTrend(聚合 data-ana.AnalyticsService.GetLearningTrend)
|
||||
- **notifications**:myNotifications / markAsRead(聚合 msg.NotificationService)
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
无。student-bff 不发布事件,仅做 gRPC 聚合。
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`BFF_STUDENT_`(如 BFF_STUDENT_UPSTREAM_UNAVAILABLE、BFF_STUDENT_AGGREGATION_FAILED、BFF_STUDENT_FORBIDDEN)
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
| 被调用方 | Service.RPC | 用途 | mock 策略 |
|
||||
| --------------- | ----------------------------------------- | ---------------- | ------------------------------------------- |
|
||||
| iam (ai06) | IamService.GetUserInfo | 获取当前学生信息 | iam 就绪前返回固定 UserInfo(student 角色) |
|
||||
| iam (ai06) | IamService.GetEffectivePermissions | 权限校验 | iam 就绪前返回学生权限集 |
|
||||
| iam (ai06) | IamService.GetViewports | 学生导航菜单 | iam 就绪前返回固定视口列表 |
|
||||
| core-edu (ai08) | ClassService.GetClass | 我的班级详情 | core-edu 就绪前返回固定 ClassInfo |
|
||||
| core-edu (ai08) | ClassService.ListStudentsByClass | 班级同学名单 | core-edu 就绪前返回固定 30 个 StudentInfo |
|
||||
| core-edu (ai08) | ExamService.ListExamsByClass | 我的考试 | core-edu 就绪前返回固定 2 个 Exam |
|
||||
| core-edu (ai08) | HomeworkService.ListHomeworkByClass | 我的作业 | core-edu 就绪前返回固定 3 个 Homework |
|
||||
| core-edu (ai08) | HomeworkService.SubmitHomework | 提交作业 | core-edu 就绪前返回 success=true |
|
||||
| core-edu (ai08) | GradeService.ListGradesByStudent | 我的成绩 | core-edu 就绪前返回固定 5 个 Grade |
|
||||
| core-edu (ai08) | AttendanceService.ListAttendanceByStudent | 我的考勤 | core-edu 就绪前返回固定 10 条 Attendance |
|
||||
| content (ai09) | TextbookService.ListTextbooks | 教材列表 | content 就绪前返回固定 5 个教材 |
|
||||
| content (ai09) | ChapterService.ListChapters | 章节列表 | content 就绪前返回固定章节树 |
|
||||
| content (ai09) | KnowledgeGraphService.GetLearningPath | 学习路径 | content 就绪前返回固定 8 个知识点推荐顺序 |
|
||||
| data-ana (ai11) | AnalyticsService.GetStudentDashboard | 学生仪表盘 | data-ana 就绪前返回固定仪表盘 |
|
||||
| data-ana (ai11) | AnalyticsService.GetStudentWeakness | 我的薄弱点 | data-ana 就绪前返回固定 3 个 weak_points |
|
||||
| data-ana (ai11) | AnalyticsService.GetLearningTrend | 学习趋势 | data-ana 就绪前返回固定趋势数据 |
|
||||
| msg (ai10) | NotificationService.ListNotifications | 学生通知 | msg 就绪前返回固定 10 条通知 |
|
||||
| msg (ai10) | NotificationService.MarkAsRead | 标记已读 | msg 就绪前返回 success=true |
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
无。student-bff 不订阅 Kafka 事件,仅做同步 gRPC 聚合。
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
无。
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] iam gRPC 50052 启用(ai06)
|
||||
- [ ] core-edu gRPC 50053 启用(ai08)
|
||||
- [ ] content gRPC 50054 启用(ai09)
|
||||
- [ ] data-ana gRPC 50055 启用(ai11)
|
||||
- [ ] msg gRPC 50056 启用(ai10)
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] student-bff GraphQL :3009 启用(/healthz 返回 200)
|
||||
- [ ] /readyz 返回 200(含 5 个下游 gRPC 连通性检查)
|
||||
- [ ] GraphQL schema 可内省(POST /graphql 返回 schema)
|
||||
- [ ] 核心 Query 可执行:currentUser / myClasses / studentDashboard / myGrades
|
||||
- [ ] 核心 Mutation 可执行:submitHomework / markAsRead
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
在 student-bff 真实就绪前,为下游(student-portal)提供以下 mock:
|
||||
|
||||
- **GraphQL mock**:使用 Apollo Server mockProviders 或 MSW 拦截 POST /graphql
|
||||
- currentUser 返回固定学生(id="student-001", name="李同学", roles=["student"])
|
||||
- myClasses 返回固定 1 个班级
|
||||
- studentDashboard 返回固定仪表盘(avg_score=85.0, class_rank=5)
|
||||
- myGrades 返回固定 5 个成绩
|
||||
- myHomework 返回固定 3 个作业(1 个待提交)
|
||||
- myNotifications 返回固定 10 条通知
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,student-bff 使用以下 mock(详见 §2.1 mock 策略列):
|
||||
|
||||
- **iam mock**:固定 UserInfo + 学生权限 + 固定视口
|
||||
- **core-edu mock**:固定班级/同学/考试/作业/成绩/考勤
|
||||
- **content mock**:固定教材/章节/学习路径
|
||||
- **data-ana mock**:固定仪表盘/薄弱点/趋势
|
||||
- **msg mock**:固定通知列表 + MarkAsRead success
|
||||
|
||||
> 所有上游 mock 通过 gRPC client 拦截器实现,上游就绪后移除拦截器切换真实调用。
|
||||
125
docs/architecture/issues/contracts/student-portal_contract.md
Normal file
125
docs/architecture/issues/contracts/student-portal_contract.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# student-portal 对接契约
|
||||
|
||||
> 负责人:ai14
|
||||
> 关联:[matrix.md](./matrix.md)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
无。student-portal 是前端微前端 Remote。
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
| Method | Path | 用途 | 认证 |
|
||||
| ------ | -------------- | ------------ | ------------------------ |
|
||||
| GET | / | 学生门户首页 | JWT 必需(前端路由守卫) |
|
||||
| GET | /my-classes | 我的班级 | JWT 必需 |
|
||||
| GET | /my-exams | 我的考试 | JWT 必需 |
|
||||
| GET | /my-homework | 我的作业 | JWT 必需 |
|
||||
| GET | /my-grades | 我的成绩 | JWT 必需 |
|
||||
| GET | /my-attendance | 我的考勤 | JWT 必需 |
|
||||
| GET | /learning-path | 学习路径 | JWT 必需 |
|
||||
| GET | /dashboard | 学生仪表盘 | JWT 必需 |
|
||||
| GET | /notifications | 通知中心 | JWT 必需 |
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。student-portal 消费 student-bff GraphQL,自身不提供 schema。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
无。
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
无(前端不定义错误码前缀,透传 BFF 错误码)。
|
||||
|
||||
### 1.6 微前端架构(补充)
|
||||
|
||||
| 角色 | 说明 |
|
||||
| ---------------------- | ----------------------------------------------------------------- |
|
||||
| MF Remote | 学生门户是微前端远程模块,由 teacher-portal AppShell 或独立壳加载 |
|
||||
| 暴露的 remote 模块 | StudentApp(学生端完整应用)、shared 学生端组件 |
|
||||
| module federation 配置 | `apps/student-portal/module-federation.config.ts` |
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
无。前端不直接调 gRPC。
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
无。前端不直接订阅 Kafka。
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
| 被调用方 | Method.Path | 用途 | mock 策略 |
|
||||
| ------------------- | ------------------------- | --------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| api-gateway (ai01) | POST /api/student/graphql | 学生 GraphQL 查询(经网关代理到 student-bff) | api-gateway/student-bff 就绪前使用 MSW 拦截返回 mock GraphQL 响应 |
|
||||
| api-gateway (ai01) | POST /api/auth/login | 学生登录 | api-gateway 就绪前使用 MSW 返回固定 JWT |
|
||||
| push-gateway (ai02) | GET /ws | WebSocket 实时通知 | push-gateway 就绪前使用 mock-socket 模拟 WS 推送 |
|
||||
|
||||
### 2.4 GraphQL 查询域(经 api-gateway 代理到 student-bff)
|
||||
|
||||
| Query/Mutation | 用途 | mock 策略 |
|
||||
| ----------------------------------- | --------------- | -------------------------------------------------- |
|
||||
| currentUser | 当前学生信息 | MSW 返回固定学生 |
|
||||
| myClasses | 我的班级 | MSW 返回固定 1 个班级 |
|
||||
| myExams | 我的考试 | MSW 返回固定 2 个考试 |
|
||||
| myHomework / submitHomework | 我的作业 + 提交 | MSW 返回固定作业 + submitHomework success |
|
||||
| myGrades | 我的成绩 | MSW 返回固定 5 个成绩 |
|
||||
| myAttendance | 我的考勤 | MSW 返回固定 10 条考勤 |
|
||||
| textbooks / chapters / learningPath | 学习内容 | MSW 返回固定内容 + 学习路径 |
|
||||
| studentDashboard | 学生仪表盘 | MSW 返回固定仪表盘(avg_score=85.0, class_rank=5) |
|
||||
| myWeakness | 我的薄弱点 | MSW 返回固定 3 个 weak_points |
|
||||
| myTrend | 学习趋势 | MSW 返回固定趋势数据 |
|
||||
| myNotifications / markAsRead | 通知中心 | MSW 返回固定通知 |
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] api-gateway HTTP :8080 启用(ai01)—— 前端请求入口
|
||||
- [ ] student-bff GraphQL :3009 启用(ai04)—— 数据来源
|
||||
- [ ] push-gateway WebSocket :8081/ws 启用(ai02)—— 实时通知
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] student-portal dev server :4001 启用
|
||||
- [ ] MF Remote 可被 AppShell 加载(暴露 StudentApp 模块)
|
||||
- [ ] 独立壳渲染(首页 + 导航 + 路由守卫)
|
||||
- [ ] 登录流程可用(POST /api/auth/login 获取 JWT 存入 cookie)
|
||||
- [ ] GraphQL 查询可执行(currentUser / myClasses / studentDashboard 返回数据)
|
||||
- [ ] WebSocket 通知可接收
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
student-portal 是前端,无下游消费方。但对开发体验提供:
|
||||
|
||||
- **Storybook**:各组件独立 story
|
||||
- **MSW handlers**:`apps/student-portal/src/mocks/handlers.ts`,拦截所有 GraphQL/HTTP 请求
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,student-portal 使用以下 mock:
|
||||
|
||||
- **HTTP/GraphQL mock**:使用 MSW 拦截所有请求
|
||||
- POST /api/auth/login → 返回固定 JWT + UserInfo(student 角色)
|
||||
- POST /api/student/graphql → 根据 operationName 返回对应 mock 响应(与 student-bff mock 数据一致)
|
||||
- 所有 mock 响应定义在 `apps/student-portal/src/mocks/fixtures/*.json`
|
||||
- **WebSocket mock**:使用 mock-socket 库
|
||||
- 连接后每 30 秒推送 1 条 mock 通知
|
||||
- **JWT mock**:使用固定 mock JWT,存入 httpOnly cookie
|
||||
- **环境切换**:通过 `NEXT_PUBLIC_API_MOCKING=enabled` 环境变量控制,上游就绪后设为 `disabled`
|
||||
136
docs/architecture/issues/contracts/teacher-bff_contract.md
Normal file
136
docs/architecture/issues/contracts/teacher-bff_contract.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# teacher-bff 对接契约
|
||||
|
||||
> 负责人:ai03
|
||||
> 关联:[matrix.md](./matrix.md)、[iam.proto](../../../packages/shared-proto/proto/iam.proto)、[core_edu.proto](../../../packages/shared-proto/proto/core_edu.proto)、[content.proto](../../../packages/shared-proto/proto/content.proto)、[analytics.proto](../../../packages/shared-proto/proto/analytics.proto)、[msg.proto](../../../packages/shared-proto/proto/msg.proto)、[ai.proto](../../../packages/shared-proto/proto/ai.proto)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
无对外 gRPC。teacher-bff 是 GraphQL 聚合层。
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
| Method | Path | 用途 | 认证 |
|
||||
| ------ | -------- | ----------------------------------------- | ----------------------- |
|
||||
| POST | /graphql | 教师 BFF GraphQL 端点 | JWT 必需 + teacher 角色 |
|
||||
| GET | /graphql | GraphQL Playground(开发环境) | 开发环境公开 |
|
||||
| GET | /healthz | 健康检查(liveness) | 公开 |
|
||||
| GET | /readyz | 就绪检查(readiness,含下游 gRPC 连通性) | 公开 |
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
GraphQL schema 文件路径:`apps/teacher-bff/src/schema/*.graphql`(端口 :3003)
|
||||
|
||||
核心 Query / Mutation 域:
|
||||
|
||||
- **auth**:currentUser(聚合 iam.GetUserInfo + GetEffectivePermissions + GetViewports)
|
||||
- **classes**:myClasses(聚合 core-edu.ClassService.GetClassesByTeacher)
|
||||
- **students**:classStudents(聚合 core-edu.ClassService.ListStudentsByClass + iam.BatchGetUsers 补用户名)
|
||||
- **exams**:classExams / createExam / updateExam(聚合 core-edu.ExamService)
|
||||
- **homework**:classHomework / assignHomework(聚合 core-edu.HomeworkService)
|
||||
- **grades**:studentGrades / recordGrade(聚合 core-edu.GradeService)
|
||||
- **attendance**:classAttendance / recordAttendance(聚合 core-edu.AttendanceService)
|
||||
- **content**:textbooks / chapters / knowledgePoints / questions(聚合 content 4 个 Service)
|
||||
- **dashboard**:teacherDashboard(聚合 data-ana.AnalyticsService.GetTeacherDashboard)
|
||||
- **notifications**:myNotifications / markAsRead(聚合 msg.NotificationService)
|
||||
- **ai**:aiChat / generateQuestion / generateLessonPlan(聚合 ai.AiService)
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
无。teacher-bff 不发布事件,仅做 gRPC 聚合。
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
`BFF_TEACHER_`(如 BFF_TEACHER_UPSTREAM_UNAVAILABLE、BFF_TEACHER_AGGREGATION_FAILED、BFF_TEACHER_FORBIDDEN)
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
| 被调用方 | Service.RPC | 用途 | mock 策略 |
|
||||
| --------------- | ------------------------------------- | ---------------- | ----------------------------------------------- |
|
||||
| iam (ai06) | IamService.GetUserInfo | 获取当前教师信息 | iam 就绪前返回固定 UserInfo(teacher 角色) |
|
||||
| iam (ai06) | IamService.BatchGetUsers | 批量补全学生姓名 | iam 就绪前返回固定用户名("学生001"~"学生030") |
|
||||
| iam (ai06) | IamService.GetEffectivePermissions | 权限校验 | iam 就绪前返回全权限(放行) |
|
||||
| iam (ai06) | IamService.GetViewports | 教师导航菜单 | iam 就绪前返回固定视口列表 |
|
||||
| core-edu (ai08) | ClassService.GetClassesByTeacher | 教师班级列表 | core-edu 就绪前返回固定 3 个 ClassInfo |
|
||||
| core-edu (ai08) | ClassService.ListStudentsByClass | 班级学生名单 | core-edu 就绪前返回固定 30 个 StudentInfo |
|
||||
| core-edu (ai08) | ExamService.* | 考试管理 | core-edu 就绪前返回固定考试数据 |
|
||||
| core-edu (ai08) | HomeworkService.* | 作业管理 | core-edu 就绪前返回固定作业数据 |
|
||||
| core-edu (ai08) | GradeService.* | 成绩管理 | core-edu 就绪前返回固定成绩数据 |
|
||||
| core-edu (ai08) | AttendanceService.* | 考勤管理 | core-edu 就绪前返回固定考勤数据 |
|
||||
| content (ai09) | TextbookService.ListTextbooks | 教材列表 | content 就绪前返回固定 5 个教材 |
|
||||
| content (ai09) | ChapterService.ListChapters | 章节列表 | content 就绪前返回固定章节树 |
|
||||
| content (ai09) | KnowledgeGraphService.* | 知识图谱 | content 就绪前返回固定知识点 |
|
||||
| content (ai09) | QuestionService.SearchQuestions | 题库检索 | content 就绪前返回固定 20 题 |
|
||||
| data-ana (ai11) | AnalyticsService.GetTeacherDashboard | 教师仪表盘 | data-ana 就绪前返回固定仪表盘数据 |
|
||||
| data-ana (ai11) | AnalyticsService.GetClassPerformance | 班级成绩分析 | data-ana 就绪前返回固定分析数据 |
|
||||
| data-ana (ai11) | AnalyticsService.GetWarningList | 预警列表 | data-ana 就绪前返回固定 5 条预警 |
|
||||
| msg (ai10) | NotificationService.ListNotifications | 教师通知列表 | msg 就绪前返回固定 10 条通知 |
|
||||
| msg (ai10) | NotificationService.MarkAsRead | 标记已读 | msg 就绪前返回 success=true |
|
||||
| ai (ai12) | AiService.Chat | AI 对话 | ai 就绪前返回固定回复 |
|
||||
| ai (ai12) | AiService.GenerateQuestion | AI 出题 | ai 就绪前返回固定题目 |
|
||||
| ai (ai12) | AiService.GenerateLessonPlan | AI 备课 | ai 就绪前返回固定教案 |
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
无。teacher-bff 不订阅 Kafka 事件,仅做同步 gRPC 聚合。
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
无。
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] iam gRPC 50052 启用(ai06)
|
||||
- [ ] core-edu gRPC 50053 启用(ai08)
|
||||
- [ ] content gRPC 50054 启用(ai09)
|
||||
- [ ] data-ana gRPC 50055 启用(ai11)
|
||||
- [ ] msg gRPC 50056 启用(ai10)
|
||||
- [ ] ai gRPC 50057 启用(ai12)
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] teacher-bff GraphQL :3003 启用(/healthz 返回 200)
|
||||
- [ ] /readyz 返回 200(含 6 个下游 gRPC 连通性检查)
|
||||
- [ ] GraphQL schema 可内省(POST /graphql 返回 schema)
|
||||
- [ ] 核心 Query 可执行:currentUser / myClasses / teacherDashboard
|
||||
- [ ] 核心 Mutation 可执行:createExam / assignHomework / recordGrade
|
||||
- [ ] admin namespace 可用(供 admin-portal 消费)
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
在 teacher-bff 真实就绪前,为下游(teacher-portal / admin-portal)提供以下 mock:
|
||||
|
||||
- **GraphQL mock**:使用 Apollo Server mockProviders 或 MSW 拦截 POST /graphql
|
||||
- currentUser 返回固定教师(id="teacher-001", name="张老师", roles=["teacher"])
|
||||
- myClasses 返回固定 3 个班级
|
||||
- teacherDashboard 返回固定仪表盘数据
|
||||
- myNotifications 返回固定 10 条通知
|
||||
- **admin namespace mock**:admin-portal 查询返回固定管理员视角数据(全校统计)
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,teacher-bff 使用以下 mock(详见 §2.1 mock 策略列):
|
||||
|
||||
- **iam mock**:固定 UserInfo + 全权限 + 固定视口
|
||||
- **core-edu mock**:固定班级/学生/考试/作业/成绩/考勤数据
|
||||
- **content mock**:固定教材/章节/知识点/题目
|
||||
- **data-ana mock**:固定仪表盘/分析/预警
|
||||
- **msg mock**:固定通知列表 + MarkAsRead success
|
||||
- **ai mock**:固定 AI 回复/题目/教案
|
||||
|
||||
> 所有上游 mock 通过 gRPC client 拦截器实现,上游就绪后移除拦截器切换真实调用。
|
||||
126
docs/architecture/issues/contracts/teacher-portal_contract.md
Normal file
126
docs/architecture/issues/contracts/teacher-portal_contract.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# teacher-portal 对接契约
|
||||
|
||||
> 负责人:ai13
|
||||
> 关联:[matrix.md](./matrix.md)
|
||||
|
||||
---
|
||||
|
||||
## §1 我提供什么(对外接口)
|
||||
|
||||
### 1.1 gRPC 接口(如有)
|
||||
|
||||
无。teacher-portal 是前端微前端 Shell。
|
||||
|
||||
### 1.2 HTTP 端点(如有)
|
||||
|
||||
| Method | Path | 用途 | 认证 |
|
||||
| ------ | -------------- | ----------------------------- | ------------------------ |
|
||||
| GET | / | 教师门户首页(MF Shell 容器) | JWT 必需(前端路由守卫) |
|
||||
| GET | /classes/* | 班级管理子应用 | JWT 必需 |
|
||||
| GET | /exams/* | 考试管理子应用 | JWT 必需 |
|
||||
| GET | /homework/* | 作业管理子应用 | JWT 必需 |
|
||||
| GET | /grades/* | 成绩管理子应用 | JWT 必需 |
|
||||
| GET | /attendance/* | 考勤管理子应用 | JWT 必需 |
|
||||
| GET | /content/* | 内容管理子应用 | JWT 必需 |
|
||||
| GET | /dashboard | 教师仪表盘 | JWT 必需 |
|
||||
| GET | /ai/* | AI 助手子应用 | JWT 必需 |
|
||||
| GET | /notifications | 通知中心 | JWT 必需 |
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
不适用。teacher-portal 消费 teacher-bff GraphQL,自身不提供 schema。
|
||||
|
||||
### 1.4 Kafka 事件发布(如有)
|
||||
|
||||
无。
|
||||
|
||||
### 1.5 错误码前缀
|
||||
|
||||
无(前端不定义错误码前缀,透传 BFF 错误码)。
|
||||
|
||||
### 1.6 微前端架构(补充)
|
||||
|
||||
| 角色 | 说明 |
|
||||
| ---------------------- | --------------------------------------------------- |
|
||||
| MF Shell(AppShell) | 教师门户是微前端宿主,加载其他子应用 |
|
||||
| 暴露的 remote 模块 | AppShell(导航/布局/路由守卫)、shared 设计系统组件 |
|
||||
| module federation 配置 | `apps/teacher-portal/module-federation.config.ts` |
|
||||
|
||||
---
|
||||
|
||||
## §2 我消费什么(依赖上游)
|
||||
|
||||
### 2.1 gRPC 调用(同步)
|
||||
|
||||
无。前端不直接调 gRPC。
|
||||
|
||||
### 2.2 Kafka 事件订阅(异步)
|
||||
|
||||
无。前端不直接订阅 Kafka。
|
||||
|
||||
### 2.3 HTTP 调用(如有)
|
||||
|
||||
| 被调用方 | Method.Path | 用途 | mock 策略 |
|
||||
| ------------------- | ------------------------- | --------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| api-gateway (ai01) | POST /api/teacher/graphql | 教师 GraphQL 查询(经网关代理到 teacher-bff) | api-gateway/teacher-bff 就绪前使用 MSW 拦截返回 mock GraphQL 响应 |
|
||||
| api-gateway (ai01) | POST /api/auth/login | 教师登录 | api-gateway 就绪前使用 MSW 返回固定 JWT |
|
||||
| push-gateway (ai02) | GET /ws | WebSocket 实时通知 | push-gateway 就绪前使用 mock-socket 模拟 WS 推送 |
|
||||
|
||||
### 2.4 GraphQL 查询域(经 api-gateway 代理到 teacher-bff)
|
||||
|
||||
| Query/Mutation | 用途 | mock 策略 |
|
||||
| -------------------------------------------------- | ------------ | ---------------------- |
|
||||
| currentUser | 当前教师信息 | MSW 返回固定教师 |
|
||||
| myClasses | 我的班级 | MSW 返回固定 3 个班级 |
|
||||
| classStudents | 班级学生名单 | MSW 返回固定 30 个学生 |
|
||||
| classExams / createExam | 考试管理 | MSW 返回固定考试数据 |
|
||||
| classHomework / assignHomework | 作业管理 | MSW 返回固定作业数据 |
|
||||
| studentGrades / recordGrade | 成绩管理 | MSW 返回固定成绩数据 |
|
||||
| classAttendance / recordAttendance | 考勤管理 | MSW 返回固定考勤数据 |
|
||||
| textbooks / chapters / knowledgePoints / questions | 内容管理 | MSW 返回固定内容数据 |
|
||||
| teacherDashboard | 教师仪表盘 | MSW 返回固定仪表盘 |
|
||||
| myNotifications / markAsRead | 通知中心 | MSW 返回固定通知 |
|
||||
| aiChat / generateQuestion / generateLessonPlan | AI 助手 | MSW 返回固定 AI 响应 |
|
||||
|
||||
---
|
||||
|
||||
## §3 就绪信号
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
- [ ] api-gateway HTTP :8080 启用(ai01)—— 前端请求入口
|
||||
- [ ] teacher-bff GraphQL :3003 启用(ai03)—— 数据来源
|
||||
- [ ] push-gateway WebSocket :8081/ws 启用(ai02)—— 实时通知
|
||||
|
||||
### 3.2 我的就绪标志(供下游消费)
|
||||
|
||||
- [ ] teacher-portal dev server :4000 启用
|
||||
- [ ] MF Shell 可加载(首页渲染 AppShell + 导航)
|
||||
- [ ] 子应用路由可访问(/classes /exams /homework 等子页面渲染)
|
||||
- [ ] 登录流程可用(POST /api/auth/login 获取 JWT 存入 cookie)
|
||||
- [ ] GraphQL 查询可执行(currentUser / myClasses 返回数据)
|
||||
- [ ] WebSocket 通知可接收(push-gateway 推送 → 前端通知中心更新)
|
||||
|
||||
---
|
||||
|
||||
## §4 Mock 策略
|
||||
|
||||
### 4.1 我提供的 mock
|
||||
|
||||
teacher-portal 是最前端,无下游消费方。但对开发体验提供:
|
||||
|
||||
- **Storybook**:各组件独立 story,供设计审查
|
||||
- **MSW handlers**:`apps/teacher-portal/src/mocks/handlers.ts`,拦截所有 GraphQL/HTTP 请求返回 mock 数据
|
||||
|
||||
### 4.2 我消费的 mock
|
||||
|
||||
在真实上游就绪前,teacher-portal 使用以下 mock:
|
||||
|
||||
- **HTTP/GraphQL mock**:使用 MSW(Mock Service Worker)拦截所有请求
|
||||
- POST /api/auth/login → 返回固定 JWT + UserInfo
|
||||
- POST /api/teacher/graphql → 根据 operationName 返回对应 mock 响应(与 teacher-bff mock 数据一致)
|
||||
- 所有 mock 响应定义在 `apps/teacher-portal/src/mocks/fixtures/*.json`
|
||||
- **WebSocket mock**:使用 mock-socket 库
|
||||
- 连接 ws://localhost:8081/ws 后每 30 秒推送 1 条 mock 通知
|
||||
- **JWT mock**:使用固定 mock JWT(与 api-gateway mock 公钥配对),存入 httpOnly cookie
|
||||
- **环境切换**:通过 `NEXT_PUBLIC_API_MOCKING=enabled` 环境变量控制是否启用 MSW,上游就绪后设为 `disabled`
|
||||
Reference in New Issue
Block a user