# data-ana 模块上下游依赖与工作清单(Next Steps) > 模块:data-ana(智能洞察域,数据分析服务) > 负责人:ai11 > 更新日期:2026-07-13 > 关联文档:[01-understanding.md](./01-understanding.md)、[02-architecture-design.md](./02-architecture-design.md)、[data-ana_contract.md](../../../docs/architecture/issues/contracts/data-ana_contract.md)、[data-ana_workline.md](../../../docs/architecture/issues/worklines/data-ana_workline.md) --- ## 1. 模块当前状态 data-ana 已完成 P2-P5 全部代码实现,P6 硬化期未开始。当前服务包含: - **HTTP 14 端点**(3 基础 + 11 业务),端口 3006 - **gRPC 12 RPC**(11 unary + 1 server-streaming),端口 50055 - **CDC 消费者**:Debezium binlog → ClickHouse 5 宽表,手动 commit + Redis 去重 - **ClickHouse 宽表**:student_dashboard_view / student_errors / mastery_snapshot / ai_usage_log / attendance_logs - **Kafka 生产者**:MasteryEvent + WarningTriggered(Outbox 豁免) - **iam gRPC 集成**:GetEffectiveDataScope + Redis 缓存 + role 降级兜底 - **降级模式**:ClickHouse/Kafka/Redis/iam 任一不可达时服务仍可启动 --- ## 2. 上游依赖(data-ana 依赖谁) ### 2.1 iam 服务(ai06 负责)— P0 | # | 依赖项 | 用途 | 状态 | | --- | ------------------------------------------- | ------------------------------------------------------------------ | ----------------------------- | | 1 | gRPC `GetEffectiveDataScope(userId)` :50052 | DataScope 6 级过滤(SELF/CLASS/GRADE/SCHOOL/DISTRICT/ALL) | ✅ 已就绪(iam.proto 已补全) | | 2 | REST `GET /healthz` :3002 | /readyz 下游健康检查 | ⏳ 待 iam 容器启动 | | 3 | JWT RS256 公钥 | (data-ana 不直接验签,由 api-gateway 验签后注入 x-user-* header) | — | **环境变量**:`DATA_ANA_IAM_GRPC_TARGET=iam:50052` **降级策略**:iam 不可达时按 role 映射默认 DataScope + `degraded: true` ### 2.2 ClickHouse(基础设施)— P0 | # | 依赖项 | 用途 | 状态 | | --- | ---------------- | ------------------------------ | -------------------------------------- | | 1 | ClickHouse :8123 | 5 宽表读写(分析查询核心存储) | ✅ Docker 已启动 | | 2 | DDL 建表 | 5 宽表 schema | ✅ 已创建 `scripts/clickhouse_ddl.sql` | | 3 | 种子数据 | mock 数据集 | ✅ 已创建 `scripts/seed_clickhouse.py` | **环境变量**:`DATA_ANA_CLICKHOUSE_HOST=clickhouse`、`DATA_ANA_CLICKHOUSE_PORT=8123`、`DATA_ANA_CLICKHOUSE_DATABASE=edu_analytics` **降级策略**:ClickHouse 不可达时服务启动跳过,查询返回 degraded 空数据 ### 2.3 Kafka(基础设施)— P1 | # | 依赖项 | 用途 | 状态 | | --- | ----------------- | ----------------------------------------------------------- | ---------------- | | 1 | Kafka :29092 消费 | CDC topic(edu-cdc.next_edu_cloud.* 等 7 topic) | ✅ Docker 已启动 | | 2 | Kafka :29092 生产 | edu.insight.mastery.updated + edu.insight.warning.triggered | ✅ Docker 已启动 | **环境变量**:`DATA_ANA_KAFKA_BROKERS=kafka:29092` **降级策略**:Kafka 不可达时 CDC 消费者不启动,事件发布静默失败 ### 2.4 Redis(基础设施)— P1 | # | 依赖项 | 用途 | 状态 | | --- | ----------- | ------------------------------------------------------------------- | ---------------- | | 1 | Redis :6379 | DataScope 缓存(5min TTL)+ CDC event_id 去重 + Warning bitmap 去重 | ✅ Docker 已启动 | **环境变量**:`DATA_ANA_REDIS_URL=redis://redis:6379` **降级策略**:Redis 不可达时跳过缓存,每次直查 iam gRPC ### 2.5 core-edu 服务(ai07 负责)— P1(CDC 依赖) | # | 依赖项 | 用途 | 状态 | | --- | --------------------------- | ------------------------------------------------------ | ------------------------- | | 1 | MySQL binlog(core_edu 库) | CDC 消费 grades/exams/homework/attendance/classes 变更 | ⏳ 待 core-edu MySQL 就绪 | | 2 | Debezium Connect | MySQL → Kafka CDC 管道 | ⏳ 待 Debezium 部署 | ### 2.6 content 服务(ai08 负责)— P2(CDC 依赖) | # | 依赖项 | 用途 | 状态 | | --- | -------------------------- | --------------------------------------------------------- | ------------------------ | | 1 | MySQL binlog(content 库) | CDC 消费 content_knowledge_points 变更 → Redis 知识点缓存 | ⏳ 待 content MySQL 就绪 | ### 2.7 ai 服务(ai12 负责)— P2(事件消费) | # | 依赖项 | 用途 | 状态 | | --- | ---------------------------------- | ------------------------------------- | ----------------------------------- | | 1 | Kafka topic `edu.insight.ai.usage` | 消费 AIUsageEvent → ai_usage_log 宽表 | ✅ events.proto 已补全 AIUsageEvent | --- ## 3. 下游依赖(谁依赖 data-ana) ### 3.1 teacher-bff(ai03 负责)— P0 | # | gRPC RPC | 用途 | 状态 | | --- | ------------------------------------- | ---------------------------- | --------- | | 1 | `GetStudentWeakness(classId)` :50055 | `studentWeakness` 查询 | ✅ 已实现 | | 2 | `GetLearningTrend(classId)` :50055 | `learningTrend` 查询 | ✅ 已实现 | | 3 | `GetClassPerformance(classId)` :50055 | `classPerformance` 查询 | ✅ 已实现 | | 4 | `GetAdminDashboard(input)` :50055 | `adminDashboard` AI 用量区块 | ✅ 已实现 | **需求来源**:[teacher-bff nextstep.md](../../teacher-bff/docs/nextstep.md) §2.4 **环境变量**(teacher-bff 侧):`DATA_ANA_GRPC_TARGET=data-ana:50055` ### 3.2 student-bff(ai04 负责)— P0 | # | gRPC RPC | 用途 | 状态 | | --- | -------------------------------------------------- | ----------------------- | --------- | | 1 | `GetStudentWeakness(studentId)` :50055 | `myWeakness` 查询 | ✅ 已实现 | | 2 | `GetLearningTrend(studentId)` :50055 | `myTrend` 查询 | ✅ 已实现 | | 3 | `GetStudentMastery(studentId)` :50055 | `myMasterySummary` 查询 | ✅ 已实现 | | 4 | `GetStudentDashboard(studentId)` :50055 | `studentDashboard` 查询 | ✅ 已实现 | | 5 | `GetMasteryDistribution(classId)` :50055 | 班级掌握度分布 | ✅ 已实现 | | 6 | HTTP `GET /analytics/student/{id}/errorbook` :3006 | `myErrorBook` 查询 | ✅ 已实现 | **需求来源**:[student-bff nextstep.md](../../student-bff/docs/nextstep.md) §3.4 **说明**:student-bff nextstep.md 中列出的 `GetStudentGrowth`/`GetAssignmentAnalysis`/`ListDiagnosticReports`/`ListErrorBookItems`/`ListPracticeSessionsByStudent`/`StartPracticeSession`/`SubmitPracticeAnswer` 等 RPC 在 analytics.proto 中未定义,data-ana 通过现有 12 RPC + HTTP 端点覆盖这些需求。 ### 3.3 parent-bff(ai05 负责)— P1 | # | gRPC RPC | 用途 | 状态 | | --- | -------------------------------------- | ------------------------------- | --------- | | 1 | `GetStudentWeakness(studentId)` :50055 | `childWeakness` 查询 | ✅ 已实现 | | 2 | `GetLearningTrend(studentId)` :50055 | `childTrend` 查询 | ✅ 已实现 | | 3 | `GetClassPerformance(classId)` :50055 | `classRank`/`classAverage` 计算 | ✅ 已实现 | **需求来源**:[parent-bff nextstep.md](../../parent-bff/docs/nextstep.md) §4.3 **说明**:parent-bff nextstep.md 中列出的 `childGrowthArchive`/`childLearningPath`/`childErrorBookStats`/`childTopWrongQuestions`/`childWeakKps`/`childMasterySummary`/`childDiagnosticReports`/`childPracticeStats`/`childPracticeSessions` 等查询在当前 RPC 中未直接覆盖,parent-bff 通过降级模式返回空数据。data-ana 可通过 HTTP 端点 `/analytics/student/{id}/errorbook` 等补充覆盖。 ### 3.4 api-gateway(ai01 负责)— P0 | # | 路由 | 用途 | 状态 | | --- | ------------------------------------- | ---------------------- | --------------------- | | 1 | `/api/v1/analytics/*` → data-ana:3006 | data-ana HTTP 端点代理 | ✅ api-gateway 已配置 | | 2 | `/api/v1/dashboard/*` → data-ana:3006 | 仪表盘代理 | ✅ api-gateway 已配置 | **需求来源**:[api-gateway nextstep.md](../../api-gateway/docs/nextstep.md) §5.2 --- ## 4. Docker 本地测试 ### 4.1 镜像构建 ```bash # 在仓库根目录执行(Docker Hub 不可达时先 docker pull + docker tag python:3.12-slim) docker build -t edu/data-ana:test -f services/data-ana/Dockerfile services/data-ana/ ``` ### 4.2 容器启动(接入 edu-full_default 网络) ```bash docker run -d \ --name edu-data-ana-test \ --network edu-full_default \ -p 3006:3006 -p 50055:50055 \ -e DATA_ANA_CLICKHOUSE_HOST=clickhouse \ -e DATA_ANA_CLICKHOUSE_PORT=8123 \ -e DATA_ANA_CLICKHOUSE_DATABASE=edu_analytics \ -e DATA_ANA_KAFKA_BROKERS=kafka:29092 \ -e DATA_ANA_REDIS_URL=redis://redis:6379 \ -e DATA_ANA_DEV_MODE=true \ -e OTEL_TRACES_EXPORTER=none \ -e OTEL_METRICS_EXPORTER=none \ -e OTEL_LOGS_EXPORTER=none \ edu/data-ana:test ``` ### 4.3 健康检查验证 ```bash # liveness curl http://localhost:3006/healthz # readiness(下游不可达时返回 degraded) curl http://localhost:3006/readyz ``` ### 4.4 ClickHouse DDL + 种子数据 ```bash # 建表 docker exec edu-clickhouse clickhouse-client --password clickhouse --multiquery < services/data-ana/scripts/clickhouse_ddl.sql # 种子数据(需安装 clickhouse-connect) cd services/data-ana && python scripts/seed_clickhouse.py ``` ### 4.5 测试结果(2026-07-13 已通过) | # | 测试项 | 结果 | 说明 | | --- | ------------------------------------------- | ---- | ------------------------------------------------------------------- | | 1 | Docker 镜像构建 | ✅ | `edu/data-ana:test` 构建成功 | | 2 | 容器启动 + 健康检查 | ✅ | `/healthz` 200 OK, `/readyz` ready=true | | 3 | ClickHouse 5 表 DDL | ✅ | 4 ReplacingMergeTree + 1 MergeTree | | 4 | 种子数据写入 | ✅ | student_dashboard_view(8) + student_errors(3) + mastery_snapshot(6) | | 5 | HTTP `/analytics/student/stu-001/weakness` | ✅ | 返回 2 个薄弱知识点(kp-math-002 mastery=0.35/0.45) | | 6 | HTTP `/analytics/student/dashboard` | ✅ | 返回 8 条学情记录 + 薄弱点 + 趋势 + 掌握度 | | 7 | HTTP `/analytics/student/stu-001/trend` | ✅ | 返回 8 个趋势点 | | 8 | HTTP `/analytics/student/stu-001/errorbook` | ✅ | 返回 3 条错题记录 | | 9 | HTTP `/analytics/student/stu-001/mastery` | ✅ | 返回 4 个知识点掌握度,overallMastery=0.6875 | | 10 | gRPC `GetStudentWeakness` :50055 | ✅ | 返回 2 个 weak_points | | 11 | gRPC `GetStudentMastery` :50055 | ✅ | 返回 4 个 knowledge_points,overall_mastery=0.6875 | | 12 | gRPC `GetLearningTrend` :50055 | ✅ | 返回 8 个 trend points | | 13 | ruff lint | ✅ | 零错误 | **降级说明**:iam gRPC 未配置(`not_configured`),HTTP 响应标记 `degraded: true` + `degraded_reason: iam_grpc_unavailable_fallback`,但 ClickHouse 真实数据正常返回。班级级查询(`class/performance`、`class/mastery-distribution`)因 DataScope 校验降级返回空数据,iam 就绪后自动恢复。 --- ## 5. 环境变量清单(Docker 部署) | 变量 | 必填 | 示例值 | 说明 | | ------------------------------ | ---- | -------------------- | -------------------------------------- | | `DATA_ANA_HTTP_PORT` | 是 | `3006` | HTTP 监听端口 | | `DATA_ANA_GRPC_PORT` | 是 | `50055` | gRPC 监听端口 | | `DATA_ANA_DEV_MODE` | 否 | `true`/`false` | 开发模式(跳过部分校验) | | `DATA_ANA_CLICKHOUSE_HOST` | 是 | `clickhouse` | ClickHouse 主机 | | `DATA_ANA_CLICKHOUSE_PORT` | 否 | `8123` | ClickHouse HTTP 端口 | | `DATA_ANA_CLICKHOUSE_DATABASE` | 否 | `edu_analytics` | ClickHouse 数据库 | | `DATA_ANA_KAFKA_BROKERS` | 是 | `kafka:29092` | Kafka broker 地址 | | `DATA_ANA_REDIS_URL` | 是 | `redis://redis:6379` | Redis 连接地址 | | `DATA_ANA_IAM_GRPC_TARGET` | 是 | `iam:50052` | iam gRPC 目标 | | `OTEL_TRACES_EXPORTER` | 否 | `none` | 禁用 OTel traces(collector 不可达时) | --- ## 6. 剩余工作 ### 6.1 Docker 本地测试(已完成 2026-07-13) | # | 工作项 | 状态 | | --- | ------------------------------ | --------- | | 1 | Docker 镜像构建 | ✅ 已通过 | | 2 | ClickHouse 容器启动 + DDL 建表 | ✅ 已通过 | | 3 | 种子数据写入 | ✅ 已通过 | | 4 | data-ana 容器启动 + 健康检查 | ✅ 已通过 | | 5 | HTTP 端点测试(无 mock 数据) | ✅ 已通过 | | 6 | gRPC 端点测试 | ✅ 已通过 | ### 6.2 P6 硬化任务 | # | 工作项 | 状态 | | --- | ------------------------------------ | --------- | | 1 | CDC 多实例水平扩展 | ⏳ 未开始 | | 2 | ExamCache Redis 化 | ⏳ 未开始 | | 3 | 容量规划 + TTL 归档策略 | ⏳ 未开始 | | 4 | 监控告警完善(Prometheus + Grafana) | ⏳ 未开始 | | 5 | readyz 深度硬化(超时控制) | ⏳ 未开始 | ### 6.3 端到端联调 | # | 工作项 | 阻塞条件 | 状态 | | --- | --------------------- | ------------------------------------- | ---- | | 1 | teacher-bff gRPC 联调 | teacher-bff 配置 DATA_ANA_GRPC_TARGET | ⏳ | | 2 | student-bff gRPC 联调 | student-bff 配置 DATA_ANA_GRPC_TARGET | ⏳ | | 3 | parent-bff gRPC 联调 | parent-bff 配置 DATA_ANA_GRPC_TARGET | ⏳ | | 4 | CDC 通道联调 | core-edu MySQL + Debezium 就绪 | ⏳ | | 5 | AIUsageEvent 消费联调 | ai 服务发布事件 | ⏳ | --- ## 7. 关键文件路径 | 文件 | 用途 | | -------------------------------------------------------------------- | ------------------------------------------------ | | `services/data-ana/src/data_ana/main.py` | HTTP 14 端点 + lifespan(gRPC + CDC 启动) | | `services/data-ana/src/data_ana/grpc_server.py` | gRPC 12 RPC(含 server-streaming) | | `services/data-ana/src/data_ana/cdc_consumer.py` | CDC 消费者(5 表 + AIUsageEvent) | | `services/data-ana/src/data_ana/analytics_service.py` | 4 端 Dashboard + DataScope 注入 | | `services/data-ana/src/data_ana/mastery_service.py` | 掌握度算法(加权滑动平均 + 遗忘曲线) | | `services/data-ana/src/data_ana/warning_service.py` | 5 类预警 + Redis 去重 | | `services/data-ana/src/data_ana/config.py` | 全配置项(DATA_ANA_ 前缀) | | `services/data-ana/src/data_ana/repository/clickhouse_repository.py` | ClickHouse 查询(FINAL/argMax 去重) | | `services/data-ana/src/data_ana/repository/iam_client.py` | iam gRPC + Redis 缓存 + 降级 | | `services/data-ana/src/data_ana/repository/kafka_producer.py` | Kafka 事件发布(idempotent) | | `services/data-ana/src/generated_proto/` | Python protobuf 生成代码(analytics/iam/events) | | `services/data-ana/scripts/clickhouse_ddl.sql` | 5 宽表建表脚本 | | `services/data-ana/scripts/seed_clickhouse.py` | 种子数据脚本 | | `services/data-ana/Dockerfile` | 多阶段构建(python:3.12-slim) | | `packages/shared-proto/proto/analytics.proto` | gRPC 12 RPC 契约 | --- **本文件由 ai11 维护。data-ana 已完成 P2-P5 全部代码实现 + Docker 本地测试通过(无 mock 数据,真实 ClickHouse 查询)。等待 iam 容器就绪后即可端到端联调。**