feat(阶段4): SQL 测试点脚本回显

GET admin/problems/:id/sql-scripts

只读磁盘上的 N.sql,不需要 SQL 引擎 —— 同组的 sql-preview / sql-ai-gen 要跑 SQLite
生成展示数据,新后端还没有那条链路,那两个仍指向旧后端。

实测:SQL 题回显两个脚本内容正确;测试点不是 SQL 类型返回 409 并说明;题目不存在 404。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-07 16:45:15 -06:00
parent cd5dd16f3b
commit 007ae8619b
3 changed files with 33 additions and 4 deletions

View File

@@ -6,6 +6,7 @@ import {
createProblemRequestSchema,
makeProblemPublicRequestSchema,
updateProblemRequestSchema,
sqlTestCaseScriptSchema,
uploadTestCaseResponseSchema,
} from "@oj2/contract"
import { and, count, desc, eq, ilike, inArray, isNull, ne, or, sql } from "drizzle-orm"
@@ -16,7 +17,7 @@ import type { AuthUser } from "../../auth/session"
import { db, schema } from "../../db"
import { failure, success } from "../../http"
import { contestStatus } from "../../services/contest"
import { packTestCaseZip, processTestCaseZip, TestCaseError } from "../../services/test-case"
import { packTestCaseZip, processTestCaseZip, readInfo, readSqlScripts, TestCaseError } from "../../services/test-case"
import { objectValue, queryInteger, sampleUser, stringArray } from "../helpers"
export const adminProblemRoutes = new Hono<AppEnv>()
@@ -569,3 +570,27 @@ adminProblemRoutes.get("/problems/:id/test-cases", requireProblemPermission, asy
throw error
}
})
/**
* 回显 SQL 题已上传的测试点脚本内容。只读磁盘上的 N.sql不需要 SQL 引擎 ——
* 同组的 sql-preview / sql-ai-gen 要跑 SQLite 生成展示数据,新后端还没有那条链路,
* 那两个仍在旧后端上。
*/
adminProblemRoutes.get("/problems/:id/sql-scripts", requireProblemPermission, async (c) => {
const [problem] = await db.select().from(schema.problem)
.where(eq(schema.problem.id, queryInteger(c.req.param("id"), 0, { min: 1 }))).limit(1)
if (!problem) return failure(c, 404, "problem-not-found", "Problem does not exists")
if (!(await canEdit(c.get("user")!, problem))) {
return failure(c, 404, "problem-not-found", "Problem does not exists")
}
const info = await readInfo(problem.testCaseId)
if (!info) return failure(c, 404, "test-case-info-unreadable", "测试点信息读取失败")
if (!info.sql) return failure(c, 409, "not-sql-test-case", "该题的测试点不是 SQL 类型")
try {
const scripts = await readSqlScripts(problem.testCaseId)
return success(c, scripts.map((script) => sqlTestCaseScriptSchema.parse(script)))
} catch (error) {
console.error("Failed to read SQL test case scripts", error)
return failure(c, 500, "test-case-error", "测试点脚本读取失败")
}
})