GET/POST admin/problems GET/PUT/DELETE admin/problems/:id POST admin/problems/:id/make-public GET/POST admin/contests/:contestId/problems POST admin/contests/:contestId/problems/from-public 合并了旧后端拆开的两套路由:旧 admin/problem 与 admin/contest/problem 的 GET 详情、PUT、DELETE 都只按题目 id 取、比赛是从题目推导出来的,分开没有意义, 还逼前端多传一个它未必知道的 contestId。现在共用 /admin/problems/:id。 归属判断按旧后端的口径分开:**比赛题看比赛的创建者,公开题看题目自己的创建者** (旧 ensure_created_by(problem.contest, user) vs ensure_created_by(problem, user))。 一道比赛题的 created_by 可能是克隆时的操作人,跟谁有权改它没关系。 题号唯一性的作用域也跟着走:公开题在全部公开题里唯一,比赛题在本场比赛内唯一。 删题不删测试用例目录,与旧后端一致(它把 rmtree 注释掉了):删错了还能从磁盘捞回来, 而误删的测试数据没有别处备份;孤儿目录另有清理入口。有提交记录的题目拒绝删除。 ## SQL 题目前只能编辑、不能新建 新后端**没有 SQL 判题链路** —— 旧 judge/sql_runner.py(378 行)+ sql_dispatcher.py (113 行)无对应实现,languages.ts 里也只有 C/C++/Java/Golang/JavaScript/Python3 六种。 题目页给学生看的表结构与期望结果(sql_display)要跑 SQLite 现算,算不出来就没法建题。 因此:新建 SQL 题返回 501 并说明原因;**编辑已有 SQL 题时原样保留 sqlDisplay 不动** —— 不动它比生成一个错的安全,它直接决定学生看到的期望结果。SQL 的前置校验 (必须是唯一语言、要有 sql_config、要有 SQL 标准答案)照旧执行。 实测:学生 403;缺样例/缺输入描述/SQL 混语言三条校验文案与旧后端一致; 题号重复 409、跨比赛题号互不影响;公开题加入比赛后计数归零且标签带过来; 比赛题转公开后 visible=false、contestId=null、重复转 409;删除级联正常。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
15 lines
342 B
TypeScript
15 lines
342 B
TypeScript
import type { Context } from "hono"
|
|
|
|
export function success<T>(c: Context, data: T, status = 200) {
|
|
return c.json({ data }, status as 200)
|
|
}
|
|
|
|
export function failure(
|
|
c: Context,
|
|
status: 400 | 401 | 403 | 404 | 409 | 429 | 500 | 501 | 502,
|
|
code: string,
|
|
message: string,
|
|
) {
|
|
return c.json({ error: { code, message } }, status)
|
|
}
|