Files
Edu/docs/architecture/issues/objections/student-portal_issue.md
SpecialX c6362f4b04
Some checks failed
CI / quality-ts (push) Failing after 53s
CI / quality-go (push) Failing after 7s
CI / quality-proto (push) Failing after 3s
CI / deploy (push) Has been skipped
docs(docs): 更新 issue 仲裁状态 + 生成集成测试阶段规划
- 14 个 issue.md 状态字段更新为"已裁决"
  - 对应 coord.md ARB-001~022 章节
  - 共 104 处状态字段更新
- 新增 integration-test-phase.md
  - 集成测试与部署验证阶段(P7)规划
  - 6 个批次任务分解
  - 8 条核心 E2E 链路定义
  - 验收标准和退出标准

Coord-AI
2026-07-10 22:05:37 +08:00

18 KiB
Raw Permalink Blame History

student-portal 问题记录

负责人ai14 关联:coord.mdcontracts/student-portal_contract.mdmatrix.md 规则AI 遇到问题时在此追加条目coord 仲裁后更新状态


§1 已有仲裁核查ARB-001 / ARB-002 对 student-portal 的影响)

1.1 ARB-001teacher-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 全量 QuerycurrentUser/myClasses/myExams/myHomework/myGrades/myAttendance/studentDashboard 已落实
P2 Mutation 范围 ⚠️ 部分参考。student-portal P3 起步即需要 submitHomework mutation作业提交是 P3 核心场景) ai14 P3 即消费 submitHomework mutationai04 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 已设计扁平 query 已落实
ActionState 信封 适用。student-bff 必须返回 ActionState 信封success/errors/data ai14 在 GraphQL 请求层02 §3.2)已处理信封解包 + 降级字段识别 已落实
降级模式(方案 B 适用。部分聚合失败时 success=true + data 内 extensions.degraded: true ai14 在 02 §18.2 降级策略矩阵 已设计 12 个降级场景 已落实
admin 命名空间 不适用。student-portal 不涉及 admin 命名空间 - -

核查结论ARB-001 是 teacher-bff 的 P2 仲裁但其设计原则Schema 集中管理、ActionState 信封、降级模式方案 B、复杂度限制适用于所有 BFFstudent-portal 已在 02-architecture-design.md v2 中全面落实。


1.2 ARB-002MF Shell 暴露清单)对 student-portal 的影响核查

