Files
Edu/docs/architecture/ai05-phase1-understanding.md
SpecialX 0a71b02e04
Some checks failed
CI / quality-ts (push) Failing after 48s
CI / quality-go (push) Failing after 4s
CI / quality-proto (push) Failing after 2s
CI / deploy (push) Has been skipped
fix: code compliance audit and fix across all services
NestJS (6 services): implement @RequirePermission decorator with
SetMetadata+Reflector, register APP_GUARD globally, fix as assertions
to type guards, add explicit return types, fix import type for express,
fix /metrics implicit any, replace native Error with ApplicationError,
remove typeorm remnants, register LifecycleService.

teacher-bff: add logger, ApplicationError, GlobalErrorFilter, forward
real userId to downstream, log downstream failures, migrate health
controller to shared/health.

Go (2 services): interface to any, doc comments, CORS dev whitelist,
JWT secret fail-fast, push-gateway internal API auth, metrics and
readyz endpoints, remove dead code.

Python (2 services): lifespan return type, dev_mode to bool, data-ana
APIRouter, ai POST body model, ClickHouse async wrapping.
2026-07-09 17:28:27 +08:00

27 KiB
Raw Blame History

ai05 阶段 1 交付物:模块理解确认书

AI 标识ai05 负责模块contentP4、msgP5 阶段:架构设计外包 · 阶段 1全局理解 日期2026-07-09 关联文档:ai-allocation.md004 架构影响地图pending-features.mdknown-issues.md


模块理解确认书 — content

1. 我在架构中的位置

  • 层级业务微服务层L5DDD 限界上下文
  • 业务领域D4 内容资源领域004 §1.1b
  • 上游(谁调用我):
    • teacher-bff3003教学场景聚合教师查教材/知识点/题库
    • student-bff学习场景P3 起):学生查学习路径、知识点前置
    • aiPythonP5gRPC 查询知识点/题库用于 AI 出题004 §4.1 AI -.gRPC.-> Content§9.3 AI 辅助出题流程)
  • 下游(我调用谁):
    • MySQL写模型主库独占
    • Neo4j知识图谱前置依赖图
    • Elasticsearch题库全文检索P4 后续补充,当前未实现)
  • 通信方式
    • 当前HTTP RESTController无 gRPC controller
    • 目标态004 §4.1 / pending-features P4gRPC 暴露 TextbookService + KnowledgeGraphService
    • Kafka消费 core-edu 教学内容变更通知004 §4.1 CoreEdu -.事件.-> Content);发布 edu.content.question.published004 §7.2
  • 端口3005content env.ts

2. 我的限界上下文

  • 聚合职责:管理 Textbook教材、Chapter章节、KnowledgePoint知识点、Question题库四个聚合
  • 我的数据属于D4 内容资源领域
  • 我不负责
    • 不负责学情分析D6由 data-ana 承载)
    • 不负责考试/作业/成绩D3由 core-edu 承载)
    • 不负责通知分发D5由 msg 承载)
    • 不直接访问 core-edu / iam / msg 的数据库
  • 现有骨架领域模块4 个,见 content/src
    • textbooks/:教材 CRUD5 端点)
    • chapters/:章节 CRUD5 端点,按 textbook 查询)
    • knowledge-points/:知识点 CRUD + Neo4j 知识图谱7 端点,含前置链路查询/添加)
    • questions/:题库 CRUD5 端点4 种题型校验)

