Skip to content

feat: 微人大 web 登录 + 课程成绩展示#6

Merged
HuanCheng65 merged 2 commits into
mainfrom
feat/web-login-and-course-grades
Jun 24, 2026
Merged

feat: 微人大 web 登录 + 课程成绩展示#6
HuanCheng65 merged 2 commits into
mainfrom
feat/web-login-and-course-grades

Conversation

@HuanCheng65

Copy link
Copy Markdown
Contributor

让学生用微人大(CAS RUC)在网页上直接登录(不依赖 CLI/密钥),登录后只读查看自己在某个 Lab 的最终课程成绩。成绩由助教在外部算好(CSV),经 Admin 导入 LabKit,学生在 Web 端查看。

Web 登录

  • 复用现有微人大 OAuth provider / browser session;新增一条不碰 device_auth_requests、不建 user_key 的 web 登录路径:微人大 → 学号 → UpsertUser(student_id) → 签发 browser session。
  • GET /auth/login 生成 CSRF state(double-submit cookie)并 302 到微人大;复用的 /api/device/verify 回调按 labkit_oauth_state cookie 是否匹配 ?state= 分流到 web 登录,否则维持原有 device flow(逻辑不变)。
  • browser session 增加 Source 标记;web 会话不绑 key。/auth/login 在 vite(dev)与 Caddy(prod)中代理到 API。
  • web 会话严格只读:Source=="web" 在 profile 写接口(改昵称/赛道)返回 403;device 会话与 CLI 签名照常可写。submit/keys/board 本就只认 key,web 会话进不去。

课程成绩

  • 新表 final_grades(lab_id, student_id,总评 + 分项,published_at 控制可见性)。
  • grade service:CSV 导入(按表头列名匹配,列序无关、容错)、发布、仅返回已发布成绩、清空重导。
  • GET /api/labs/{labID}/grade(browser session 优先,CLI 签名兼容)。
  • Admin(adminGuard):POST .../grades/importPOST .../grades/publishDELETE .../grades

前端

  • LoginView(微人大登录,自动判断已登录态)、GradeView(总评 + 分项 + 计分公式 + 备注;404 → 成绩尚未发布,401 → 引导登录),路由 /login/grade/labs/:labID/grade,导航加 "Grade" 入口。

顺带修复

  • apps/migrateTestBaselineMarksLegacyDatabaseWithoutReplayingMigrations 此前既有失败:其 applyLegacyMigrations 把所有迁移先全跑一遍,再从 baseline 7 重放,撞上非幂等的 0008。现支持只应用到指定版本,使 Baseline(7)+Up() 等价于正常前向序列。同步把全量迁移计数断言 10 → 11 并新增 final_grades 存在性校验。

验证

  • Go 全工作区 go test ./... 通过(含修复后的 migrate baseline 测试);新增单测覆盖 web 登录分流、CSRF、成绩 service/handler、web 会话只读 403、admin 导入/发布/删除。
  • 迁移链在真实 Postgres 16/18 跑通(未发布隐藏 → 发布可见 → down 删表)。
  • 前端 76/76 vitest 通过,生产构建成功。

已知/取舍

  • browser session 仍为内存态(沿用既有限制)→ 需单实例部署;后续可落库/Redis。
  • 默认成绩页 lab 为 colab-2026-p2(可用 ?lab=/labs/:id/grade 覆盖);成绩页只展示 remark,不含申诉入口/排名。

🤖 Generated with Claude Code

HuanCheng65 and others added 2 commits June 24, 2026 19:08
Add a browser-only 微人大 login path and a read-only course-grade view so
students can sign in on the web (no CLI/key) and see their externally-computed
final grade for a lab.

Web login:
- auth.BuildWebLoginAuthorizeURL / HandleWebLoginCallback (UpsertUser by
  student_id; no device_auth_requests, no user_key)
- GET /auth/login mints a CSRF state (double-submit cookie) and redirects to
  微人大; the shared /api/device/verify callback routes to web login when the
  labkit_oauth_state cookie matches, else falls through to the device flow
- browser session gains a Source marker; web sessions are key-less
- /auth/login proxied via vite (dev) and Caddy (prod)

Final grades:
- final_grades table (lab_id, student_id, total + breakdown, published_at)
- grade service: CSV import (header-matched), publish, published-only read
- GET /api/labs/{labID}/grade (browser session or CLI signature)
- POST /api/admin/labs/{labID}/grades/{import,publish} under adminGuard

Frontend:
- LoginView (微人大登录) and GradeView (total, breakdown, formula, remark;
  404 -> 成绩尚未发布, 401 -> login), /login, /grade, /labs/:labID/grade

Submit/keys/board stay key-only; web sessions can't reach them. Bumped the
migrate runner migration-count assertion 10 -> 11.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…baseline test

- Reject read-only web-login sessions (Source=="web") on profile write
  endpoints (UpdateProfile/Nickname/Track) with 403; device-paired sessions
  and CLI signatures still write. Submit/keys/board were already key-only.
- Add DELETE /api/admin/labs/{labID}/grades (DeleteGrades) under adminGuard so
  a corrected grade CSV can be re-imported cleanly.
- Fix pre-existing failure in apps/migrate runner: applyLegacyMigrations now
  applies only up to a given version, so Baseline(7)+Up() replays 8+ as the
  normal forward sequence instead of re-running non-idempotent migration 0008.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@HuanCheng65 HuanCheng65 merged commit 88e240c into main Jun 24, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant