Merge worktree branch merge-15-modules-to-main-5ug5xJ
This commit is contained in:
@@ -1,12 +1,208 @@
|
||||
# student-portal 问题记录
|
||||
|
||||
> 负责人:ai14
|
||||
> 关联:[coord.md](../coord.md)、[contracts/student-portal_contract.md](../contracts/student-portal_contract.md)
|
||||
> 关联:[coord.md](../coord.md)、[contracts/student-portal_contract.md](../contracts/student-portal_contract.md)、[matrix.md](../matrix.md)
|
||||
> 规则:AI 遇到问题时在此追加条目,coord 仲裁后更新状态
|
||||
|
||||
---
|
||||
|
||||
## 问题列表
|
||||
## §1 已有仲裁核查(ARB-001 / ARB-002 对 student-portal 的影响)
|
||||
|
||||
### 1.1 ARB-001(teacher-bff GraphQL schema 第一版)对 student-portal 的影响核查
|
||||
|
||||
| 裁决点 | 对 student-portal 的适用性 | ai14 落实方案 | 状态 |
|
||||
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------ |
|
||||
| Schema 存放位置 | ✅ 适用(原则一致)。student-bff GraphQL schema 应存放于 `packages/shared-ts/contracts/graphql/student-bff.graphql`(集中管理,与 teacher-bff 同源) | ai14 在 contract.md §1.3 已标注预期路径;实际由 ai04 创建,ai14 仅消费 | ⏳ 待 ai04 |
|
||||
| P2 Query 范围 | ⚠️ 部分参考。ARB-001 是 teacher-bff 的 P2 范围;student-portal 起步于 P3(不在 P2),因此 student-bff 直接以 P3 全量 Query 起步 | ai14 在 P3 直接消费 student-bff 全量 Query(currentUser/myClasses/myExams/myHomework/myGrades/myAttendance/studentDashboard) | ✅ 已落实 |
|
||||
| P2 Mutation 范围 | ⚠️ 部分参考。student-portal P3 起步即需要 submitHomework mutation(作业提交是 P3 核心场景) | ai14 P3 即消费 submitHomework mutation;ai04 P3 必须提供 | ⏳ 待 ai04 |
|
||||
| DataLoader 防 N+1 | ✅ 适用。student-bff 聚合多 gRPC 时(如 studentDashboard 聚合 iam+core-edu+data-ana)必须使用 DataLoader | ai14 不直接实现,但依赖 student-bff 返回结构稳定(无 N+1 慢查询) | ⏳ 待 ai04 |
|
||||
| 复杂度限制(depth ≤ 7) | ✅ 适用。student-portal 发起的 GraphQL query 深度必须 ≤ 7 | ai14 在 [02-architecture-design.md §4.2](../../../apps/student-portal/docs/02-architecture-design.md) 已设计扁平 query | ✅ 已落实 |
|
||||
| ActionState 信封 | ✅ 适用。student-bff 必须返回 ActionState 信封(success/errors/data) | ai14 在 GraphQL 请求层(02 §3.2)已处理信封解包 + 降级字段识别 | ✅ 已落实 |
|
||||
| 降级模式(方案 B) | ✅ 适用。部分聚合失败时 success=true + data 内 `extensions.degraded: true` | ai14 在 [02 §18.2 降级策略矩阵](../../../apps/student-portal/docs/02-architecture-design.md) 已设计 12 个降级场景 | ✅ 已落实 |
|
||||
| admin 命名空间 | ❌ 不适用。student-portal 不涉及 admin 命名空间 | - | - |
|
||||
|
||||
**核查结论**:ARB-001 是 teacher-bff 的 P2 仲裁,但其设计原则(Schema 集中管理、ActionState 信封、降级模式方案 B、复杂度限制)适用于所有 BFF,student-portal 已在 02-architecture-design.md v2 中全面落实。
|
||||
|
||||
---
|
||||
|
||||
### 1.2 ARB-002(MF Shell 暴露清单)对 student-portal 的影响核查
|
||||
|
||||
| 裁决点 | 对 student-portal 的适用性 | ai14 落实方案 | 状态 |
|
||||
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
|
||||
| Shell 身份 | ✅ 适用。teacher-portal 是 MF Shell,student-portal 是 P3 首个 Remote | ai14 在 [02 §3.2 MF 配置](../../../apps/student-portal/docs/02-architecture-design.md) 已声明 `remotes: { teacher: 'teacher@http://localhost:4000/_next/static/chunks/remoteEntry.js' }` | ✅ 已落实 |
|
||||
| P3 首个 Remote | ✅ 适用。ARB-002 §2.3 明确 P3 首个 Remote 是 student-portal | ai14 P3 任务启动即接入 MF Remote | ✅ 已落实 |
|
||||
| GraphQL client 归属 | ✅ 适用。Shell 暴露 GraphQLProvider,student-portal 复用,**不重复创建 client** | ai14 在 [02 §3.2 GraphQL 请求层](../../../apps/student-portal/docs/02-architecture-design.md) 已使用 `useGraphQLClient()` 从 `@edu/hooks` 获取 | ✅ 已落实 |
|
||||
| MF shared singleton 配置 | ✅ 适用。student-portal 必须将 react/react-dom/urql/graphql/@edu/* 声明为 singleton | ai14 在 [02 §3.2 next.config.js](../../../apps/student-portal/docs/02-architecture-design.md) 已声明全部 singleton | ✅ 已落实 |
|
||||
| AppShell 复用 | ✅ 适用。student-portal 不重复实现 AppShell,复用 Shell 暴露的 AppShell | ai14 在 02 §3.2 已设计 `<AppShell>` 包裹 + 学生端导航覆写 | ✅ 已落实 |
|
||||
| useAuth / usePermission 复用 | ✅ 适用。student-portal 复用 Shell 暴露的 useAuth/usePermission | ai14 在 [01-understanding.md §6](../../../apps/student-portal/docs/01-understanding.md) 已声明权限校验走 usePermission | ✅ 已落实 |
|
||||
| ErrorBoundary / Loading / Empty 复用 | ✅ 适用。student-portal 复用 Shell 暴露的共享 UI 组件 | ai14 在 02 §6 组件设计已使用 `@edu/ui-components` | ✅ 已落实 |
|
||||
| feature flag | ✅ 适用。`NEXT_PUBLIC_MF_ENABLED` 控制是否走 MF;P3 默认 true | ai14 在 02 §3.2 已设计独立壳回退(MF 关闭时独立渲染) | ✅ 已落实 |
|
||||
| 登录页 | ✅ 适用。P2 登录页由 Shell 独占;student-portal 不实现登录页,未登录跳转 Shell `/login` | ai14 在 02 §3.2 已设计未认证 → 跳转 `window.location.href = 'http://localhost:4000/login?redirect=student'` | ✅ 已落实 |
|
||||
|
||||
**核查结论**:ARB-002 是 student-portal 接入 MF 的直接依据,ai14 已在 02-architecture-design.md v2 中全面落实。无异议。
|
||||
|
||||
---
|
||||
|
||||
### 1.3 ARB-001 / ARB-002 核查总结
|
||||
|
||||
| 仲裁 | 对 student-portal 的影响 | ai14 落实情况 | 异议 |
|
||||
| ------ | ------------------------ | ------------- | ---- |
|
||||
| ARB-001 | 设计原则适用(GraphQL + ActionState + 降级模式) | ✅ 已落实 | 无 |
|
||||
| ARB-002 | 直接适用(P3 首个 Remote + Shell 暴露清单) | ✅ 已落实 | 无 |
|
||||
|
||||
> **ai14 声明**:ARB-001 / ARB-002 已在 02-architecture-design.md v2 中全面落实,无需新增仲裁。
|
||||
|
||||
---
|
||||
|
||||
## §2 新提请异议(待 coord 仲裁)
|
||||
|
||||
### ISSUE-014-01-ai14:GraphQL endpoint 路径不一致(`/api/student/graphql` vs `/api/v1/student/graphql`)
|
||||
|
||||
- **提请方**:ai14
|
||||
- **日期**:2026-07-10
|
||||
- **类型**:契约不明确
|
||||
- **描述**:
|
||||
- `student-portal_contract.md` §2.3 当前写 `POST /api/student/graphql`(无 `/v1/` 前缀)
|
||||
- `matrix.md` §5 HTTP 接口矩阵明确写 `api-gateway` 反向代理 `student-portal` 的路径是 `/api/v1/student/*`
|
||||
- `01-understanding.md` v2 §3.1 和 `02-architecture-design.md` v2 §4.1 已统一为 `POST /api/v1/student/graphql`
|
||||
- 三处不一致,需要 coord 仲裁统一为 `/api/v1/student/graphql`(与 matrix.md §5 对齐,与 teacher-portal `/api/v1/teacher/graphql` 保持命名一致性)
|
||||
- **建议方案**:
|
||||
- 统一为 `POST /api/v1/student/graphql`
|
||||
- 由 ai01(api-gateway)确认路由:`/api/v1/student/*` → `student-bff:3009/*`(即 `/api/v1/student/graphql` → `student-bff:3009/graphql`)
|
||||
- 由 ai04(student-bff)确认 GraphQL endpoint 路径为 `POST /graphql`(与 teacher-bff 一致)
|
||||
- **状态**:待 coord 仲裁
|
||||
|
||||
---
|
||||
|
||||
### ISSUE-014-02-ai14:student-bff GraphQL schema 文件存放位置不一致(集中管理 vs 应用内管理)
|
||||
|
||||
- **提请方**:ai14
|
||||
- **日期**:2026-07-10
|
||||
- **类型**:契约不明确
|
||||
- **描述**:
|
||||
- ARB-001 §1.3 关键裁决明确:teacher-bff GraphQL schema 存放于 `packages/shared-ts/contracts/graphql/teacher-bff.graphql`(集中管理,总裁裁决 §2.17 SDL-first + 集中管理)
|
||||
- `student-bff_contract.md` §1.3 写:`apps/student-bff/src/schema/*.graphql`(应用内管理,与 ARB-001 原则不一致)
|
||||
- `matrix.md` §3 GraphQL 接口提供方矩阵写:`packages/shared-ts/contracts/graphql/student-bff.graphql`(与 ARB-001 一致)
|
||||
- 两处不一致,需要 coord 仲裁统一
|
||||
- **建议方案**:
|
||||
- 统一为 `packages/shared-ts/contracts/graphql/student-bff.graphql`(与 ARB-001 原则对齐,集中管理便于前端 codegen)
|
||||
- ai14 在 student-portal 端使用 `graphql-codegen` 从该 schema 生成 TypeScript 类型
|
||||
- 由 ai04(student-bff)创建该 schema 文件并维护
|
||||
- **状态**:待 coord 仲裁
|
||||
|
||||
---
|
||||
|
||||
### ISSUE-014-03-ai14:考试作答页全屏策略与防作弊检测边界
|
||||
|
||||
- **提请方**:ai14
|
||||
- **日期**:2026-07-10
|
||||
- **类型**:契约不明确
|
||||
- **描述**:
|
||||
- student-portal 02-architecture-design.md §14 设计了防作弊检测(visibilitychange/copy/paste/fullscreen/contextmenu),但未明确以下边界:
|
||||
1. **全屏 API 强制策略**:是否强制全屏(Fullscreen API)?退出全屏是否触发警告/记录?
|
||||
2. **离开页面策略**:visibilitychange hidden 触发时,是仅记录还是自动提交?
|
||||
3. **多标签检测**:BroadcastChannel 检测到多标签时,是警告还是阻止作答?
|
||||
4. **防作弊事件上报**:前端采集的防作弊事件如何上报?走 student-bff GraphQL mutation 还是 push-gateway WebSocket?
|
||||
- 这些决策影响 ai04(student-bff)是否需要提供 `recordExamViolation` mutation,以及 ai08(core-edu)是否需要存储违规记录
|
||||
- **建议方案**:
|
||||
- **全屏策略**:P3 推荐但不强制(提示"建议全屏作答"),P4 评估是否升级为强制(基于教师反馈)
|
||||
- **离开页面策略**:visibilitychange hidden 触发时仅记录(不自动提交),累计 3 次警告后教师端可见
|
||||
- **多标签检测**:警告 + 记录,不阻止作答(避免误伤合法场景如查词典)
|
||||
- **防作弊事件上报**:走 student-bff GraphQL mutation `recordExamViolation(examId, type, payload)`,由 ai04 在 P3 提供
|
||||
- **状态**:待 coord 仲裁
|
||||
|
||||
---
|
||||
|
||||
### ISSUE-014-04-ai14:主观题粘贴策略(防作弊 vs 学生体验)
|
||||
|
||||
- **提请方**:ai14
|
||||
- **日期**:2026-07-10
|
||||
- **类型**:契约不明确
|
||||
- **描述**:
|
||||
- 02-architecture-design.md §14 防作弊检测包含 `paste` 事件拦截,但学生作答主观题时可能需要粘贴(如从草稿本粘贴长文本)
|
||||
- 策略不明确:全部禁止粘贴?仅主观题允许?仅客观题禁止?
|
||||
- 影响学生体验和防作弊效果平衡
|
||||
- **建议方案**:
|
||||
- **客观题**:禁止粘贴(防作弊优先)
|
||||
- **主观题(简答/论述)**:允许粘贴,但记录粘贴事件 + 粘贴内容长度,教师端批改时可见
|
||||
- **作文题**:允许粘贴(学生体验优先),不记录
|
||||
- 由 ai04(student-bff)在 P3 提供 `recordPasteEvent` mutation(或复用 ISSUE-014-03 的 `recordExamViolation`,type=`PASTE`)
|
||||
- **状态**:待 coord 仲裁
|
||||
|
||||
---
|
||||
|
||||
### ISSUE-014-05-ai14:作业附件上传协议(GraphQL mutation vs REST multipart)
|
||||
|
||||
- **提请方**:ai14
|
||||
- **日期**:2026-07-10
|
||||
- **类型**:契约不明确
|
||||
- **描述**:
|
||||
- 学生提交作业时可能需要上传附件(图片/PDF/文档),GraphQL mutation 不适合处理大文件上传(multipart/form-data)
|
||||
- 当前 contract.md 未明确附件上传协议
|
||||
- 选项:
|
||||
- A. 走 api-gateway REST 端点(`POST /api/v1/student/upload` → 对象存储),返回 URL,再走 GraphQL mutation 提交 URL
|
||||
- B. 走 student-bff GraphQL multipart(graphql-upload,需要 ai04 支持)
|
||||
- C. 走独立上传服务(如 push-gateway 扩展或新建 upload-service)
|
||||
- **建议方案**:
|
||||
- **推荐 A**:走 api-gateway REST `POST /api/v1/student/upload` → 对象存储(MinIO/OSS),返回 signed URL,再走 GraphQL `submitHomework(attachmentUrls: [String!])` mutation 提交
|
||||
- 理由:GraphQL 不适合大文件传输;REST + 对象存储是业界通用方案;api-gateway 已有 JWT 鉴权
|
||||
- 由 ai01(api-gateway)确认是否提供 `/api/v1/student/upload` 路由,由 ai04(student-bff)确认 `submitHomework` mutation 是否接受 `attachmentUrls` 字段
|
||||
- **状态**:待 coord 仲裁
|
||||
|
||||
---
|
||||
|
||||
### ISSUE-014-06-ai14:考试延长/题目重排等实时事件命名未确认
|
||||
|
||||
- **提请方**:ai14
|
||||
- **日期**:2026-07-10
|
||||
- **类型**:契约不明确
|
||||
- **描述**:
|
||||
- student-portal 02-architecture-design.md §16 设计了 WebSocket 实时通知,但以下事件命名未在 matrix.md §4 Kafka 事件矩阵中确认:
|
||||
1. **考试延长**(教师延长考试时间):事件名 `ExamExtended`?还是 `ExamUpdated`?由 ai08(core-edu)发布?
|
||||
2. **题目重排**(教师重排题目顺序):事件名 `ExamQuestionReordered`?是否需要前端实时重排?
|
||||
3. **考试强制提交**(教师强制收卷):事件名 `ExamForceSubmitted`?前端收到后立即提交?
|
||||
- 这些事件影响 student-portal 考试作答页的实时响应逻辑
|
||||
- **建议方案**:
|
||||
- **考试延长**:ai08(core-edu)发布 `ExamExtended` 事件到 `edu.exam.events` topic,msg(ai10)消费后通过 push-gateway 推送,student-portal 收到后更新倒计时
|
||||
- **题目重排**:P3 不实现(题目顺序固定),P4 评估是否需要实时重排
|
||||
- **考试强制提交**:ai08 发布 `ExamForceSubmitted` 事件,student-portal 收到后立即触发提交流程
|
||||
- 由 ai08(core-edu)确认事件命名,由 ai10(msg)确认推送路径
|
||||
- **状态**:待 coord 仲裁
|
||||
|
||||
---
|
||||
|
||||
### ISSUE-014-07-ai14:学生端 DataScope L0 边界(仅能查看自己数据)的强制执行层
|
||||
|
||||
- **提请方**:ai14
|
||||
- **日期**:2026-07-10
|
||||
- **类型**:契约不明确
|
||||
- **描述**:
|
||||
- 01-understanding.md §8 和 02-architecture-design.md §6 声明学生 DataScope L0(仅能查看自己数据)
|
||||
- 但强制执行层不明确:
|
||||
- A. student-bff 在 Resolver 层基于 JWT 的 `x-user-id` 强制过滤(推荐,前端无法绕过)
|
||||
- B. student-portal 在 GraphQL query 中显式传 `studentId`(不安全,前端可篡改)
|
||||
- 当前 02-architecture-design.md §4.2 的 GraphQL query 设计中,部分 query 显式传 `studentId`(如 `myClasses(studentId: ID!)`),这与 L0 强制执行矛盾
|
||||
- **建议方案**:
|
||||
- **统一为方案 A**:student-bff 在 Resolver 层从 JWT `x-user-id` 提取 studentId,强制过滤,前端 query 不传 `studentId` 参数
|
||||
- ai14 修改 02-architecture-design.md §4.2 的 GraphQL query 定义,移除 `studentId` 参数(如 `myClasses` 改为无参 query)
|
||||
- 由 ai04(student-bff)确认所有学生端 Query 均从 JWT 提取 studentId,不接受前端传入
|
||||
- **状态**:待 coord 仲裁
|
||||
|
||||
---
|
||||
|
||||
## §3 异议状态汇总
|
||||
|
||||
| 编号 | 类型 | 标题 | 状态 |
|
||||
| ------------- | ------------ | -------------------------------------------------------- | ------------ |
|
||||
| ISSUE-014-01 | 契约不明确 | GraphQL endpoint 路径不一致 | 待 coord 仲裁 |
|
||||
| ISSUE-014-02 | 契约不明确 | student-bff GraphQL schema 存放位置不一致 | 待 coord 仲裁 |
|
||||
| ISSUE-014-03 | 契约不明确 | 考试作答页全屏策略与防作弊检测边界 | 待 coord 仲裁 |
|
||||
| ISSUE-014-04 | 契约不明确 | 主观题粘贴策略(防作弊 vs 学生体验) | 待 coord 仲裁 |
|
||||
| ISSUE-014-05 | 契约不明确 | 作业附件上传协议(GraphQL mutation vs REST multipart) | 待 coord 仲裁 |
|
||||
| ISSUE-014-06 | 契约不明确 | 考试延长/题目重排等实时事件命名未确认 | 待 coord 仲裁 |
|
||||
| ISSUE-014-07 | 契约不明确 | 学生端 DataScope L0 边界的强制执行层 | 待 coord 仲裁 |
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
追加条目格式:
|
||||
@@ -20,5 +216,3 @@
|
||||
- **建议方案**:[AI 的建议]
|
||||
- **状态**:待 coord 仲裁 / 已裁决(见 coord.md §X)
|
||||
-->
|
||||
|
||||
(暂无问题)
|
||||
|
||||
Reference in New Issue
Block a user