refactor(WebSocket): 判题/流程图推送改用驼峰,去掉没人读的三个字段

submission_id / time_cost / memory_cost / err_info 是 OJ2 两端自己定的线上格式,
没有第三方消费(/ws/submissions 只有 apps/web 一个客户端),没理由留着 snake。
flowchart 那条更别扭:同一个对象里 submission_id 是 snake、criteriaDetails 是驼峰。

三个字段直接删掉而不是改名 —— 它们是从 statistic_info 原样抄出来的一份,前端
一处都没读过(useSubmissionMonitor 只用 submissionId / result / status)。耗时和
错误信息在提交详情里本来就有,判完了去拉一次就是,不必让推送顺带背一份 JSONB
的形状。score 保留,它不涉及大小写。

**没动的都是有外部约束的**,别顺手一起改:

- 发给判题沙箱的请求体(language_config / max_cpu_time / max_memory /
  test_case_id / io_mode)和它回的字段(cpu_time / memory / test_case)——
  那是沙箱的 API,不是我们的
- 测试点 info 文件的键,沙箱直接读那个文件
- submission.statistic_info 里的 time_cost / err_info / ast_results ——
  判题机按这套写,12 万条历史提交就是这形状
- acm_problems_status、progress_detail 这些存量 JSONB
- AST 规则键(for_loop)、成就指标(accepted_count)、reaction 语义键 ——
  那是词汇表标识符不是字段名,for_loop 还要映射到 tree-sitter 的 while_statement

验证:起 dev 栈(api + worker + 沙箱),学生账号真提一次代码,抓 /ws/submissions
的帧:

    {"type":"submission_update","submissionId":"bf13b7f0…","result":6,"status":"pending"}
    {"type":"submission_update","submissionId":"bf13b7f0…","result":7,"status":"judging"}
    {"type":"submission_update","submissionId":"bf13b7f0…","result":-2,"status":"finished","score":0}

subscribe 帧也换成 submissionId 并被接受(否则会回一个 error 帧,没有)。
流程图那条路径要 AI 评分才跑得起来,本机没配,只做了类型检查。

前后端同一个 docker 栈一起构建部署,没有版本错配窗口。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-27 00:48:54 -06:00
parent bc0b782443
commit 6ac458e6f3
7 changed files with 29 additions and 39 deletions

View File

@@ -78,7 +78,7 @@ export const flowchartUpdateSchema = z.object({
"flowchart_evaluation_failed",
"flowchart_evaluation_update",
]),
submission_id: z.string(),
submissionId: z.string(),
score: z.number().optional(),
grade: z.string().optional(),
feedback: z.string().optional(),

View File

@@ -68,15 +68,20 @@ export const embeddedSubmissionSchema = submissionDetailSchema
// 站内信页面拿它拼 `/problem/<题号>` 链接,给数字 id 会拼出打不开的地址。
.extend({ problem: z.string() })
/**
* 判题进度推送。**只带前端真正要用的东西**:靠 submissionId 认领、靠 result /
* status 决定是继续等还是去拉详情。
*
* 这里曾经还带着 time_cost / memory_cost / err_info —— 从 statistic_info 原样
* 抄一份出来,前端一处都没读过。耗时和错误信息在提交详情里本来就有,判完了去
* 拉一次就是了,不必让推送顺带背一份 JSONB 的形状。
*/
export const submissionUpdateSchema = z.object({
type: z.literal("submission_update"),
submission_id: z.string(),
submissionId: z.string(),
result: judgeStatusSchema,
status: z.enum(["pending", "judging", "finished", "error"]),
time_cost: z.number().optional(),
memory_cost: z.number().optional(),
score: z.number().optional(),
err_info: z.string().optional(),
})
export const submissionListItemSchema = z.object({