裁决点 对 student-portal 的适用性 ai14 落实方案 状态
Shell 身份 适用。teacher-portal 是 MF Shellstudent-portal 是 P3 首个 Remote ai14 在 02 §3.2 MF 配置 已声明 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 暴露 GraphQLProviderstudent-portal 复用,不重复创建 client ai14 在 02 §3.2 GraphQL 请求层 已使用 useGraphQLClient()@edu/hooks 获取 已落实
MF shared singleton 配置 适用。student-portal 必须将 react/react-dom/urql/graphql/@edu/* 声明为 singleton ai14 在 02 §3.2 next.config.js 已声明全部 singleton 已落实
AppShell 复用 适用。student-portal 不重复实现 AppShell复用 Shell 暴露的 AppShell ai14 在 02 §3.2 已设计 <AppShell> 包裹 + 学生端导航覆写 已落实
useAuth / usePermission 复用 适用。student-portal 复用 Shell 暴露的 useAuth/usePermission ai14 在 01-understanding.md §6 已声明权限校验走 usePermission 已落实
ErrorBoundary / Loading / Empty 复用 适用。student-portal 复用 Shell 暴露的共享 UI 组件 ai14 在 02 §6 组件设计已使用 @edu/ui-components 已落实
feature flag 适用。NEXT_PUBLIC_MF_ENABLED 控制是否走 MFP3 默认 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-ai14GraphQL 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
    • 由 ai01api-gateway确认路由/api/v1/student/*student-bff:3009/*(即 /api/v1/student/graphqlstudent-bff:3009/graphql
    • 由 ai04student-bff确认 GraphQL endpoint 路径为 POST /graphql(与 teacher-bff 一致)
  • 状态:已裁决(见 coord.md §21

ISSUE-014-02-ai14student-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 类型
    • 由 ai04student-bff创建该 schema 文件并维护
  • 状态:已裁决(见 coord.md §21

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
    • 这些决策影响 ai04student-bff是否需要提供 recordExamViolation mutation以及 ai08core-edu是否需要存储违规记录
  • 建议方案
    • 全屏策略P3 推荐但不强制(提示"建议全屏作答"P4 评估是否升级为强制(基于教师反馈)
    • 离开页面策略visibilitychange hidden 触发时仅记录(不自动提交),累计 3 次警告后教师端可见
    • 多标签检测:警告 + 记录,不阻止作答(避免误伤合法场景如查词典)
    • 防作弊事件上报:走 student-bff GraphQL mutation recordExamViolation(examId, type, payload),由 ai04 在 P3 提供
  • 状态:已裁决(见 coord.md §21

ISSUE-014-04-ai14主观题粘贴策略防作弊 vs 学生体验)

  • 提请方ai14
  • 日期2026-07-10
  • 类型:契约不明确
  • 描述
    • 02-architecture-design.md §14 防作弊检测包含 paste 事件拦截,但学生作答主观题时可能需要粘贴(如从草稿本粘贴长文本)
    • 策略不明确:全部禁止粘贴?仅主观题允许?仅客观题禁止?
    • 影响学生体验和防作弊效果平衡
  • 建议方案
    • 客观题:禁止粘贴(防作弊优先)
    • 主观题(简答/论述):允许粘贴,但记录粘贴事件 + 粘贴内容长度,教师端批改时可见
    • 作文题:允许粘贴(学生体验优先),不记录
    • 由 ai04student-bff在 P3 提供 recordPasteEvent mutation或复用 ISSUE-014-03 的 recordExamViolationtype=PASTE
  • 状态:已裁决(见 coord.md §21

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 multipartgraphql-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 鉴权
    • 由 ai01api-gateway确认是否提供 /api/v1/student/upload 路由,由 ai04student-bff确认 submitHomework mutation 是否接受 attachmentUrls 字段
  • 状态:已裁决(见 coord.md §21

ISSUE-014-06-ai14考试延长/题目重排等实时事件命名未确认

  • 提请方ai14
  • 日期2026-07-10
  • 类型:契约不明确
  • 描述
    • student-portal 02-architecture-design.md §16 设计了 WebSocket 实时通知,但以下事件命名未在 matrix.md §4 Kafka 事件矩阵中确认:
      1. 考试延长(教师延长考试时间):事件名 ExamExtended?还是 ExamUpdated?由 ai08core-edu发布
      2. 题目重排(教师重排题目顺序):事件名 ExamQuestionReordered?是否需要前端实时重排?
      3. 考试强制提交(教师强制收卷):事件名 ExamForceSubmitted?前端收到后立即提交?
    • 这些事件影响 student-portal 考试作答页的实时响应逻辑
  • 建议方案
    • 考试延长ai08core-edu发布 ExamExtended 事件到 edu.exam.events topicmsgai10消费后通过 push-gateway 推送student-portal 收到后更新倒计时
    • 题目重排P3 不实现题目顺序固定P4 评估是否需要实时重排
    • 考试强制提交ai08 发布 ExamForceSubmitted 事件student-portal 收到后立即触发提交流程
    • 由 ai08core-edu确认事件命名由 ai10msg确认推送路径
  • 状态:已裁决(见 coord.md §21

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 强制执行矛盾
  • 建议方案
    • 统一为方案 Astudent-bff 在 Resolver 层从 JWT x-user-id 提取 studentId强制过滤前端 query 不传 studentId 参数
    • ai14 修改 02-architecture-design.md §4.2 的 GraphQL query 定义,移除 studentId 参数(如 myClasses 改为无参 query
    • 由 ai04student-bff确认所有学生端 Query 均从 JWT 提取 studentId不接受前端传入
  • 状态:已裁决(见 coord.md §21

§3 异议状态汇总

编号 类型 标题 状态
ISSUE-014-01 契约不明确 GraphQL endpoint 路径不一致 已裁决
ISSUE-014-02 契约不明确 student-bff GraphQL schema 存放位置不一致 已裁决
ISSUE-014-03 契约不明确 考试作答页全屏策略与防作弊检测边界 已裁决
ISSUE-014-04 契约不明确 主观题粘贴策略(防作弊 vs 学生体验) 已裁决
ISSUE-014-05 契约不明确 作业附件上传协议GraphQL mutation vs REST multipart 已裁决
ISSUE-014-06 契约不明确 考试延长/题目重排等实时事件命名未确认 已裁决
ISSUE-014-07 契约不明确 学生端 DataScope L0 边界的强制执行层 已裁决