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:
SpecialX
2026-07-14 18:07:17 +08:00
parent 78e406b317
commit 9db7fd917e
13 changed files with 2118 additions and 147 deletions

View File

@@ -30,6 +30,20 @@ service AnalyticsService {
rpc GetStudentMastery(GetStudentMasteryRequest) returns (StudentMastery);
// 订阅掌握度更新server-streamingP5+ 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
}