docs(student-portal): add arbitration check and new objections to issue record
add verification of ARB-001 and ARB-002 impacts, and submit seven new disputed issues for coord arbitration
This commit is contained in:
@@ -1,45 +1,271 @@
|
||||
# student-portal 工作排期
|
||||
|
||||
> 负责人:ai14
|
||||
> 关联:[workline.md](../workline.md)、[coord.md](../coord.md)、[contracts/student-portal_contract.md](../contracts/student-portal_contract.md)
|
||||
> 模式:全并行(各 AI 一口气完成 P2-P6 全部代码,最后统一集成测试)
|
||||
> 关联:[workline.md](../workline.md)、[coord.md §1 ARB-001](../coord.md)、[coord.md §2 ARB-002](../coord.md)、[contracts/student-portal_contract.md](../contracts/student-portal_contract.md)、[matrix.md](../matrix.md)
|
||||
> 模式:全并行(各 AI 一口气完成 P2-P6 全部代码,开发期间用 mock,最后统一集成测试)
|
||||
> 依据:president-final-rulings.md §3.6(ai14 P3 功能范围)+ §7.14(ai14 工作内容最终清单)+ ARB-002 §2.3(P3 首个 Remote)+ 02-architecture-design.md v2 阶段能力累积矩阵
|
||||
|
||||
---
|
||||
|
||||
## §1 总览
|
||||
|
||||
student-portal 是学生端微前端,通过 MF Remote 接入主应用,覆盖考试作答、作业提交等场景。全阶段目标:P2 MF Remote 骨架 → P3 考试作答+作业提交 → P4-P6 持续优化。
|
||||
student-portal 是学生端微前端(MF Remote),通过 Module Federation 接入 teacher-portal Shell,覆盖考试作答、作业提交、学情查看等场景。全阶段目标:P2 MF Remote 骨架预埋 → P3 考试作答 + 作业提交 + 基础页面 → P4 知识图谱 + 学情诊断 → P5 实时通知 + AI 辅助 → P6 可观测性硬化 + A11y + 性能。
|
||||
|
||||
**全并行模式**:ai14 一口气完成 P2-P6 全部代码,开发期间用 MSW mock 上游(student-bff GraphQL / api-gateway HTTP / push-gateway WebSocket),上游就绪后在 [matrix.md](../matrix.md) §8 更新就绪信号,最后统一集成测试。
|
||||
|
||||
**批次归属**(见 [workline.md §1](../workline.md)):
|
||||
|
||||
- 批次 2(P3):ai14 与 ai07 + ai08 + ai04 + ai03扩展 并行启动(`b2d, after b1d, 8d`)
|
||||
- 批次 3(P4):与 ai09 + ai11 + ai05 + ai15 并行
|
||||
- 批次 4(P5):与 ai10 + ai02 + ai12 + ai03扩展 并行
|
||||
- 批次 5(P6):与 ai16 + 持续优化 并行
|
||||
|
||||
---
|
||||
|
||||
## §2 全阶段甘特图(P2-P6,各 AI 自行细化)
|
||||
## §2 全阶段甘特图(P2-P6)
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
title ai14 student-portal 全阶段排期
|
||||
title ai14 student-portal 全阶段排期(全并行)
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %m-%d
|
||||
|
||||
section P2-P6
|
||||
[阶段任务] :a14a, 2026-07-10, Xd
|
||||
```
|
||||
section P2 预埋
|
||||
项目骨架+设计令牌三层+独立壳路由 :crit, a14p0, 2026-07-10, 2d
|
||||
MF Remote配置(NextFederationPlugin remotes) :crit, a14a, after a14p0, 2d
|
||||
MSW基础设施+GraphQL请求层骨架 :a14b, after a14a, 2d
|
||||
|
||||
> **注意**:以上为 coord 初始规划,ai14 接管后必须自行细化为完整 P2-P6 排期。
|
||||
section P3 学生核心
|
||||
AppShell复用+学生端导航+路由守卫 :crit, a14c, after a14b, 2d
|
||||
Dashboard页(studentDashboard query) :a14d, after a14c, 2d
|
||||
我的班级页+我的考试列表+我的作业列表 :a14e, after a14d, 3d
|
||||
考试作答页(状态机+服务器时间同步) :crit, a14f, after a14e, 4d
|
||||
IDB断网恢复队列+自动保存+DraftRecovery :crit, a14g, after a14f, 3d
|
||||
防作弊采集+BroadcastChannel多标签检测 :a14h, after a14g, 2d
|
||||
作业提交页(submitHomework mutation+乐观更新) :a14i, after a14h, 2d
|
||||
我的成绩页+我的考勤页 :a14j, after a14i, 2d
|
||||
|
||||
section P4 知识与学情
|
||||
学习路径页(learningPath query+知识点卡片) :a14k, after a14j, 3d
|
||||
学情诊断页(myWeakness+myTrend query+图表) :a14l, after a14k, 3d
|
||||
教材章节浏览页(textbooks+chapters) :a14m, after a14l, 2d
|
||||
|
||||
section P5 推送与AI
|
||||
WebSocket通知中心(myNotifications+markAsRead) :a14n, after a14m, 2d
|
||||
跨Tab通知同步(BroadcastChannel) :a14o, after a14n, 1d
|
||||
AI辅助答疑(SSE流式,可选) :a14p, after a14o, 3d
|
||||
|
||||
section P6 硬化
|
||||
Sentry+RUM+OTel browser :a14q, after a14p, 2d
|
||||
A11y审计(WCAG 2.2 AA) :a14r, after a14q, 2d
|
||||
性能优化+bundle门禁(Remote <80KB) :a14s, after a14r, 2d
|
||||
P3未尽事项补全+降级策略验证 :a14t, after a14s, 2d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §3 详细任务
|
||||
|
||||
### 全阶段任务
|
||||
### P2:MF Remote 骨架预埋
|
||||
|
||||
- **负责人**:ai14
|
||||
- **交付物**:⚠️ 由 ai14 自行补充
|
||||
- **依赖**:见 [contracts/student-portal_contract.md](../contracts/student-portal_contract.md)
|
||||
- **验收标准**:⚠️ 由 ai14 自行补充
|
||||
- **裁决依据**:ARB-002 §2.3(P3 首个 Remote,但 P2 可预埋骨架)+ 总裁裁决 §3.6(ai14 P3 起步)+ §2.17(MF GraphQL client 单例方案 A)
|
||||
- **交付物**:
|
||||
- 项目骨架(`apps/student-portal/` 目录结构:`src/app/`、`src/components/`、`src/lib/`、`src/hooks/`、`src/mocks/`)
|
||||
- 设计令牌三层(primitive.css / semantic.css / tailwind-theme.ts,与 teacher-portal Shell 一致)
|
||||
- 独立壳路由(next.config.js + app/layout.tsx + app/page.tsx,MF 关闭时可独立渲染)
|
||||
- NextFederationPlugin 配置(`remotes: { teacher: 'teacher@http://localhost:4000/_next/static/chunks/remoteEntry.js' }`,`exposes: { './StudentApp': './src/app/student-app.tsx' }`)
|
||||
- MF shared singleton 配置(react/react-dom/urql/graphql/@tanstack/react-query/zustand/nuqs/@edu/* 全部 singleton)
|
||||
- MSW 基础设施(`src/mocks/handlers.ts` + `src/mocks/fixtures/*.json` + `NEXT_PUBLIC_API_MOCKING=enabled`)
|
||||
- GraphQL 请求层骨架(`src/lib/graphql.ts` 复用 Shell `useGraphQLClient()`,不重复创建 client)
|
||||
- **依赖**:
|
||||
- packages 骨架(ui-tokens/ui-components/hooks,ai13 批次 0.15 已完成)
|
||||
- teacher-portal MF Shell 配置(ai13 P2,exposes 就绪)
|
||||
- **Mock 策略**:MSW 拦截 `POST /api/v1/student/graphql` + `POST /api/auth/login`
|
||||
- **验收标准**:
|
||||
- `pnpm dev` 启动 :4001 可访问
|
||||
- MF 配置不破坏独立壳渲染(`NEXT_PUBLIC_MF_ENABLED=false` 时独立渲染首页)
|
||||
- MSW 拦截 GraphQL 请求返回 mock 数据
|
||||
- lint + typecheck 零错误
|
||||
|
||||
### P3:考试作答 + 作业提交 + 基础页面(核心)
|
||||
|
||||
- **负责人**:ai14
|
||||
- **裁决依据**:总裁裁决 §3.6(ai14 P3 功能范围)+ ARB-001 §1.3(ActionState 信封 + 降级模式方案 B)+ ARB-002 §2.2(复用 Shell 暴露清单)+ 02-architecture-design.md v2 §14(考试作答架构设计)
|
||||
- **交付物**:
|
||||
- **AppShell 复用 + 学生端导航**:从 Shell 导入 `AppShell`,覆写学生端视口(myClasses/myExams/myHomework/myGrades/myAttendance/learningPath/dashboard/notifications)
|
||||
- **路由守卫**:未登录跳转 `http://localhost:4000/login?redirect=student`,登录后回跳
|
||||
- **Dashboard 页**(`/dashboard`):消费 `studentDashboard` query(upcomingHomework + upcomingExams + recentGrades + attendanceRate + learningStreakDays)
|
||||
- **我的班级页**(`/my-classes`):消费 `myClasses` query
|
||||
- **我的考试列表页**(`/my-exams`):消费 `myExams` query,按状态分组(未开始/进行中/已提交/已批改)
|
||||
- **我的作业列表页**(`/my-homework`):消费 `myHomework` query,按状态分组
|
||||
- **考试作答页**(`/my-exams/[id]/take`):
|
||||
- 状态机(NotStarted → InProgress → AutoSaving → Submitting → Submitted,见 02 §14 状态机图)
|
||||
- 服务器时间同步(`useServerTimeSync` hook,5 分钟重新同步,倒计时基于服务器时间)
|
||||
- IDB 断网恢复队列(`idb-keyval` 存草稿 + 队列,网络恢复后重试)
|
||||
- 自动保存(每 30s + blur 事件触发,乐观更新本地状态)
|
||||
- DraftRecovery 草稿恢复(进入作答页时检查 IDB 草稿,提示恢复)
|
||||
- 防作弊采集(visibilitychange/copy/paste/fullscreen/contextmenu 事件监听 + 记录)
|
||||
- BroadcastChannel 多标签检测(`edu-exam-session` channel,检测到多标签警告)
|
||||
- 提交防重复(idempotency key + 提交按钮 disabled + 提交中状态)
|
||||
- **作业提交页**(`/my-homework/[id]/submit`):
|
||||
- 消费 `submitHomework` mutation
|
||||
- 乐观更新(useMutation onMutate 回滚 + invalidateQueries)
|
||||
- 附件上传(待 ISSUE-014-05 仲裁后实现,暂走 mock)
|
||||
- **我的成绩页**(`/my-grades`):消费 `myGrades` query,成绩列表 + 趋势图
|
||||
- **我的考勤页**(`/my-attendance`):消费 `myAttendance` query,考勤日历
|
||||
- **依赖**:
|
||||
- student-bff GraphQL schema(ai04 P3,`packages/shared-ts/contracts/graphql/student-bff.graphql`,待 ISSUE-014-02 仲裁)
|
||||
- api-gateway 路由(ai01 P3,`/api/v1/student/*` 反向代理 student-bff,待 ISSUE-014-01 仲裁)
|
||||
- core-edu gRPC(ai08 P3,提供 ExamService/HomeworkService/GradeService/AttendanceService/ClassService)
|
||||
- iam gRPC(ai06 P2,GetUserInfo + GetEffectivePermissions + GetViewports)
|
||||
- data-ana gRPC(ai11 P4,但 studentDashboard 聚合需要,P3 用 mock)
|
||||
- **Mock 策略**:
|
||||
- MSW 拦截 `POST /api/v1/student/graphql`,按 operationName 返回 mock 响应
|
||||
- mock-socket 模拟 WebSocket 推送(考试延长/强制提交事件)
|
||||
- IDB 草稿恢复用真实 idb-keyval(前端可独立测试)
|
||||
- **验收标准**:
|
||||
- Dashboard 页渲染(mock 数据):upcomingHomework + upcomingExams + recentGrades 三栏
|
||||
- 考试作答页状态机完整:进入 → 作答 → 自动保存 → 提交 → 跳转结果页
|
||||
- 断网恢复:手动 offline → 作答 → 恢复网络 → 草稿自动提交
|
||||
- 防作弊采集:visibilitychange hidden 触发记录(mock 上报)
|
||||
- 多标签检测:开第二个 Tab 作答,第一个 Tab 收到警告
|
||||
- 作业提交乐观更新:提交后立即 UI 反馈,失败回滚
|
||||
- lint + typecheck 零错误
|
||||
|
||||
### P4:知识图谱 + 学情诊断
|
||||
|
||||
- **负责人**:ai14
|
||||
- **交付物**:
|
||||
- **学习路径页**(`/learning-path`):消费 `learningPath` query,知识点卡片列表 + 掌握度进度条
|
||||
- **学情诊断页**(`/dashboard/weakness`):消费 `myWeakness` query,薄弱点雷达图(recharts)
|
||||
- **学习趋势页**(`/dashboard/trend`):消费 `myTrend` query,趋势折线图(recharts)
|
||||
- **教材章节浏览页**(`/textbooks`、`/textbooks/[id]/chapters`):消费 `textbooks` + `chapters` query
|
||||
- **依赖**:
|
||||
- student-bff 扩展 content + data-ana gRPC 调用(ai04 P4)
|
||||
- content gRPC(ai09 P4,TextbookService + ChapterService + KnowledgeGraphService)
|
||||
- data-ana gRPC(ai11 P4,AnalyticsService.GetStudentWeakness + GetLearningTrend)
|
||||
- **Mock 策略**:MSW 返回固定知识点 + 薄弱点 + 趋势数据
|
||||
- **验收标准**:
|
||||
- 学习路径页渲染知识点卡片 + 掌握度(mock)
|
||||
- 学情诊断页雷达图 + 趋势折线图渲染(mock)
|
||||
- 教材章节树形导航可用
|
||||
|
||||
### P5:实时通知 + AI 辅助
|
||||
|
||||
- **负责人**:ai14
|
||||
- **交付物**:
|
||||
- **WebSocket 通知中心**(`/notifications`):
|
||||
- 消费 `myNotifications` query + `markAsRead` mutation
|
||||
- WebSocket 连接 `ws://push-gateway:8081/ws`,实时接收通知
|
||||
- 通知分类(作业/考试/成绩/系统),未读计数
|
||||
- **跨 Tab 通知同步**(BroadcastChannel `edu-notification` channel,新通知在所有 Tab 同步)
|
||||
- **AI 辅助答疑**(可选,`/ai-tutor`):
|
||||
- SSE 流式接收 AI 回答
|
||||
- 消费 ai 服务(待 ai12 P5 就绪)
|
||||
- **依赖**:
|
||||
- push-gateway WebSocket(ai02 P5,`/ws` 端点)
|
||||
- msg gRPC(ai10 P5,NotificationService)
|
||||
- ai 服务 gRPC(ai12 P5,AiService.Chat,可选)
|
||||
- **Mock 策略**:mock-socket 模拟 WS 推送(每 30 秒 1 条通知)+ MSW 返回固定 AI 响应(SSE 用 ReadableStream mock)
|
||||
- **验收标准**:
|
||||
- 通知中心实时接收 WS 推送(mock)
|
||||
- 多 Tab 同步:Tab A 收到通知,Tab B 未读计数同步更新
|
||||
- AI 辅助答疑流式输出(mock)
|
||||
|
||||
### P6:可观测性硬化 + A11y + 性能
|
||||
|
||||
- **负责人**:ai14
|
||||
- **交付物**:
|
||||
- **Sentry 错误追踪**(`NEXT_PUBLIC_SENTRY_DSN` + beforeSend PII 过滤,学生隐私合规)
|
||||
- **Web Vitals RUM**(LCP/INP/CLS/TTFB → `/api/v1/admin/web-vitals`)
|
||||
- **OTel browser SDK**(自动埋点 fetch/XHR/document load → OTLP collector)
|
||||
- **A11y 审计**(WCAG 2.2 AA:eslint-plugin-jsx-a11y + @axe-core/playwright + 对比度审计)
|
||||
- **性能优化**(bundle analyzer + size-limit CI 门禁:Remote < 80KB / CSS < 50KB)
|
||||
- **P3 未尽事项补全**(根据 ISSUE-014-03/04/05/06/07 仲裁结果补全防作弊策略、附件上传、实时事件响应、DataScope 强制执行)
|
||||
- **降级策略验证**(02 §18.2 降级策略矩阵的 12 个场景端到端验证)
|
||||
- **依赖**:
|
||||
- push-gateway WebSocket 真实就绪(ai02 P5)
|
||||
- Sentry DSN + OTel collector(基础设施)
|
||||
- 全部上游就绪(统一集成测试)
|
||||
- **验收标准**:
|
||||
- 99.9% 可用 + WCAG 2.2 AA + LCP < 2.5s / INP < 200ms / CLS < 0.1(P75)
|
||||
- Remote bundle < 80KB / CSS < 50KB
|
||||
- 12 个降级场景全部验证通过
|
||||
|
||||
---
|
||||
|
||||
## §4 依赖与就绪信号
|
||||
|
||||
- **我依赖**:⚠️ 由 ai14 自行补充(见 contract.md)
|
||||
- **我的就绪信号**:⚠️ 由 ai14 自行补充
|
||||
### §4.1 我依赖的上游就绪标志
|
||||
|
||||
| 上游 | 就绪标志 | 阻塞阶段 | 状态 |
|
||||
| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------- | ----------- |
|
||||
| packages 骨架(ai13 批次 0.15) | ui-tokens/ui-components/hooks 可 import | P2 启动 | ✅ 已就绪 |
|
||||
| teacher-portal MF Shell(ai13 P2) | exposes AppShell/GraphQLProvider/useGraphQLClient/useAuth/usePermission + shared singleton | P2 启动 | ⏳ 待 ai13 P2 |
|
||||
| api-gateway HTTP :8080(ai01 P3) | `/api/v1/student/*` 反向代理 student-bff 可用 | P3 启动 | ⏳ 待 ai01 P3 |
|
||||
| student-bff GraphQL(ai04 P3) | `POST /graphql` :3009 + 核心 Query/Mutation 可执行 | P3 启动 | ⏳ 待 ai04 P3 |
|
||||
| student-bff GraphQL schema(ai04 + ISSUE-014-02 仲裁) | `packages/shared-ts/contracts/graphql/student-bff.graphql` 创建 | P3 启动 | ⏳ 待仲裁 |
|
||||
| core-edu gRPC 50053(ai08 P3) | ExamService/HomeworkService/GradeService/AttendanceService/ClassService 全部 RPC | P3 启动 | ⏳ 待 ai08 P3 |
|
||||
| iam gRPC 50052(ai06 P2) | GetUserInfo + GetEffectivePermissions + GetViewports | P3 启动 | ⏳ 待 ai06 P2 |
|
||||
| student-bff content/data-ana 扩展(ai04 P4) | learningPath/myWeakness/myTrend/textbooks/chapters query 可用 | P4 启动 | ⏳ 待 ai04 P4 |
|
||||
| content gRPC 50054(ai09 P4) | TextbookService + ChapterService + KnowledgeGraphService | P4 启动 | ⏳ 待 ai09 P4 |
|
||||
| data-ana gRPC 50055(ai11 P4) | AnalyticsService.GetStudentWeakness + GetLearningTrend | P4 启动 | ⏳ 待 ai11 P4 |
|
||||
| push-gateway WebSocket :8081/ws(ai02 P5) | WS 连接可建立 + 推送可接收 | P5 启动 | ⏳ 待 ai02 P5 |
|
||||
| msg gRPC 50056(ai10 P5) | NotificationService.ListNotifications + MarkAsRead | P5 启动 | ⏳ 待 ai10 P5 |
|
||||
| ai 服务 gRPC 50057(ai12 P5,可选) | AiService.Chat(SSE 流式) | P5 启动 | ⏳ 待 ai12 P5 |
|
||||
| Sentry DSN + OTel collector(基础设施) | Sentry 项目创建 + OTel collector 可接收 OTLP | P6 启动 | ⏳ 待基础设施 |
|
||||
|
||||
### §4.2 我的就绪信号(供下游消费)
|
||||
|
||||
| 信号 | 就绪标志 | 消费方 |
|
||||
| ------------------------------- | --------------------------------------------------------- | ------ |
|
||||
| student-portal dev server :4001 | `pnpm dev` 启动 + 首页可访问 | 无(最前端,但 teacher-portal Shell 需加载 Remote) |
|
||||
| MF Remote 可加载 | teacher-portal Shell 可加载 `student-portal/StudentApp` | teacher-portal(ai13 P3 集成测试) |
|
||||
| 登录流程可用 | 未登录跳转 Shell `/login`,登录后回跳 student | 无 |
|
||||
| GraphQL 查询可执行 | currentUser/studentDashboard/myClasses 返回数据 | 无 |
|
||||
| 考试作答链路通 | 进入作答 → 自动保存 → 提交 → 跳转结果页 | 无 |
|
||||
| WebSocket 通知可接收 | 通知中心实时更新(mock) | 无 |
|
||||
|
||||
---
|
||||
|
||||
## §5 全并行开发说明
|
||||
|
||||
按 [matrix.md](../matrix.md) §全并行模式:
|
||||
|
||||
1. ai14 一口气完成 P2-P6 全部代码,开发期间用 MSW mock 上游
|
||||
2. 上游就绪后在 matrix.md §8 更新就绪信号(`student-portal | ai14 | :4001 可访问 + MF Remote | ⏳ → ✅`)
|
||||
3. 所有模块就绪后统一集成测试(matrix.md §9 检查清单)
|
||||
4. Mock 切换:`NEXT_PUBLIC_API_MOCKING=enabled` → `disabled`
|
||||
5. MF 切换:`NEXT_PUBLIC_MF_ENABLED=false`(P2 独立壳)→ `true`(P3 接入 Shell)
|
||||
|
||||
---
|
||||
|
||||
## §6 阶段能力累积矩阵(与 02-architecture-design.md v2 §20 对齐)
|
||||
|
||||
| 阶段 | 能力 | 关键页面/功能 |
|
||||
| ---- | --------------------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| P2 | 项目骨架 + MF Remote 配置 + MSW 基础设施 | 独立壳首页(占位) |
|
||||
| P3 | + 考试作答 + 作业提交 + 基础页面 | Dashboard / myClasses / myExams / myHomework / myGrades / myAttendance |
|
||||
| P4 | + 知识图谱 + 学情诊断 + 教材章节 | learningPath / myWeakness / myTrend / textbooks / chapters |
|
||||
| P5 | + 实时通知 + 跨 Tab 同步 + AI 辅助(可选) | notifications / ai-tutor |
|
||||
| P6 | + 可观测性 + A11y + 性能 + 降级验证 + 尽事项补全 | Sentry / RUM / OTel / WCAG 2.2 AA / bundle 门禁 |
|
||||
|
||||
---
|
||||
|
||||
## §7 关键风险与缓解
|
||||
|
||||
| 风险 | 影响 | 缓解措施 |
|
||||
| ---------------------------------------------------- | ---- | ---------------------------------------------------------------------------------------------- |
|
||||
| student-bff GraphQL schema 未就绪(ai04 P3 延迟) | 高 | MSW mock 全量 query/mutation,schema 就绪后切换;ai14 自行维护 mock schema 用于 codegen |
|
||||
| 考试作答断网恢复逻辑复杂(IDB 队列 + 服务器时间对齐)| 高 | 02 §14 已设计完整状态机 + 时间同步算法;P3 优先实现核心链路,P6 验证降级场景 |
|
||||
| MF Remote 加载失败(Shell 未就绪或版本不兼容) | 中 | 02 §3.2 已设计独立壳回退(`NEXT_PUBLIC_MF_ENABLED=false` 时独立渲染) |
|
||||
| 防作弊策略未仲裁(ISSUE-014-03/04) | 中 | P3 先实现采集 + 本地记录,P6 根据仲裁结果补全上报逻辑 |
|
||||
| 附件上传协议未仲裁(ISSUE-014-05) | 中 | P3 先实现文本作业提交,附件上传 P6 根据仲裁结果补全 |
|
||||
| 实时事件命名未确认(ISSUE-014-06) | 低 | P3 不依赖实时事件(考试作答页基于本地倒计时),P5 根据仲裁结果接入 WebSocket 实时事件 |
|
||||
|
||||
---
|
||||
|
||||
**AI Agent**: ai14(student-portal)
|
||||
**Branch**: feat-review-student-portal-docs-9yN6Av
|
||||
**Coordinator**: coord-ai
|
||||
|
||||
Reference in New Issue
Block a user