feat(阶段3): oj 侧端点铺开(基线提交,未经评审)

由外部 agent (Codex) 在本会话额度中断期间完成。原样提交作为基线,
后续修复单独成 commit,便于区分与回退。

覆盖 oj 侧 65 个端点,新增 9 组路由(account/achievement/ai/classroom/
content/contest/flowchart/problemset/site)与对应 Zod 契约。

已核验:tsc --noEmit 退出码 0;API 可启动;/api/problems 返回真实数据;
judge 与 flowchart worker 均 ready。
未核验:权限边界与数据泄露,评审进行中。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-07 01:25:36 -06:00
parent ec274419c3
commit 8c00cdc947
52 changed files with 4273 additions and 300 deletions

View File

@@ -1,6 +1,5 @@
import { userProfileSchema } from "@oj2/contract"
import api2 from "utils/api2"
import http from "utils/http"
import type { ApiResponse } from "utils/http"
import type { Profile, Tag } from "utils/types"
@@ -13,7 +12,7 @@ export function signup(data: {
email: string
password: string
}) {
return http.post("register", data)
return api2.post("users", data)
}
export function logout() {
@@ -23,9 +22,9 @@ export function logout() {
export async function getProfile(
username: string = "",
): Promise<ApiResponse<Profile | null>> {
if (username) return http.get<Profile>("profile", { params: { username } })
const response = await api2.get<unknown>("me")
const response = await api2.get<unknown>(
username ? `profiles/${encodeURIComponent(username)}` : "me",
)
if (response.data === null) return { error: null, data: null }
const profile = userProfileSchema.parse(response.data)
return {
@@ -61,13 +60,13 @@ export async function getProfile(
}
export function getProblemTagList() {
return http.get<Tag[]>("problem/tags")
return api2.get<Array<Tag & { problemCount: number }>>("problem-tags")
}
export function getHitokoto() {
return http.get("hitokoto")
return api2.get("quotes/random")
}
export function getClassUsernames(classroom: string) {
return http.get("class_usernames", { params: { classroom: classroom } })
return api2.get(`classes/${encodeURIComponent(classroom)}/usernames`)
}

View File

@@ -448,8 +448,10 @@ export interface FlowchartEvaluationUpdate extends WebSocketMessage {
*/
class FlowchartWebSocket extends BaseWebSocket<FlowchartEvaluationUpdate> {
constructor() {
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"
super({
path: "flowchart", // 使用专门的 flowchart WebSocket 路径
path: "flowchart",
url: `${protocol}//${window.location.host}/ws2/submissions`,
})
}