feat(data-ana): v2 P6 硬化完成 + 6 新 RPC + Prometheus 监控
P6 硬化(5 项全部完成):
- CDC 多实例水平扩展: _INSTANCE_ID + get_lag() 真实 lag 计算
- ExamCache Redis 化: key data_ana:exam:{exam_id}, TTL 30 天 + 内存 LRU fallback
- ClickHouse TTL 归档: 5 表均加 TTL(1-3 年),分区级删除
- Prometheus 监控: 18 个指标(CDC/CH/ExamCache/DataScope/gRPC/业务)
- readyz 深度硬化: 4 依赖超时检查(CH 1s/Redis 200ms/iam 2s/CDC lag<1000)
v2 新增 6 个 RPC(analytics.proto 扩展为 18 RPC):
- GetStudentGrowth / GetAssignmentAnalysis / GetMasterySummary
- ListDiagnosticReports(占位,待 ai 服务)/ ListErrorBookItems / GetErrorBookStats
监控与可观测性: lifespan 预热 + gRPC ServerInterceptor + CDC 消费者指标
Docker 本地测试 19 项全部通过(healthz/readyz/metrics + 11 HTTP + 10 gRPC + ruff)
nextstep-v2.md: 上游需求对齐 + 下游要求(iam/core-edu/content/ai/SRE)
This commit is contained in:
@@ -30,6 +30,20 @@ service AnalyticsService {
|
||||
rpc GetStudentMastery(GetStudentMasteryRequest) returns (StudentMastery);
|
||||
// 订阅掌握度更新(server-streaming,P5+ AI 个性化推荐实时推送通道).
|
||||
rpc SubscribeMasteryUpdate(SubscribeMasteryUpdateRequest) returns (stream MasteryUpdateEvent);
|
||||
|
||||
// ===== P6+ v2 扩展 RPC(响应上游 parent-bff / student-bff v2 请求) =====
|
||||
// 学生成长档案(综合成绩趋势 + 掌握度变化 + 考勤统计,供 parent-bff GrowthArchiveService).
|
||||
rpc GetStudentGrowth(GetStudentGrowthRequest) returns (StudentGrowth);
|
||||
// 作业/考试分析(单次作业/考试维度统计,供 student-bff / parent-bff).
|
||||
rpc GetAssignmentAnalysis(GetAssignmentAnalysisRequest) returns (AssignmentAnalysis);
|
||||
// 学生掌握度汇总(轻量级,仅返回总体掌握度 + 三档分布,供 parent-bff MasteryService.GetSummary).
|
||||
rpc GetMasterySummary(GetMasterySummaryRequest) returns (MasterySummary);
|
||||
// 诊断报告列表(占位实现,真实数据需 ai 服务集成,供 parent-bff / student-bff).
|
||||
rpc ListDiagnosticReports(ListDiagnosticReportsRequest) returns (DiagnosticReportList);
|
||||
// 错题本列表(gRPC 版本,供 parent-bff ErrorBookService.List).
|
||||
rpc ListErrorBookItems(ListErrorBookItemsRequest) returns (ErrorBookList);
|
||||
// 错题本统计(按知识点聚合,供 parent-bff ErrorBookService.GetStats).
|
||||
rpc GetErrorBookStats(GetErrorBookStatsRequest) returns (ErrorBookStats);
|
||||
}
|
||||
|
||||
// ===== 请求消息 =====
|
||||
@@ -101,6 +115,44 @@ message SubscribeMasteryUpdateRequest {
|
||||
string class_id = 2; // 可选,订阅指定班级全部学生
|
||||
}
|
||||
|
||||
// ===== P6+ v2 扩展 RPC 请求消息 =====
|
||||
|
||||
message GetStudentGrowthRequest {
|
||||
string student_id = 1;
|
||||
int64 start_date = 2; // Unix timestamp(秒)
|
||||
int64 end_date = 3;
|
||||
string subject_id = 4; // 可选
|
||||
}
|
||||
|
||||
message GetAssignmentAnalysisRequest {
|
||||
string class_id = 1;
|
||||
string assignment_id = 2; // exam_id 或 homework_id
|
||||
string subject_id = 3; // 可选
|
||||
}
|
||||
|
||||
message GetMasterySummaryRequest {
|
||||
string student_id = 1;
|
||||
string subject_id = 2; // 可选
|
||||
}
|
||||
|
||||
message ListDiagnosticReportsRequest {
|
||||
string student_id = 1;
|
||||
int64 since = 2; // Unix timestamp(秒)
|
||||
int32 limit = 3; // 默认 10
|
||||
}
|
||||
|
||||
message ListErrorBookItemsRequest {
|
||||
string student_id = 1;
|
||||
string subject_id = 2; // 可选,按学科过滤
|
||||
int32 limit = 3; // 默认 100
|
||||
int32 offset = 4; // 分页偏移
|
||||
}
|
||||
|
||||
message GetErrorBookStatsRequest {
|
||||
string student_id = 1;
|
||||
string subject_id = 2; // 可选
|
||||
}
|
||||
|
||||
// ===== 响应消息 =====
|
||||
|
||||
message ClassPerformance {
|
||||
@@ -260,3 +312,111 @@ message MasteryUpdateEvent {
|
||||
double previous_level = 5;
|
||||
int64 calculated_at = 6; // Unix timestamp(秒)
|
||||
}
|
||||
|
||||
// ===== P6+ v2 扩展 RPC 响应消息 =====
|
||||
|
||||
message StudentGrowth {
|
||||
string student_id = 1;
|
||||
// 成绩趋势(来自 LearningTrend)
|
||||
repeated TrendPoint score_trend = 2;
|
||||
// 掌握度变化趋势(按时间排序的快照)
|
||||
repeated MasteryTrendPoint mastery_trend = 3;
|
||||
// 考勤统计
|
||||
AttendanceSummary attendance = 4;
|
||||
// 总体成长评分(综合分数、掌握度、考勤计算)
|
||||
double growth_score = 5;
|
||||
// 成长等级(excellent / good / average / needs_improvement)
|
||||
string growth_level = 6;
|
||||
}
|
||||
|
||||
message MasteryTrendPoint {
|
||||
int64 calculated_at = 1;
|
||||
double overall_mastery = 2;
|
||||
}
|
||||
|
||||
message AttendanceSummary {
|
||||
int32 total_days = 1;
|
||||
int32 present_days = 2;
|
||||
int32 absent_days = 3;
|
||||
int32 late_days = 4;
|
||||
double attendance_rate = 5; // 出勤率 0.0-1.0
|
||||
}
|
||||
|
||||
message AssignmentAnalysis {
|
||||
string assignment_id = 1;
|
||||
string class_id = 2;
|
||||
string subject_id = 3;
|
||||
double average_score = 4;
|
||||
double highest_score = 5;
|
||||
double lowest_score = 6;
|
||||
int32 total_students = 7;
|
||||
int32 submitted_count = 8;
|
||||
double pass_rate = 9; // 及格率
|
||||
// 分数段分布(90-100 / 80-89 / 70-79 / 60-69 / <60)
|
||||
repeated ScoreRange ranges = 10;
|
||||
}
|
||||
|
||||
message ScoreRange {
|
||||
string label = 1; // "90-100" / "80-89" etc.
|
||||
int32 count = 2;
|
||||
double percentage = 3; // 占比 0.0-1.0
|
||||
}
|
||||
|
||||
message MasterySummary {
|
||||
string student_id = 1;
|
||||
double overall_mastery = 2; // 0.0-1.0
|
||||
int32 mastered_count = 3; // mastery >= 0.8
|
||||
int32 progressing_count = 4; // 0.4 <= mastery < 0.8
|
||||
int32 weak_count = 5; // mastery < 0.4
|
||||
int32 total_knowledge_points = 6;
|
||||
string mastery_level = 7; // mastered / progressing / weak(总体)
|
||||
}
|
||||
|
||||
message DiagnosticReportList {
|
||||
string student_id = 1;
|
||||
repeated DiagnosticReport reports = 2;
|
||||
int32 total = 3;
|
||||
}
|
||||
|
||||
message DiagnosticReport {
|
||||
string report_id = 1;
|
||||
string student_id = 2;
|
||||
string report_type = 3; // KNOWLEDGE_GAP / LEARNING_STYLE / WEAKNESS_ANALYSIS
|
||||
string title = 4;
|
||||
string summary = 5; // 报告摘要
|
||||
int64 generated_at = 6; // Unix timestamp(秒)
|
||||
string status = 7; // pending / completed / failed
|
||||
}
|
||||
|
||||
message ErrorBookList {
|
||||
string student_id = 1;
|
||||
repeated ErrorBookItem items = 2;
|
||||
int32 total = 3;
|
||||
}
|
||||
|
||||
message ErrorBookItem {
|
||||
string question_id = 1;
|
||||
string knowledge_point_id = 2;
|
||||
string knowledge_point_title = 3;
|
||||
int32 error_count = 4;
|
||||
int64 last_error_time = 5; // Unix timestamp(秒)
|
||||
string content = 6; // 题目内容摘要
|
||||
}
|
||||
|
||||
message ErrorBookStats {
|
||||
string student_id = 1;
|
||||
int32 total_error_questions = 2;
|
||||
int32 total_error_count = 3; // 总错误次数
|
||||
// 按知识点聚合的错题统计
|
||||
repeated KnowledgePointErrorStats by_knowledge_point = 4;
|
||||
// 最近 7 天错误次数
|
||||
int32 recent_7d_errors = 5;
|
||||
}
|
||||
|
||||
message KnowledgePointErrorStats {
|
||||
string knowledge_point_id = 1;
|
||||
string title = 2;
|
||||
int32 error_count = 3;
|
||||
int32 question_count = 4;
|
||||
double error_rate = 5; // 错误率 0.0-1.0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user