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

@@ -0,0 +1,41 @@
import { sessionUserSchema, userProfileSchema } from "@oj2/contract"
import { and, eq } from "drizzle-orm"
import { db, schema } from "../db"
export async function getUserProfileById(userId: number, showRealName: boolean) {
const [row] = await db
.select({ profile: schema.userProfile, user: schema.user })
.from(schema.userProfile)
.innerJoin(schema.user, eq(schema.userProfile.userId, schema.user.id))
.where(and(eq(schema.user.id, userId), eq(schema.user.isDisabled, false)))
.limit(1)
if (!row) return null
return userProfileSchema.parse({
id: row.profile.id,
user: sessionUserSchema.parse({
id: row.user.id,
username: row.user.username,
email: row.user.email,
adminType: row.user.adminType,
problemPermission: row.user.problemPermission,
createTime: row.user.createTime,
lastLogin: row.user.lastLogin,
openApi: row.user.openApi,
isDisabled: row.user.isDisabled,
className: row.user.className,
}),
realName: showRealName ? row.profile.realName : null,
acmProblemsStatus: row.profile.acmProblemsStatus,
avatar: row.profile.avatar,
blog: row.profile.blog,
mood: row.profile.mood,
github: row.profile.github,
school: row.profile.school,
major: row.profile.major,
language: row.profile.language,
acceptedNumber: row.profile.acceptedNumber,
submissionNumber: row.profile.submissionNumber,
})
}