3. 我与外部的契约

  • 消费的 proto message(从 shared-proto
    • 无直接消费其他服务 proto通过 Kafka 事件接收 core-edu 教学内容变更(事件契约见 events.proto
  • 暴露的契约(见 content.proto,包名 next_edu_cloud.content.v1
    • TextbookServiceCreateTextbook / GetTextbook / ListTextbooks
    • KnowledgeGraphServiceGetPrerequisites / GetLearningPath
    • 当前实现均为 RESTgRPC controller 未实现proto 已定义待迁移)
  • 事件契约
    • 发布:edu.content.question.published(题库新增/发布,消费者 AI、ES见 004 §7.2
    • 消费core-edu 教学内容变更事件004 §4.1,具体 topic 待 core-edu ai03 设计确认)
  • 错误码前缀CONTENT_*CONTENT_VALIDATION_ERROR / NOT_FOUND / PERMISSION_DENIED / CONFLICT / BUSINESS_ERROR / DATABASE_ERROR / INTERNAL_ERRORapplication-error.ts
  • 权限点16 个,见 permission.guard.ts
    • CONTENT_TEXTBOOK_{CREATE,READ,UPDATE,DELETE}
    • CONTENT_CHAPTER_{CREATE,READ,UPDATE,DELETE}
    • CONTENT_QUESTION_{CREATE,READ,UPDATE,DELETE}
    • CONTENT_KNOWLEDGE_POINT_{CREATE,READ,UPDATE,DELETE}

4. 我的技术栈

  • 语言TypeScript 5.6ESM 模式,相对 import 带 .js 后缀)
  • 框架NestJS 10
  • ORMDrizzle ORM 0.31 + mysql2 3.11
  • 知识图谱neo4j-driver 5.23PREREQUISITE_OF 关系Cypher 查询深度 1..5
  • 全文检索Elasticsearch待引入env.ts 预留 ES_URL 但 package.json 未装 @elastic/elasticsearch
  • 可观测pino logger + prom-client metrics + OpenTelemetry tracer三支柱已具备
  • 消息总线Kafka待引入pending-features P4 未明确要求 content 发事件,但 004 §7.2 列了 edu.content.question.published

5. 我的阶段归属

  • P4 内容分析阶段pending-features §P4
    • 教材/章节/知识点 CRUD仅 CRUD不实现检索+ 知识图谱查询Neo4j+ 题库 CRUD不实现检索
    • MySQL schematextbooks / chapters / knowledge_points / questions
    • Neo4j 数据:知识点前置依赖图(从 MySQL 同步)
    • CDC 链路Debezium 监听 MySQL binlog → Kafka → data-ana 消费写 ClickHouse
  • 退出标准教师查看知识图谱前置依赖Neo4j 秒级返回)→ 学生查看学情诊断ClickHouse 宽表 5s 内返回)→ CDC 链路延迟 < 5s
  • 依赖上游P1 黄金模板 classes横切关注点对齐、P3 core-edu教学内容变更事件待 ai03 设计确认 topic

6. 我需要对齐的黄金模板项(对照 classes 服务)

  • 权限装饰器 @RequirePermission16 个 CONTENT_* 权限点,全部 Controller 方法已覆盖)
  • 错误码前缀统一(CONTENT_*
  • logger / metrics / tracer 三支柱(已具备)
  • /healthz 健康检查HealthModule 已注册)
  • [⚠️] /readyz仅检查 DB SELECT 1,未检查 Neo4j 连通性Neo4j 故障时仍返回 ok
  • 优雅关闭 SIGTERMmain.ts 已处理closeNeo4j → closeDb → shutdownTracer
  • 测试覆盖率 ≥ 80%当前 0%,无测试文件)
  • Dockerfile 多阶段构建(已具备)
  • [⚠️] Zod 输入验证questions 用 service 层手动 if 校验抛 ValidationError非 Controller 层 schema.parse
  • GlobalErrorFilter 统一兜底

7. 现有骨架差距与待决策(提请 coord 仲裁)

# 差距 影响 提请决策
C1 ES 完全未实现env.ts 预留 ES_URL 但无 @elastic/elasticsearch 依赖、无 config/elasticsearch.ts、无 service 调用 P4 退出标准要求题库检索pending-features 注明"P4 仅 CRUDP5 引入 ES" 确认 content 的 ES 检索归属 P4 还是 P5004 §2.2 列 ES 使用者为 Content、AI
C2 无 Outbox / Kafka:骨架无 shared/outbox/,无 Kafka producer/consumer 004 §7.2 列 edu.content.question.published 事件需发布 确认 content 是否需 Outboxiam 无 Outboxcore-edu 有)
C3 README 与实现脱节README 声称 TextbooksService.createKnowledgeGraphgetPrerequisites,源码中 createKnowledgeGraph 不存在getPrerequisites 在 KnowledgePointsService 文档误导 阶段 2 设计需同步修正 README
C4 gRPC 未实现proto 定义了 TextbookService/KnowledgeGraphService但无 gRPC controller pending-features P4 未强制 gRPC004 §4.1 目标态 gRPC 确认 P4 是否启用 gRPCai03 提请统一决策)
C5 schema 定义分散textbooks.schema.ts 定义 3 张表textbooks/chapters/knowledgePointschapters/knowledge-points schema 仅 re-exportquestions.schema.ts 独立 维护成本 阶段 2 设计统一 schema 归属
C6 DB 连接模式与 iam 不一致content 用模块级 const dbiam 用 getDb() 函数式懒加载 测试 mock 困难 coord 已在 known-issues 记录"db 常量导出对齐黄金模板",需确认统一方向
C7 表时间戳不统一textbooks/questions 有 created_at+updated_atchapters/knowledge_points 无时间戳 审计追踪缺失 阶段 2 设计补齐
C8 无外键约束questions.knowledge_point_id → knowledge_points.id 等无 Drizzle 外键 引用完整性靠应用层 阶段 2 设计评估是否加外键
C9 addPrerequisite 降级策略不一致safeCreateNode 非阻塞Neo4j 失败仅 warnaddPrerequisite 在 Neo4j 不可用时抛 InternalError 行为不一致 阶段 2 设计统一降级策略
C10 proto 包名:实际 next_edu_cloud.content.v1project_rules §5 规定 edu.content.v1 命名规范不一致 coord 仲裁ai03 已提请)

模块理解确认书 — msg

1. 我在架构中的位置

  • 层级业务微服务层L5DDD 限界上下文
  • 业务领域D5 沟通通知领域004 §1.1b
  • 上游(谁调用我):
    • teacher-bff / student-bff / parent-bff聚合层调 msg 查询用户通知列表、发送通知
    • api-gatewayREST 转发通知请求
    • Kafka消费 core-edu / iam 事件触发通知004 §4.1 CoreEdu -.事件.-> MsgIAM -.事件.-> Msg
  • 下游(我调用谁):
    • MySQL写模型主库独占
    • Elasticsearch全文检索已实现 safeSearch
    • push-gatewaygRPC 推送通道004 §4.1 PushGW → Msg,当前用 fetch POST /internal/push 降级)
  • 通信方式
    • 当前HTTP RESTController无 gRPC controller
    • 目标态004 §4.1 / pending-features P5gRPC 暴露 NotificationService
    • Kafka消费 core-eduExamPublished/HomeworkGraded/GradeRecorded、iamUserRegistered事件004 §7.3
  • 端口3007msg env.ts

2. 我的限界上下文

  • 聚合职责:管理 Notification通知聚合 + NotificationPreference用户通知偏好
  • 我的数据属于D5 沟通通知领域
  • 我不负责
    • 不负责 WebSocket 长连接管理(由 push-gateway 承载)
    • 不负责业务数据变更(仅消费事件触发通知)
    • 不直接访问 core-edu / iam 的数据库
  • 现有骨架领域模块1 个,见 msg/src
    • notifications/:通知 CRUD + ES 全文检索 + Push Gateway 推送 + 用户偏好6 端点)

3. 我与外部的契约

  • 消费的 proto message(从 shared-proto
    • 消费 events.proto 的事件 messageClassEvent/ExamEvent/HomeworkEvent/GradeEvent
    • events.proto 当前无 NotificationEvent,若 msg 发事件需补充
  • 暴露的契约(见 msg.proto,包名 next_edu_cloud.msg.v1
    • NotificationServiceSendNotification / ListNotifications / MarkAsRead / SearchNotifications
    • 当前实现均为 RESTgRPC controller 未实现
  • 事件契约
    • 消费004 §7.2 / §7.3
      • edu.identity.user.created / edu.identity.user.updatedIAM 发msg 发欢迎通知)
      • edu.teaching.exam.publishedcore-edu 发msg 推送考试通知给学生)
      • edu.teaching.assignment.submittedcore-edu 发msg 通知教师)
      • edu.teaching.grade.recordedcore-edu 发msg 通知学生)
      • edu.insight.mastery.updateddata-ana 发msg 触发预警)
    • 发布无明确pending-features 未要求 msg 发事件)
  • 错误码前缀MSG_*MSG_VALIDATION_ERROR / NOT_FOUND / PERMISSION_DENIED / CONFLICT / BUSINESS_ERROR / DATABASE_ERROR / INTERNAL_ERRORapplication-error.ts
  • 权限点3 个,见 permission.guard.ts
    • MSG_NOTIFICATION_SENDMSG_NOTIFICATION_READMSG_NOTIFICATION_MANAGE

4. 我的技术栈

  • 语言TypeScript 5.6ESM 模式)
  • 框架NestJS 10
  • ORMDrizzle ORM 0.31 + mysql2 3.11
  • 全文检索:@elastic/elasticsearch 8.15(已实现 safeIndex/safeSearch无 mapping 定义,依赖动态 mapping
  • 消息总线kafkajs 2.2已装依赖但无 consumer/producer 代码env.ts 有 KAFKA_BROKERS 默认值)
  • 推送fetch POST 到 push-gateway /internal/push降级模式PUSH_GATEWAY_URL 未配置或失败时跳过)
  • 幂等去重Redisenv.ts 预留 REDIS_URL 但无 redis 客户端依赖pending-features P5 要求 event_id 去重)
  • 可观测pino + prom-client + OpenTelemetry三支柱已具备

5. 我的阶段归属

  • P5 沟通与 AI 阶段pending-features §P5
    • 会话/消息 CRUD + 调 Push Gateway 推送 + 通知偏好
    • 多渠道(站内/SMS/邮件/微信),沿用旧项目 dispatcher 模式
    • Elasticsearch 题库全文检索(从 MySQL 同步)
  • 退出标准:教师发广播通知 → 全在线学生实时收到Push Gateway→ AI 辅助出题流式返回 → 题库全文检索 < 200ms
  • 依赖上游P1 黄金模板 classes、P3 core-edu事件来源、P5 push-gateway推送通道ai01 设计、P5 ai无直接依赖

6. 我需要对齐的黄金模板项(对照 classes 服务)

  • 权限装饰器 @RequirePermission3 个 MSG_* 权限点,全部 Controller 方法已覆盖)
  • 错误码前缀统一(MSG_*
  • logger / metrics / tracer 三支柱(已具备)
  • /healthz 健康检查HealthModule 已注册)
  • [⚠️] /readyz仅检查 DB SELECT 1,未检查 ES 连通性ES 故障时仍返回 ok
  • 优雅关闭 SIGTERMmain.ts 已处理app.close → closeEs → closeDb → shutdownTracer
  • 测试覆盖率 ≥ 80%当前 0%,无测试文件)
  • Dockerfile 多阶段构建(已具备)
  • [⚠️] Zod 输入验证Controller 用 schema.parse(body)但 ZodError 未在 GlobalErrorFilter 特殊处理,走默认 500 而非 400
  • GlobalErrorFilter 统一兜底

7. 现有骨架差距与待决策(提请 coord 仲裁)

# 差距 影响 提请决策
M1 Kafka 消费未实现:装了 kafkajs 但无 consumer 代码,无 shared/kafka/ 目录 004 §7.3 列 msg 消费 5 类事件ExamPublished/HomeworkGraded/GradeRecorded/UserRegistered/MasteryUpdated 阶段 2 设计需补 Kafka consumer + 幂等去重
M2 无 Outbox:骨架无 shared/outbox/ msg 作为通知中心,发送通知后可能需发事件(如 NotificationSent 确认 msg 是否需 Outboxiam 无core-edu 有)
M3 ES 无 mapping 定义:依赖动态 mapping索引名 "notifications" 硬编码在 service 检索质量不稳定,索引管理缺失 阶段 2 设计补 mapping + ensureIndex
M4 无独立 repositorynotifications.service.ts 直接用 db无 repository 抽象 与黄金模板分层不一致iam 有 repository 阶段 2 设计补 repository 层
M5 Redis 未引入env.ts 预留 REDIS_URL 但无 redis 客户端依赖 pending-features P5 要求 event_id 去重Redis SETNX 或 DB 唯一索引) 阶段 2 设计决策Redis SETNX vs DB 唯一索引
M6 createBatch 无事务/无批量优化for 循环串行调 send无批量 INSERT 性能瓶颈(广播场景) 阶段 2 设计改为批量 INSERT
M7 NotificationsModule 缺 exportsnotifications.module.ts 无 exports: [NotificationsService] 未来 BFF 注入受阻 阶段 2 设计补 exports
M8 ZodError 未特殊处理GlobalErrorFilter 未识别 ZodError走默认 500 输入校验错误返回码错误500 而非 400 阶段 2 设计 GlobalErrorFilter 补 ZodError 分支iam 已有可参考)
M9 gRPC 未实现proto 定义了 NotificationService但无 gRPC controller pending-features P5 未强制 gRPC 确认 P5 是否启用 gRPCai03 提请统一决策)
M10 README 与实现脱节README API 表标 POST /notifications/:id/read,实际是 PUT漏 batch/user/:userId/user/:userId/page 端点;声称"消费 Kafka 事件"但无代码 文档误导 阶段 2 设计同步修正 README
M11 main.ts 与 LifecycleService 重复关闭资源:两者都调 closeDb/closeEs 重复关闭可能报错(虽有 try-catch 阶段 2 设计统一关闭逻辑到 LifecycleService
M12 proto 包名:实际 next_edu_cloud.msg.v1project_rules §5 规定 edu.msg.v1 命名规范不一致 coord 仲裁ai03 已提请)

