feat(题单): 「截止时间」改成「布置期」,布置期内没加入的人也藏旧代码;老师能看全班情况,后台一次加好几道题

- 布置期(列名仍是 end_time,机房共库不改名)+ 新列 assigned_at:布置期内题单里这几道题,
  学生在布置开始之前交的代码先藏起来,不管加没加入,堵住「先抄再加入」;做对或到期放出来,不拦做题
- 「总分达到 N」奖章换成「做对 N 道」,草稿并进「不公开」(0026)
- /problem-sets 带布置期、必做题数、奖章获得时间;题目带做对时刻、错几次、旧代码藏着没有
- 新增 /problem-sets/:id/class-view(老师看一个班:真名 × 每题,加入前就做对过)、/problem-sets/locks
- 后台:批量加题、拖动排序、切必做;去掉状态、难度、分数、提示和单独的进度页

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-09 22:01:39 +08:00
1 parent 2224478294
commit 8c53e28dcb
11 files changed
+4958 -617

No files matched your search

+11 -1
View File
@@ -417,7 +417,17 @@ export const problemset = pgTable(
difficulty: text().notNull().$type<ProblemSetDifficulty>(),
status: text().notNull().$type<ProblemSetStatus>(),
createdById: integer("created_by_id").notNull(),
endTime: timestamp("end_time", { withTimezone: true, mode: "string" }),
/**
* 布置期:assignedAt 是这一轮布置开始的时刻,assignedUntil 是布置到哪天(东八区当天结束)。
* 布置期内,题单里这几道题学生在 assignedAt 之前交的代码先藏起来(防抄),见
* services/problemset.ts 的 problemSetLockCutoffs。不拦做题,过期照样做、照样记进度。
* 两个都为空 = 没布置。
*
* 列名还是 end_time(以前叫「截止时间」,名不副实):机房那套和服务器共用这个库、
* 不一定同时升级,改列名会让没升级的那边一查题单就报错,所以只改代码里的名字
*/
assignedUntil: timestamp("end_time", { withTimezone: true, mode: "string" }),
assignedAt: timestamp("assigned_at", { withTimezone: true, mode: "string" }),
},
(table) => [
index("problemset_created_by_id_01b5197f").using(