# content 问题记录 > 负责人:ai09 > 关联:[coord.md](../coord.md)、[contracts/content_contract.md](../contracts/content_contract.md)、[../../services/content/docs/01-understanding.md](../../../services/content/docs/01-understanding.md)、[../../services/content/docs/02-architecture-design.md](../../../services/content/docs/02-architecture-design.md) > 规则:AI 遇到问题时在此追加条目,coord 仲裁后更新状态 --- ## §0 已有仲裁核查(2026-07-10 复核) > 复核依据:[coord-final-decisions.md §3.3](../../coord-final-decisions.md) N1-N5、[01-understanding.md §A](../../../services/content/docs/01-understanding.md) ai09 复核记录 ### 0.1 coord-final-decisions.md N1-N5 核查 | 编号 | 仲裁结论 | 02-architecture-design.md 落实位置 | 核查结果 | | ---- | -------------------------------------------- | ----------------------------------------------- | --------- | | N1 | P4 首次实现即启用 gRPC server 50054 | §1.2 入口 HTTP 3005 / gRPC 50054;§4.2 gRPC API | ✅ 已落实 | | N2 | 首次实现即检查 DB/Neo4j/Kafka | §6.6 /readyz 多依赖检查 | ✅ 已落实 | | N3 | P4 即补全 QuestionService proto(不等到 P5) | §4.2.4 QuestionService 6 RPC | ✅ 已落实 | | N4 | 首次实现即对齐 ActionState | §4.3 错误响应结构 success/error 信封 | ✅ 已落实 | | N5 | P4 首次实现即补全 ChapterService | §4.2.2 ChapterService 3 RPC | ✅ 已落实 | ### 0.2 01-understanding.md §A 已裁决项核查 | 原编号 | 仲裁结论 | 02-architecture-design.md 落实位置 | 核查结果 | | ------ | ------------------------------------------ | ------------------------------------------------------- | --------- | | C2 | P4 必须引入 Outbox(004 §12.2 强制条款) | §3.1.5 content_outbox_events 表 + §5.4 Outbox Publisher | ✅ 已落实 | | C4 | P4 必须实现 gRPC controller | §4.2 gRPC API(4 个 Service) | ✅ 已落实 | | C10 | proto 包名保持 `next_edu_cloud.content.v1` | —(保持现状) | ✅ 已落实 | ### 0.3 核查结论 N1-N5 与 C2/C4/C10 共 8 项已有仲裁**全部在 02-architecture-design.md 中正确落实**,无遗漏、无偏离。 --- ## §1 新提请异议(2026-07-10 ai09 复审) ### ISSUE-001-ai09:REST 端点设计文档与现有实现不一致 - **提请方**:ai09 - **日期**:2026-07-10 - **类型**:契约不明确 - **描述**:02-architecture-design.md §4.1 列出的 REST API 与现有源码实现存在三处偏差: 1. **knowledge-points 列表**:设计文档为 `GET /knowledge-points?chapterId=`(query 参数),源码 [knowledge-points.controller.ts](../../../services/content/src/knowledge-points/knowledge-points.controller.ts) 实现为 `GET /knowledge-points/chapter/:chapterId`(path 参数) 2. **knowledge-points 删除前置**:设计文档列 `DELETE /knowledge-points/:id/prerequisites/:prereqId`,源码未实现该端点 3. **chapters 列表**:设计文档为 `GET /chapters?textbookId=`,源码实现为 `GET /chapters/textbook/:textbookId` - **建议方案**:以设计文档为目标态(query 参数 + 补 DELETE prerequisite 端点),在 P4 重构时统一对齐。但需 coord 确认是否允许 API 路径变更(影响 teacher-bff 消费方)。 - **状态**:已裁决(见 coord.md §5) ### ISSUE-002-ai09:content 发布事件 topic 命名策略与契约文档不一致 - **提请方**:ai09 - **日期**:2026-07-10 - **类型**:契约不明确 - **描述**:事件 topic 命名存在两种策略冲突: - **02-architecture-design.md §5.1 + §5.3 TOPIC_MAP**:每个事件类型独立 topic(`edu.content.textbook.created` / `edu.content.question.published` 等共 12 个 topic) - **contracts/content_contract.md §1.4 + matrix.md §4**:按聚合根聚合 topic(`edu.content.knowledge_point.events` / `edu.content.question.events` 共 2 个 topic,事件类型用 `action` 字段区分) - **events.proto**:未定义 KnowledgePointEvent / QuestionEvent message(仅 ClassEvent/ExamEvent/HomeworkEvent/GradeEvent) - **建议方案**:采用**聚合 topic + action 字段**策略(与契约文档、matrix.md、events.proto ClassEvent 模式一致),原因: 1. 与 core-edu 既有模式(edu.exam.events / edu.homework.events 等)一致 2. 减少 topic 数量(12 → 4),降低 Kafka 集群元数据压力 3. 消费方按 action 字段过滤,订阅灵活性更高 4. 需补 `KnowledgePointEvent` / `QuestionEvent` / `TextbookEvent` / `ChapterEvent` proto message - **状态**:已裁决(见 coord.md §5) ### ISSUE-003-ai09:Textbook/Chapter 事件在契约文档遗漏 - **提请方**:ai09 - **日期**:2026-07-10 - **类型**:契约不明确 - **描述**:02-architecture-design.md §5.1 列出 4 类 textbook 事件 + 1 类 chapter 事件,但 contracts/content_contract.md §1.4 仅列出 knowledge_point 与 question 两类事件,Textbook/Chapter 事件未登记。matrix.md §4 也仅列 kp + question。导致下游(data-ana)无法感知教材/章节变更。 - **建议方案**:在 contract.md 与 matrix.md 补登记 `edu.content.textbook.events`(action: created/updated/published/archived)与 `edu.content.chapter.events`(action: created/updated/deleted)。若 coord 认为教材/章节无需对外发事件,则在 design doc §5.1 删除相关事件。 - **状态**:已裁决(见 coord.md §5) ### ISSUE-004-ai09:gRPC RPC 数量三方文档不一致 - **提请方**:ai09 - **日期**:2026-07-10 - **类型**:契约不明确 - **描述**:content gRPC RPC 数量在三处文档不一致: | Service | 02-architecture-design.md §4.2 | contracts/content_contract.md §1.1 | matrix.md §2 | | --------------------- | ------------------------------ | ---------------------------------- | ------------ | | TextbookService | 5(含 Update/Delete 新增) | 3(无 Update/Delete) | 18(总数) | | ChapterService | 3(Create/List/Get) | 4(含 Update,无 Delete) | — | | KnowledgeGraphService | 4 | 4 | — | | QuestionService | 6(无 Publish/Search) | 7(含 Publish/Search) | — | | **合计** | **18** | **18** | **18** | - design doc 缺 QuestionService.PublishQuestion / SearchQuestions(contract 有) - contract 缺 TextbookService.Update/Delete(design doc 有) - design doc ChapterService 缺 Update(contract 有);contract ChapterService 缺 Delete(design doc 也缺) - **建议方案**:以 contract.md 为契约唯一源(已对齐 matrix.md 18 RPC 总数),反向修正 design doc: 1. TextbookService 补 Update/Delete(与 contract 对齐) 2. ChapterService 补 Update + Delete(design doc + contract 都缺 Delete,需补) 3. QuestionService 补 PublishQuestion + SearchQuestions(与 contract 对齐) 4. 最终 RPC 总数:TextbookService 5 + ChapterService 5 + KnowledgeGraphService 4 + QuestionService 7 = **21 RPC**(需同步更新 matrix.md §2 的 18 → 21) - **状态**:已裁决(见 coord.md §5) ### ISSUE-005-ai09:core-edu → content 失效事件 topic 无定义 - **提请方**:ai09 - **日期**:2026-07-10 - **类型**:前置依赖缺失 - **描述**:02-architecture-design.md §5.2 列出 content 消费 `edu.teaching.content.invalidated`(待 ai03 确认 topic),但: 1. events.proto 无 ContentInvalidatedEvent message 2. matrix.md §4 未登记该 topic 3. core-edu 设计文档(ai08)未明确发布该事件 4. 01-understanding.md §5 也标注"具体 topic 待 core-edu ai03 设计确认"——此处 ai03 疑为笔误,core-edu 实际由 ai08 负责 - **建议方案**:content 不主动消费 core-edu 失效事件(content 是上游内容提供方,core-edu 是消费方),删除 §5.2 中该条目;若确有联动需求,由 core-edu 主动调用 content gRPC UpdateQuestion 状态变更,而非事件驱动。 - **状态**:已裁决(见 coord.md §5) ### ISSUE-006-ai09:文档结尾"直接 push main"与项目规则冲突 - **提请方**:ai09 - **日期**:2026-07-10 - **类型**:其他 - **描述**:01-understanding.md 末尾与 02-architecture-design.md 末尾均标注 `Branch: 单仓库并行模式(直接 push main)`,但 [project_rules §8 Git 工作流](../../../../.trae/rules/project_rules.md) 明确规定: - §8:分支开发,AI 不得自行切换/创建/合并分支 - §14.3:AI 禁止 `git merge`、`git push origin main` - 当前 worktree 分支为 `feat-review-content-module-docs-WAIyMA` - **建议方案**:删除两份文档末尾"单仓库并行模式(直接 push main)"字样,改为 `Branch: feat-review-content-module-docs-WAIyMA(分支开发,提交后通知人类合并)`。 - **状态**:已裁决(见 coord.md §5) ### ISSUE-007-ai09:questions 表 created_by 字段迁移风险 - **提请方**:ai09 - **日期**:2026-07-10 - **类型**:其他 - **描述**:02-architecture-design.md §3.1.4 questions 表新增 `created_by varchar(32) NOT NULL`,但现有 [questions.schema.ts](../../../services/content/src/questions/questions.schema.ts) 无该字段,且现有数据无 created_by 值。schema 迁移时 NOT NULL 约束会导致历史数据迁移失败。 - **建议方案**:迁移期间先用 `created_by varchar(32) NULL`,数据回填后再加 NOT NULL 约束;或为新数据强制要求 created_by(应用层校验),历史数据用 `'system'` 默认值回填。 - **状态**:已裁决(见 coord.md §5) ### ISSUE-008-ai09:设计文档缺缓存策略与 API 版本化策略 - **提请方**:ai09 - **日期**:2026-07-10 - **类型**:其他 - **描述**:02-architecture-design.md 未涉及两个长远架构必备项: 1. **缓存策略**:[env.ts](../../../services/content/src/config/env.ts) 已预留 `REDIS_URL`,但 design doc 未设计缓存层(教材树/知识点树是典型读多写少场景,应缓存) 2. **API 版本化**:REST 端点无 `/v1/` 前缀(matrix.md §5 显示 api-gateway 路由为 `/api/v1/teacher/*`,但 content 自身端点 `/textbooks` 无版本号),未来破坏性变更无版本隔离机制 - **建议方案**: 1. P4 在 design doc §6 补"缓存策略"小节:教材树/章节树 Redis 缓存 + 失效策略(Outbox 事件触发缓存失效) 2. P4 在 design doc §4 补"API 版本化"说明:REST 端点统一加 `/v1/` 前缀(gRPC 用 proto package version) - **状态**:已裁决(见 coord.md §5) ### ISSUE-009-ai09:knowledge-points schema 实际缺 difficulty/metadata 字段 - **提请方**:ai09 - **日期**:2026-07-10 - **类型**:其他 - **描述**:02-architecture-design.md §3.1.3 knowledge_points 表列出 `difficulty tinyint NOT NULL DEFAULT 3` 与 `metadata json NULL`,但实际 [textbooks.schema.ts](../../../services/content/src/textbooks/textbooks.schema.ts) 中 `knowledgePoints` 表仅含 id/chapterId/title/description 四个字段,无 difficulty 与 metadata。01-understanding.md C7 提到"时间戳缺失"但未提到 difficulty/metadata 缺失。 - **建议方案**:P4 schema 迁移时一并补齐 difficulty + metadata + created_at + updated_at(与 design doc §3.1.3 对齐)。 - **状态**:已裁决(见 coord.md §5) ### ISSUE-010-ai09:Neo4j Sync Worker 与 ES Sync Worker 在 P4 阶段不必要 - **提请方**:ai09 - **日期**:2026-07-10 - **类型**:工作量超批 - **描述**:02-architecture-design.md §1.1 分层图将 Neo4j Sync Worker 与 ES Sync Worker 并列展示,但: 1. ES 在 P5 才引入,ES Sync Worker 在 P4 不必要 2. 当前 [knowledge-points.service.ts](../../../services/content/src/knowledge-points/knowledge-points.service.ts) 的 `safeCreateNode` 是同步双写(业务事务内写 Neo4j),与 design doc §0.1 第 3 条"禁止业务事务内同步双写"原则冲突 3. P4 应改为 Outbox 事件驱动异步同步 Neo4j,但 design doc §1.1 图中 Neo4j Sync Worker 的输入源同时画了"Kafka Consumer"与"CONSUMER",链路不清晰 - **建议方案**: 1. §1.1 图中明确标注 ES Sync Worker 为 P5 组件(虚线或灰显) 2. §1.1 图中 Neo4j Sync Worker 的输入仅来自 content 自身 Outbox 事件(不消费 core-edu 事件) 3. P4 任务 T6 明确"重构 knowledge-points.service.ts:移除 safeCreateNode 同步写,改为发 Outbox 事件" - **状态**:已裁决(见 coord.md §5) --- ## §2 仲裁项汇总(ARB-005 全部已裁决,2026-07-10) | # | 标题 | 阻塞性 | 状态 | | --- | ---------------------------------------- | ------------------- | ------ | | 001 | REST 端点设计与实现不一致 | 🟡 P4 重构时对齐 | 已裁决 | | 002 | 事件 topic 命名策略冲突(独立 vs 聚合) | 🔴 阻塞 Outbox 实现 | 已裁决 | | 003 | Textbook/Chapter 事件在契约文档遗漏 | 🟡 契约完整性 | 已裁决 | | 004 | gRPC RPC 数量三方文档不一致 | 🔴 阻塞 proto 修改 | 已裁决 | | 005 | core-edu → content 失效事件 topic 无定义 | 🟢 建议删除 | 已裁决 | | 006 | "直接 push main"与项目规则冲突 | 🟡 文档修正 | 已裁决 | | 007 | questions.created_by 迁移风险 | 🟡 schema 迁移 | 已裁决 | | 008 | 缓存策略与 API 版本化策略缺失 | 🟢 长远架构 | 已裁决 | | 009 | knowledge-points schema 实际缺字段 | 🟡 P4 schema 迁移 | 已裁决 | | 010 | Sync Worker 链路与 P4 阶段不必要 | 🟡 设计澄清 | 已裁决 |