# coord 仲裁结果汇总 > 维护者:coord(协调 AI) > 维护规则:各 AI 在 `objections/[模块名]_issue.md` 提请异议 → coord 审阅 → 在本文件写入仲裁结果 > 关联文档:[president-final-rulings.md](../president-final-rulings.md)、[ai-work-orchestration.md](../ai-work-orchestration.md)、[workline.md](./workline.md)、[matrix.md](./matrix.md) --- ## 仲裁记录索引 | 编号 | 日期 | 提请方 | 主题 | 状态 | 仲裁章节 | | ------- | ---------- | ---------------------- | --------------------------------- | --------- | -------- | | ARB-001 | 2026-07-09 | coord(批次 1 启动前) | teacher-bff GraphQL schema 第一版 | ✅ 已裁决 | §1 | | ARB-002 | 2026-07-09 | coord(批次 1 启动前) | MF Shell 暴露清单 | ✅ 已裁决 | §2 | --- ## §1 ARB-001:teacher-bff GraphQL schema 第一版 ### 1.1 背景 批次 1(P2)启动前,需仲裁 teacher-bff GraphQL schema 第一版,作为 ai03(teacher-bff)和 ai13(teacher-portal)的共同契约。 数据源:ai03 的 [02-architecture-design.md §5](../../services/teacher-bff/docs/02-architecture-design.md#L503) 提供了目标态 schema(P4),但 P2 只需 Must Have 子集。 ### 1.2 仲裁结论 **P2 第一版 schema 范围**(Must Have,对应 ai03 P2 工作量分级 Must Have 13 项): ```graphql # ============ P2 第一版 schema ============ # 存放位置:packages/shared-ts/contracts/graphql/teacher-bff.graphql # 仲裁原则:仅包含 P2 可实现的 Query(iam + classes 已就绪),Mutation 延后到 P3 scalar DateTime enum DataScope { SELF CLASS GRADE SCHOOL DISTRICT 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 + classes.byTeacher) dashboard: DashboardData! # 视口配置(导航) viewports: [ViewportItem!]! # 当前用户信息 me: User! # 班级列表(按教师 dataScope 过滤) 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+ 评估 ``` ### 1.3 关键裁决 | 裁决点 | 结论 | 依据 | | ---------------- | ---------------------------------------------------------- | ------------------------------------------------------------ | | Schema 存放位置 | `packages/shared-ts/contracts/graphql/teacher-bff.graphql` | 总裁裁决 §2.17 SDL-first + 集中管理 | | P2 Query 范围 | dashboard / viewports / me / classes / class(5 个) | 仅依赖 iam + classes(P2 就绪) | | 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 不包含**,P6 admin-portal 阶段新增 `admin` 命名空间 | 总裁裁决 §5.1 admin 复用 teacher-bff + admin schema 命名空间 | | 错误响应 | ActionState 信封(success/errors/data) | coord-final-decisions F9 | | 降级模式 | success=true + error=null + data 内 degraded 字段 | 总裁裁决 §3.4 方案 B | ### 1.4 ai03 执行项 1. 在 `packages/shared-ts/contracts/graphql/teacher-bff.graphql` 创建 P2 第一版 schema 文件 2. teacher-bff 实现 Yoga GraphQL endpoint(`POST /graphql`) 3. 实现 5 个 Query Resolver(dashboard / viewports / me / classes / class) 4. dashboard Resolver 并行调用 iam(3 RPC)+ classes(1 RPC),用 DataLoader 防御 N+1 5. 实现 ActionState 信封 + 降级模式(方案 B) ### 1.5 ai13 执行项 1. teacher-portal Shell 暴露 `GraphQLProvider`(urql client 单例) 2. 使用 `useGraphQLClient()` 从 packages/hooks 获取 client 3. P2 页面(dashboard / classes)通过 GraphQL query 拉取数据 4. **不调用 REST 端点**(除登录外,P2 起 all-in GraphQL) --- ## §2 ARB-002:MF Shell 暴露清单 ### 2.1 背景 批次 1(P2)启动前,需仲裁 teacher-portal 作为 MF Shell 暴露哪些模块给 Remote(student/parent/admin),作为 ai13 的实现依据。 数据源:ai13 的 [03-long-term-architecture.md §1.4](../../apps/teacher-portal/docs/03-long-term-architecture.md) 提供了 GraphQL client 单例设计。 ### 2.2 仲裁结论 **P2 第一版 MF Shell 暴露清单**: ```typescript // 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)配置**: ```typescript 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 执行项 1. teacher-portal `next.config.js` 添加 NextFederationPlugin(exposes + shared,**无 remotes**) 2. 创建 `src/app/providers.tsx`(GraphQLProvider 包裹) 3. AppShell 改造:从 REST `/api/v1/teacher/viewports` 切换为 GraphQL query `viewports` 4. P2 页面(dashboard / classes)全部用 GraphQL 5. feature flag `NEXT_PUBLIC_MF_ENABLED=false`(P2 默认单体路由) ### 2.5 ai03 执行项(联动) 1. teacher-bff 暴露 `POST /graphql` endpoint 2. 提供GraphQL playground(仅开发环境) --- ## §3 仲裁流程说明 ### 3.1 提请异议 各 AI 在自己模块的 `objections/[模块名]_issue.md` 中追加异议条目,格式: ```markdown ### ISSUE-[编号]-[AI标识]:[标题] - **提请方**:aiXX - **日期**:YYYY-MM-DD - **类型**:契约不明确 / 工作量超批 / 前置依赖缺失 / 编号冲突 / 其他 - **描述**:[详细描述问题] - **建议方案**:[AI 的建议] - **状态**:待 coord 仲裁 / 已裁决(见 coord.md §X) ``` ### 3.2 coord 仲裁 coord 审阅各 `objections/[模块名]_issue.md` 后,在本文件(coord.md)追加仲裁章节: ```markdown ## §N ARB-XXX:[主题] ### N.1 背景 ### N.2 仲裁结论 ### N.3 关键裁决(表格) ### N.4 相关 AI 执行项 ``` ### 3.3 状态同步 - 仲裁完成后,coord 在对应 `objections/[模块名]_issue.md` 中更新状态为"已裁决(见 coord.md §N)" - coord 在 [workline.md](./workline.md) §8 就绪信号跟踪表中更新进度 ### 3.4 目录结构 ``` issues/ ├── coord.md # 本文件(仲裁汇总) ├── workline.md # 总工作安排 ├── matrix.md # 上下游对接总矩阵 ├── objections/ # 各模块问题/异议 │ ├── [模块名]_issue.md │ └── cross_issue.md # 跨模块问题 ├── worklines/ # 各模块工作排期 │ └── [模块名]_workline.md └── contracts/ # 各模块对接契约 └── [模块名]_contract.md ``` --- ## §4 历史仲裁(已迁移) 以下仲裁已在此前完成,原始记录见 [coord-final-decisions.md](../coord-final-decisions.md) 和 [president-final-rulings.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 起)的仲裁。