submission 新增 problemset_id,学生从 /problemset/:id/problem/:pid 入口提交时 前端带上、后端落库,提交列表在题目后面挂一个「题单 xxx」的标签,点了进题单。 只是来源标记:题单进度和奖章仍由判完之后的 recordSolvedProblem 按「已加入且含 这道题的所有题单」记账,和从哪个入口进来无关,所以这个字段带错顶多标签不准, 不影响成绩。校验只确认这道题在那个题单里 —— 不查 visible / status、也不查有没有 加入,藏起来的题单里还困着已加入的学生;对不上就当没带,提交照收。 外键 ON DELETE SET NULL:删题单不该带走提交,清掉标记就行。索引建成部分索引 (WHERE problemset_id IS NOT NULL),绝大多数提交不来自题单,全列索引是给 12 万行 白建一遍;谓词能被 problemset_id = $1 蕴含,删题单时的外键检查也用得上它。 列表按页单独查一次题单标题,没有把 problemset join 进那条调过的深翻页查询。 比赛提交恒为 null:题单只收非比赛题。 历史回填从 problemset_submission 取「当年首次 AC 那条」,其余老提交无从判断入口, 一律留空。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7AsqceaUfC81k7UCDcSk2
This commit is contained in:
@@ -22,6 +22,15 @@ export const createSubmissionRequestSchema = z.object({
|
||||
language: z.string().min(1).max(32),
|
||||
code: z.string().min(1).max(1024 * 1024),
|
||||
contestId: z.number().int().positive().optional(),
|
||||
/**
|
||||
* 来源题单。学生从 `/problemset/:id/problem/:pid` 那个入口提交时前端带上,
|
||||
* 后端落进 `submission.problemset_id`,提交列表据此标出「这条是刷题单刷出来的」。
|
||||
*
|
||||
* 只是**来源标记**,不参与判题、也不参与题单进度记账 —— 进度由判完之后的
|
||||
* `recordSolvedProblem` 记进所有已加入且含这道题的题单,和从哪个入口进来无关。
|
||||
* 所以这里带错了顶多是标记不准,不会影响成绩。
|
||||
*/
|
||||
problemSetId: z.number().int().positive().optional(),
|
||||
})
|
||||
|
||||
export const createSubmissionResponseSchema = z.object({
|
||||
@@ -96,6 +105,12 @@ export const submissionListItemSchema = z.object({
|
||||
language: z.string(),
|
||||
shared: z.boolean(),
|
||||
statisticInfo: z.record(z.string(), z.unknown()),
|
||||
/**
|
||||
* 来源题单,非题单入口提交的为 null。比赛提交恒为 null(比赛题不会进题单)。
|
||||
* 历史提交里只有「当年首次 AC 那一条」有值 —— 迁移 0007 从 problemset_submission
|
||||
* 回填的就是这些,其余老提交无从判断入口,一律留空。
|
||||
*/
|
||||
problemSet: z.object({ id: z.number().int(), title: z.string() }).nullable(),
|
||||
})
|
||||
|
||||
export const submissionListSchema = paginatedSchema(submissionListItemSchema)
|
||||
|
||||
Reference in New Issue
Block a user