三、服务审计表 — ai05

审计标准对照 project_rules §3known-issues §2.2 classes 黄金模板

服务 权限装饰器 错误码前缀 logger metrics tracer /healthz /readyz 优雅关闭 测试覆盖率 Dockerfile
content 16 端点全覆盖 CONTENT_* pino prom-client OTel + auto-instrumentations ⚠️ 仅 DB 不查 Neo4j closeNeo4j→closeDb 0%
msg 6 端点全覆盖 MSG_* pino prom-client OTel + auto-instrumentations ⚠️ 仅 DB 不查 ES closeEs→closeDb 0%

四、跨模块契约对齐提请coord 交叉审查)

4.1 接口一致性检查

本服务声明 对方服务声明 是否匹配 备注
ai05 content: 暴露 KnowledgeGraphService.GetPrerequisites ai06 ai: 调 content 查知识点004 §9.3 ⚠️ 待确认 ai06 设计文档需确认调用签名
ai05 content: 暴露 TextbookService.ListTextbooks ai03 teacher-bff: 聚合 content 查教材004 §4.1 ⚠️ 待确认 ai03 设计文档需确认调用
ai05 content: 发布 edu.content.question.published ai06 ai: 消费题库事件004 §7.2 消费者 AI ⚠️ 待确认 ai06 设计需确认是否消费
ai05 msg: 消费 edu.teaching.exam.published ai03 core-edu: 发布考试事件 ⚠️ 待确认 ai03 提请 topic 命名统一004 edu.teaching.exam.published vs core-edu 代码 edu.exam.events
ai05 msg: 消费 edu.identity.user.created ai02 iam: 发布用户创建事件 ⚠️ 待确认 ai02 设计需确认 topic
ai05 msg: 调 push-gateway /internal/push ai01 push-gateway: 暴露推送端点 已实现 msg 当前用 fetch POSTpush-gateway 已有 /internal/push 端点

4.2 全局冲突检查

检查项 检查结果 备注
端口不冲突 content 3005、msg 3007 与 iam(3002)/classes(3001)/teacher-bff(3003)/core-edu(3004)/data-ana(3006)/ai(3008) 不冲突
Topic 不重复 ⚠️ 待汇总 content 发布 edu.content.question.publishedmsg 仅消费不发布
错误码前缀不重叠 CONTENT_* / MSG_* 唯一 与 iam IAM_* / core-edu CORE_EDU_* 不重叠
Proto message 不遗漏 ⚠️ 待确认 events.proto 无 NotificationEvent若 msg 发事件需补充content.proto 缺 Update/Delete/分页(对比 classes.proto 有 page_token
proto 包名规范 ⚠️ 不一致 实际 next_edu_cloud.<domain>.v1,规则要求 edu.<domain>.v1提请 coord 仲裁ai03 已提请)

4.3 待 coord 仲裁的决策项

  1. proto 包名统一next_edu_cloud.* vs edu.*(影响全部 proto需 coord 决策)
  2. gRPC 启用时机P4/P5 是否启用 gRPC controller还是继续 REST影响 content/msg/iam/core-edu 全部服务)
  3. content ES 检索归属P4pending-features 注明"P4 仅 CRUDP5 引入 ES"vs 004 §2.2(列 ES 使用者 Content、AI—— 需明确 content 何时引入 ES
  4. content Outbox是否需要004 §7.2 列 content 发事件,但 pending-features P4 未要求)
  5. msg Outbox是否需要msg 仅消费事件触发通知,是否需发 NotificationSent 事件)
  6. msg Redis 引入env.ts 预留 REDIS_URL 但无依赖,幂等去重用 Redis SETNX 还是 DB 唯一索引
  7. events.proto 补充:若 msg 发事件需追加 NotificationEvent message

五、下一步

  1. 等待 coord 审核本确认书§4 跨模块契约对齐 + §4.3 仲裁项)
  2. coord 放行后进入阶段 2模块架构设计文档,按 ai-allocation.md §7 模板产出:
    • content 模块架构设计文档(含 Neo4j 图模型、ES 索引 mapping、题库 CRUD API、与 ai 的 gRPC 接口、教材/章节结构树)
    • msg 模块架构设计文档含通知渠道抽象策略模式、ES 降级查询、Kafka 消费幂等、push-gateway 推送协议、通知模板、已读/未读状态管理)
  3. 阶段 2 设计完成后同步更新 README修正 §C3/M10 文档脱节问题)