185 lines
15 KiB
Markdown
185 lines
15 KiB
Markdown
# data-ana 对接契约
|
||
|
||
> 负责人:ai11
|
||
> 关联:[matrix.md](../matrix.md)、[coord-cross-review.md](../../coord-cross-review.md)、[analytics.proto](../../../packages/shared-proto/proto/analytics.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)、[iam.proto](../../../packages/shared-proto/proto/iam.proto)
|
||
> 对齐文档:[01-understanding.md](../../../services/data-ana/docs/01-understanding.md)、[02-architecture-design.md](../../../services/data-ana/docs/02-architecture-design.md)、[objections/data-ana_issue.md](../objections/data-ana_issue.md)、[worklines/data-ana_workline.md](../worklines/data-ana_workline.md)
|
||
> 修订:v2(2026-07-10 by ai11)—— 修正 topic 命名 / gRPC 调用声明 / HTTP 端点声明 / 引用断裂,对齐 01/02 v2.1
|
||
|
||
---
|
||
|
||
## §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 | GetWarnings | GetWarningsRequest | WarningList | 50055 |
|
||
| AnalyticsService | TriggerWarning | TriggerWarningRequest | TriggerWarningResponse | 50055 |
|
||
| AnalyticsService | GetMasteryDistribution | GetMasteryDistributionRequest | MasteryDistribution | 50055 |
|
||
| AnalyticsService | GetStudentMastery | GetStudentMasteryRequest | StudentMastery | 50055 |
|
||
| AnalyticsService | SubscribeMasteryUpdate | SubscribeMasteryUpdateRequest | stream MasteryUpdateEvent | 50055 |
|
||
|
||
> **proto 状态**:analytics.proto 当前仅 3 RPC(GetClassPerformance / GetStudentWeakness / GetLearningTrend),扩展至 12 RPC 待 coord 补全或 ai11 在 P4 阶段自行补全(见 [ISSUE-003](../objections/data-ana_issue.md))。完整 message 定义见 [02-architecture-design.md §4.2](../../../services/data-ana/docs/02-architecture-design.md)。
|
||
> **gRPC 启用阶段**:P4 启用(coord-cross-review.md §2.3 裁决),P2-P3 仅 HTTP。
|
||
> **响应信封**:所有 RPC 返回 ActionState[T](coord-cross-review.md §5.3 P0 整改)。
|
||
|
||
### 1.2 HTTP 端点
|
||
|
||
data-ana 保留 HTTP :3006 端点作 Gateway 直连降级(gRPC 不可用时 BFF 可走 HTTP)。共 14 端点(3 基础 + 11 业务):
|
||
|
||
| method | path | 权限 | 响应 |
|
||
| ------ | -------------------------------------------- | ----------------------------- | ----------------------------------- |
|
||
| GET | `/healthz` | — | `{status, service}` |
|
||
| GET | `/readyz` | — | `{status, ready, degraded, clickhouse, cdc_consumer, redis, iam_grpc}` |
|
||
| GET | `/metrics` | — | Prometheus 格式 |
|
||
| GET | `/analytics/class/{class_id}/performance` | `ANALYTICS_CLASS_READ` | `ActionState<ClassPerformanceData>` |
|
||
| GET | `/analytics/student/{student_id}/weakness` | `ANALYTICS_STUDENT_READ` | `ActionState<StudentWeaknessData>` |
|
||
| GET | `/analytics/student/{student_id}/errorbook` | `ANALYTICS_STUDENT_READ` | `ActionState<StudentErrorBookData>` |
|
||
| GET | `/analytics/student/{student_id}/trend` | `ANALYTICS_STUDENT_READ` | `ActionState<LearningTrendData>` |
|
||
| GET | `/analytics/student/{student_id}/attendance` | `ANALYTICS_STUDENT_READ` | `ActionState<AttendanceData>` |
|
||
| GET | `/analytics/dashboard/teacher/{user_id}` | `ANALYTICS_TEACHER_DASHBOARD` | `ActionState<TeacherDashboardData>` |
|
||
| GET | `/analytics/dashboard/student/{user_id}` | `ANALYTICS_STUDENT_DASHBOARD` | `ActionState<StudentDashboardData>` |
|
||
| GET | `/analytics/dashboard/parent/{user_id}` | `ANALYTICS_PARENT_DASHBOARD` | `ActionState<ParentDashboardData>` |
|
||
| GET | `/analytics/dashboard/admin/{user_id}` | `ANALYTICS_ADMIN_DASHBOARD` | `ActionState<AdminDashboardData>` |
|
||
| GET | `/analytics/warnings` | `ANALYTICS_WARNING_READ` | `ActionState<WarningListData>` |
|
||
| GET | `/analytics/mastery/distribution` | `ANALYTICS_CLASS_READ` | `ActionState<MasteryDistributionData>` |
|
||
|
||
> 完整端点设计见 [02-architecture-design.md §4.1](../../../services/data-ana/docs/02-architecture-design.md)。
|
||
|
||
### 1.3 GraphQL schema(如 BFF)
|
||
|
||
不适用。data-ana 是业务服务,不提供 GraphQL。BFF 层(teacher-bff / student-bff / parent-bff)聚合 data-ana gRPC 后对外暴露 GraphQL。
|
||
|
||
### 1.4 Kafka 事件发布
|
||
|
||
| Topic | Event | 消费方 | Outbox | 说明 |
|
||
| -------------------------------- | --------------- | ------------------------------- | ------ | ---- |
|
||
| `edu.insight.mastery.updated` | MasteryUpdated | core-edu(推荐个性化练习)/ msg | ❌ 豁免 | 掌握度计算完成触发 |
|
||
| `edu.insight.warning.triggered` | WarningTriggered | msg(推送通知)/ core-edu(标记关注) | ❌ 豁免 | 预警阈值触发 |
|
||
|
||
> **Outbox 豁免**:派生数据事件(非业务事务写),豁免 Outbox 约束([coord-cross-review.md §3.3](../../coord-cross-review.md) 已仲裁)。直接用 aiokafka AIOKafkaProducer 发布,`idempotent=true` + `transactional_id="data-ana-producer"`。
|
||
>
|
||
> **topic 命名说明**:按 004 §7.2 命名规范 `edu.<domain>.<aggregate>.<action>`,data-ana 属于 D6 智能洞察领域(domain=insight),故 `edu.insight.mastery.updated` 符合规范。matrix.md §4 中 `edu.analytics.mastery` 命名不符合规范(缺 action 层级,domain 用了服务名而非领域名),已提请 coord 统一(见 [ISSUE-005](../objections/data-ana_issue.md))。
|
||
|
||
### 1.5 错误码前缀
|
||
|
||
`DATA_ANA_`(如 DATA_ANA_DASHBOARD_UNAVAILABLE、DATA_ANA_MASTERY_NOT_COMPUTED、DATA_ANA_CLICKHOUSE_UNAVAILABLE)
|
||
|
||
> 来源:[matrix.md §6](../matrix.md) 错误码前缀矩阵。
|
||
|
||
### 1.6 ClickHouse 宽表(供 coord 统一管理 DDL)
|
||
|
||
| 宽表名 | 用途 | 引擎 |
|
||
| ------------------------- | -------------------- | ----------------------------- |
|
||
| student_dashboard_view | 学生学情宽表 | ReplacingMergeTree(last_updated) |
|
||
| student_errors | 学生错题本 | ReplacingMergeTree(last_error_time) |
|
||
| mastery_snapshot | 知识点掌握度历史快照 | MergeTree |
|
||
| attendance_logs | 学生考勤记录 | ReplacingMergeTree(occurred_at) |
|
||
| ai_usage_log | AI 用量计费记录 | ReplacingMergeTree(occurred_at) |
|
||
|
||
> DDL 由 coord 统一管理在 `infra/clickhouse/ddl/`(待 coord 建立),data-ana 提供内容。完整 DDL 见 [02-architecture-design.md §3](../../../services/data-ana/docs/02-architecture-design.md)。
|
||
|
||
---
|
||
|
||
## §2 我消费什么(依赖上游)
|
||
|
||
### 2.1 gRPC 调用(同步)
|
||
|
||
| 调用方 | 被调用方 | RPC | 用途 | 端口 | 阶段 | 状态 |
|
||
| -------- | -------- | ------------------------- | ---------------------------- | ----- | ---- | ---- |
|
||
| data-ana | iam | GetEffectiveDataScope | DataScope 6 级过滤解析 | 50052 | P4 | ⚠️ iam.proto 当前未实现(ISSUE-001) |
|
||
|
||
> **降级兜底**:iam GetEffectiveDataScope 未就绪时,data-ana 按 role 映射默认 DataScope(教师=CLASS,学生=SELF,管理员=SCHOOL),标注 `details.degraded: true`。结果 Redis 缓存 5min(key: `data_ana:datascope:{user_id}`)。
|
||
>
|
||
> **裁决依据**:coord-cross-review.md §2.2 #3 已仲裁 iam P4 补全此 RPC。
|
||
|
||
### 2.2 Kafka 事件订阅(异步)
|
||
|
||
| Topic | Event | 发布方 | mock 策略 |
|
||
| -------------------------------------- | ------------------- | --------------- | ------------------------------------------------- |
|
||
| `edu.teaching.exam.published` | ExamEvent | core-edu (ai08) | core-edu 就绪前使用 CDC 模拟数据 + 本地 stub 事件 |
|
||
| `edu.teaching.homework.assigned` | HomeworkEvent | core-edu (ai08) | 同上 |
|
||
| `edu.teaching.grade.recorded` | GradeEvent | core-edu (ai08) | 同上 |
|
||
| `edu.teaching.class.transferred` | ClassEvent | core-edu (ai08) | 同上 |
|
||
| `edu.content.kp.events` | KnowledgePointEvent | content (ai09) | content 就绪前使用内置知识点维度表 |
|
||
| `edu.content.question.events` | QuestionEvent | content (ai09) | content 就绪前忽略 |
|
||
| `edu.insight.ai.usage` | AIUsageEvent | ai (ai12) | ai 就绪前忽略,AI 用量统计为空(P5) |
|
||
|
||
> **topic 命名对齐**:core-edu 教学事件 topic 按 coord-cross-review.md §3.1 裁决统一为 `edu.teaching.<aggregate>.<action>` 风格。core-edu 代码实际发布 `edu.exam.events` 等,待 core-edu 整改后切换。
|
||
>
|
||
> **AIUsageEvent 缺失**:events.proto 当前缺 AIUsageEvent message(ISSUE-002),P5 前需 coord 补全。
|
||
|
||
### 2.3 HTTP 调用(如有)
|
||
|
||
无。data-ana 不通过 HTTP 调用上游服务。
|
||
|
||
### 2.4 CDC 数据源
|
||
|
||
| 数据源 | 用途 | mock 策略 |
|
||
| ----------------------------------------------------- | ------------------------------- | --------------------------------------------------------------------------- |
|
||
| core-edu MySQL(exams/homework/grades/attendance 表) | Debezium CDC → Kafka 同步读模型 | core-edu 就绪前使用 ClickHouse 内置模拟数据集(30 学生 × 5 考试 × 10 作业) |
|
||
| content MySQL(knowledge_points 表) | Debezium CDC → 知识点元数据同步 | content 就绪前使用内置固定知识点表(数学 50 个知识点) |
|
||
| iam MySQL(users 表) | Debezium CDC → 用户 dataScope 同步 | iam 就绪前使用硬编码 DataScope 降级 |
|
||
|
||
> **CDC topic 命名**:`edu-cdc.next_edu_cloud.<table>`(coord-cross-review.md §3.2 裁决补登 CDC topic 命名规范段,待 coord 在 004 §7.2 落实)。
|
||
|
||
---
|
||
|
||
## §3 就绪信号
|
||
|
||
### 3.1 我依赖的上游就绪标志
|
||
|
||
- [ ] core-edu gRPC 50053 启用(ai08)—— 业务事件 + CDC 数据源
|
||
- [ ] core-edu MySQL Debezium CDC 配置(ai08 + SRE)—— CDC 通道前提
|
||
- [ ] `edu.teaching.exam.published` / `edu.teaching.homework.assigned` / `edu.teaching.grade.recorded` / `edu.teaching.class.transferred` topic 有事件发布(ai08)
|
||
- [ ] content gRPC 50054 启用(ai09)—— 知识点维度 CDC
|
||
- [ ] `edu.content.kp.events` topic 有事件发布(ai09)
|
||
- [ ] iam.proto 补全 GetEffectiveDataScope RPC(ai06/coord,ISSUE-001)—— P4 阻塞项
|
||
- [ ] analytics.proto 扩展至 12 RPC(coord/ai11,ISSUE-003)—— gRPC stub 生成前提
|
||
- [ ] events.proto 补全 AIUsageEvent message(coord,ISSUE-002)—— P5 前补全
|
||
- [ ] ai gRPC 50057 启用(ai12)—— AI 用量统计(P5,可选)
|
||
|
||
### 3.2 我的就绪标志(供下游消费)
|
||
|
||
- [ ] **P4 就绪**:data-ana gRPC 50055 启用(HealthService.Check 返回 SERVING)
|
||
- [ ] **P4 就绪**:AnalyticsService 12 RPC 可调用(含 4 端 Dashboard + Warning + Mastery + Server Streaming SubscribeMasteryUpdate)
|
||
- [ ] **P4 就绪**:GetTeacherDashboard / GetStudentDashboard / GetParentDashboard / GetAdminDashboard 返回结构化数据
|
||
- [ ] **P4 就绪**:`edu.insight.mastery.updated` topic 可发布(mastery.updated / warning.triggered)
|
||
- [ ] **P5 就绪**:SubscribeMasteryUpdate server-streaming RPC 可订阅
|
||
- [ ] **P6 就绪**:CDC 多实例水平扩展 + ExamCache Redis 化完成
|
||
|
||
---
|
||
|
||
## §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)
|
||
- GetWarnings 返回固定 5 条预警(severity: warning/critical)
|
||
- GetMasteryDistribution 返回固定分布(mastered=20, progressing=7, weak=3)
|
||
- SubscribeMasteryUpdate 返回固定流(每 5 秒推 1 个 MasteryUpdateEvent)
|
||
- **Kafka mock**:data-ana 就绪前不发布真实 MasteryUpdated / WarningTriggered,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 批量导入模拟数据
|
||
- **DataScope**:iam GetEffectiveDataScope 未就绪前,按 role 映射默认 DataScope 降级(教师=CLASS,学生=SELF,管理员=SCHOOL),标注 `details.degraded: true`
|