总裁确认采纳方案 A(双 /v1 前缀)。 - coord.md: 新增 §24 ARB-022(api-gateway 8 项 ISSUE 仲裁) - coord.md: §24.4 ISSUE-003 方案 A 裁决 + 总裁确认记录 - matrix.md: §5 路径前缀修正为双 /v1(方案 A) - api-gateway_issue.md: §2 状态更新为已裁决 AI: coord
138 KiB
coord 仲裁结果汇总
维护者:coord(协调 AI) 维护规则:各 AI 在
objections/[模块名]_issue.md提请异议 → coord 审阅 → 在本文件写入仲裁结果 关联文档:president-final-rulings.md、ai-work-orchestration.md、workline.md、matrix.md
仲裁记录索引
| 编号 | 日期 | 提请方 | 主题 | 状态 | 仲裁章节 |
|---|---|---|---|---|---|
| ARB-001 | 2026-07-09 | coord(全并行启动前) | teacher-bff GraphQL schema 第一版 | ✅ 已裁决 | §1 |
| ARB-002 | 2026-07-09 | coord(全并行启动前) | MF Shell 暴露清单 | ✅ 已裁决 | §2 |
| ARB-003 | 2026-07-10 | ai06 | iam 模块 7 项 ISSUE 仲裁 | ✅ 已裁决 | §3 |
| ARB-004 | 2026-07-10 | ai08 | core-edu 模块 7 项 ISSUE 仲裁 | ✅ 已裁决 | §4 |
| ARB-005 | 2026-07-10 | ai09 | content 模块 10 项 ISSUE 仲裁 | ✅ 已裁决 | §5 |
| ARB-006 | 2026-07-10 | coord(跨模块) | events.proto 补全(跨 iam/core-edu/content) | ✅ 已裁决 | §6 |
| ARB-007 | 2026-07-10 | coord(跨模块) | proto 契约补全汇总(iam.proto + core_edu.proto) | ✅ 已裁决 | §7 |
| ARB-008 | 2026-07-10 | ai10 | msg 模块 15 项 ISSUE 仲裁 | ✅ 已裁决 | §10 |
| ARB-009 | 2026-07-10 | ai11 | data-ana 模块 6 项 ISSUE 仲裁 | ✅ 已裁决 | §11 |
| ARB-010 | 2026-07-10 | ai12 | ai 模块 9 项 ISSUE 仲裁 | ✅ 已裁决 | §12 |
| ARB-011 | 2026-07-10 | coord(跨模块) | events.proto 扩展补全(msg/data-ana/ai message)+ proto package 命名统一 | ✅ 已裁决 | §13 |
| ARB-012 | 2026-07-10 | coord(跨模块) | analytics.proto + ai.proto 补全 | ✅ 已裁决 | §14 |
| ARB-013 | 2026-07-10 | coord(跨模块) | Kafka topic 命名统一裁决(跨全模块) | ✅ 已裁决 | §15 |
| ARB-014 | 2026-07-10 | ai01 | api-gateway 模块 4 项内联 ISSUE 仲裁 | ✅ 已裁决 | §16 |
| ARB-015 | 2026-07-10 | ai02 | push-gateway 模块 7 项 ISSUE 仲裁 | ✅ 已裁决 | §17 |
| ARB-016 | 2026-07-10 | ai03 | teacher-bff 模块 3 项 ISSUE 仲裁 | ✅ 已裁决 | §18 |
| ARB-017 | 2026-07-10 | ai04 | student-bff 模块 4 项新 ISSUE 仲裁 | ✅ 已裁决 | §19 |
| ARB-018 | 2026-07-10 | ai05 | parent-bff 模块 10 项 ISSUE 仲裁 | ✅ 已裁决 | §20 |
| ARB-019 | 2026-07-10 | ai14 | student-portal 模块 7 项 ISSUE 仲裁 | ✅ 已裁决 | §21 |
| ARB-020 | 2026-07-10 | ai15 | parent-portal 模块 10 项 ISSUE 仲裁 | ✅ 已裁决 | §22 |
| ARB-021 | 2026-07-10 | ai16 | admin-portal 模块 7 项 ISSUE 仲裁 | ✅ 已裁决 | §23 |
| ARB-022 | 2026-07-10 | ai01 | api-gateway 模块 8 项 ISSUE 仲裁(v2 正式版) | ✅ 已裁决 | §24 |
§1 ARB-001:teacher-bff GraphQL schema 第一版
1.1 背景
全并行启动前,需仲裁 teacher-bff GraphQL schema 第一版,作为 ai03(teacher-bff)和 ai13(teacher-portal)的共同契约。
数据源:ai03 的 02-architecture-design.md §5 提供了目标态 schema(P4),但 P2 只需 Must Have 子集。
1.2 仲裁结论
P2 第一版 schema 范围(Must Have,对应 ai03 P2 工作量分级 Must Have 13 项):
# ============ P2 第一版 schema ============
# 存放位置:packages/shared-ts/contracts/graphql/teacher-bff.schema.graphql
# 仲裁原则:仅包含 P2 可实现的 Query(iam 已就绪),Mutation 延后到 P3
# 修订(ARB-016 §18):admin 命名空间 P2 预留 schema 占位(总裁 §5.1 + §7.3 裁决优先级 president > coord)
# 修订(ARB-016 §18):schema 文件名统一为 <bff-name>.schema.graphql(总裁 §2.17)
scalar DateTime
enum DataScope {
SELF
CLASS
GRADE
SCHOOL
SUBJECT
ALL
}
enum ExamStatus {
DRAFT
PUBLISHED
IN_PROGRESS
GRADING
SCORED
ARCHIVED
}
enum SubmissionStatus {
NOT_SUBMITTED
SUBMITTED
GRADED
}
type User {
id: ID!
email: String!
name: String!
roles: [String!]!
dataScope: DataScope!
}
type ViewportItem {
key: String!
label: String!
route: String!
icon: String
sortOrder: String!
requiredPermission: String
}
type Class {
id: ID!
name: String!
gradeId: String!
studentCount: Int!
}
type DashboardStats {
totalExams: Int!
pendingGrading: Int!
todayHomework: Int!
}
type DashboardData {
user: User!
classes: [Class!]!
viewports: [ViewportItem!]!
stats: DashboardStats!
}
# ============ Query(P2 仅读,无 Mutation) ============
type Query {
# 仪表盘聚合(并行:iam.me + iam.viewports + iam.permissions + iam.classesByTeacher)
dashboard: DashboardData!
# 视口配置(导航)
viewports: [ViewportItem!]!
# 当前用户信息
me: User!
# 班级列表(按教师 dataScope 过滤,数据来自 iam gRPC,总裁 §3.5)
classes: [Class!]!
class(id: ID!): Class
}
# ============ P2 不包含(P3+ 扩展) ============
# - exams / homework / grades Query → P3(core-edu 就绪后)
# - classPerformance / studentWeakness / learningTrend → P4(data-ana 就绪后)
# - notifications → P5(msg 就绪后)
# - 所有 Mutation → P3+
# - Subscription → P6+ 评估
# ============ admin 命名空间(P2 预留 schema 占位,P6 实现) ============
# 总裁 §5.1:admin-portal 复用 teacher-bff,admin 命名空间 P2 预留 schema 占位
# P2 仅声明类型骨架,Resolver 返 null;P6 实现(ARB-021 ISSUE-005)
# 详见 ARB-021 §23.4 admin 命名空间 schema 清单
extend type Query {
# adminUsers / adminRoles / adminPermissions / adminViewports
# adminOrganization / adminClasses / adminTeachers / adminStudents
# auditLogs / adminDashboard
# (P6 实现,P2 仅占位)
}
extend type Mutation {
# createUser / updateUser / deleteUser / toggleUserStatus
# createRole / updateRolePermissions / updateViewport
# (P6 实现,P2 仅占位)
}
1.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| Schema 存放位置 | packages/shared-ts/contracts/graphql/teacher-bff.schema.graphql |
总裁裁决 §2.17 SDL-first + 集中管理 |
| schema 文件名格式 | <bff-name>.schema.graphql(统一格式,对齐 student-bff/parent-bff) |
总裁裁决 §2.17 + ARB-016 §18.3 |
| P2 Query 范围 | dashboard / viewports / me / classes / class(5 个) | 仅依赖 iam(P2 就绪),classes 数据从 iam gRPC 获取(总裁 §3.5) |
| P2 Mutation 范围 | 无(P2 纯读) | Mutation 依赖 core-edu(P3),P2 无下游可写 |
| DataLoader | dashboard 内 classes 列表用 DataLoader | N+1 防御(ai03 §5.1 第 4 条) |
| 复杂度限制 | depth ≤ 7,cost ≤ 1000 | ai03 §5.1 第 5 条 |
| admin 命名空间 | P2 预留 schema 占位(声明 admin Query/Mutation 类型骨架,Resolver 返 null),P6 实现 | 总裁裁决 §5.1 + §7.3(裁决优先级 president > coord,修正原 ARB-001 "P2 不包含") |
| DataScope 枚举 | SELF / CLASS / GRADE / SCHOOL / SUBJECT / ALL(SUBJECT 替代 DISTRICT) | coord DataScope 6 级统一 |
| 错误响应 | ActionState 信封(success/errors/data) | coord-final-decisions F9 |
| 降级模式 | success=true + error=null + data 内 degraded 字段 | 总裁裁决 §3.4 方案 B |
修订记录(ARB-016 §18,2026-07-10):
- admin 命名空间由 "P2 不包含" 修正为 "P2 预留 schema 占位"(总裁 §5.1 + §7.3 优先级 president > coord)
- schema 文件名由
teacher-bff.graphql修正为teacher-bff.schema.graphql(统一<bff-name>.schema.graphql格式,总裁 §2.17)- classes 数据来源明确为 iam gRPC(总裁 §3.5,非 core-edu)
1.4 ai03 执行项
- 在
packages/shared-ts/contracts/graphql/teacher-bff.schema.graphql创建 P2 第一版 schema 文件 - teacher-bff 实现 Yoga GraphQL endpoint(
POST /graphql) - 实现 5 个 Query Resolver(dashboard / viewports / me / classes / class)
- dashboard Resolver 并行调用 iam(3 RPC)+ iam.classesByTeacher(1 RPC),用 DataLoader 防御 N+1(总裁 §3.5:classes 数据从 iam gRPC 获取)
- 实现 ActionState 信封 + 降级模式(方案 B)
- P2 预留 admin 命名空间 schema 占位(声明类型骨架,Resolver 返 null;P6 实现见 ARB-021 §23.4)
1.5 ai13 执行项
- teacher-portal Shell 暴露
GraphQLProvider(urql client 单例) - 使用
useGraphQLClient()从 packages/hooks 获取 client - P2 页面(dashboard / classes)通过 GraphQL query 拉取数据
- 不调用 REST 端点(除登录外,P2 起 all-in GraphQL)
§2 ARB-002:MF Shell 暴露清单
2.1 背景
全并行启动前,需仲裁 teacher-portal 作为 MF Shell 暴露哪些模块给 Remote(student/parent/admin),作为 ai13 的实现依据。
数据源:ai13 的 03-long-term-architecture.md §1.4 提供了 GraphQL client 单例设计。
2.2 仲裁结论
P2 第一版 MF Shell 暴露清单:
// teacher-portal/next.config.js — NextFederationPlugin exposes
exposes: {
// 1. AppShell(布局 + 导航 + 认证守卫)
'./AppShell': './src/components/AppShell.tsx',
// 2. GraphQLProvider(urql client 单例,总裁 §2.17 方案 A)
'./GraphQLProvider': './src/app/providers.tsx',
// 3. 共享 hooks
'./useAuth': './packages/hooks/src/use-auth.ts',
'./usePermission': './packages/hooks/src/use-permission.ts',
'./useGraphQLClient': './packages/hooks/src/use-graphql-client.ts',
// 4. 共享 UI 组件
'./ErrorBoundary': './packages/ui-components/src/error-boundary.tsx',
'./Loading': './packages/ui-components/src/loading.tsx',
'./Empty': './packages/ui-components/src/empty.tsx',
'./RequirePermission': './packages/ui-components/src/require-permission.tsx',
}
MF shared(singleton)配置:
shared: {
react: { singleton: true, requiredVersion: '^18.3.0' },
'react-dom': { singleton: true, requiredVersion: '^18.3.0' },
urql: { singleton: true, requiredVersion: '^2.2.0' },
graphql: { singleton: true, requiredVersion: '^16.8.0' },
'@edu/ui-tokens': { singleton: true },
'@edu/ui-components': { singleton: true },
'@edu/hooks': { singleton: true },
}
2.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| Shell 身份 | teacher-portal 是 MF Shell(非 Remote) | 总裁裁决 §2.17 + ai13 §1.3 |
| P2 Remote 数量 | 0(P2 暂无 Remote,仅配置 exposes/shared) | ai13 §1.3 绞杀者模式 step 3 |
| P3 首个 Remote | student-portal | ai13 §1.3 step 4 |
| GraphQL client 归属 | Shell 暴露 GraphQLProvider,Remote 复用 | 总裁 §2.17 方案 A |
| MF shared singleton | react / react-dom / urql / graphql / @edu/* | 避免多实例 + 缓存不一致 |
| AppShell 暴露 | 是(Remote 复用布局 + 导航 + 认证守卫) | ai13 §1.3 |
| feature flag | NEXT_PUBLIC_MF_ENABLED=false(P2 默认关) |
ai13 §1.3 回退策略 |
| 登录页 | P2 不走 MF(Shell 独占 /login) |
登录是认证前提,MF 依赖认证 |
2.4 ai13 执行项
- teacher-portal
next.config.js添加 NextFederationPlugin(exposes + shared,无 remotes) - 创建
src/app/providers.tsx(GraphQLProvider 包裹) - AppShell 改造:从 REST
/api/v1/teacher/viewports切换为 GraphQL queryviewports - P2 页面(dashboard / classes)全部用 GraphQL
- feature flag
NEXT_PUBLIC_MF_ENABLED=false(P2 默认单体路由)
2.5 ai03 执行项(联动)
- teacher-bff 暴露
POST /graphqlendpoint - 提供GraphQL playground(仅开发环境)
§3 ARB-003:iam 模块 7 项 ISSUE 仲裁
3.1 背景
ai06 在 iam_issue.md §2 提请 7 项异议,涉及文档回写、events.proto 缺失、Topic 命名不一致、DataScope 枚举冲突、iam.proto 未补全、AI 身份署名错误、双入口策略冲突。coord 对照 iam_contract.md(v1.0,已含双入口策略 + 12 RPC + REST 端点清单)逐条仲裁。
3.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 001 | 01/02 文档未回写 I1-I8 裁决 | ✅ 支持 ai06 方案:3 个工作日内回写 01/02,删除全部过渡方案,对齐 contract.md v1.0 | ai06 |
| 002 | events.proto 缺 UserEvent/RoleEvent/AuditEvent | ✅ coord 批次 0 补全(见 §6 ARB-006 统一处理) | coord |
| 003 | Topic 命名三方不一致(edu.identity.* vs edu.iam.*) | ✅ 统一 edu.iam.* 域名 + 聚合 topic 风格 |
coord 修 004 + matrix.md |
| 004 | DataScope 枚举三方不一致 | ✅ 采用 president §3.2 P2.2 方案:ALL/SCHOOL/GRADE/CLASS/SUBJECT/SELF(SUBJECT 替代 DISTRICT) | coord 修 004 + ai06 修源码 + coord 修 ARB-001 GraphQL schema |
| 005 | iam.proto 仅 4 RPC,未补全至 12 RPC | ✅ coord 批次 0 补全(见 §7 ARB-007 统一处理) | coord |
| 006 | 01/02 文档 AI 身份署名错误 | ✅ 与 ISSUE-001 一并回写,署名改为 ai06 | ai06 |
| 007 | contract.md §1.2 与双入口策略冲突 | ✅ contract.md 已修正为双入口策略(REST + gRPC),ai06 回写 02 文档时对齐 | ai06 |
3.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| Topic 域名 | edu.iam.*(服务名 iam,非 identity) |
G16 规则 edu.<domain>.<aggregate>.<action>,domain=服务名 |
| Topic 粒度 | 聚合 topic(edu.iam.user.events 含多 action) |
与 events.proto ClassEvent 模式一致,减少 topic 数量 |
| DataScope 枚举 | ALL/SCHOOL/GRADE/CLASS/SUBJECT/SELF(6 级) | president §3.2 P2.2;SUBJECT 替代 DISTRICT(K12 学科级更实用) |
| 双入口策略 | REST /iam/v1/* 供 gateway 透传 + gRPC 50052 供 BFF 聚合 |
president §2.16 |
| iam.proto 补全 | 12 RPC(contract.md §1.1 已定义) | coord-final-decisions §5.1 + president §6 批次 0 |
| events.proto 补全 | UserEvent/RoleEvent/AuditEvent + schema_version 字段 | coord-final-decisions §5.1 + president §5.5 |
| 004 §7.2 修正 | edu.identity.* → edu.iam.*,改为聚合 topic 风格 |
与 matrix.md §4 / iam_contract.md §1.4 统一 |
3.4 ai06 执行项
- 回写 iam 01/02 文档(3 个工作日内):
- 删除全部过渡方案(P2 仅 REST / 自建 Outbox / PermissionGuard 待改造 / AuthMiddleware P2 不注册 / iam_parent_student_relations / 无 /v1 前缀 / HTTP 调用 iam)
- 对齐 contract.md v1.0(12 RPC + 双入口 + REST
/iam/v1/*+ gRPC 50052) - 署名从 ai02 改为 ai06
- 02 文档 §3.1.2 表名改为
iam_student_guardians(I6 裁决) - 02 文档 §8.1 决策点 5 改为"P2 即启用 gRPC 50052"(I1 裁决)
- 02 文档 §8.1 决策点 4 改为"使用 shared-ts Outbox 工具包"(I2 裁决)
- 02 文档 §8.1 决策点 9 改为"P2 即 DB 驱动 + Redis 缓存"(I3 裁决)
- 02 文档 §1.1/§1.2/§8.1 决策点 10 改为"P2 即注册 AuthMiddleware"(I4 裁决)
- 02 文档 §4.1 REST API 加
/v1前缀(I7 裁决)
- 修改源码 iam.schema.ts DataScope 枚举:DISTRICT → SUBJECT(ISSUE-004)
- 实现源码 PermissionGuard DB 驱动 + Redis 缓存(I3 裁决)
- 实现源码 AuthMiddleware 注册(I4 裁决)
- 实现源码 RS256 密钥(I5 裁决,本地文件 IAM_PRIVATE_KEY_PATH / IAM_PUBLIC_KEY_PATH)
- 实现源码 iam_student_guardians 表 + GetChildrenByParent RPC + GET /iam/v1/children(I6 裁决)
3.5 coord 执行项
- 补全 iam.proto 至 12 RPC(ARB-007,批次 0)
- 补全 events.proto UserEvent/RoleEvent/AuditEvent + schema_version(ARB-006,批次 0)
- 修正 004 §7.2:
edu.identity.*→edu.iam.*,改为聚合 topic 风格 - 修正 004 §5.3 表:DataScope 枚举 DISTRICT → SUBJECT;行 505 语义命名与枚举表对齐
- 修正 ARB-001 GraphQL schema DataScope 枚举:去掉 DISTRICT,加 SUBJECT
- 修正 matrix.md §4:iam topic 已为
edu.iam.*(核查无需改);补 DataScope 枚举说明
§4 ARB-004:core-edu 模块 7 项 ISSUE 仲裁
4.1 背景
ai08 在 core-edu_issue.md 提请 7 项异议,涉及 proto 实际状态与仲裁声称不符、events.proto 未同步、状态命名跨模块不一致、class.transferred topic 不一致、RPC 数量统计口径冲突、7 项设计决策未仲裁、01 文档审计待核对项。coord 对照 core-edu_contract.md(已更新为 P3 目标态 27 RPC)逐条仲裁。
4.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 001 | core_edu.proto 实际状态与仲裁声称不符 | ✅ coord 批次 0 补全至 5 Service 27 RPC(见 §7 ARB-007) | coord |
| 002 | events.proto 未同步 topic 命名仲裁 | ✅ coord 批次 0 补全(见 §6 ARB-006:AttendanceEvent + schema_version + edu.teaching.* 注释) | coord |
| 003 | 考试/作业状态命名跨模块不一致 | ✅ 采用 ai08 方案 A:统一用 graded(去掉 SCORED);submissions 统一为 not_submitted/submitted/graded |
ai08 修源码 + coord 修 ARB-001 GraphQL schema |
| 004 | class.transferred 事件 topic 三处不一致 | ✅ 统一为 edu.teaching.class.transferred |
coord 修 matrix.md + ai08 修文档 |
| 005 | RPC 数量统计口径不一致 | ✅ 统一为 P3 全量 27 RPC(ClassService 4 + ExamService 8 + HomeworkService 5 + GradeService 6 + AttendanceService 4) | coord 修 matrix.md + ai08 修文档 |
| 006 | 7 项设计决策待仲裁 | ✅ 全部采用 ai08 倾向方案(见 §4.4) | ai08 |
| 007 | 01 文档审计表"待核对"项 | ✅ 3 项纳入 P3 验收硬性标准 | ai08 |
4.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| proto 补全范围 | 5 Service 27 RPC(含 ClassService + AttendanceService + P3 新增 5 RPC + Exam/Homework/Grade message 补字段 + SubmitHomeworkRequest 补 answers) | ISSUE-001 建议 |
| Topic 命名 | 统一 edu.teaching.<aggregate>.<action>(含 class.transferred) |
coord-cross-review §3.1 |
| 聚合 topic | core-edu 采用具体动作 topic(edu.teaching.exam.created 等独立 topic,非聚合) |
与 iam 聚合 topic 不同:core-edu 事件量大,独立 topic 利于分区与消费隔离 |
| ExamStatus | draft/published/in_progress/grading/graded/archived/cancelled(小写) | 统一为 graded,去掉 SCORED |
| SubmissionStatus | not_submitted/submitted/graded(exam + homework 一致) | 统一初始状态为 not_submitted |
| GraphQL 枚举映射 | DRAFT/PUBLISHED/IN_PROGRESS/GRADING/GRADED/ARCHIVED/CANCELLED;NOT_SUBMITTED/SUBMITTED/GRADED | 大写映射,去掉 SCORED |
| RPC 统计口径 | 27 RPC(P3 全量) | ClassService 4 + ExamService 8 + HomeworkService 5 + GradeService 6 + AttendanceService 4 |
注:core-edu topic 策略采用"具体动作 topic"(
edu.teaching.exam.created等),与 iam/content 的"聚合 topic"(edu.iam.user.events/edu.content.knowledge_point.events)不同。原因:core-edu 事件量大(12 个事件类型),独立 topic 利于 Kafka 分区与消费者隔离;iam/content 事件量小,聚合 topic 减少元数据压力。此为 coord 裁决的策略差异,非矛盾。
4.4 ISSUE-006 七项设计决策仲裁
| # | 决策点 | 仲裁结论 | ai08 倾向 |
|---|---|---|---|
| 1 | classes 合并时机 | ✅ (a) P3 初期合并 | (a) |
| 2 | room_id | ✅ (b) 仅预留字段 | (b) |
| 3 | scope 优先级 | ✅ (a) class > subject > school | (a) |
| 4 | grace_period | ✅ (b) 300 秒(schema 默认值改为 .default(300)) |
(b) |
| 5 | schema 校验 | ✅ (b) 仅文档约束(P3 不强制) | (b) |
| 6 | exam.submitted 事件 | ✅ (b) 仅含 submission_id | (b) |
| 7 | archived 考试 | ✅ (b) P3 仅软删除 | (b) |
4.5 ai08 执行项
- 修改 core-edu 01/02 文档:
- 01 §L48 补"ClassService 也缺失"
- 02 §4.2 对齐 27 RPC(补 ClassService 4 + AttendanceService 4 + P3 新增 5 RPC + message 字段)
- 02 §5.1 TOPIC_MAP 对齐
edu.teaching.*命名(具体动作 topic) - 02 §13.3 七项决策按 §4.4 仲裁结论更新(决策 #4 schema
.default(300)) - class.transferred topic 统一为
edu.teaching.class.transferred
- 修改源码 status 字段值:exam
graded(非scored);submissions 统一not_submitted - P3 实施时补齐 Dockerfile 多阶段 / ActionState traceId / 权限装饰器覆盖(ISSUE-007 验收标准)
4.6 coord 执行项
- 补全 core_edu.proto 至 5 Service 27 RPC(ARB-007,批次 0)
- 补全 events.proto AttendanceEvent + schema_version + edu.teaching.* 注释(ARB-006,批次 0)
- 修正 coord-cross-review.md L312:"✅ 已补全" → "⏳ 待 coord 补全(ARB-007)"
- 修正 matrix.md §2:core-edu 22 RPC → 27 RPC
- 修正 matrix.md §4:class.transferred topic 统一为
edu.teaching.class.transferred - 修正 ARB-001 GraphQL schema:ExamStatus 去掉 SCORED 加 CANCELLED;SubmissionStatus 去掉 IN_PROGRESS(如有)确认 NOT_SUBMITTED/SUBMITTED/GRADED
- 修正 core-edu_contract.md §2.2:UserEvent topic 从
edu.identity.user.*改为edu.iam.user.events(与 iam ISSUE-003 仲裁一致,聚合 topic 风格)
§5 ARB-005:content 模块 10 项 ISSUE 仲裁
5.1 背景
ai09 在 content_issue.md 提请 10 项异议,涉及 REST 端点设计不一致、事件 topic 命名策略冲突、Textbook/Chapter 事件遗漏、RPC 数量三方不一致、core-edu 失效事件无定义、文档 push main 冲突、created_by 迁移风险、缓存/API 版本化缺失、schema 字段缺失、Sync Worker 链路。coord 对照 content_contract.md(v1.1,已更新为 21 RPC + 4 聚合 topic)逐条仲裁。
5.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 001 | REST 端点设计与实现不一致 | ✅ P4 重构时统一为 query 参数风格 + 补 DELETE prerequisite 端点;允许 API 路径变更(BFF 走 GraphQL 解耦) | ai09 |
| 002 | 事件 topic 命名策略冲突 | ✅ 采用聚合 topic + action 字段策略(4 聚合 topic) | ai09 修文档 + coord 补 events.proto |
| 003 | Textbook/Chapter 事件遗漏 | ✅ 补登记 edu.content.textbook.events + chapter.events | ai09 已在 contract.md 补 + coord 同步 matrix.md |
| 004 | gRPC RPC 数量三方不一致 | ✅ 统一为 21 RPC(Textbook 5 + Chapter 5 + KG 4 + Question 7) | ai09 修文档 + coord 修 matrix.md |
| 005 | core-edu → content 失效事件 topic 无定义 | ✅ 删除 02 文档 §5.2 该条目;联动改用 gRPC 调用 | ai09 |
| 006 | "直接 push main"与项目规则冲突 | ✅ 遵循总裁裁决(trunk-based,直接 push main,post-commit review);措辞优化为"trunk-based development" | ai09 |
| 007 | questions.created_by 迁移风险 | ✅ schema 用 created_by varchar(32) NOT NULL DEFAULT 'system'(历史数据回填 'system') |
ai09 |
| 008 | 缓存策略与 API 版本化缺失 | ✅ P4 补缓存策略小节 + API 版本化说明 | ai09 |
| 009 | knowledge-points schema 缺字段 | ✅ P4 迁移补齐 difficulty + metadata + created_at + updated_at | ai09 |
| 010 | Sync Worker 链路 P4 不必要 | ✅ ES Sync Worker 标 P5;Neo4j Sync Worker 输入仅 Outbox 事件;P4 移除 safeCreateNode 同步写 | ai09 |
5.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| REST 端点风格 | query 参数(GET /knowledge-points?chapterId=) |
RESTful 规范 + 与 design doc 一致 |
| 事件 topic 策略 | 聚合 topic + action 字段(4 topic:textbook/chapter/knowledge_point/question) | 与 matrix.md / events.proto ClassEvent 模式一致;减少 topic 数量 |
| RPC 总数 | 21(TextbookService 5 + ChapterService 5 + KnowledgeGraphService 4 + QuestionService 7) | contract.md 为契约唯一源 |
| content 与 core-edu 关系 | content 是上游(core-edu 调 content),不消费 core-edu 事件 | ISSUE-005 建议 |
| Git 工作流 | trunk-based development(直接 push main + post-commit review) | 总裁裁决覆盖 project_rules §8 分支开发规则 |
| created_by 迁移 | NOT NULL DEFAULT 'system'(历史数据回填 + 新数据应用层校验) |
ISSUE-007 方案二 |
| 缓存策略 | Redis 缓存教材树/章节树 + Outbox 事件触发失效 | 读多写少场景 |
| API 版本化 | REST /v1/ 前缀 + gRPC proto package version |
破坏性变更隔离 |
| Neo4j 同步 | P4 改为 Outbox 事件驱动异步同步(移除 safeCreateNode 同步写) | 禁止业务事务内同步双写 |
5.4 ai09 执行项
- 修改 content 02 文档:
- §4.1 REST 端点改 query 参数风格 + 补 DELETE prerequisite 端点
- §5.1 TOPIC_MAP 改为 4 聚合 topic(textbook/chapter/knowledge_point/question events)
- §5.2 删除 core-edu 失效事件条目
- §4.2 gRPC RPC 对齐 21 RPC(补 Textbook Update/Delete + Chapter Update/Delete + Question Publish/Search)
- §6 补"缓存策略"小节(Redis + Outbox 失效)
- §4 补"API 版本化"说明(REST
/v1/前缀) - §1.1 图 ES Sync Worker 标 P5(虚线/灰显);Neo4j Sync Worker 输入仅 Outbox 事件
- 文档末尾措辞优化为"trunk-based development(直接 push main,post-commit review)"
- 修改源码 schema:questions.created_by
NOT NULL DEFAULT 'system';knowledge_points 补 difficulty/metadata/created_at/updated_at - P4 任务 T6:重构 knowledge-points.service.ts 移除 safeCreateNode 同步写,改为发 Outbox 事件
5.5 coord 执行项
- 补全 events.proto TextbookEvent/ChapterEvent/KnowledgePointEvent/QuestionEvent + schema_version(ARB-006,批次 0)
- 修正 matrix.md §2:content 18 RPC → 21 RPC
- 修正 matrix.md §4:补登记 edu.content.textbook.events + chapter.events(共 4 聚合 topic)
§6 ARB-006:events.proto 补全(跨 iam/core-edu/content)
6.1 背景
iam ISSUE-002、core-edu ISSUE-002、content ISSUE-002/003 共同指向 events.proto 不完整。当前 events.proto 仅定义 4 个 message(ClassEvent/ExamEvent/HomeworkEvent/GradeEvent),缺 iam 的 UserEvent/RoleEvent/AuditEvent、core-edu 的 AttendanceEvent、content 的 TextbookEvent/ChapterEvent/KnowledgePointEvent/QuestionEvent,且所有 message 缺 schema_version 字段,文件头注释仍用旧 topic 命名。
6.2 仲裁结论
coord 在批次 0(P2 启动前)补全 events.proto:
| 新增 message | 字段 | 来源 |
|---|---|---|
| UserEvent | event_id/aggregate_id/event_type/occurred_at/user_id/email/name/roles/action(created/updated/deleted/role_changed)/schema_version/metadata | iam 02 §5.2 + president §5.5 |
| RoleEvent | event_id/aggregate_id/event_type/occurred_at/role_id/role_name/permissions/action(created/updated)/schema_version/metadata | iam 02 §5.2 |
| AuditEvent | event_id/aggregate_id/event_type/occurred_at/user_id/action(create/update/delete/login/logout/permission_change)/resource_type/resource_id/schema_version/metadata | president §5.5 |
| AttendanceEvent | event_id/aggregate_id/event_type/occurred_at/attendance_id/student_id/class_id/schedule_id/status/action(recorded)/schema_version/metadata | core-edu 02 §5.1 |
| TextbookEvent | event_id/aggregate_id/event_type/occurred_at/textbook_id/title/subject_id/grade_id/version/action(created/updated/published/archived)/schema_version/metadata | content contract.md §1.4 |
| ChapterEvent | event_id/aggregate_id/event_type/occurred_at/chapter_id/textbook_id/title/order/action(created/updated/deleted)/schema_version/metadata | content contract.md §1.4 |
| KnowledgePointEvent | event_id/aggregate_id/event_type/occurred_at/kp_id/chapter_id/title/difficulty/action(created/updated/prerequisite_added/prerequisite_removed)/prerequisite_id/schema_version/metadata | content contract.md §1.4 |
| QuestionEvent | event_id/aggregate_id/event_type/occurred_at/question_id/kp_id/type/difficulty/status/source/created_by/action(created/updated/published/deleted)/schema_version/metadata | content contract.md §1.4 |
同时:
- 所有现有 message(ClassEvent/ExamEvent/HomeworkEvent/GradeEvent)补
string schema_version = N;字段 - 文件头注释改为
edu.teaching.*命名(core-edu 事件)+edu.iam.*命名(iam 事件)+edu.content.*命名(content 事件)
6.3 Topic 命名策略(跨模块统一)
| 服务 | Topic 策略 | 示例 | 原因 |
|---|---|---|---|
| iam | 聚合 topic + action 字段 | edu.iam.user.events(含 created/updated/deleted/role_changed) |
事件量小,聚合减少 topic 数 |
| core-edu | 具体动作 topic | edu.teaching.exam.created(每事件独立 topic) |
事件量大,独立 topic 利于分区与消费隔离 |
| content | 聚合 topic + action 字段 | edu.content.knowledge_point.events(含 created/updated/prerequisite_*) |
事件量中等,聚合减少 topic 数 |
| msg | 具体动作 topic | edu.notify.notification.created |
通知事件量大,独立 topic |
coord 裁决:允许跨服务采用不同 topic 粒度策略(聚合 vs 具体动作),以服务特征为准。所有 topic 命名统一遵循
edu.<domain>.<aggregate>.<action>或edu.<domain>.<aggregate>.events格式。
§7 ARB-007:proto 契约补全汇总(iam.proto + core_edu.proto)
7.1 背景
iam ISSUE-005 和 core-edu ISSUE-001 共同指向 proto 契约未补全。coord 作为 shared-proto 维护者,在批次 0 统一补全。
7.2 iam.proto 补全(12 RPC)
| Service | RPC | 请求 | 响应 |
|---|---|---|---|
| IamService | Register | RegisterRequest | AuthResponse |
| IamService | Login | LoginRequest | AuthResponse |
| IamService | RefreshToken | RefreshTokenRequest | TokenPair |
| IamService | Logout | LogoutRequest | LogoutResponse |
| IamService | GetUserInfo | GetUserInfoRequest | UserInfo |
| IamService | BatchGetUsers | BatchGetUsersRequest | BatchGetUsersResponse |
| IamService | GetEffectivePermissions | GetEffectivePermissionsRequest | EffectivePermissionsResponse |
| IamService | GetEffectiveAccess | GetEffectiveAccessRequest | EffectiveAccessResponse |
| IamService | GetEffectiveDataScope | GetEffectiveDataScopeRequest | DataScopeResponse |
| IamService | GetViewports | GetViewportsRequest | ViewportsResponse |
| IamService | GetPublicKey | GetPublicKeyRequest | PublicKeyResponse |
| IamService | GetChildrenByParent | GetChildrenByParentRequest | ChildrenResponse |
对齐 iam_contract.md §1.1 的 12 RPC 清单。新增 8 RPC(Logout/BatchGetUsers/GetEffectivePermissions/GetEffectiveAccess/GetEffectiveDataScope/GetViewports/GetPublicKey/GetChildrenByParent)。
7.3 core_edu.proto 补全(5 Service 27 RPC)
| Service | RPC | 状态 |
|---|---|---|
| ClassService | GetClass / GetClassesByTeacher / BatchGetClasses / ListStudentsByClass | 新增 4 RPC |
| ExamService | CreateExam / GetExam / ListExamsByClass / UpdateExam / DeleteExam / PublishExam / SubmitExam / GradeExam | 已有 5 + 新增 3 |
| HomeworkService | AssignHomework / GetHomework / ListHomeworkByClass / SubmitHomework / GradeHomework | 已有 4 + 新增 1 |
| GradeService | RecordGrade / GetGrade / ListGradesByStudent / ListGradesByExam / ListGradesByHomework / UpdateGrade | 已有 5 + 新增 1 |
| AttendanceService | RecordAttendance / GetAttendance / ListAttendanceByStudent / ListAttendanceByClass | 新增 4 RPC |
同时补全 message 字段:
- Exam:补 subject_id / school_id / status_changed_at / status_changed_by / archived_at
- Homework:补 subject_id / grace_period / school_id
- Grade:补 total_score / school_id / idempotency_key
- SubmitHomeworkRequest:补 answers 字段
对齐 core-edu_contract.md §1.1 的 27 RPC 清单。
7.4 coord 执行项
- 补全 iam.proto 至 12 RPC(含全部 message 定义)
- 补全 core_edu.proto 至 5 Service 27 RPC(含 ClassService + AttendanceService + P3 新增 5 RPC + message 字段补全)
- 补全 events.proto(ARB-006,7 个新 message + schema_version + 注释更新)
- 运行
buf lint+buf breaking确保零错误 - 运行
buf generate产出 TS gRPC 代码 - 修正 coord-cross-review.md L312 状态
- 更新 matrix.md §2 RPC 统计
§10 ARB-008:msg 模块 15 项 ISSUE 仲裁
10.1 背景
ai10 在 msg_issue.md 提请 15 项异议(ISSUE-001005 已有仲裁核查 + ISSUE-006015 新发现),涉及 events.proto 字段缺失、proto 包名规则冲突、Kafka topic 三套约定、RPC 数量超预算、权限点不一致、降级方向矛盾、DLQ/幂等防线缺失、events.proto 缺 message、RPC 清单不一致、Kafka 发布事件不一致。
10.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 001~005 | 已有仲裁核查 | ✅ 核查通过(001/002/003);004 待 coord 同步 events.proto 注释(ARB-006 已覆盖);005 待 coord 修正 004 §4.1 PushGW 方向 | coord |
| 006 | events.proto GradeEvent 缺 class_id + 全部事件缺 student_ids[] | ✅ coord 补全:GradeEvent 补 class_id;Exam/Homework/GradeEvent 补 student_ids[](fan-out 广播用) | coord |
| 007 | proto 包名规则冲突(project_rules §5 vs 实际) | ✅ 统一为 next_edu_cloud.<domain>.v1(与实际 proto 一致);coord 更新 project_rules §5(见 §13 ARB-011) |
coord |
| 008 | Kafka topic 命名三套约定并存 | ✅ 统一裁决(见 §15 ARB-013):msg 采用具体动作 topic(edu.notify.notification.sent 等,与 core-edu 策略一致) |
coord |
| 009 | RPC 数量超预算(17 vs 13) | ✅ 采用方案 A:维持 13 RPC 预算,裁剪 4 RPC(BatchSendNotification/GetUnreadCount/BatchMarkAsRead/MarkAllAsRead 降级为 REST only) | ai10 |
| 010 | markAsRead 权限点不一致 | ✅ 以 02 文档 §6.1 为准:MSG_NOTIFICATION_READ(非 MANAGE) |
ai10 |
| 011 | DB→ES 降级方向与 ai-allocation 相反 | ✅ 采用双向降级:ES 故障→DB LIKE;DB 故障→ES 只读(仅读操作可降级,写操作必须等 DB 恢复) | ai10 |
| 012 | 缺 DLQ 与三层幂等防线 | ✅ 非阻塞,ai10 自行补充设计文档(§3.1 补 msg_idempotency 表 + §5.5 三层幂等 + §5 DLQ 设计) | ai10 |
| 013 | events.proto 缺 4 类 message | ✅ coord 补全(见 §13 ARB-011:MasteryEvent/NotificationEvent + UserEvent/RoleEvent 已在 ARB-006 覆盖) | coord |
| 014 | msg_contract.md 与 02 文档 RPC 清单不一致 | ✅ 待 ISSUE-009 仲裁后统一为 13 RPC,两文档对齐 | ai10 |
| 015 | Kafka 发布事件不一致 | ✅ 待 ISSUE-008 仲裁后统一(见 §15 ARB-013) | ai10 + coord |
10.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| msg RPC 总数 | 13(NotificationService 5 + PreferenceService 4 + TemplateService 4) | 维持 ai-allocation 预算;裁剪 4 RPC 降级 REST |
| Kafka topic 策略 | 具体动作 topic(edu.notify.notification.sent / .read / .recalled / .failed) |
与 core-edu 策略一致;事件量大,独立 topic 利于消费隔离 |
| markAsRead 权限 | MSG_NOTIFICATION_READ |
02 文档为准 |
| 降级策略 | 双向(ES 故障→DB LIKE;DB 故障→ES 只读) | ai-allocation §5 + 02 文档双向覆盖 |
| 三层幂等 | L1 Redis SETNX + L2 msg_idempotency 表 + L3 notifications.source_event_id 唯一索引 | known-issues 已记录 |
| DLQ | 重试 3 次后投递 edu.notify.dlq + 告警 |
known-issues 已记录 |
| proto package | next_edu_cloud.msg.v1(保留现状) |
见 §13 ARB-011 |
10.4 ai10 执行项
- 修改 msg 02 文档:
- §4.2 RPC 裁剪至 13(移除 BatchSendNotification/GetUnreadCount/BatchMarkAsRead/MarkAllAsRead,降级 REST only)
- §5.2 Kafka topic 改为具体动作 topic(
edu.notify.notification.sent等 4 个 per-event topic) - §3.1 补 msg_idempotency 表 schema
- §5.5 改为三层幂等防线
- §5 补 DLQ 设计(
edu.notify.dlq+ 重试 3 次 + 告警) - §3.2.2/§3.4 补双向降级策略(DB 故障→ES 只读)
- §6.1 markAsRead 权限改为
MSG_NOTIFICATION_READ
- 修改源码 notifications.controller.ts markAsRead 权限点
- msg_contract.md §1.1 RPC 清单对齐 13 RPC + §1.4 topic 对齐具体动作 topic
10.5 coord 执行项
- 补全 events.proto(ARB-011:NotificationEvent + MasteryEvent + GradeEvent 补 class_id + 全部事件补 student_ids[])
- 修正 004 §4.1 PushGW 方向表述为"Msg → push-gateway (gRPC)"
- 修正 matrix.md §4:msg topic 改为
edu.notify.notification.*具体动作 topic
§11 ARB-009:data-ana 模块 6 项 ISSUE 仲裁
11.1 背景
ai11 在 data-ana_issue.md 提请 6 项异议,涉及 iam.proto 缺 GetEffectiveDataScope、events.proto 缺 AIUsageEvent、analytics.proto 未补全至 12 RPC、004 章节引用断裂、MasteryEvent topic 不一致、coord-cross-review §8.2 声明与实际不符。
11.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 001 | iam.proto 缺 GetEffectiveDataScope RPC | ✅ coord 批次 0 补全 iam.proto 12 RPC(ARB-007 已覆盖,含 GetEffectiveDataScope) | coord |
| 002 | events.proto 缺 AIUsageEvent message | ✅ coord 补全(见 §13 ARB-011) | coord |
| 003 | analytics.proto 仅 3 RPC,声称 12 RPC 未落实 | ✅ coord 批次 0 补全 analytics.proto 至 12 RPC(见 §14 ARB-012) | coord |
| 004 | 004 章节引用断裂(coord 整改 #7/#8/#9/#10 未落实) | ✅ coord 补全 004 §7.2/§1.2/§4.1/§12.2 对应章节 | coord |
| 005 | MasteryEvent topic 命名三处不一致 | ✅ 统一为 edu.insight.mastery.updated + edu.insight.warning.triggered(domain=insight 智能洞察领域) |
coord 修 matrix.md + ai11 已对齐 |
| 006 | coord-cross-review §8.2 声明与实际不符 | ✅ coord 更正 §8.2 状态为"待执行",明确补全时间点 | coord |
11.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| analytics.proto | 12 RPC(4 端 Dashboard + Warning + Mastery + Server Streaming) | 02 文档 §4.2 已设计,coord 补全 proto |
| MasteryEvent topic | edu.insight.mastery.updated |
004 §7.2 命名规范 edu.<domain>.<aggregate>.<action>,domain=insight |
| WarningEvent topic | edu.insight.warning.triggered |
同上 |
| 004 章节补全 | coord 补全 §7.2/§1.2/§4.1/§12.2 对应段落 | coord-cross-review §6 整改 #7/#8/#9/#10 |
| §8.2 声明更正 | "✅ 已完成" → "⏳ 待 coord 补全(ARB-007/012)" | 实际 proto 未补全 |
| Python Outbox 豁免 | ✅ 确认(MasteryUpdated/WarningTriggered 派生数据豁免) | coord-cross-review §3.3 |
11.4 ai11 执行项
- data-ana 01/02 文档:将 004 §4.2/§11.4/§11.5/§15.3 引用从 coord-cross-review.md 回切到 004 对应章节(待 coord 补全后)
- contract.md §1.4 topic 已对齐
edu.insight.*(核查通过)
11.5 coord 执行项
- 补全 analytics.proto 至 12 RPC(ARB-012,批次 0)
- 补全 events.proto AIUsageEvent + MasteryEvent(ARB-011,批次 0)
- 补全 iam.proto GetEffectiveDataScope(ARB-007 已覆盖)
- 补全 004 §7.2(补登 6 个 topic + CDC 命名规范)/§1.2(端口列)/§4.1(gRPC 启用阶段矩阵)/§12.2(派生数据事件 Outbox 豁免条款)
- 更正 coord-cross-review.md §8.2 状态
- 修正 matrix.md §4:data-ana topic 改为
edu.insight.*
§12 ARB-010:ai 模块 9 项 ISSUE 仲裁
12.1 背景
ai12 在 ai_issue.md 提请 9 项异议,涉及 matrix.md 端口不同步、ai 用量事件 topic 三义、ai.proto 待补全、events.proto 缺 AIUsageEvent、contract 与设计文档矛盾、Temporal 决策点、iam GetEffectiveDataScope、proto package 命名、ActionState 整改。
12.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 01 | matrix.md 端口 50057 vs 50058 不同步 | ✅ 统一为 50058(port-allocation.md §7 为准);coord 修 matrix.md | coord |
| 02 | ai 用量事件 topic 三义未决 | ✅ 统一为 edu.ai.usage(见 §15 ARB-013) |
coord |
| 03 | ai.proto 待补全 | ✅ P5 目标 6 RPC(Chat/StreamChat/GenerateQuestion/StreamGenerateQuestion/OptimizeExpression/GenerateLessonPlan);备课状态查询/确认用 HTTP 端点(见 §14 ARB-012) | coord 补 proto |
| 04 | events.proto 缺 AIUsageEvent | ✅ coord 补全(见 §13 ARB-011) | coord |
| 05 | contract 与设计文档矛盾 | ✅ ai12 自纠重写 contract(端口 50058 / 补 HTTP 端点 / topic 待 §15 裁决后填 / 错误码对齐 02 §6.2 / 删除消费事件) | ai12 |
| 06 | 备课工作流 Temporal(P6 决策点) | ✅ P5 用 BackgroundTasks + Redis;P6 由 coord 评估 Temporal 引入(roadmap 标注 P6 决策点) | ai12 P5 + coord P6 |
| 07 | iam GetEffectiveDataScope 待 P4 补全 | ✅ coord 批次 0 补全 iam.proto 12 RPC(ARB-007 已覆盖) | coord |
| 08 | proto package 命名不符合 project_rules §5 | ✅ 统一为 next_edu_cloud.<domain>.v1(见 §13 ARB-011) |
coord |
| 09 | 响应信封偏离 ActionState | ✅ P5 实施时整改:所有返回值改为 ActionState;degraded 移至 error.details.degraded |
ai12 |
12.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| ai gRPC 端口 | 50058 | port-allocation.md §7 为准 |
| ai RPC 总数 | 6(P5 目标) | 避免 RPC 膨胀;备课状态查询/确认用 HTTP |
| ai 用量 topic | edu.ai.usage |
最简短,符合 edu.<domain>.<action> 约定 |
| proto package | next_edu_cloud.ai.v1(保留现状) |
见 §13 ARB-011 |
| Temporal | P5 不引入(BackgroundTasks + Redis);P6 评估 | 避免过早引入复杂度 |
| ActionState | P5 强制整改(degraded 移至 error.details) | 004 §11.5 |
12.4 ai12 执行项
- 重写 ai_contract.md 对齐设计文档(端口 50058 / 补 HTTP 端点 / topic
edu.ai.usage/ 错误码对齐 02 §6.2 / 删除消费事件或标注 P6+) - P5 实施时整改 ActionState(main.py 返回值改为
{success, data, error:{code,message,details,traceId}};degraded 移至error.details.degraded) - P5 备课工作流用 BackgroundTasks + Redis(02 文档 §2.4 状态机已设计)
- 修正 01/02 文档引用:004 §7.2/§1.2 引用失实,改引 port-allocation.md + coord 仲裁
12.5 coord 执行项
- 补全 ai.proto 至 6 RPC(ARB-012,批次 0)
- 补全 events.proto AIUsageEvent(ARB-011,批次 0)
- 修正 matrix.md §2/§8:ai gRPC 端口 50057 → 50058
- 在 roadmap 标注 P6 决策点(Temporal 引入评估)
- 在 known-issues §2.9 ai 分区记录 ActionState 整改约束
§13 ARB-011:events.proto 扩展补全 + proto package 命名统一
13.1 背景
msg ISSUE-013、data-ana ISSUE-002、ai ISSUE-04 共同指向 events.proto 还缺 msg/data-ana/ai 相关 message(ARB-006 已覆盖 iam/core-edu/content 的 7 个 message)。msg ISSUE-007 + ai ISSUE-08 共同指向 proto package 命名规则冲突。
13.2 events.proto 扩展补全(在 ARB-006 基础上)
| 新增 message | 字段 | 来源 |
|---|---|---|
| MasteryEvent | event_id/aggregate_id/event_type/occurred_at/student_id/subject_id/mastery_score/action(updated)/schema_version/metadata | data-ana 02 文档 |
| WarningEvent | event_id/aggregate_id/event_type/occurred_at/student_id/warning_type/severity/action(triggered)/schema_version/metadata | data-ana 02 文档 |
| NotificationEvent | event_id/aggregate_id/event_type/occurred_at/notification_id/user_id/channel/action(sent/read/recalled/failed)/schema_version/metadata | msg 02 文档 |
| AIUsageEvent | event_id/request_id/user_id/school_id/provider/model/operation/prompt_tokens/completion_tokens/total_tokens/latency_ms/success/degraded/action(usage)/schema_version/metadata | ai 02 文档 §3.3 |
同时:
- GradeEvent 补
class_id字段 - ExamEvent/HomeworkEvent/GradeEvent 补
student_ids[]字段(复数,fan-out 广播用)
events.proto 最终包含 15 个 message:ClassEvent/ExamEvent/HomeworkEvent/GradeEvent(原有 4 + 补字段)+ UserEvent/RoleEvent/AuditEvent/AttendanceEvent/TextbookEvent/ChapterEvent/KnowledgePointEvent/QuestionEvent(ARB-006 新增 8)+ MasteryEvent/WarningEvent/NotificationEvent/AIUsageEvent(本节新增 4)= 4+8+4 = 16 个 message(含原有 4)。
13.3 proto package 命名统一
| 裁决点 | 结论 | 依据 |
|---|---|---|
| proto package 命名 | next_edu_cloud.<domain>.v1(保留现状) |
所有 proto 文件已采用此格式,改动成本高 |
| project_rules §5 更新 | edu.<domain>.v1 → next_edu_cloud.<domain>.v1 |
与实际 proto 一致 |
13.4 coord 执行项
- 补全 events.proto 4 个新 message(MasteryEvent/WarningEvent/NotificationEvent/AIUsageEvent)
- 补全 GradeEvent class_id + 全部事件 student_ids[] 字段
- 更新 project_rules §5 包名规范为
next_edu_cloud.<domain>.v1(需人类审批,project_rules §15.7 敏感文件) - 运行
buf lint+buf breaking确保零错误
§14 ARB-012:analytics.proto + ai.proto 补全
14.1 背景
data-ana ISSUE-003 和 ai ISSUE-03 共同指向 proto 契约未补全。coord 作为 shared-proto 维护者,在批次 0 统一补全。
14.2 analytics.proto 补全(12 RPC)
| Service | RPC | 说明 |
|---|---|---|
| AnalyticsService | GetClassPerformance | 班级表现 |
| AnalyticsService | GetStudentWeakness | 学生薄弱点 |
| AnalyticsService | GetLearningTrend | 学习趋势 |
| AnalyticsService | StreamClassPerformance | Server Streaming 班级实时表现 |
| AnalyticsService | GetStudentDashboard | 学生仪表盘 |
| AnalyticsService | GetTeacherDashboard | 教师仪表盘 |
| AnalyticsService | GetAdminDashboard | 管理员仪表盘 |
| AnalyticsService | GetParentDashboard | 家长仪表盘 |
| AnalyticsService | TriggerWarning | 触发预警 |
| AnalyticsService | GetWarnings | 查询预警列表 |
| AnalyticsService | UpdateMastery | 更新掌握度 |
| AnalyticsService | GetMasteryByStudent | 查询学生掌握度 |
对齐 data-ana 02 文档 §4.2 的 12 RPC 清单(含 1 Server Streaming)。
14.3 ai.proto 补全(6 RPC)
| Service | RPC | 说明 |
|---|---|---|
| AiService | Chat | 单轮对话 |
| AiService | StreamChat | 流式对话 |
| AiService | GenerateQuestion | 生成题目 |
| AiService | StreamGenerateQuestion | 流式生成题目 |
| AiService | OptimizeExpression | 优化表达 |
| AiService | GenerateLessonPlan | 生成教案 |
同时扩展 message 字段:
- GenerateQuestionRequest:补 grade / knowledge_point_ids / question_type / count
- ChatRequest:补 user_id / session_id / data_scope(可选)
备课工作流状态查询/确认用 HTTP 端点(非 gRPC):
GET /ai/v1/lesson/preparation/{id}:查询备课状态POST /ai/v1/lesson/preparation/{id}/confirm:确认入库
14.4 coord 执行项
- 补全 analytics.proto 至 12 RPC(含 Server Streaming)
- 补全 ai.proto 至 6 RPC + message 字段扩展
- 运行
buf lint+buf breaking确保零错误 - 运行
buf generate产出 TS/Go/Python gRPC 代码
§15 ARB-013:Kafka topic 命名统一裁决(跨全模块)
15.1 背景
msg ISSUE-008/015、data-ana ISSUE-005、ai ISSUE-02 共同指向 Kafka topic 命名跨模块不一致。需 coord 统一裁定。
15.2 仲裁结论
统一命名规则:edu.<domain>.<aggregate>.<action> 或 edu.<domain>.<aggregate>.events
Topic 粒度策略(按服务特征区分,coord 裁决允许差异):
| 服务 | Topic 策略 | Topic 清单 | 原因 |
|---|---|---|---|
| iam | 聚合 topic + action 字段 | edu.iam.user.events / edu.iam.role.events / edu.iam.audit.created |
事件量小,聚合减少 topic 数 |
| core-edu | 具体动作 topic | edu.teaching.exam.created / .updated / .deleted / .published / .submitted / edu.teaching.homework.assigned / .submitted / .graded / edu.teaching.grade.recorded / .updated / edu.teaching.attendance.recorded / edu.teaching.class.transferred |
事件量大,独立 topic 利于分区 |
| content | 聚合 topic + action 字段 | edu.content.textbook.events / edu.content.chapter.events / edu.content.knowledge_point.events / edu.content.question.events |
事件量中等,聚合减少 topic 数 |
| msg | 具体动作 topic | edu.notify.notification.sent / .read / .recalled / .failed |
通知事件量大,独立 topic |
| data-ana | 具体动作 topic | edu.insight.mastery.updated / edu.insight.warning.triggered |
派生数据事件(Outbox 豁免) |
| ai | 具体动作 topic | edu.ai.usage |
派生数据事件(Outbox 豁免) |
15.3 域名映射
| 服务 | domain | 依据 |
|---|---|---|
| iam | iam |
服务名 |
| core-edu | teaching |
教学领域(非服务名 core_edu) |
| content | content |
内容领域 |
| msg | notify |
通知领域(非服务名 msg) |
| data-ana | insight |
智能洞察领域(非服务名 data_ana) |
| ai | ai |
AI 领域 |
15.4 matrix.md §4 同步更新
coord 修正 matrix.md §4 Kafka 事件矩阵,全部 topic 对齐上述清单。
15.5 各 AI 执行项
各 AI 检查自身 02 文档 TOPIC_MAP + contract.md §1.4,对齐本仲裁的 topic 命名。具体差异见各模块 ARB 章节。
§16 ARB-014:api-gateway 模块 4 项内联 ISSUE 仲裁
16.1 背景
ai01 的 api-gateway_issue.md 文件仅含标题未填写实质内容(文件截断,仅 2 行),但其 api-gateway_contract.md v2 内联了 4 项待仲裁 ISSUE(§1.2.2 注 3 + §2.4 + §3.1)。coord 提取 contract.md 中的内联 ISSUE 逐条仲裁。
16.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 001 | JWKS 拉取方式(gRPC vs HTTP) | ✅ 已确认 HTTP JWKS(contract v2 §2.3 已执行:GET /.well-known/jwks.json,TTL 5min 缓存) |
ai01(已完成) |
| 002 | shared-go 包接入 | ✅ shared-go 包骨架已完成(contract §3.1 显示 ✅);ai01 直接 import packages/shared-go 的 jwks/logger/tracer/env 4 模块 |
ai01(已就绪) |
| 003 | API 版本化路由方案(双 /v1 前缀) | ✅ 采纳方案 A:前端调用 /api/v1/<service>/v1/*(双 /v1 前缀,Gateway 纯透传无路径重写) |
ai01 |
| 004 | zap vs slog 日志库选型 | ✅ 遵循 project_rules §12 使用 zap(project_rules 明确规定 Go 日志用 zap) | ai01 |
16.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| JWKS 拉取 | HTTP GET /.well-known/jwks.json(非 gRPC) |
president §2.16 + contract v2 §2.3 |
| Gateway gRPC 消费 | 无(Gateway 不消费任何 gRPC,纯 HTTP 透传) | president §2.16 + B3 裁决(权限由下游 Controller 自校验) |
| API 版本化 | 方案 A:/api/v1/<service>/v1/* 双前缀,Gateway 不做路径重写 |
纯透传最简,避免路径重写 bug;/api/v1 是 Gateway API 前缀,/<service>/v1 是服务内部 API 前缀 |
| Go 日志库 | zap(对齐 project_rules §12) | project_rules 强制规定;Go 1.22 slog 为备选,需 project_rules 变更后评估 |
| matrix.md §2 修正 | 移除 api-gateway 为 iam gRPC 消费方(contract §2.1 勘误已指出) | Gateway 不消费 gRPC |
16.4 ISSUE-003 方案 A 路径规范
| 层级 | 路径格式 | 示例 |
|---|---|---|
| 前端调用 | /api/v1/<service>/v1/<resource> |
/api/v1/iam/v1/register |
| Gateway 透传 | 原样转发到 <service>:<port>/<service>/v1/<resource> |
iam:3002/iam/v1/register |
| 服务内部路由 | /<service>/v1/<resource> |
iam Controller 注册 /iam/v1/register |
双 /v1 语义:外层
/api/v1是 Gateway 层 API 版本(全局),内层/v1是服务内部 API 版本(独立演进)。此设计允许 Gateway 和服务各自独立版本化。
16.5 ai01 执行项
- P2.7 任务统一迁移路由至
/api/v1/<service>/v1/*双前缀格式(当前 P1 代码为/api/v1/<service>/*单前缀) - 使用 zap 日志库(import
packages/shared-go/logger) - ISSUE-001/002 已落地,无需额外动作
- 补充 issue.md 文件内容(当前为空,后续如有新问题需按格式追加)
16.6 coord 执行项
- 修正 matrix.md §2 gRPC 接口提供方矩阵:移除 api-gateway 为 iam gRPC 消费方
- 确认 shared-go 4 模块骨架已就绪(contract §3.1 已标 ✅)
§17 ARB-015:push-gateway 模块 7 项 ISSUE 仲裁
17.1 背景
ai02 在 push-gateway_issue.md 提请 7 项异议,涉及 SSE 端点冲突、内部 API 鉴权命名、容量目标、端点路径、审计表设计、Redis /readyz 冲突、02 文档缺 ADR/NFR。coord 对照 push-gateway_contract.md v2 逐条仲裁。
17.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 001 | SSE 端点三方冲突 | ✅ 采纳 ai02 建议:不支持 SSE,仅 WebSocket。移除 contract.md §1.2 的 /sse 端点 + matrix.md §5 SSE 行 |
coord 修 contract + matrix + ai02 确认 |
| 002 | 内部 API 鉴权命名不一致 | ✅ 统一为 X-Internal-Token 头 + INTERNAL_API_TOKEN 环境变量(对齐总裁 §7.2) |
ai02 改代码 + coord 修 contract |
| 003 | 容量目标 50k vs 10w+ | ✅ 统一为 10w+(对齐 02 文档 + pending-features 权威) | coord 修 modules/README §7 |
| 004 | /internal/send vs /internal/push | ✅ 统一为 /internal/push(ai02 已自行修复,contract v2 已对齐) |
ai02(已完成) |
| 005 | 审计表设计缺失 | ✅ 方案 2:审计由 msg 服务维护(msg 已落库),push-gateway 保持无 DB 定位 | ai10 确认审计字段 + ai02 无需引入 DB |
| 006 | ISSUE-058 与 055 Redis /readyz 冲突 | ✅ Redis 软失败(仅告警 + degraded: true + 返 200,不返 503);从 ISSUE-055 必需依赖列表中移除 push-gateway → Redis |
coord 澄清两裁决优先级 |
| 007 | 02 文档缺 ADR/NFR/容量/失败模式 | ✅ P5(批次 4)补全 02 文档 §14-§17 四章节(ADR/非功能性需求/失败模式/容量估算) | ai02 |
17.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| SSE 端点 | 不支持,仅 WebSocket | 单一协议降低维护成本;SSE 单向下行不适合双向协议 |
| 内部鉴权 | X-Internal-Token + INTERNAL_API_TOKEN(共享密钥) |
总裁 §7.2;mTLS P5 成本过高,K8s NetworkPolicy 已隔离 |
| 容量目标 | 10w+ 连接/单实例 | pending-features 权威;Go goroutine-per-connection 约 2-3GB/10w 连接 |
| 审计表归属 | msg 服务维护(push-gateway 无 DB) | 保持 push-gateway 无 DB 定位,避免引入持久化层 |
| Redis /readyz | 软失败(仅告警不阻塞,返 200 + degraded) | push-gateway 重启不解决 Redis 故障;Redis 故障时单实例仍能服务本地连接 |
| Kafka /readyz | 软失败(仅告警 + degraded) | ISSUE-055 裁决 |
| 心跳协议 | RFC 6455 控制帧(Ping/Pong,30s 间隔) | 02 文档 §10 |
17.4 ISSUE-006 Redis 软失败裁决详情
冲突:
- ISSUE-055(president §3.3):Redis 列为"必需依赖",失败返 503
- ISSUE-058(president §4.3):Redis /readyz "仅告警不阻塞,避免雪崩"
coord 裁决:以 ISSUE-058 为准(后裁决优先),Redis 对 push-gateway 为软失败。
理由:
- push-gateway 重启不解决 Redis 故障(Redis 是跨实例广播依赖,非本地状态)
- Redis 故障时单实例仍能服务本地连接(仅跨实例广播失效)
- 重启会丢失本地连接表,加剧雪崩风险
- ISSUE-055 的"必需依赖"列表应排除 push-gateway → Redis(Redis 故障不触发 Pod 重启)
修正:004 §7.2 / coord-cross-review 中 ISSUE-055 必需依赖列表,push-gateway → Redis 标注为"软失败(ISSUE-058 裁决覆盖)"。
17.5 ai02 执行项
- 修改源码鉴权头:
X-Internal-Key→X-Internal-Token;INTERNAL_API_KEY→INTERNAL_API_TOKEN(ISSUE-002) - 02 文档 §3.1 补 Hub 启动重建机制(SADD + EXPIRE 60s + 清空旧 instanceID 成员,ISSUE-058 回写)
- 02 文档 §6.7 /readyz Redis 检查改为软失败(返 200 + degraded,不返 503,ISSUE-006)
- 02 文档 §5.4 添加"设计决策记录:gRPC vs HTTP 协议选型"章节,标注"coord 已采纳 P1"(ISSUE-056 回写)
- 02 文档 §5.1 topic 已对齐
edu.notification.requested(ISSUE-053 回写确认) - 02 文档补 §14-§17 四章节(ADR/NFR/失败模式/容量估算,P5 批次 4 补全,ISSUE-007)
- 02 文档补
push_gateway_redis_set_rebuild_total指标 + 60s 不一致窗口文档说明(ISSUE-058 回写) - ISSUE-001/003/004/005 由 coord 修文档,ai02 确认
17.6 coord 执行项
- 修正 contract.md §1.2:移除
/sse端点(ISSUE-001) - 修正 matrix.md §5:移除 push-gateway SSE 行(ISSUE-001)
- 修正 modules/push-gateway/README.md §7:50k → 10w+(ISSUE-003)
- 修正 contract.md §1.2:鉴权头统一为
X-Internal-Token(ISSUE-002,contract v2 已部分对齐,确认最终) - 修正 004 §7.2 / coord-cross-review:ISSUE-055 必需依赖列表中 push-gateway → Redis 标注"软失败"
- ISSUE-005 协调 ai10 确认 msg 审计表覆盖 push-gateway 推送结果字段
§18 ARB-016:teacher-bff 模块 3 项 ISSUE 仲裁
18.1 背景
ai03 在 teacher-bff_issue.md 提请 3 项异议,涉及 admin 命名空间 P2 预留与 ARB-001 冲突、dashboard classes 数据来源与调用链冲突、GraphQL schema 文件命名不一致。coord 对照 teacher-bff_contract.md v2 逐条仲裁。
18.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 001 | admin 命名空间 P2 预留与 ARB-001 "P2 不包含" 冲突 | ✅ 以总裁裁决为准(president > coord),修正 ARB-001 §1.3 为 "P2 预留 admin schema 命名空间占位" | coord 修 ARB-001 |
| 002 | P2 dashboard classes 数据来源与调用链冲突 | ✅ 采纳 president §3.5:P2 classes 数据从 iam gRPC 获取(GetViewports/GetEffectiveAccess),不调 classes 服务 | coord 修 ARB-001 + ai03 修文档 |
| 003 | GraphQL schema 文件命名不一致 | ✅ 以总裁 §2.17 为准:统一为 teacher-bff.schema.graphql |
coord 修 ARB-001 + ai03 创建文件 |
18.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| admin 命名空间 P2 | P2 预留 schema 占位(声明 admin Query/Mutation 类型骨架,Resolver 返 null),P6 实现 |
president §5.1 + §7.3(裁决优先级 president > coord) |
| P2 classes 数据来源 | iam gRPC(GetViewports/GetEffectiveAccess 返回关联班级),不调 classes 服务 | president §3.5 + B2 裁决(classes P2 无 gRPC,禁止 REST 过渡) |
| P3+ classes 数据来源 | 切换为 core-edu.ClassService.GetClassesByTeacher RPC(core-edu gRPC 50053 就绪后) |
ARB-007 已补全 ClassService 4 RPC |
| schema 文件名 | teacher-bff.schema.graphql(统一 <bff-name>.schema.graphql 格式) |
president §2.17 |
| 裁决优先级 | president > coord(ARB-001 修正为对齐总裁裁决) | 总裁裁决覆盖 coord 仲裁 |
18.4 ISSUE-002 P2 dashboard 调用链修正
原 ARB-001 §1.4 第 4 条:
dashboard Resolver 并行调用 iam(3 RPC)+ classes(1 RPC),用 DataLoader 防御 N+1
修正为:
dashboard Resolver 并行调用 iam gRPC(GetUserInfo + GetViewports + GetEffectiveAccess),classes 列表从 iam 返回数据推导,P3 core-edu gRPC 就绪后切换为
GetClassesByTeacherRPC
理由:
- classes P2 无 gRPC server(classes.proto 注释 "P3 起转 gRPC")
- B2 裁决禁止 REST 过渡
- president §3.5 裁决 P2 班级列表数据来自 iam
18.5 ai03 执行项
- 创建
packages/shared-ts/contracts/graphql/teacher-bff.schema.graphql(文件名用.schema.graphql,ISSUE-003) - schema 中预留
admin命名空间占位(admin.*Query/Mutation 类型骨架,Resolver 返 null,ISSUE-001) - dashboard Resolver P2 实现:调 iam gRPC 获取 classes 数据(不调 classes 服务,ISSUE-002)
- P3+ 切换 dashboard classes 数据源为
core-edu.ClassService.GetClassesByTeacher
18.6 coord 执行项
- 修正 ARB-001 §1.3:admin 命名空间改为 "P2 预留 schema 占位"
- 修正 ARB-001 §1.3/§1.4:文件名改为
teacher-bff.schema.graphql - 修正 ARB-001 §1.4 第 4 条:dashboard classes 数据来源改为 iam gRPC(不调 classes 服务)
- 修正 ARB-001 §1.2 GraphQL schema 代码块:DataScope 枚举去掉 DISTRICT 改 SUBJECT(ARB-003 ISSUE-004 已裁决,需同步 ARB-001)
§19 ARB-017:student-bff 模块 4 项新 ISSUE 仲裁
19.1 背景
ai04 在 student-bff_issue.md §1 提请 4 项新异议(STU-001~004),涉及 01 文档与 B1/B2/B5 裁决冲突、02 引用不存在的 004 章节、02 §8.3 八项已裁决决策未更新、GraphQL schema 第一版未起草。coord 对照 student-bff_contract.md v2 逐条仲裁。
19.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| STU-001 | 01 文档与 B1/B2/B5 裁决冲突 | ✅ 与 ISSUE-028 合并处理:01 文档随 02 文档一并回写(删除 REST 端点清单、改 GraphQL、错误码改 BFF_STUDENT_) | ai04 |
| STU-002 | 02 引用不存在的 004 §11.4/§11.5 | ✅ coord 补全 004 §11.4(错误码前缀矩阵)+ §11.5(ActionState 信封规范)章节 | coord |
| STU-003 | 02 §8.3 八项已裁决决策未更新 | ✅ 02 文档回写时删除已裁决项的"待仲裁"标注,改为"已裁决(见 coord-final-decisions §2 BX)" | ai04 |
| STU-004 | GraphQL schema 第一版未起草 | ✅ ai04 在批次 1 等待期产出 schema 草案,存放 packages/shared-ts/contracts/graphql/student-bff.schema.graphql |
ai04 |
19.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| 01 文档回写范围 | 01 + 02 一并回写(01 不作为历史快照保留,必须对齐裁决) | ISSUE-028 + STU-001 合并 |
| 004 §11.4/§11.5 补全 | coord 补全错误码前缀矩阵 + ActionState 信封规范章节 | 004 作为架构设计意图唯一源,不应有断裂引用 |
| schema 仲裁时机 | ai04 批次 1 等待期起草 → coord 批次 2 启动前仲裁第一版 | president §2.2 |
| schema 文件名 | student-bff.schema.graphql(统一格式,对齐 teacher-bff) |
president §2.17 |
| 02 §8.3 已裁决项 | B1/B2/B3/B4/B5/B6/B7/B8 全部已裁决,删除"待仲裁"标注 | coord-final-decisions §2 |
19.4 ISSUE-028 回写范围确认
ai04 须在批次 2 启动前完成 02 文档回写(president §3.4 裁决),回写范围:
- §4 API 设计:21 个 REST 端点 → GraphQL Query/Mutation 清单
- §9.2 演进路线:删除"REST→GraphQL 演进"(违反"不分阶段"原则)
- §9.3 通信协议演进:删除"HTTP→gRPC 演进"(违反 B2)
- §3.1 下游通信:"HTTP fetch(当前阶段)" → "gRPC 调用下游(@grpc/grpc-js + @bufbuild/protobuf)"
- §3.3/§6 错误码:
STUDENT_BFF_→BFF_STUDENT_ - §8.3 未决决策:8 项已裁决项标注"已裁决",仅保留 #7/#10/#11/#12 合理设计决策
- 01 文档:同步回写(删除 REST 假设、对齐错误码前缀、删除已裁决项重复提请)
19.5 ai04 执行项
- 批次 1 等待期产出
student-bff.schema.graphql草案(ISSUE-STU-004) - 批次 2 启动前回写 01 + 02 文档(ISSUE-028 + STU-001/003,范围见 §19.4)
- 02 文档引用源修正:004 §11.4/§11.5 → coord 补全后引用(或暂引 coord-final-decisions G14/G8)
- 实现 DownstreamClient 回写 teacher-bff(B8 裁决)
19.6 coord 执行项
- 补全 004 §11.4(错误码前缀矩阵:GW_/IAM_/CORE_EDU_/BFF_TEACHER_/BFF_STUDENT_/BFF_PARENT_/MSG_/PUSH_/DATA_ANA_/AI_)+ §11.5(ActionState 信封规范:
{success, data, error:{code,message,details,traceId}}+ degraded 放 error.details) - 批次 2 启动前仲裁 student-bff schema 第一版(president §2.2)
§20 ARB-018:parent-bff 模块 10 项 ISSUE 仲裁
20.1 背景
ai05 在 parent-bff_issue.md 提请 10 项异议,涉及 01 文档未同步、ChildGuard TTL 不一致、契约引用错误、004 依赖图未同步、parent-portal REST vs GraphQL 跨模块冲突、proto 包名缺失、Notification.childId 缺失、ClassService 缺失、责任方过时、02 缺 ADR/NFR。coord 对照 parent-bff_contract.md 逐条仲裁。
20.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 001 | 01 文档未同步 ai05 接手 + U3/U4/C1 仲裁 | ✅ 01 作为阶段 1 历史快照保留原样,以 02 为准(02 已执行 U3/U4/C1) | ai05 标注 01 为历史快照 |
| 002 | 02 文档 ChildGuard TTL 三处不一致(60s/30s) | ✅ 统一为 30s(§3.1.1 表格改为 30s,对齐 §9 #2 + §13 #7) | ai05 修文档勘误 |
| 003 | contract.md 引用 I3 → 应为 I6 | ✅ 修正为 I6 裁决(coord-final-decisions §1 I6:家长-学生关联) | ai05 修 contract 引用 |
| 004 | 004 §4 + matrix.md §1 未同步 C6 仲裁(缺 DataAna + Msg) | ✅ coord 补全 004 §4 服务依赖图 + matrix.md §1 依赖矩阵(加 PBFF → DataAna + PBFF → Msg) | coord |
| 005 | parent-portal 01 文档按 REST 消费 parent-bff(跨模块冲突) | ✅ coord 协调 ai15 将 parent-portal 01/02 改为 GraphQL 消费(POST /api/v1/parent/v1/graphql) |
coord 协调 ai15 |
| 006 | proto 包名引用缺 next_edu_cloud 前缀 | ✅ 统一补 next_edu_cloud. 前缀(ARB-011 已裁决,ai05 修 02 §3.3 DTO 映射表) |
ai05 |
| 007 | GraphQL Notification.childId 在 msg.proto 缺失 | ✅ coord 协调 ai10 在 msg.proto Notification message 补 string child_id = 9;(可选,非家长通知为空) |
coord 协调 ai10 |
| 008 | core_edu.proto 缺 ClassService | ✅ coord 已在 ARB-007 补全 ClassService 4 RPC(GetClass/GetClassesByTeacher/BatchGetClasses/ListStudentsByClass);02 §7.1 状态改 "✅ 已有";Grade.score string→Float 转换规则补 §3.3 | ai05 修 02 §7.1 + §3.3 |
| 009 | ai-allocation iam 责任方 ai02 → ai06 | ✅ 修正为 ai06(iam 现归属 ai06,ai-allocation §3.2 确认) | ai05 修 01/02 引用 |
| 010 | 02 缺 ADR/NFR/容量规划/威胁建模 | ✅ P6 硬化阶段补全(当前不阻塞 P4 实施) | ai05 P6 补全 |
20.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| 01 文档定位 | 历史快照保留原样,02 为权威源 | 避免回写成本;01 标注"阶段 1 历史快照,以 02 为准" |
| ChildGuard TTL | 30s + 主动失效(统一三处) | §9 #2 + §13 #7 已调整,§3.1.1 表格勘误 |
| 契约引用 | I6(非 I3),ISSUE-047 编号虚构,删除 | coord-final-decisions §1 I6 |
| C6 依赖图同步 | coord 补 004 §4 + matrix.md §1:PBFF → IAM + CoreEdu + DataAna + Msg | C6 仲裁 |
| parent-portal 消费方式 | GraphQL(POST /api/v1/parent/v1/graphql),非 REST |
U3 仲裁 + parent-bff 02 §4.1 不实现 REST |
| proto 包名 | next_edu_cloud.<domain>.v1(全引用补前缀) |
ARB-011 已裁决 |
| msg.proto Notification.child_id | 补 string child_id = 9;(可选字段) |
ISSUE-007 家长场景需按孩子过滤通知 |
| ClassService 归属 | core-edu(ARB-007 已补全 4 RPC) | coord 批次 0 补全 |
| Grade.score 类型转换 | BFF response-mapper 做 Number.parseFloat(score),失败抛 BFF_PARENT_BAD_GATEWAY |
ai05 建议 |
| iam 责任方 | ai06(非 ai02) | ai-allocation §3.2 |
20.4 ISSUE-005 跨模块契约冲突处理
冲突:parent-portal(ai15)01 文档 §3.1 按 REST 消费 parent-bff,但 parent-bff 02 §4.1 明确"不实现 REST 业务端点"。
coord 仲裁:按 project_rules §14.4 跨模块变更顺序处理:
- parent-bff 契约已定义(GraphQL
POST /api/v1/parent/v1/graphql) - coord 协调 ai15 将 parent-portal 01/02 文档的 parent-bff 消费契约从 REST 改为 GraphQL
- 同步 C4 仲裁:iam 路径
/iam/permissions/effective(非/iam/effective-permissions) - parent-portal §3.1 标注 "BFF 对接:parent-bff(ai05 设计)"
20.5 ISSUE-007 msg.proto Notification 字段补全
coord 协调 ai10 在 msg.proto Notification message 补字段:
message Notification {
string id = 1;
string user_id = 2;
string type = 3;
string title = 4;
string content = 5;
string channel = 6;
bool is_read = 7;
int64 created_at = 8;
string child_id = 9; // 新增:关联孩子 ID(可选,非家长通知为空)
}
parent-bff GraphQL
Notification.childId映射自此字段。ai10 在 msg 02 文档同步补字段说明。
20.6 ISSUE-008 ClassService + Grade.score 处理
ClassService:coord 已在 ARB-007 补全 core_edu.proto ClassService 4 RPC(GetClass/GetClassesByTeacher/BatchGetClasses/ListStudentsByClass)。parent-bff 02 §7.1 状态从 "❌ 待补" 改为 "✅ 已有"。
Grade.score 类型转换:parent-bff 02 §3.3 DTO 映射表补转换规则说明:
core_edu.v1.Grade.score(string)→ GraphQLGrade.score(Float!)- BFF response-mapper 执行
Number.parseFloat(score) - 转换失败(NaN)抛
BFF_PARENT_BAD_GATEWAY+ i18n keyerror.bffParent.bad_gateway
20.7 ai05 执行项
- 02 §3.1.1 ChildGuard TTL 改为 30s(ISSUE-002 勘误)
- 02 §3.3 DTO 映射表补
next_edu_cloud.前缀(ISSUE-006) - 02 §3.3 补 Grade.score string→Float 转换规则(ISSUE-008)
- 02 §7.1 ClassService.GetClass 状态改 "✅ 已有"(ISSUE-008,ARB-007 已补全)
- contract.md §2.1 引用 I3 → I6 修正(ISSUE-003)
- 01 §7.1/§7.3 + 02 §7.3 #1 责任方 ai02 → ai06(ISSUE-009)
- 01 文档头部标注"阶段 1 历史快照,以 02 为准"(ISSUE-001)
- P6 硬化阶段补 02 ADR/NFR/容量规划/威胁建模(ISSUE-010,非阻塞)
20.8 coord 执行项
- 补全 004 §4 服务依赖图:加
PBFF --> DataAna+PBFF --> Msg(ISSUE-004,C6 仲裁同步) - 补全 matrix.md §1 服务依赖矩阵:加
PBFF --> DataAna+PBFF --> Msg(ISSUE-004) - 协调 ai10 在 msg.proto Notification 补
child_id = 9字段(ISSUE-007) - 协调 ai15 将 parent-portal 01/02 改为 GraphQL 消费 parent-bff(ISSUE-005,跨模块变更)
- 确认 ClassService 已在 ARB-007 补全(ISSUE-008 已覆盖)
§21 ARB-019:student-portal 模块 7 项 ISSUE 仲裁
21.1 背景
ai14 在 student-portal_issue.md 提请 7 项异议,涉及 GraphQL endpoint 路径、schema 文件存放位置、考试防作弊策略、主观题粘贴策略、附件上传协议、实时事件命名、DataScope L0 强制执行层。coord 对照 student-portal_contract.md v2 + student-bff_contract.md v2 + ARB-001/ARB-002/ARB-014 逐条仲裁。
21.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 014-01 | GraphQL endpoint 路径不一致 | ✅ 统一为 POST /api/v1/student/graphql(对齐 matrix.md §5 + ARB-014 方案 A 双 /v1 前缀) |
ai14 修 contract.md §2.3 路径 + ai01 确认路由 |
| 014-02 | student-bff GraphQL schema 存放位置不一致 | ✅ 统一为 packages/shared-ts/contracts/graphql/student-bff.schema.graphql(对齐 president §2.17 + ARB-016/017) |
ai04 创建并维护 |
| 014-03 | 考试作答页全屏策略与防作弊检测边界 | ✅ P3 不强制全屏 + visibilitychange 仅记录 + 多标签警告不阻止 + 走 student-bff GraphQL mutation recordExamViolation |
ai14 + ai04 |
| 014-04 | 主观题粘贴策略(防作弊 vs 学生体验) | ✅ 客观题禁止 + 主观题允许记录 + 作文题允许不记录;复用 recordExamViolation(type=PASTE) | ai14 + ai04 |
| 014-05 | 作业附件上传协议 | ✅ 方案 A:api-gateway REST POST /api/v1/student/upload → 对象存储 → GraphQL mutation 提交 URL |
ai01 路由 + ai04 mutation 接受 attachmentUrls |
| 014-06 | 考试延长/题目重排等实时事件命名 | ✅ ai08 发布 ExamExtended + ExamForceSubmitted;题目重排 P3 不实现 P4 评估 | ai08 发布 + ai10 推送 |
| 014-07 | 学生端 DataScope L0 边界强制执行层 | ✅ 方案 A:student-bff Resolver 从 JWT x-user-id 提取 studentId,前端 query 不传 studentId | ai14 修 query 设计 + ai04 实现 |
21.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| GraphQL endpoint | POST /api/v1/student/graphql(双 /v1 前缀,对齐 ARB-014 方案 A) |
matrix.md §5 + ARB-014 §16.4 |
| schema 文件路径 | packages/shared-ts/contracts/graphql/student-bff.schema.graphql |
president §2.17 + ARB-017 §19.3 |
| 全屏策略 | P3 推荐不强制(提示"建议全屏作答");P4 基于教师反馈评估升级 | 防止误伤合法场景 |
| 离开页面策略 | visibilitychange hidden 仅记录,累计 3 次警告教师端可见;不自动提交 | 误触发风险高 |
| 多标签检测 | BroadcastChannel 警告 + 记录,不阻止作答 | 合法场景如查词典 |
| 防作弊事件上报 | student-bff GraphQL mutation recordExamViolation(examId, type, payload) |
GraphQL 统一入口;不走 push-gateway |
| 粘贴策略分层 | 客观题禁止 / 主观题允许记录 / 作文题允许不记录 | 防作弊与学生体验平衡 |
| 附件上传协议 | api-gateway REST + 对象存储 + GraphQL mutation 提交 URL | GraphQL 不适合大文件;REST + 对象存储业界通用 |
| 实时事件命名 | ExamExtended + ExamForceSubmitted(ai08 发布到 edu.exam.events topic) |
事件命名规范 <Aggregate>.<Action> |
| 题目重排 | P3 不实现(题目顺序固定),P4 评估实时重排需求 | 降低 P3 复杂度 |
| DataScope L0 | student-bff Resolver 层从 JWT 强制过滤(方案 A),前端不传 studentId | 前端无法绕过;gRPC 层重新校验 |
21.4 ISSUE-014-03 防作弊策略详情
全屏 API:P3 不强制(提示"建议全屏作答"),P4 评估是否升级为强制(基于教师反馈)
visibilitychange 策略:
- hidden 触发时仅记录(不自动提交)
- 累计 3 次警告后教师端可见(走
recordExamViolationmutation 上报) - 避免误伤合法场景(如切到词典查询)
多标签检测:
- BroadcastChannel 检测到多标签时警告 + 记录
- 不阻止作答(避免误伤)
事件上报链路:
student-portal → POST /api/v1/student/graphql (recordExamViolation mutation)
→ student-bff Resolver
→ core-edu gRPC ExamService.RecordViolation(ai08 在 P3 补全 RPC)
→ 落库 + 教师端可见
21.5 ISSUE-014-05 附件上传协议详情
方案 A(采纳):
- 前端:
POST /api/v1/student/upload(multipart/form-data)→ api-gateway 鉴权 → 对象存储(MinIO/OSS)→ 返回 signed URL - 前端:GraphQL mutation
submitHomework(input: { homeworkId, answers, attachmentUrls: [String!] })提交作业 + 附件 URL - student-bff Resolver 接收 attachmentUrls 字段,透传给 core-edu
路由配置:
- api-gateway:
/api/v1/student/upload→student-bff:3009/upload(或直接到对象存储代理) - 由 ai01(api-gateway)确认路由配置 + 大小限制(建议 20MB)+ 类型白名单(图片/PDF/文档)
21.6 ISSUE-014-06 实时事件命名详情
| 事件 | 发布方 | topic | 消费链路 | 阶段 |
|---|---|---|---|---|
| ExamExtended | ai08(core-edu) | edu.exam.events |
msg 消费 → push-gateway → student-portal 更新倒计时 | P3 |
| ExamForceSubmitted | ai08(core-edu) | edu.exam.events |
msg 消费 → push-gateway → student-portal 触发提交 | P3 |
| ExamQuestionReordered | ai08(core-edu) | edu.exam.events |
P3 不实现,P4 评估 | P4 |
21.7 ISSUE-014-07 DataScope L0 强制执行详情
方案 A(采纳):student-bff Resolver 层从 JWT 提取 studentId,强制过滤
ai14 修改 02-architecture-design.md §4.2:
- 移除所有 query 的
studentId参数(如myClasses(studentId: ID!)→myClasses) - 所有 query 改为无参或仅含分页/筛选参数
- 前端不传 studentId(无法绕过 L0 边界)
ai04 实现:
- 所有 student-bff Query Resolver 从 JWT
x-user-id提取 studentId - 强制过滤(
WHERE student_id = :jwtStudentId) - 不接受前端传入的 studentId 参数(GraphQL schema 层不暴露)
21.8 ai14 执行项
- 修 contract.md §2.3:统一路径为
POST /api/v1/student/graphql(ISSUE-014-01) - 02 §4.2 GraphQL query 定义:移除所有
studentId参数(ISSUE-014-07) - 02 §14 防作弊策略:补全屏策略 + visibilitychange + 多标签 + 事件上报链路(ISSUE-014-03)
- 02 §14 粘贴策略:补客观题/主观题/作文题分层(ISSUE-014-04)
- 02 §16 实时事件:补 ExamExtended + ExamForceSubmitted 命名(ISSUE-014-06)
- 02 §4.2 mutation 域:确认 recordExamViolation + recordPasteEvent 参数(依赖 ai04 补全)
21.9 ai04 执行项
- 创建
packages/shared-ts/contracts/graphql/student-bff.schema.graphql(ISSUE-014-02) - 所有 Query Resolver 从 JWT 提取 studentId,不接受前端参数(ISSUE-014-07)
- P3 提供
recordExamViolation(input: RecordExamViolationInput!): RecordExamViolationPayload!mutation(ISSUE-014-03) - P3 提供
recordPasteEventmutation 或复用 recordExamViolation(type=PASTE)(ISSUE-014-04) - submitHomework mutation 接受
attachmentUrls: [String!]字段(ISSUE-014-05)
21.10 ai01 执行项
- 确认路由
/api/v1/student/*→student-bff:3009/*(ISSUE-014-01) - 确认
/api/v1/student/upload路由配置(大小限制 + 类型白名单)(ISSUE-014-05)
21.11 ai08 执行项
- P3 发布 ExamExtended 事件到
edu.exam.eventstopic(ISSUE-014-06) - P3 发布 ExamForceSubmitted 事件到
edu.exam.eventstopic(ISSUE-014-06) - P3 补全 ExamService.RecordViolation RPC(防作弊违规落库)(ISSUE-014-03)
21.12 coord 执行项
- 确认 matrix.md §5 路径前缀对齐
/api/v1/student/*(ISSUE-014-01) - 协调 ai08 补全 ExamService.RecordViolation RPC(ISSUE-014-03)
§22 ARB-020:parent-portal 模块 10 项 ISSUE 仲裁
22.1 背景
ai15 在 parent-portal_issue.md 提请 10 项异议,涉及 01/02 文档 REST 消费与 ARB-001 冲突、MF shared 配置缺 urql、switch-child 端点不一致、登录端点三方不一致、未决决策过时、contract §1.2 误标 HTTP 端点、MF 配置文件位置不一致、GraphQL 路径缺 v1、switchChild Mutation 未明确、iam GetChildrenByParent 缺失。coord 对照 parent-portal_contract.md + parent-bff_contract.md + ARB-001/ARB-002/ARB-018 逐条仲裁。
22.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 001 | 01/02 文档 REST 消费 parent-bff 与 ARB-001 冲突 | ✅ 统一 GraphQL 消费(对齐 ARB-018 ISSUE-005 跨模块裁决) | ai15 修 01/02 |
| 002 | MF shared 配置缺 urql/graphql/@edu/* | ✅ 补全 7 项 singleton(react/react-dom/urql/graphql/@edu/ui-tokens/@edu/ui-components/@edu/hooks) | ai15 修 02 §1.2 |
| 003 | switch-child 端点在 01/02 不一致 | ✅ GraphQL Mutation switchChild(childId: ID!): SwitchChildPayload!(走 GraphQL,对齐 ISSUE-001) |
ai15 修 01/02 + ai05 补 schema |
| 004 | 登录端点三方不一致 | ✅ 统一为 POST /api/v1/iam/login(对齐 matrix.md §5);登录走 REST,其余走 GraphQL |
ai15 修 contract §2.3 |
| 005 | 02 §11.3 未决决策 #2 已由 ARB-001 裁决 | ✅ 移除未决项,改为"已裁决:见 ARB-001" | ai15 修 02 §11.3 |
| 006 | contract §1.2 误标前端路由为 HTTP 端点 | ✅ §1.2 改为"无(parent-portal 是前端 Remote,不对外提供 HTTP API)" | ai15 修 contract §1.2 |
| 007 | contract §1.6 MF 配置文件位置不一致 | ✅ 统一为 apps/parent-portal/next.config.js(对齐 02 + teacher-portal Shell) |
ai15 修 contract §1.6 |
| 008 | contract §2.3 GraphQL 路径缺 v1 | ✅ 统一为 POST /api/v1/parent/graphql(对齐 matrix.md §5) |
ai15 修 contract §2.3 + §2.4 |
| 009 | parent-bff GraphQL schema 是否含 switchChild | ✅ parent-bff 提供 switchChild Mutation(后端记录选中子女用于审计),同时前端 Zustand + localStorage 缓存 |
ai05 补 schema + ai15 前端实现 |
| 010 | iam GetChildrenByParent 缺失(P0 阻塞) | ✅ ai06 P3 收尾前补全(I6 裁决);补全前用 mock(固定 2 个孩子 student-001 + student-002) | ai06 补全 + ai15 mock |
22.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| parent-portal 消费方式 | GraphQL(POST /api/v1/parent/graphql),非 REST |
ARB-001 + ARB-018 ISSUE-005 |
| MF shared | 7 项 singleton 全补齐(含 urql/graphql/@edu/*) | ARB-002 §2.2 |
| switchChild 归属 | parent-bff GraphQL Mutation(后端审计)+ 前端 Zustand 缓存 | 双层记录,避免状态不一致 |
| 登录端点 | POST /api/v1/iam/login(REST),登录前无 JWT 不能走 GraphQL |
matrix.md §5 + ARB-014 方案 A |
| 前端路由分类 | 前端页面路由不进 contract §1.2 HTTP 端点表 | parent-portal 是前端 Remote |
| MF 配置文件 | apps/parent-portal/next.config.js(NextFederationPlugin) |
对齐 teacher-portal Shell |
| GraphQL 路径 | POST /api/v1/parent/graphql(双 /v1 前缀,对齐 ARB-014) |
ARB-014 + matrix.md §5 |
| iam GetChildrenByParent | ai06 P3 收尾前补全(I6 裁决,P0 阻塞) | coord-final-decisions §1 I6 |
| mock 数据一致性 | parent-portal mock 与 parent-bff mock 一致(student-001 + student-002) | ChildGuard 越权校验依赖 |
22.4 ISSUE-003 switchChild 端点裁决详情
裁决:switchChild 走 GraphQL Mutation(对齐 ISSUE-001 GraphQL 消费方式)
GraphQL schema(ai05 补 parent-bff schema):
type SwitchChildPayload {
childId: ID!
childName: String!
selectedAt: DateTime!
}
type Mutation {
switchChild(childId: ID!): SwitchChildPayload!
}
后端职责(parent-bff):
- 记录选中子女用于审计(写 Redis
parent:selected:{parentId}TTL 30s) - ChildGuard 校验基于 iam.GetChildrenByParent 返回列表
前端职责(parent-portal):
- Zustand store 缓存当前选中子女(
selectedChildId) - localStorage 持久化(避免刷新丢失)
- 切换子女时同时调 mutation(后端审计)+ 更新 Zustand
22.5 ISSUE-009 switchChild Mutation 归属裁决
裁决:parent-bff 提供 switchChild Mutation(后端记录审计),同时前端 Zustand + localStorage 缓存
理由:
- 纯前端方案无法记录审计日志(谁在何时切换了哪个子女)
- 后端记录用于异常行为检测(频繁切换可能暗示越权尝试)
- 前端缓存提升用户体验(刷新不丢失选中状态)
- 双层记录:后端审计 + 前端缓存,Redis TTL 30s 与 ChildGuard 对齐
22.6 ISSUE-010 iam GetChildrenByParent P0 阻塞处理
裁决:ai06 在 P3 收尾前补全(I6 裁决),补全前用 mock
mock 数据要求:
- 返回固定 2 个孩子:
student-001(李同学)+student-002(李妹妹) - 与 parent-bff mock 数据一致(ChildGuard 校验依赖)
- parent-portal 启动时校验 myChildren 返回的 user_id 与下游查询的 student_id 一致性
补全时间点:
- ai06 P3 收尾前(parent-portal P4 启动前)
- coord 在 workline.md §4 跟踪 ai06 进度
22.7 ai15 执行项
- 01 §3.1 + 02 §4.1:REST → GraphQL 消费(ISSUE-001)
- 02 §1.2 MF shared:补齐 7 项 singleton(ISSUE-002)
- 01 §3.1 + 02 §2.2/§4.1:switch-child → GraphQL Mutation
switchChild(ISSUE-003) - contract.md §2.3:登录端点改为
POST /api/v1/iam/login(ISSUE-004) - 02 §11.3 #2:移除未决项,标注"已裁决:见 ARB-001"(ISSUE-005)
- contract.md §1.2:改为"无(前端 Remote,不对外提供 HTTP API)"(ISSUE-006)
- contract.md §1.6:MF 配置文件改为
apps/parent-portal/next.config.js(ISSUE-007) - contract.md §2.3 + §2.4:GraphQL 路径改为
POST /api/v1/parent/graphql(ISSUE-008) - 前端实现
useChildSwitcherhook:调 mutation + Zustand + localStorage(ISSUE-009) - mock 数据与 parent-bff 一致(student-001 + student-002)(ISSUE-010)
22.8 ai05 执行项
- parent-bff GraphQL schema 补
switchChild(childId: ID!): SwitchChildPayload!Mutation(ISSUE-003/009) - switchChild Resolver:写 Redis
parent:selected:{parentId}TTL 30s + 审计记录
22.9 ai06 执行项
- P3 收尾前补全 iam GetChildrenByParent RPC + iam_student_guardians 表(ISSUE-010,I6 裁决)
22.10 coord 执行项
- 协调 ai05 补 switchChild Mutation schema(ISSUE-003/009)
- 跟踪 ai06 GetChildrenByParent 补全进度(ISSUE-010,P0 阻塞)
- 确认 matrix.md §5 路径前缀对齐
/api/v1/parent/*(ISSUE-008)
§23 ARB-021:admin-portal 模块 7 项 ISSUE 仲裁
23.1 背景
ai16 在 admin-portal_issue.md 提请 7 项异议,涉及 01/02 文档归属错误(ai07→ai16)、端口错误(3003→4003)、通信协议与 ARB-001/002 不一致、遗漏审计日志与学校设置、teacher-bff 缺 admin 命名空间 schema、推送策略与同类 portal 不一致、matrix.md §4 将 admin-portal 列为 Kafka 直消费方。coord 对照 admin-portal_contract.md + ARB-001/ARB-002 逐条仲裁。
23.2 仲裁结论
| ISSUE | 标题 | 仲裁结论 | 执行方 |
|---|---|---|---|
| 001 | 01/02 模块文档归属错误(ai07 → ai16) | ✅ 修正为 ai16;ai07 产出视为历史草稿 | ai16 修 01/02 头部 |
| 002 | 01/02 端口错误(3003 → 4003) | ✅ 确认 admin-portal 端口 4003;同步更新 full-stack-runbook §2.1 补齐 4 个 portal 4000 段 | ai16 修 01/02 + coord 修 runbook |
| 003 | 01/02 通信协议与 ARB-001/002 不一致(REST → GraphQL) | ✅ 统一 GraphQL(POST /api/admin/graphql → teacher-bff admin 命名空间);删除 useApi/ApiClient |
ai16 修 01/02 全文 |
| 004 | 01/02 遗漏审计日志与学校设置 | ✅ 视口补齐为 11 个:dashboard/users/roles/permissions/viewports/organization/classes/teachers/students/audit-logs/system | ai16 修 01/02 |
| 005 | teacher-bff 缺 admin 命名空间 GraphQL schema | ✅ ai03 在 P6 启动前补齐 teacher-bff admin 命名空间 schema(参照 contract §2.4) | ai03 补 schema |
| 006 | 01/02 推送策略与同类 portal 不一致(轮询 → WebSocket) | ✅ admin-portal 接入 push-gateway WebSocket(审计告警/异常登录/系统异常);保留轮询仅用于监控指标 | ai16 修 01/02 |
| 007 | matrix.md §4 将 admin-portal 列为 Kafka 直消费方 | ✅ 修正为 teacher-bff(admin-portal 经 teacher-bff 间接消费,链路:iam → Kafka → teacher-bff → GraphQL → admin-portal) | coord 修 matrix.md §4 |
23.3 关键裁决
| 裁决点 | 结论 | 依据 |
|---|---|---|
| 模块归属 | ai16(非 ai07);ai07 产出视为历史草稿 | ai-allocation §5 |
| 端口 | 4003(非 3003,3003 与 teacher-bff 冲突) | matrix.md §1 + ai-allocation §5 |
| 通信协议 | GraphQL(POST /api/admin/graphql),非 REST |
ARB-001 + ARB-002 |
| GraphQL 端点路径 | POST /api/admin/graphql(对齐 contract §2.3,非双 /v1 前缀) |
admin 走 teacher-bff,非独立 BFF |
| 视口数量 | 11 个(补齐审计日志 + 学校设置) | ai-allocation §5 + contract §1.2 |
| admin 命名空间 schema | ai03 在 P6 启动前补齐 teacher-bff admin schema | ARB-001 §1.3 P6 新增 admin 命名空间 |
| 推送策略 | WebSocket(审计告警/异常登录/系统异常)+ 轮询(监控指标 60s / 统计 5min) | 同类 portal 一致 + 低频数据轮询合理 |
| Kafka 消费链路 | iam → Kafka → teacher-bff 消费 → GraphQL auditLogs Query → admin-portal | 前端不直连 Kafka,经 BFF 聚合 |
23.4 ISSUE-005 teacher-bff admin 命名空间 schema 补全
裁决:ai03 在 P6 启动前补齐 teacher-bff admin 命名空间 GraphQL schema
补全范围(参照 admin-portal contract §2.4):
# teacher-bff.graphql admin 命名空间部分(ai03 在 P6 补齐)
type Query {
# 用户管理
adminUsers(filter: AdminUserFilter, page: PageInput): AdminUserConnection!
adminUser(id: ID!): AdminUser
# 角色权限
adminRoles: [AdminRole!]!
adminPermissions: [AdminPermissionGroup!]!
# 视口配置
adminViewports(scope: ViewportScope): [ViewportItem!]!
# 组织管理
adminOrganization(parentId: ID): [OrganizationNode!]!
# 全局管理
adminClasses(filter: ClassFilter): [Class!]!
adminTeachers(filter: TeacherFilter): [Teacher!]!
adminStudents(filter: StudentFilter): [Student!]!
# 审计日志
auditLogs(filter: AuditLogFilter, page: PageInput): AuditLogConnection!
# 仪表盘
adminDashboard: AdminDashboard!
}
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: UpdateUserInput!): User!
deleteUser(id: ID!): Boolean!
toggleUserStatus(id: ID!): User!
createRole(input: CreateRoleInput!): AdminRole!
updateRolePermissions(id: ID!, permissions: [String!]!): AdminRole!
updateViewport(key: String!, input: UpdateViewportInput!): ViewportItem!
}
存放位置:packages/shared-ts/contracts/graphql/teacher-bff.graphql(admin 命名空间部分,对齐 ARB-001 §1.3 集中管理)
就绪信号:
- ai03 P6 启动前完成
- 作为 admin-portal P6 的前置就绪信号
- 更新 matrix.md §3 teacher-bff 行的 schema 文件状态
23.5 ISSUE-006 推送策略裁决详情
裁决:admin-portal 接入 push-gateway WebSocket + 保留轮询低频数据
WebSocket 消费场景:
- 审计告警(异常权限变更、敏感操作)
- 异常登录(非工作时间登录、异地登录)
- 系统异常(服务健康检查异常、资源告警)
轮询保留场景:
- 监控指标(60s 间隔,Prometheus 数据)
- 统计数据(5min 间隔,全校统计)
实现:
ws://push-gateway:8081/ws(与同类 portal 一致)- JWT 鉴权
- 事件类型:审计告警 / 异常登录 / 系统异常
23.6 ISSUE-007 Kafka 消费链路修正
裁决:matrix.md §4 该行消费方更正为 teacher-bff(admin-portal 经 teacher-bff 间接消费)
实际链路:
iam → Kafka edu.iam.audit.created → teacher-bff 消费
↓
GraphQL auditLogs Query
↓
admin-portal 消费
修正范围:
- matrix.md §4 第 111 行:
admin-portal→teacher-bff - 避免误导架构分层(前端不直连 Kafka)
23.7 GraphQL 端点路径说明
admin-portal 路径:POST /api/admin/graphql(非双 /v1 前缀)
与 ARB-014 方案 A 的关系:
- ARB-014 方案 A 适用于独立服务(iam/core-edu 等):
/api/v1/<service>/v1/* - admin-portal 走 teacher-bff admin 命名空间:
POST /api/admin/graphql(teacher-bff 已有/api/v1/teacher/*前缀,admin 命名空间作为 teacher-bff 子路径) - 由 ai01 确认 api-gateway 路由:
/api/admin/*→teacher-bff:3003/admin/*
23.8 ai16 执行项
- 01/02 头部:ai07 → ai16;分支名更正(ISSUE-001)
- 01 §1 + 02 §12.1:端口 3003 → 4003(ISSUE-002)
- 01 §3.1 + 02 §1/§4:REST → GraphQL(useApi → useGraphQLClient)(ISSUE-003)
- 01 §2.1/§L1 导航/§L2 路由表:补齐 11 个视口(含 audit-logs + system)(ISSUE-004)
- 01 §3.3 + 02 §5:推送策略改为 WebSocket + 轮询低频数据(ISSUE-006)
- 02 §11.3:移除已裁决的"GraphQL vs REST"未决项(ISSUE-003)
23.9 ai03 执行项
- P6 启动前补齐 teacher-bff admin 命名空间 schema(参照 §23.4 清单)(ISSUE-005)
- schema 存放
packages/shared-ts/contracts/graphql/teacher-bff.graphqladmin 部分
23.10 coord 执行项
- 修正 matrix.md §4 第 111 行:
admin-portal→teacher-bff(ISSUE-007)—— ✅ 已执行(基础设施批次) - 同步 full-stack-runbook §2.1:补齐 4 个 portal 4000 段端口(ISSUE-002)—— ⏳ 文件不存在,SRE AI 创建时同步
- 确认 ai03 admin 命名空间 schema 作为 admin-portal P6 前置就绪信号(ISSUE-005)—— ✅ 已确认
- 协调 ai01 确认
/api/admin/*→teacher-bff:3003/admin/*路由配置 —— 见 §24.4 ARB-022 ISSUE-003 裁决
§24 ARB-022:api-gateway 模块 8 项 ISSUE 仲裁
24.1 背景
ai01 在 api-gateway_issue.md §1 正式提请 8 项 ISSUE(ISSUE-001~005/007/008/009,ISSUE-006 预留),涉及 matrix.md 契约修正、shared-go 接入、API 版本化路由方案、日志选型、Go 版本不一致、文档过时、错误码 GW_ 前缀 + ActionState 信封。
ARB-014 曾基于 v1 早期 issue.md(仅 2 行)从 contract.md v2 内联 4 项 ISSUE 做过初步仲裁;本次基于 ai01 正式提请的 v2 issue.md 重新仲裁,ARB-014 中与此冲突的部分以本节为准。
24.2 仲裁结论总览
| ISSUE | 主题 | 仲裁结论 | 影响范围 | 严重度 |
|---|---|---|---|---|
| ISSUE-001 | matrix.md gRPC 矩阵修正 | ✅ 确认(已执行) | 无(matrix 已修) | 低 |
| ISSUE-002 | shared-go 接入方式 | go.work 已含;ai01 go.mod 补 github.com/edu-cloud/shared-go 依赖 |
ai01 P2.1 | 中 |
| ISSUE-003 | API 版本化路由方案(/v1 前缀位置) | 采纳方案 A(双 /v1 前缀) | 全模块 | 高 |
| ISSUE-004 | zap vs slog 选型 | shared-go/logger 用 zap(现状保留) | ai01 + 所有 Go 服务 | 中 |
| ISSUE-005 | go.mod 与 Dockerfile 版本不一致 | 统一为 go 1.22(Dockerfile + go.mod + go.work) |
ai01 + ai02 | 中 |
| ISSUE-007 | 01-understanding.md §6 审计表过时 | ai01 更新文档 | ai01 文档 | 低 |
| ISSUE-008 | 01-understanding.md §7.1 死代码过时 | ai01 删除该行 | ai01 文档 | 低 |
| ISSUE-009 | W1/W2 错误码 GW_ + ActionState | P2.3 统一修复(ai01 已在 workline 列出) | ai01 P2.3 | 中 |
24.3 ISSUE-001 matrix.md gRPC 矩阵修正
裁决:✅ 已执行(基础设施批次)
- matrix.md §2 iam "消费方"列已移除
api-gateway(保留teacher-bff / student-bff / parent-bff) - matrix.md §7 Mock 策略表已修正为"硬编码 RS256 公钥(DEV_MODE)→ HTTP JWKS 端点"
- 依据:总裁 §2.16 裁决第 3 条"gateway 保持 HTTP 透传,不改为 gRPC 客户端"
跨模块影响:无(matrix.md 已修正,其他 AI 不受影响)
24.4 ISSUE-003 API 版本化路由方案(/v1 前缀位置)
裁决:采纳方案 A(双 /v1 前缀)
⚠️ 严重影响说明:此裁决与总裁 §2.15 裁决第 4 条"避免双 v1"存在冲突。coord 经审查后认为方案 A 更符合实际架构现状,但需明确说明冲突原因与修正范围。
路由方案:
| 前端调用路径 | Gateway 路由 | proxy 透传目标 | 下游 Controller 路径 |
|---|---|---|---|
/api/v1/iam/v1/auth/login |
/api/v1/iam/v1/*path |
iam:3002 /iam/v1/*path |
@Controller('v1/iam/auth') |
/api/v1/teacher/v1/graphql |
/api/v1/teacher/v1/*path |
teacher-bff:3003 /teacher/v1/*path |
GraphQL /graphql(BFF 无 Controller 分层) |
/api/v1/student/v1/graphql |
/api/v1/student/v1/*path |
student-bff:3009 /student/v1/*path |
GraphQL /graphql |
/api/v1/parent/v1/graphql |
/api/v1/parent/v1/*path |
parent-bff:3010 /parent/v1/*path |
GraphQL /graphql |
/api/v1/admin/v1/graphql |
/api/v1/admin/v1/*path |
teacher-bff:3003 /admin/v1/*path |
GraphQL admin 命名空间 |
理由:
- iam_contract.md §2.3 已明确
GET /iam/v1/.well-known/jwks.json(Controller 内含 /v1),若 Gateway 透传不含 /v1,则前端需调用/api/v1/iam/.well-known/jwks.json(缺服务级 /v1),与 iam 实际 Controller 路径不一致 - api-gateway_contract.md §1.2.2 v2 已列方案 A(双 /v1),且注明"方案 A,双 v1"
- matrix.md §5 已对齐方案 A(
/api/v1/teacher/*→ 方案 A 下应为/api/v1/teacher/v1/*) - ARB-014 §16.4 已采纳方案 A,ARB-019/020/021 前端 portal 仲裁均引用方案 A(
/api/v1/student/v1/graphql等) - 方案 B 的"避免双 v1"虽符合总裁裁决字面意思,但要求下游 Controller 不加 /v1 前缀,与 iam_contract.md §2.3 实际路径
/iam/v1/.well-known/jwks.json矛盾
与总裁 §2.15 裁决的冲突说明:
- 总裁 §2.15 第 4 条"避免双 v1"字面要求"Controller 加 /v1,Gateway 转发路径不含 /v1"
- 但总裁 §2.15 第 3 条"Gateway 透传时不改路径"与第 4 条存在内在矛盾:若 Controller 加 /v1,Gateway 透传时必然携带 /v1,前端调用必然双 /v1
- coord 裁决:以总裁 §2.15 第 3 条"Gateway 不改路径"为准,接受双 /v1(方案 A);第 4 条"避免双 v1"在实际执行中无法同时满足第 3 条,故第 4 条不适用
- 提请总裁复核:若总裁坚持"避免双 v1",需修正 iam_contract.md §2.3 的 Controller 路径(移除
/v1前缀),并同步修正所有服务的 Controller 路径设计
matrix.md §5 修正:
当前 matrix.md §5 路径为 /api/v1/teacher/*(单 /v1),需修正为 /api/v1/teacher/v1/*(双 /v1,方案 A):
| 修正前 | 修正后 |
|---|---|
/api/v1/teacher/* |
/api/v1/teacher/v1/* |
/api/v1/student/* |
/api/v1/student/v1/* |
/api/v1/parent/* |
/api/v1/parent/v1/* |
/api/v1/iam/* |
/api/v1/iam/v1/* |
跨模块影响:
- 前端 4 个 portal(ai13/ai14/ai15/ai16):文档已统一为双 /v1(ARB-019/020/021 已采纳方案 A),无影响
- BFF 层(ai03/ai04/ai05):GraphQL endpoint 路径
/graphql不变,仅 Gateway 路由前缀变化,BFF 内部无影响 - iam(ai06):Controller 路径已含
/v1(如/iam/v1/.well-known/jwks.json),无影响 - core-edu/content/msg/data-ana/ai:Controller 需加
/v1前缀(总裁 §2.15 第 1 条"各服务按自身节奏推进"),P3-P5 各服务启动时由对应 AI 落实
24.5 ISSUE-002 shared-go 接入方式
裁决:go.work 已含 ./packages/shared-go(已执行);ai01 go.mod 需补 github.com/edu-cloud/shared-go 依赖
现状核查:
- go.work L3-6 已含
./packages/shared-go(ISSUE-002 部分已解决) - go.mod 未含
github.com/edu-cloud/shared-go(待 ai01 P2.1 接入时补充)
ai01 执行项:
- go.mod 增加
require github.com/edu-cloud/shared-go v0.0.0(go work replace 模式) - P2.1 任务接入 jwks/logger/tracer/env 4 模块
- 若 shared-go 模块路径命名与预期不符,提请 coord 仲裁
跨模块影响:无(仅 ai01 自身依赖配置)
24.6 ISSUE-004 zap vs slog 选型
裁决:shared-go/logger 用 zap(现状保留,W3 裁决修正为 zap)
现状核查:
- packages/shared-go/logger/logger.go 实际用
go.uber.org/zap(不是标准库log/slog) - 实现:生产 JSON Info 级 / 开发 console Debug 级 + OTel trace_id 关联
与 W3 裁决的冲突说明:
- W3 裁决原文"首次实现即用 slog"
- 但 shared-go/logger 已用 zap 实现,且 zap 在 Go 生态中性能与生态成熟度优于 slog
- coord 裁决:接受现状(zap),W3 裁决修正为"shared-go/logger 基于 zap 封装;ai01 通过 import shared-go/logger 间接使用 zap,不直接 import zap"
ai01 执行项:
- P2.1 任务 import
github.com/edu-cloud/shared-go/logger - 替换全部
log.Printf为logger.FromContext(ctx).Info/Error/Warn - 涉及文件:main.go L70/160/169/176、config.go L38/41、recovery.go L22、circuit-breaker.go L38、tracer.go L25/31/43/51/65/70
跨模块影响:
- ai02(push-gateway):同样 import shared-go/logger,使用 zap,无影响
- 其他 Go 服务:若后续有 Go 服务,统一通过 shared-go/logger 使用 zap
24.7 ISSUE-005 go.mod 与 Dockerfile Go 版本不一致
裁决:统一为 go 1.22(与 Dockerfile + 01-understanding.md §4 一致)
版本对齐:
| 文件 | 当前 | 修正后 |
|---|---|---|
| Dockerfile L1 | golang:1.22-alpine |
golang:1.22-alpine(不变) |
| go.mod L3 | go 1.25.0 |
go 1.22 |
| go.work L1 | go 1.26.0 |
go 1.22 |
理由:
- Dockerfile 1.22-alpine 是实际构建环境,必须以它为准
- 01-understanding.md §4 声明 Go 1.22
- go.mod 1.25.0 / go.work 1.26.0 是误升版本,回退到 1.22
ai01 执行项:
- go.mod L3 改为
go 1.22 - go.work L1 改为
go 1.22 - 验证
go build ./...通过
跨模块影响:
- ai02(push-gateway):同样需对齐 go 1.22(若 push-gateway go.mod/go.work 版本不一致,ai02 同步修正)
- 其他服务:TS/Python 服务无影响
24.8 ISSUE-007 01-understanding.md §6 审计表 metrics 行过时
裁决:ai01 更新文档
ai01 执行项:
- 01-understanding.md §6 审计表 metrics 行:
❌ 无→⚠️ 端点已注册,缺 7 个业务指标 - 01-understanding.md §7.1 issue #1:更新为"已注册 /metrics,需补 7 个业务指标(见 workline P2.5)"
跨模块影响:无
24.9 ISSUE-008 01-understanding.md §7.1 issue #3 死代码引用过时
裁决:ai01 删除该行
ai01 执行项:
- 01-understanding.md §7.1 issue #3 整行删除(死代码
RequestIDMiddleware()+generateUUID()已修复)
跨模块影响:无
24.10 ISSUE-009 W1/W2 错误码 GW_ 前缀 + ActionState 信封
裁决:P2.3 任务统一修复(ai01 已在 workline 列出)
修复范围:
| 文件 | 当前问题 | 修复后 |
|---|---|---|
| auth.go | 错误码 UNAUTHORIZED/INVALID_TOKEN/INVALID_CLAIMS(无 GW_ 前缀) |
GW_UNAUTHORIZED/GW_INVALID_TOKEN/GW_INVALID_CLAIMS |
| ratelimit.go L51-54 | {"error":"rate_limited","retry_after":60}(无信封) |
{"success":false,"error":{"code":"GW_RATE_LIMITED","message":"..."},"retry_after":60} |
| circuit-breaker.go L55-58 | {"error":"circuit_open","retry_after":30}(无信封) |
{"success":false,"error":{"code":"GW_CIRCUIT_OPEN","message":"..."},"retry_after":30} |
| recovery.go L24-27 | {"error":"internal_error","request_id":"..."}(无信封) |
{"success":false,"error":{"code":"GW_INTERNAL_ERROR","message":"...","traceId":"..."}} |
ActionState 信封规范:见 004 §11.5 ActionState 信封规范(coord 基础设施批次已补充)
ai01 执行项:
- P2.3 任务统一修复 4 个中间件文件
- 错误码统一
GW_前缀(对齐 contract.md §1.6 错误码清单) - 响应体统一 ActionState 信封(对齐 004 §11.5)
跨模块影响:无(仅 ai01 自身代码修复)
24.11 ai01 执行项汇总
| 任务 | ISSUE | 阶段 | 阻塞 |
|---|---|---|---|
| go.mod 补 shared-go 依赖 + 接入 jwks/logger/tracer/env | ISSUE-002/004 | P2.1 | P2.1 |
| 替换 log.Printf 为 shared-go/logger | ISSUE-004 | P2.1 | P2.1 |
| go.mod/go.work 版本回退到 1.22 | ISSUE-005 | P2.0 | P2.0 |
| 01-understanding.md §6/§7.1 文档更新 | ISSUE-007/008 | P2.0 | — |
| 错误码 GW_ + ActionState 信封统一修复 | ISSUE-009 | P2.3 | P2.3 |
| API 版本化路由方案 A 落实(P1 代码迁移到 /v1 前缀) | ISSUE-003 | P2.7 | P2.7 |
24.12 coord 执行项
- ✅ matrix.md §2 移除 api-gateway 为 iam gRPC 消费方(基础设施批次已执行)
- matrix.md §5 路径前缀修正为双 /v1(方案 A)—— 本节裁决后立即执行
- ✅ 004 §11.5 ActionState 信封规范已补充(基础设施批次已执行)
- 协调 ai02 同步修正 push-gateway go.mod/go.work 版本到 1.22
- ✅ 总裁已确认采纳方案 A(2026-07-10),§2.15 第 4 条"避免双 v1"不再适用
§8 仲裁流程说明
8.1 提请异议
各 AI 在自己模块的 objections/[模块名]_issue.md 中追加异议条目,格式:
### ISSUE-[编号]-[AI标识]:[标题]
- **提请方**:aiXX
- **日期**:YYYY-MM-DD
- **类型**:契约不明确 / 工作量超批 / 前置依赖缺失 / 编号冲突 / 其他
- **描述**:[详细描述问题]
- **建议方案**:[AI 的建议]
- **状态**:待 coord 仲裁 / 已裁决(见 coord.md §X)
8.2 coord 仲裁
coord 审阅各 objections/[模块名]_issue.md 后,在本文件(coord.md)追加仲裁章节:
## §N ARB-XXX:[主题]
### N.1 背景
### N.2 仲裁结论
### N.3 关键裁决(表格)
### N.4 相关 AI 执行项
8.3 状态同步
- 仲裁完成后,coord 在对应
objections/[模块名]_issue.md中更新状态为"已裁决(见 coord.md §N)" - coord 在 workline.md §8 就绪信号跟踪表中更新进度
8.4 目录结构
issues/
├── coord.md # 本文件(仲裁汇总)
├── workline.md # 总工作安排
├── matrix.md # 上下游对接总矩阵
├── objections/ # 各模块问题/异议
│ ├── [模块名]_issue.md
│ └── cross_issue.md # 跨模块问题
├── worklines/ # 各模块工作排期
│ └── [模块名]_workline.md
└── contracts/ # 各模块对接契约
└── [模块名]_contract.md
§9 历史仲裁(已迁移)
以下仲裁已在此前完成,原始记录见 coord-final-decisions.md 和 president-final-rulings.md:
- I1-I8:iam P2 契约(coord-final-decisions.md §1)
- F1-F9:BFF 设计裁决(coord-final-decisions.md §2)
- G1-G3:Gateway 裁决(coord-final-decisions.md §3)
- N1-N3:content 裁决(coord-final-decisions.md §4)
- 总裁裁决 70+ 项(president-final-rulings.md §1-§5)
本文件仅记录新流程启动后(2026-07-09 起)的仲裁。